Brief CS when Shopify packs expand at checkout
A support brief for Shopify Functions packs: why the cart showed one product and one price but the order, confirmation email, and refund screen show component lines with allocated prices — the ticket shape for free-item, spread, and order-level packs, a two-minute triage for expansion vs a real bug, and macros agents can send without refunding money the store never took.
Jeshua Leger
Founder, Leger Studio ·
Ticket #2210: “I bought the Morning Routine Kit for $79. My confirmation lists a cleanser, a serum, and a travel bag with three different prices, and the serum says $47.40 — your site says $60. Did you send the wrong thing, or overcharge me?” The agent opens the order, sees three lines where the customer bought one product, and does the reasonable thing: tags it as a checkout bug, refunds the $12.60 “difference,” and asks the developer to look. Nothing was broken. The kit expanded into its real components at checkout, the saving was allocated across them exactly as configured, and the store just gave back money it never took.
This post does one job: brief customer support so an agent can read a pack order — component lines, allocated prices, a $0.00 gift, or a separate order discount — explain it to the customer in one reply, and tell an honest expansion apart from a real bug before anyone refunds or escalates. It is not the post about what the warehouse prints (pack lines your 3PL can pick), how the allocation is calculated (exact component prices with Shopify Functions), or what a partial return should refund (returns and partial refunds). Those assume the person reading the order already knows what they are looking at. This one is for the agent who does not, yet.
One product in the cart, real components on the order
On the product page and in the cart, the pack is one product with one price — that is the point of selling it as a real product rather than a widget. At checkout, two functions registered by the app run: a Cart Transform expands the pack into its component variants (real SKUs, real quantities), and a Discount function places the pack’s saving according to the bundle’s settings. Everything Shopify records from there — the confirmation email, the admin order page, the refund screen — is the expanded version. Four things an agent has to internalize before reading a pack order:
- The order total is the pack price times the quantity bought. The lines changed shape; the money did not. If the total is right, nothing was “charged twice.”
- There is no line for a pack SKU on the order. Fulfillment picks components, by design — a “Morning Routine Kit” line with its own stock number is exactly the fake SKU the app avoids.
- Component line prices are set by the merchant’s allocation choice, not by the product page. In two of the three configurations below, a line price that differs from the PDP price is the expected result, not a bug.
- The confirmation email lists the component lines. Whether the pack’s name appears above them depends on your notification template — check it on a test order and put that screenshot in the brief, because it is the document the customer is quoting.
The three facts an agent needs before the first ticket
Most pack tickets cannot be answered without knowing how the pack was configured, and most support teams are never told: the merchant picked an allocation mode for merchandising reasons and an application mode for finance or 3PL reasons, and the agent inherits both without a memo. Put these on a one-page card — per store if every pack uses the same settings, per pack if not:
- Allocation mode: free item or spread. This decides whether one line reads $0.00 or every line reads a little less than its product page.
- Application mode: product-level (the default, every plan) or order-level (Growth and Pro). This decides whether the saving is inside the line prices or sits in its own discount row on the order.
- The contents card for each Active pack: component names, SKUs, quantities, pack price, and the expected line prices copied from the bundle editor’s live preview. The agent compares the order against this list, not against memory.
Three ticket shapes, one per configuration
Every example below uses the same kit: Cleanser $30, Serum $60, Travel bag $10 — $100 at product-page prices, sold as a pack for $79 — plus a hoodie-and-stand gift pack where the $20 stand is marked free and the pack sells for the $60 hoodie price.
Free-item packs: “why does it say $0.00?”
On product-level application the gift line reads $0.00. Customers read that three ways: “was it supposed to be free?”, “does $0.00 mean it is out of stock or not shipping?”, and, occasionally, “I think you forgot to charge me.” The answer is the same each time — the pack’s saving was applied to that item first, so the free thing reads free, and it ships with the rest of the order. This is the gift-with-purchase pattern working as intended. One edge the agent should be warned about: if a merchant configured a discount larger than the free items are worth, the editor warns and the remainder spreads onto the paid lines — so a hoodie line reading $58.00 next to a $0.00 stand is also correct, and the card should say so.
Spread packs: “the price is lower than on the website”
In spread mode the $21 saving is shared across components by price, so the lines read $23.70 / $47.40 / $7.90. Ticket #2210 is this shape: the customer sees a serum at $47.40 against a $60 product page and reads it as a markdown, an old batch, or the wrong item. The answer is that the saving is shared across the set, and the proof is arithmetic — the allocation runs in integer cents with largest-remainder rounding, so the lines sum to $79.00 exactly, which is what the customer was charged. An agent who adds three numbers in the reply closes the ticket; an agent who apologizes for “the discrepancy” invites a refund request for a discrepancy that does not exist.
Order-level packs (Growth and Pro): “the items add up to more than I paid”
With order-level application the lines read $30 / $60 / $10 with a −$21 discount row against the order. Two ticket shapes follow. First, the customer reads the line prices, sums them to $100, and asks why they were charged for full price — they stopped reading before the discount row. Second, “what is this discount? I never entered a code” — the saving applied automatically because they bought the set. There is also a pre-purchase version of this ticket: “my discount disappeared when I removed the travel bag in my cart.” That is by design — an order-level pack discount needs the whole pack in the cart, and removing a component line cancels it (troubleshooting docs). The customer can put the bag back and keep the pack price, or buy the items they want at their regular prices.
Triage: honest expansion or a real bug
With the card and the admin order page open, an agent should reach a verdict in under two minutes. The test is arithmetic and inventory, not whether the order “looks odd” — pack orders always look odd to someone who has not seen one.
- Sum the component lines — and the order discount row, if there is one. Does it equal the pack price times the quantity bought? Yes: pricing is honest; pick the macro for the mode. No: go to step 5.
- Compare SKUs and quantities against the pack’s contents card. Everything present, nothing extra? Yes: contents are honest. A missing or surplus component: step 5.
- Did the customer buy two or more of the pack? Lines scale — two kits show two of each component with the saving doubled. That is one order, not a duplicate.
- Is the customer quoting a document support does not own — a packing slip price, a customs value? Route it to ops; that is the warehouse documents question, not a checkout one.
- Escalate with evidence: order number, pack name, a screenshot of the order lines and totals, and what the customer expected. On the merchant side the checks are: the bundle is Active in the app and the product is Active in Shopify; Settings → Checkout functions shows both the Cart Transform and the Discount function as registered (Re-sync if not); and the bundle was re-saved after its last edit, which pushes the latest configuration to checkout. If all three pass and the order is still wrong, email support@legerstudio.pro with the store URL and the bundle name.
Macros that explain without apologizing
Replace the bracketed names and numbers with the real ones from the card. State what happened, show the arithmetic, confirm nothing is missing. No “sorry for the confusion” — the order is correct, and apologizing for it teaches the customer that it was not.
- Free-item pack: “The [Stand] is the free item in your [Hoodie + Stand] pack, so it shows as $0.00 on your order — that is the pack’s saving applied to it. It is in stock and ships with your [Hoodie]; nothing is missing or on backorder.”
- Spread pack: “Your [Morning Routine Kit] is priced at $79 for the set. At checkout that saving is shared across the three items in proportion to their price, so each line shows a little less than its individual price: $23.70 + $47.40 + $7.90 = $79.00, which is what you were charged. You received the full kit at the kit price.”
- Order-level pack: “Each item in your [Morning Routine Kit] is listed at its regular price, and the kit saving of $21 appears once as a discount on the order, bringing your total to $79. No code was needed — it applied automatically because you bought the set.”
- Why the components at all: “The kit is listed as one product so it is easy to buy, but your order shows each item inside it so our warehouse ships exactly what the kit contains and so any return can be handled per item.”
Refund and change requests an agent can answer alone
Because every component is a normal Shopify line item, most follow-up requests have a standard answer. The card should state these so the agent does not improvise:
- Return one component: the refund is the allocated line price on the order — $23.70 for the cleanser in the spread kit, not the $30 the customer remembers. On an order-level pack Shopify prorates the discount, so the number lands in the same place but the receipt showed $30, which makes the gap louder. The exact figure comes from the pre-launch refund test in returns and partial refunds, not from an estimate.
- Return only the free gift: a $0.00 line has no refund value. Tell the customer to keep it; do not buy a return label for it.
- Swap one component for a different size or colour: this is not a pack return. The replacement is a solo variant with no pack saving on it, so it needs one of the exchange paths from the returns post — not an order edit.
- “Can I add another kit?” Yes, as a normal product; the saving scales with quantity exactly.
- “Can you make the serum show its full price?” No — that is an application-mode decision for the merchant, not a ticket. Changing it mid-campaign changes the shape of every order from that point on, which means every macro on the card is wrong for the next customer.
CS tickets are not warehouse tickets
Support reads the confirmation email, the admin order page, and the refund screen. The warehouse or 3PL reads a pick ticket, a packing slip, and — across a border — a customs form, each printing whichever price field its template maps. A customer quoting “$0.00” from the email is a support ticket answered by this brief. A customer quoting “$100.00” from a packing slip on a $79 order is a documents problem owned by ops — pack lines your 3PL can pick. Put both runbooks on the same card so a slip-template fix does not get logged as a checkout bug.
Brief support before the pack goes Active
Do this once per configuration you run — each allocation and application combination — and again the day any pack changes mode or a new pack goes Active. It fits in half an hour.
- Place a paid test order for the pack — a real card refunded afterwards is closest to what customers see. Buy quantity two on at least one test so the team sees how lines scale.
- Screenshot the product page price, the single cart line, the admin order lines with the totals block, and the confirmation email as the customer receives it. File them next to the card.
- Write the card: allocation mode, application mode, contents with SKUs and quantities, pack price, and the expected line prices from the bundle editor’s preview.
- Adapt the macros above with real product names and the numbers from the test order. An agent doing arithmetic live will get it wrong once.
- Refund one component on the test order and write the amount Shopify proposes onto the card, so the partial-return answer is a lookup, not a guess.
- If you run spread or order-level packs, add one sentence to the order confirmation template or the pack’s product page — “bundle savings are shared across the items on your order” — so the customer reads the explanation before writing the ticket.
- Name the escalation owner and the evidence they need, and put the app support email on the card for cases where the merchant-side checks pass and the order is still wrong.
- Any change to a pack’s mode, contents, or price updates the card the same day. Yesterday’s macro describes yesterday’s order.
A pack is easy to support when the agent knows what a correct order looks like before the first customer asks. Better Bundles expands each pack into its real component lines at checkout on every plan, with the saving placed by the allocation mode you chose and — on Growth and Pro — optionally applied once at the order level so component lines keep their product-page prices. Basic is free forever with up to 3 active bundles; Starter, Growth, and Pro are $17 / $37 / $77 a month with a 15-day trial. Build the pack in create your first bundle, read the allocated prices off the preview, and hand support the card before the pack goes Active — or install from the Shopify App Store and run the test order first.