You are here:
Configure Receipts to Show Product Bundle Children in Point of Sale
Add a child-loop row to your receipt template so each bundle's items print together under it, in sales and returns.
Keep the product ID and name together on the parent product row of your existing receipt template. This anchors bundle grouping.
When an associate sells or returns a bundle, the app groups that bundle's items by their shared bundle group. It removes them from the ordinary item list so they don't print twice. The app doesn't build a child row layout, indent rows, or print a child price. Your template controls the formatting. Without a child-loop row, the bundle's items have nowhere to print. They disappear from the receipt.
- In your receipt template's product section, add a new row directly under the row that prints the bundle (parent) line.
-
On the new row, add the :ps_p_bundle_child prefix in front of each product tag you want to show for a child. For example: :ps_p_bundle_child:ps_p_id, :ps_p_bundle_child:ps_p_title, and :ps_p_bundle_child:ps_p_qty.
The engine repeats this row once for each item in the bundle. Most product tags resolve for a child, including:
- Identity fields: ID, title, quantity, SKU, GTIN, variant group ID
- Item detail: serial number, item status, registry ID, notes
- Fulfillment type, and the full shipping and pickup detail sets
Price, discount, and tax tags are the exception. A bundle child has no price on the receipt, so a money tag like :ps_p_bundle_child:ps_p_price prints nothing for a child. Put the bundle's price, discount, and tax on the parent row only.
-
To indent the child row under the bundle name, type leading spaces on the row, or add a narrow empty cell before it.
Indent is a layout choice that you make on the template—there's no app-side indent setting.
-
If you add more than one child-loop row (for example, a second row for the variant group ID), keep the rows adjacent. Don't put a plain row between them.
Adjacent child rows print as one block per child. For example, child A's ID, title, and quantity print first. Child A's variant group ID prints right after. Then child B's rows print the same way. A plain, non-child row between two child rows breaks that block.
This example authors a receipt product section as six rows. Only rows 2 and 3 carry the :ps_p_bundle_child prefix. The engine repeats those two rows once per child. The bundle (parent) line preceding them prints once.
| Row | What's on it | Resolves against |
|---|---|---|
| 1 | :ps_p_id :ps_p_title, :ps_p_qty_and_price (right-aligned) | Parent—the bundle line, with the bundle's single price |
| 2 | Narrow empty cell, :ps_p_bundle_child:ps_p_id :ps_p_bundle_child:ps_p_title, :ps_p_bundle_child:ps_p_qty (right-aligned) | Child |
| 3 | Narrow empty cell, Variant Group Id: :ps_p_bundle_child:ps_p_variant_group_id | Child |
| 4 | Variant Group Id: :ps_p_variant_group_id | Parent |
| 5 | :ps_p_fulfillment_type | Parent |
| 6 | :ps_p_discount_title, :ps_p_discount_amount (right-aligned) | Parent |
Print a test receipt for a sale that includes a bundle. Confirm that each child prints once, directly under the bundle line. Also confirm that no child shows its own price. If children are missing entirely, add the child-loop row from this task. The token is :ps_p_bundle_child. It doesn't include is. There's no separate on/off token or condition to configure.
