Documentation Index
Fetch the complete documentation index at: https://docs.launchmystore.io/llms.txt
Use this file to discover all available pages before exploring further.
Post-Purchase Bridge
Post-purchase extensions render between order-placement and the order-confirmation page. They run as same-origin iframes inside CustomerLMS at the/checkout/post-purchase route. The host implements
a strict subset of the full App Bridge action set — anything that
would interfere with order finalisation (modals, contextual save bars,
admin chrome) is intentionally absent.
This page is the action-by-action reference for that subset. For end-
to-end concepts (manifest shape, sandbox flags, mount lifecycle) see
Post-Purchase Extensions.
Initializing
Post-purchase iframes are same-origin, socreateApp({ host: 'post-purchase' })
is the canonical setup — the SDK detects the sentinel and uses
window.location.origin as the host origin.
BRIDGE_PING handshake responds with { ok: true, host: 'post-purchase' }
so a single extension iframe can detect which host it’s running in and
swap behaviour:
Capability table
| Action | Post-purchase host | Notes |
|---|---|---|
BRIDGE_PING | yes | { ok: true, host: 'post-purchase' } |
ORDER_GET | yes | Read-only snapshot of the placed order |
CUSTOMER_GET | yes | Customer’s email (same shape as checkout) |
CURRENCY_GET | yes | Order currency ISO code |
CART_LINES_CHANGE | yes (addCartLine only) | Creates a follow-on order tied to the original |
REDIRECT | yes | Send the buyer to a URL (e.g. account, custom thank-you) |
DONE | yes | Finish post-purchase flow and redirect to /orders/<id> |
CLIPBOARD_WRITE | yes | iframe-side write (no host round-trip needed) |
TOAST_SHOW | no | Use in-iframe UI for messaging |
MODAL_OPEN / MODAL_CLOSE | no | Would block the buyer; render inline |
RESOURCE_PICKER_* | no | Admin-only |
TITLE_BAR_UPDATE, NAV_MENU_UPDATE | no | No admin chrome here |
CONTEXTUAL_SAVE_BAR | no | Post-purchase has no dirty-state flow |
SESSION_TOKEN_REQUEST | no | Customer context — no merchant JWT |
BUYER_JOURNEY_INTERCEPT_* | no | The buyer has already placed the order |
CART_GET, DISCOUNT_CODE_CHANGE, NOTE_CHANGE, ATTRIBUTE_CHANGE | no | Original cart is sealed; use ORDER_GET |
SHIPPING_ADDRESS_GET, DELIVERY_GROUPS_GET | no | Order has already shipped to the captured address |
METAFIELD_CHANGE | no | Cart metafields are migrated; mutate via REST if needed |
FULLSCREEN_*, SCANNER_*, PRINT, SHARE, HISTORY_* | no | Not wired for the post-purchase surface |
USER_FETCH, CONFIG_FETCH, ENVIRONMENT_FETCH, FEATURES_QUERY | no | Admin-only data APIs |
Action reference
BRIDGE_PING
Capability handshake. Always responds with the host identifier so a
shared iframe URL can branch by host.
ORDER_GET
Read the order that was just placed. The shape mirrors the
Shopify-compatible order envelope returned by the storefront API.
totalPrice to
present a “complete your order” CTA priced in the same currency.
CUSTOMER_GET
Customers
row, but the post-purchase iframe is not given the customer id directly
— look it up via order.customerId from ORDER_GET if you need to
read additional data via REST.
CURRENCY_GET
ORDER_GET().totalPrice.currencyCode. Exposed separately so
extensions that only need currency don’t have to fetch the full order
object.
CART_LINES_CHANGE (post-purchase upsell)
Post-purchase extensions can add line items, which the host packages as
a follow-on order that bills to the same payment method as the
original. Only addCartLine is supported.
error: 'not supported in post- purchase'. To roll back a mistaken add, call DONE without further
interaction — the buyer will see only the original order on the next
page.
When the addCartLine targets a variant already on the original order,
the new line is enriched from existing data (title, image, price) so
the post-purchase UI doesn’t render placeholder content while the host
re-runs verifyCart.
REDIRECT
Send the buyer somewhere other than the default order-status page.
Useful for “claim your reward” flows or surveys.
external: true to short-circuit
the same-origin assertion:
DONE — the host treats the redirect
as the terminal action.
DONE
Finish the post-purchase flow and forward the buyer to
/orders/<id> (the standard order confirmation page). The action is
fire-and-forget; the host immediately removes the iframe.
DONE when your extension finishes — without it the iframe
stays mounted indefinitely. If the user adds an upsell, complete the
async settlement first and then dispatch DONE:
CLIPBOARD_WRITE
Same iframe-side path used in the admin host. Useful for “copy your
order number” style affordances on the post-purchase page.
Clipboard.read() is not available — the host doesn’t broker
CLIPBOARD_READ_REQUEST for the post-purchase surface. Plan UIs that
only need write (copy invoice number, copy support link).
Iframe resize
Like the checkout host, the post-purchase host acceptsAPP_BRIDGE_RESIZE messages and clamps the iframe height to a
reasonable range. Use a ResizeObserver for responsive content:
Worked example: post-purchase upsell with skip
Persistence and side effects
Two things to be aware of about state that survives the post-purchase flow:- Lines added via
CART_LINES_CHANGEcreate a real order. The new order is linked to the original via the customer record and uses the same payment method (no re-prompt). If your extension dispatchesDONEimmediately after the add, the buyer lands on/orders/<originalId>which renders both the original line items and the follow-on order as a single combined receipt. REDIRECTskips the order page. If you redirect away, your extension owns the “thank you” experience. The order is still placed — but the buyer never sees the default confirmation page unless your destination links back to it.
- No webhook re-emit.
orders/createfires when the original order is placed (pre-bridge). Upsell adds emit a freshorders/createfor the follow-on order, thenorders/updatedon the original to reflect the linkage. - No discount re-eval on the original. Adding upsell lines does not
re-run the original order’s
cart_transform/ discount functions. Apply discounts as merchant rules before the buyer reaches post-purchase if they need to gate on the upsell.
Security
- Post-purchase iframes are same-origin with the storefront. The host treats every same-origin frame as trusted; do not rely on the message channel for authentication.
- Customer PII is limited to what the buyer entered at checkout — email
- shipping address only. Payment details are never exposed.
- The customer is not necessarily logged in. Do not assume
emailmaps to a logged-inCustomersrow — guests reach post-purchase via the email captured during checkout.
Troubleshooting
dispatchAndWait('ORDER_GET') times out.
The host hasn’t mounted yet. Wait for BRIDGE_PING to resolve once
before issuing real calls, or retry the read once on the first
timeout.
Iframe never goes away after I call DONE.
Confirm you’re dispatching to the right host. app.dispatch('DONE')
posts a message to window.parent; if your iframe was opened in a new
tab (not embedded by the host) there is no parent to receive it.
My upsell add succeeded but the buyer didn’t see the new line.
The host removes the iframe immediately on DONE. The combined
receipt renders on /orders/<id> once the follow-on order finishes
settling — that can take a second on slow networks. If you want a
visible “Adding…” affordance, await the applyCartLinesChange promise
before dispatching DONE.
CART_LINES_CHANGE with updateCartLine returns an error.
Post-purchase only supports addCartLine. Update / remove operations
are rejected on this host.
See Also
- Post-Purchase Extensions — manifest shape, lifecycle, sandbox flags.
- Actions Reference — full action catalogue including the admin-only entries.
- App Bridge for Checkout — the larger sibling
surface (
host: 'checkout'). - Error Handling — timeout + rejection patterns shared by all hosts.