Cart Transform Functions
Cart transform functions modify per-line prices and titles inside the cart — volume pricing, bundle discounts, expand-on-fulfillment bundles, VIP-tier prices, anything that needs to change what a customer sees on a specific line. The platform records each negative delta as its owncartTransformDiscounts[]
entry on the persisted order, so cart, checkout, order page, and email
receipts all render one line per transform op with the title you supplied.
Bundles live here. LaunchMyStore does not expose a dedicated
productBundleCreate REST resource — bundles are authored as cart-transform
merge ops (see Bundle pricing below). Apps that
need fixed-price kits, mix-and-match sets, or expand-on-fulfillment bundles
should ship a cart_transform function and treat each merchant-configured
bundle as configuration passed to that function. Each bundle is expressed as
a merge op that collapses child lines into a single bundle total at cart
time, leaving the underlying lines on the order for refund and reporting.How It Works
Runs in both cart verification and order placement so the preview matches the persisted order exactly. Don’t fold the savings intoprice yourself — the
platform reports raw price plus a separate cartTransformDiscount line.
Function Manifest
Input Schema
Prices are in display currency units, not minor units (cents).
price: 19.99 means ₹19.99 / $19.99.Output Schema
A cart transform function returns operations. Three op kinds are supported:update, merge, and expand. Each op may carry a title that
becomes the customer-facing label on the resulting discount row.
Operations
update — change unit price / title for a line
The most common op. Use for VIP pricing, volume breaks, member-only prices.
priceis the new unit price. Per-line savings =(oldUnit - newUnit) * quantity.title(optional) overrides the line title and the discount-row label. If omitted, the label falls back to"Bundle Discount".
merge — collapse N lines into one bundle total
Use for “buy these three together for $X” bundles. The child lines stay in
the order (for refund/reporting), but the bundle savings get a single
discount row.
priceis the total for the bundle — savings =sum(oldLineTotals) - price.- The savings appear as a single
cartTransformDiscounts[]entry with yourtitleas the label.
expand — replace one line with multiple
Use for mystery boxes, multi-pack splits, or any case where one purchased
line needs to render as several line items.
- Each
expandedItems[i]may set its ownprice(defaults to the original line’s unit price). - Total savings =
originalLineTotal - sum(expandedItems[i].price * expandedItems[i].quantity).
Example Implementations
Volume / quantity-break pricing
Bundle pricing (merge)
Mystery box (expand)
How the backend uses your output
For every op that yields a negative delta (lower price than original), the platform:- Mutates the per-line price/title on the order so receipts and refunds reflect the bundle.
-
Appends an entry to
additionalFields.cartTransformDiscounts[]: -
Sums all op deltas into the scalar
additionalFields.cartTransformDiscountfor backwards compatibility. - Returns both shapes from cart verification.
How it renders in the UI
The customer-facing summary renders one row per op, using thetitle you
supplied:
additionalFields.cartTransformDiscount.
Best Practices
Always set a `title`
Always set a `title`
The title becomes the discount-row label. Without it, the customer sees
a generic “Bundle Discount” row — fine for prototypes, vague in
production.
Make ops idempotent
Make ops idempotent
update ops re-run on every cart change. Always derive the new price
from originalPrice (or the static config), not from the current
price, so re-running doesn’t compound discounts.Don't fold savings into `price`
Don't fold savings into `price`
Return the new unit price; the platform handles the bag total +
separate discount row. If your function discounts and rewrites
payload.price itself, the line total ends up doubly discounted.Keep `merge` totals authoritative
Keep `merge` totals authoritative
Test against the real checkout
Test against the real checkout
Cart transforms run at both cart verification and order placement —
they must produce identical totals on both sides. Compare the cart
preview against the placed order’s totals after every change.
See Also
- Discount Functions — order-/line-/shipping-level
discounts. Surfaces as
appDiscount. - Order Validation Functions — block order placement, e.g. when a bundle is incomplete at checkout.