Campaigns

Post-Purchase offers in depth - accept, decline & downsell

How the two-stage post-purchase offer surface works — the main offer, the downsell fallback, one-click order edits, and every error a customer can hit.

This is the behavior-and-mechanics companion to the Post-Purchase setup guide. The setup page walks you through creating an offer; this page explains exactly how the offer behaves once a customer reaches it: where the offer page lives, the two-stage main-then-downsell flow, how an accepted offer is stitched into the order they just placed without a second payment, and the precise error states a customer can run into. If you have ever wondered "what does my customer actually see and do here, step by step," this is the page.

For how the app decides which post-purchase campaign wins, how priority is ranked, and how the countdown timer and skip button are configured, see the priority, downsell & timer page. This page does not repeat the campaign-creation steps.

The post-purchase surface

The post-purchase offer is not part of your storefront or your theme. It renders on Shopify's native post-checkout page — the page Shopify itself shows in the brief window after the customer's payment is taken but before the thank-you (order confirmation) page loads. The order has already been placed and paid for by the time the offer appears, which is what makes the one-click accept possible.

A few properties of this surface are worth understanding because they shape everything else on this page:

  • No theme editing. Because the offer lives on Shopify's own post-checkout page, you never place a block or widget in your theme. Activating a Post-Purchase campaign is all it takes for the offer to appear in the flow.
  • Isolated iframe. The offer renders inside an isolated frame on Shopify's page. Your theme's CSS cannot leak in and change the offer, and the offer's styles cannot leak out into the rest of the post-checkout experience. This is also why button colors come from Shopify's checkout editor rather than this app's customizer — see the Post-Purchase customizer reference for that split.
  • One offer page per order. A customer sees at most one post-purchase offer page for a given order. Shopify shows this surface a single time in the flow, so you get exactly one chance to present an offer (a main offer, and optionally its downsell) for each completed checkout.

Because the offer never appears until payment is complete, it can never interrupt or jeopardize the original sale. The worst case for the customer is that they skip it and continue to the thank-you page exactly as they would have anyway.

Two-stage flow: main offer, then downsell

Every post-purchase offer page is a two-stage experience: a main offer first, and — only if the customer declines — a downsell offer. The two are never shown at the same time. The page starts on the main offer and only switches to the downsell on a decline.

Here is the full flow from the moment checkout completes:

The main offer renders

When checkout completes, the app shows the main offer first. The products come from the winning campaign's condition — the offer products you chose on the campaign, together with that campaign's per-variant discount settings and quantity settings. This is the primary upsell; it is what the customer sees the instant the order is placed.

Accept adds it to the order

If the customer accepts, the offered product is added to the order they just placed in a single click — no re-entered payment details, no second checkout. The page then closes and the customer continues to the thank-you page. The downsell never loads, because the customer already converted.

Decline (Skip) lazily fetches the downsell

If the customer declines (taps the Skip / decline button), the app lazily fetches the campaign's downsell offer. The downsell is a separate fallback configured on the same campaign with its own products, its own discount settings, and its own quantity settings — none of which are inherited from the main offer. The view then switches from the main offer to the downsell.

The downsell renders, or the page simply closes

If the downsell has products to show, it renders as a second-chance offer. If the campaign has no downsell products configured (or none that are showable), there is nothing to render, so the page simply closes and the customer goes straight to the thank-you page — there is no empty downsell screen and no extra step.

The downsell is fetched only at the moment of decline, not up front. That means the downsell reflects inventory and availability at the time the customer declines — not at the time the page first loaded. A downsell variant that sells out between page load and the decline will be filtered out by the time the downsell is requested.

How the offer is added to the order

When a customer accepts a post-purchase offer, the app does not run a second checkout. Instead it uses Shopify's one-click changeset mechanism to edit the order that was just placed. The sequence is:

A changeset is built

The app assembles a changeset describing the change to apply — add the selected variant at the chosen quantity, optionally carrying a discount, and tagging the change with the campaign so the added item can be attributed back to your campaign.

The token is signed server-side

The changeset is sent to the app's server to be signed, producing a secure token. Signing happens on the server, not in the browser, so the change cannot be tampered with on the customer's device. This is what keeps the one-click accept tamper-proof.

Shopify applies the change to the just-placed order

The signed token is handed to Shopify, which applies the change directly to the order the customer just completed. Because the order already exists and is already paid, no payment is re-entered — the new line item is simply added to that order.

The accepted offer's discount

If the offer carries a discount, it is applied per variant as part of the same changeset. Two discount types are supported:

Discount typeWhat it doesExample
PercentageTakes a percentage off the variant's price.15% off a $40 add-on → customer pays $34
Fixed amountTakes a fixed currency amount off the variant's price.$5 off a $20 accessory → customer pays $15

The discount is configured on the offer (main offer or downsell, each independently) and is applied automatically the moment the customer accepts — there is no code for the customer to enter.

When acceptance can fail

Most accepts succeed instantly. But because the change is applied to a live, already-paid order against live inventory, a customer can occasionally hit an error when they tap accept. When that happens the app shows a short message and the offer is not added. The exact messages, and what each one means, are below — use this table when a customer reports a confusing post-purchase error.

Message the customer seesWhat it meansWhat to tell the customer / what to check
Insufficient inventoryThe offer variant sold out in the gap between when the offer page loaded and when the customer tapped accept.The item is no longer in stock. Restock the variant or remove it from the offer. Stock-sensitive offers are most exposed to this.
Payment method is not supportedThe payment method used at checkout cannot have a post-purchase change applied to it.The order's payment method does not allow post-purchase edits. See Post-Purchase eligibility & payment-method limits for which methods and order shapes are supported.
Payment is not completeThe original payment has not finished processing, so the order cannot be edited yet.Payment is still settling. The customer should not be charged extra; the offer simply cannot be applied to an unsettled order.
Purchase has already been appliedThe changeset was already applied to this order — typically a double-submit, or the offer was already accepted.The item was already added; tapping accept again is a no-op. This protects against accidental double-adds.
Invalid purchaseThe change request was rejected as invalid.The offer could not be applied as requested. Re-check the offer's variant and discount configuration.
Something went wrongA catch-all for any error not covered by the specific cases above.An unexpected error occurred. The order itself is unaffected; the customer can continue to the thank-you page.

A change can also come back as partially processed rather than fully processed. The app treats a partial result the same as success — the change still completes and the page closes to the thank-you page. The customer does not need to retry, and you do not need to take any action.

Why these errors are normal (and rare)

Post-purchase edits operate on a real order and real, live inventory in the seconds after checkout. That is exactly why the offer can be accepted in one click — but it is also why a handful of edge conditions (a variant selling out in the last few seconds, a payment method that does not support edits, a payment still settling) can block an individual accept. None of these affect the original order, which is already placed and paid; they only stop the additional item from being added.

Downsell recipes

The downsell shines when its product or discount is meaningfully different from the main offer — a cheaper or smaller alternative, usually with a deeper or differently-shaped discount. Because the downsell has its own products, discount, and quantity settings, you can tune it as a genuine second-chance deal.

Give the downsell its own headline and body copy in the customizer's declined-state fields so it reads as a fresh offer rather than a repeat of the one the customer just turned down. The declined-state title and description fields, and the full customizer reference, are on the Post-Purchase customizer page.

Edge cases

These are the boundary behaviors that surprise merchants most often. Each is intentional.

Troubleshooting

On this page