Price testing (Shopify)
A price test shows different prices for the same Shopify products to different groups of visitors. You measure which price earns the most revenue or profit per visitor. You can run it as an A/B test, splitting traffic randomly, or as a personalization, showing a price to a specific audience. Shoppers pay the price they were shown at checkout.
Available on: Shopify Online Store. Headless (Hydrogen) storefronts: contact support. Plan: price campaigns must be included in your plan. Available as: A/B test · Personalization
Test or personalize. You can run a price campaign as an A/B test, where visitors are split at random and you measure which version wins, or as a personalization, where each variation is shown to a specific audience, with an optional control group to measure the lift. The setup is the same; Personalizations covers what's different.
How it works
- You pick products and set rules per variation. For each variation you set a fixed price, or an increase or decrease by an amount or a percentage, at product or variant level. See Price rules and rounding.
- Visitors are assigned once and stay assigned. On the first page view where the campaign applies, the snippet buckets the visitor into control or a variation. The assignment is stored in the visitor's browser and reused on every later page. See How visitors are assigned.
- Prices are repainted on the storefront. The snippet finds the price, compare-at price, savings and savings % elements of every campaign product. It uses your price selectors to find them, then rewrites them in your shop's money format. This covers product pages, collection grids, recommendations, quick views and Personizely product widgets. Price elements of campaign products stay hidden until they've been rewritten, so visitors don't see the original price flash.
- The cart and checkout charge the variation price. How this happens depends on the strategy Personizely picks for your store.
- Orders are attributed server-side. The snippet writes the visitor's campaign and variation into a cart attribute (__campaignVariations). When the order comes in through Shopify's webhook, Personizely credits it to that variation. Revenue, profit (if you track cost of goods) and AOV show up per variation in the report. See Revenue attribution.
Strategies
Personizely picks one of two strategies when you create the campaign, based on your Shopify plan. You don't configure it.
| Cart transform | Duplicate products (clones) |
|---|---|---|
Used on | Shopify Plus, Plus trial and development stores | All other Shopify plans, and any campaign with Products with subscriptions or bundles turned on |
How checkout gets the new price | A Shopify Function (Cart Transform) sets the line price at checkout from the cart attribute | Personizely creates an unlisted copy of each product per variation with the new prices, and the visitor buys the copy |
Product catalog | Unchanged | One hidden duplicate per product per variation |
Compare-at price at checkout | Storefront only (Shopify Functions can't change compare-at) | Written to the duplicate, so shown everywhere |
Setup before launch | None | Inventory, shipping profiles, discounts and apps may need adjusting. See Duplicate products |
The strategy is saved on the campaign. If you upgrade to Shopify Plus later, existing campaigns keep the clone strategy; new campaigns use cart transform.
Cart transform (Shopify Plus)
When your first cart-transform campaign starts, Personizely activates its Cart Transform function in your store. It deactivates the function when no such campaign is running. At checkout, the function sets each matching line to the visitor's variation price, converted to the checkout currency. Price edits take effect within seconds of saving.
Duplicate products (all other plans)
Each variation gets a duplicate of every campaign product. Duplicates keep all of the original product's tags and are also tagged ply_campaign_<campaignId>, ply_campaign_variation_<variationId> and ply_source_product_<productId>. They're Unlisted while the campaign runs and Archived while it's paused or stopped. Visitors stay on the original product URL. When they add to cart, the duplicate's matching variant goes into the cart instead of the original, so the duplicate is what's bought. This works with standard theme product forms, AJAX carts and headless storefronts. Links to a duplicate's URL are rewritten to the original, and direct visits to a duplicate redirect back to the original.
With Products with subscriptions or bundles turned on (redirect mode), visitors on the original product page are instead redirected to their variation's duplicate. Use this when a subscription or bundle app has to see the duplicate on the product page. Selling plans and bundle settings aren't copied, so configure them on each duplicate in that app.
Set up a price test
- Go to Campaigns → New campaign → Product price, and choose Experiment or Personalization.
- Select the products to include.
- For each variation, add price rules for the whole product or for specific variants.
- Choose goals. Purchase with Revenue per visitor or Profit per visitor as the primary metric is usually what you want.
- Check that prices are detected on your theme: Settings → Campaigns, under the product selectors. Presets exist for Dawn, Taste, Trade, Spotlight, Craft, Colorblock, Sense, Refresh, Origin, Studio, Ride, Publisher and Crave. Custom themes may need their own selectors.
- Preview each variation, then go through the price test QA checklist.
- Start the campaign.
Option | What it does | Values / default |
|---|---|---|
Products | Products included in the test | Any products in your catalog |
Price rule: target | What the rule changes | Price, Compare-at price |
Price rule: action | How the price changes | Set, Increase, Decrease |
Price rule: method | How the value is read | Fixed amount (store currency, converted per market) or Percentage |
Price rule: rounding | Rounds the result; ignored for Set | None, Round, Round with .99, Round upward, Round upward with .99 |
Products with subscriptions or bundles | Forces the duplicate strategy and redirects visitors to the duplicate's URL | Off |
Target mode | Whether the audience is re-checked on every page | Always Permanent for price tests, so a shopper never sees the price change back |
Traffic allocation | Share of eligible visitors who enter the test | 100% |
Behavior details and limitations
- A variant with its own rule uses only that rule. Product-level rules apply only to variants that have no rule of their own, and a variant with neither keeps its original price. On collection cards, where no variant is selected, the product-level rule (or the default variant's rule) is shown.
- Prices are read from the page. The original price comes from the element's data-price attribute if present, otherwise from its text. Add data-price if your theme formats prices in unusual ways.
- Opting an element out. Add data-ply-transform-skip="true" to a price element you don't want rewritten.
- One price campaign per product. Nothing stops you from putting the same product in two running price campaigns, but on the storefront the first campaign to rewrite an element wins. Results for both would be unreliable.
- Lowering traffic allocation mid-test removes visitors. Allocation is re-checked on every page, so already-exposed visitors can drop out of the test.
- Store currency and markets. Fixed amounts are in your store's base currency and are converted to the visitor's market currency. Percentage rules apply to the market price.
- Deleting a source product stops the campaign. You'll get an email ("Campaign stopped: Product was deleted"). A duplicate deleted outside Personizely is recreated the next time the campaign is activated.
- Duplicates follow price changes. When you change a source product's price in Shopify, relative rules (increase or decrease) are re-applied to its duplicates. Set rules stay as entered.
- Reports use the original products. Purchases of duplicates are mapped back to the original product and variant IDs in Personizely's reports. In Shopify's own reports they appear under the duplicate.
- Deploying a winner is permanent. Deploy writes the winning variation's prices to your real Shopify products. It can't be undone, and the campaign can't be restarted (clone it instead).
- Preview doesn't change checkout. A preview link (?ply_preview_campaign=<campaignId>.<variationId>) outlines rewritten prices in red so you can see what changed. The checkout price only changes for a running campaign.
Troubleshooting
- Price doesn't change on some pages → the element isn't matched by your price selectors, or it isn't inside an element with a product ID. Add the selector in Settings → Campaigns, or add data-product-id to the card's root element.
- Product page shows the new price, but the cart shows the old one (duplicate strategy) → your theme or a cart app adds to cart in a way the snippet doesn't intercept. Contact support with the product URL.
- Checkout shows the original price (cart transform) → the cart attribute wasn't set, usually because a custom cart drawer creates the cart through its own API call. Check that __campaignVariations is present in the cart (/cart.js).
- Duplicates appear in search results → exclude products tagged ply_campaign_ in your search app.
Running it as a personalization
- One target per variation, first match wins. Each variation has its own target, and a visitor gets the first variation in the list whose target they match. Put narrow audiences above broad ones. A visitor who matches no variation sees your original prices.
- Control group. 25% of matched visitors by default see and pay your original prices and are counted as control, so you can check that a lower price pays for itself.
- Always Permanent. Price personalizations always use Permanent targeting: once a visitor gets a price, they keep it, even if they stop matching the target, so the price never changes back during their visit.
- No deploy. Personalizations can't be deployed, so the report has no Deploy. A personalization keeps running until you stop it, and you can edit its variations and targets as needed. To stop measuring and show it to every matching visitor, set the control group to 0%. To make a personalized price your real price for everyone, change it in Shopify.
- Example audiences: lower prices for one market or country, using the Market filter or the Location filter; or VIP pricing for customers tagged vip, using the Customer filter.
Examples
- Find the best price point: control at $49, variation A at $43.99 (−10%, rounded with .99), variation B at $54. Primary metric: profit per visitor.
- Free-shipping-threshold interplay: raise the price of a bestseller to $52 so typical carts cross a $50 free-shipping threshold. Measure AOV and revenue per visitor.
- Market-specific pricing: a personalization that shows a lower price to visitors in one country, with a 25% control group to measure the lift.