Â
This guide shows you how to modify your Shopify Order Printer packing slip / invoice template to display bundle items (products within the bundle) nested under their dummy bundle products.
Â
Prerequisite
- Enable “Enable bundle metafields” setting in Bundle Kit > Settings > Bundle Metafields.
- Enable “Add bundle items (products within the bundle) to orders” setting in Bundle Kit > Settings > Bundle Order.
- Have the “Shopify Order Printer” app installed.
Â
A. Packing Slip
Steps
1. Access Your Packing Slip Template
Go to Shopify admin > Apps > Shopify Order Printer > Templates > Packing slip.
Â
We recommend backing up your packing slip template in case you would like to revert to the original version.
Â

Â
2. Locate the Line Items Section
Find this similar section in your template:
<tbody> {% for line_item in order.line_items %} <tr> <td style="text-align: left;">{{ line_item.quantity }}</td> <td style="text-align: left;">{{ line_item.title }}</td> </tr> {% endfor %} </tbody>
Â

Â
3. Replace with Bundle-Aware Code
Replace the entire
<tbody>
section with:<tbody> {% assign nested_quantities = '' %} {% comment %}First pass: Display bundle products with their nested bundle items{% endcomment %} {% for line_item in order.line_items %} {% assign bundle_items = line_item.variant.metafields.app--5234301.bundle_items %} {% if bundle_items and bundle_items.size > 0 %} <tr> <td style="text-align: left;">{{ line_item.quantity }}</td> <td style="text-align: left;"><strong>{{ line_item.title }}</strong></td> </tr> {% for bundle_item in bundle_items %} {% assign nested_quantity = bundle_item.bundle_item_quantity | times: line_item.quantity %} <tr> <td style="text-align: left; padding-left: 20px;">{{ nested_quantity }}</td> <td style="text-align: left; padding-left: 20px; font-style: italic;"> {% if bundle_item.variant_title == "Default Title" %}{{ bundle_item.product_title }}{% else %}{{ bundle_item.product_title }} - {{ bundle_item.variant_title }}{% endif %} </td> </tr> {% comment %}Track nested quantities by variant_id{% endcomment %} {% assign variant_key = bundle_item.variant_id | append: ':' %} {% assign existing_quantity = 0 %} {% assign nested_entries = nested_quantities | split: ',' %} {% for nested_entry in nested_entries %} {% if nested_entry contains variant_key %} {% assign entry_parts = nested_entry | split: ':' %} {% assign existing_quantity = entry_parts[1] | plus: 0 %} {% assign old_entry = bundle_item.variant_id | append: ':' | append: existing_quantity %} {% assign nested_quantities = nested_quantities | remove: old_entry %} {% break %} {% endif %} {% endfor %} {% assign new_quantity = existing_quantity | plus: nested_quantity %} {% assign new_entry = bundle_item.variant_id | append: ':' | append: new_quantity %} {% if nested_quantities == blank %} {% assign nested_quantities = new_entry %} {% else %} {% assign nested_quantities = nested_quantities | append: ',' | append: new_entry %} {% endif %} {% endfor %} {% endif %} {% endfor %} {% comment %}Second pass: Display remaining quantities for each unique variant{% endcomment %} {% assign displayed_variants = ',' %} {% for line_item in order.line_items %} {% assign bundle_items = line_item.variant.metafields.app--5234301.bundle_items %} {% unless bundle_items and bundle_items.size > 0 %} {% assign variant_check = ',' | append: line_item.variant_id | append: ',' %} {% unless displayed_variants contains variant_check %} {% comment %}Calculate total quantity for this variant{% endcomment %} {% assign total_quantity = 0 %} {% for all_line_items in order.line_items %} {% assign check_bundle = all_line_items.variant.metafields.app--5234301.bundle_items %} {% unless check_bundle and check_bundle.size > 0 %} {% if all_line_items.variant_id == line_item.variant_id %} {% assign total_quantity = total_quantity | plus: all_line_items.quantity %} {% endif %} {% endunless %} {% endfor %} {% comment %}Get nested quantity for this variant{% endcomment %} {% assign nested_quantity = 0 %} {% assign variant_key = line_item.variant_id | append: ':' %} {% assign nested_entries = nested_quantities | split: ',' %} {% for nested_entry in nested_entries %} {% if nested_entry contains variant_key %} {% assign entry_parts = nested_entry | split: ':' %} {% assign nested_quantity = entry_parts[1] | plus: 0 %} {% break %} {% endif %} {% endfor %} {% assign remaining_quantity = total_quantity | minus: nested_quantity %} {% if remaining_quantity > 0 %} <tr> <td style="text-align: left;">{{ remaining_quantity }}</td> <td style="text-align: left;">{{ line_item.title }}</td> </tr> {% endif %} {% assign displayed_variants = displayed_variants | append: line_item.variant_id | append: ',' %} {% endunless %} {% endunless %} {% endfor %} </tbody>
Â
4. Preview and Save
Â
Original version:

Â
Modified version:

Â
B. Invoice
Steps
1. Access Your Invoice Template
Go to Shopify admin > Apps > Shopify Order Printer > Templates > Invoice.
Â
We recommend backing up your invoice template in case you would like to revert to the original version.
Â

Â
2. Locate the Line Items Section
Find this similar section in your template:
{% for line_item in order.line_items %} <tr> <td>{{ line_item.quantity }}</td> <td>{{ line_item.title }} {% if line_item.line_level_discount_allocations.size > 0 %} <span class="subduedText"> {% for discount_allocation in line_item.line_level_discount_allocations %} <br>{{ discount_allocation.discount_application.title }} (-{{ discount_allocation.amount | money }}) {% endfor %} </span> {% endif %} </td> <td style="text-align: right;"> {% if line_item.original_price != line_item.final_price %} <span class="subduedText"><s>{{ line_item.original_price | money }}</s></span> {% endif %} {{ line_item.final_price | money }} </td> </tr> {% endfor %}
Â

Â
3. Replace with Bundle-Aware Code
Replace the entire
<tbody>
section with:<tbody> {% assign nested_quantities = '' %} {% comment %}First pass: Display bundle products with their nested bundle items{% endcomment %} {% for line_item in order.line_items %} {% assign bundle_items = line_item.variant.metafields.app--20787593217.bundle_items %} {% if bundle_items and bundle_items.size > 0 %} <tr> <td>{{ line_item.quantity }}</td> <td><strong>{{ line_item.title }}</strong> {% if line_item.line_level_discount_allocations.size > 0 %} <span class="subduedText"> {% for discount_allocation in line_item.line_level_discount_allocations %} <br>{{ discount_allocation.discount_application.title }} (-{{ discount_allocation.amount | money }}) {% endfor %} </span> {% endif %} </td> <td style="text-align: right;"> {% if line_item.original_price != line_item.final_price %} <span class="subduedText"><s>{{ line_item.original_price | money }}</s></span> {% endif %} {{ line_item.final_price | money }} </td> </tr> {% comment %}Display bundle items from metafield data with their discount information{% endcomment %} {% for bundle_item in bundle_items %} {% assign nested_quantity = bundle_item.bundle_item_quantity | times: line_item.quantity %} {% comment %}Find the corresponding bundle item line item for discount information{% endcomment %} {% assign found_bundle_item_line = false %} {% for check_line_item in order.line_items %} {% if check_line_item.variant_id == bundle_item.variant_id and check_line_item.final_price == 0 and found_bundle_item_line == false %} {% assign has_bundle_kit_discount = false %} {% for discount_allocation in check_line_item.line_level_discount_allocations %} {% if discount_allocation.discount_application.title contains 'Bundle Kit' %} {% assign has_bundle_kit_discount = true %} {% break %} {% endif %} {% endfor %} {% if has_bundle_kit_discount %} {% assign found_bundle_item_line = true %} <tr> <td style="padding-left: 20px;">{{ nested_quantity }}</td> <td style="padding-left: 20px; font-style: italic;"> {% if bundle_item.variant_title == "Default Title" %}{{ bundle_item.product_title }}{% else %}{{ bundle_item.product_title }} - {{ bundle_item.variant_title }}{% endif %} {% if check_line_item.line_level_discount_allocations.size > 0 %} <span class="subduedText"> {% for discount_allocation in check_line_item.line_level_discount_allocations %} <br>{{ discount_allocation.discount_application.title }} (-{{ discount_allocation.amount | money }}) {% endfor %} </span> {% endif %} </td> <td style="text-align: right; font-style: italic;"> {% if check_line_item.original_price != check_line_item.final_price %} <span class="subduedText"><s>{{ check_line_item.original_price | money }}</s></span> {% endif %} {{ check_line_item.final_price | money }} </td> </tr> {% endif %} {% endif %} {% endfor %} {% comment %}If no bundle item line found, show generic nested item{% endcomment %} {% unless found_bundle_item_line %} <tr> <td style="padding-left: 20px;">{{ nested_quantity }}</td> <td style="padding-left: 20px; font-style: italic;"> {% if bundle_item.variant_title == "Default Title" %}{{ bundle_item.product_title }}{% else %}{{ bundle_item.product_title }} - {{ bundle_item.variant_title }}{% endif %} </td> <td style="text-align: right; font-style: italic;">$0.00</td> </tr> {% endunless %} {% comment %}Track nested quantities by variant_id{% endcomment %} {% assign variant_key = bundle_item.variant_id | append: ':' %} {% assign existing_quantity = 0 %} {% assign nested_entries = nested_quantities | split: ',' %} {% for nested_entry in nested_entries %} {% if nested_entry contains variant_key %} {% assign entry_parts = nested_entry | split: ':' %} {% assign existing_quantity = entry_parts[1] | plus: 0 %} {% assign old_entry = bundle_item.variant_id | append: ':' | append: existing_quantity %} {% assign nested_quantities = nested_quantities | remove: old_entry %} {% break %} {% endif %} {% endfor %} {% assign new_quantity = existing_quantity | plus: nested_quantity %} {% assign new_entry = bundle_item.variant_id | append: ':' | append: new_quantity %} {% if nested_quantities == blank %} {% assign nested_quantities = new_entry %} {% else %} {% assign nested_quantities = nested_quantities | append: ',' | append: new_entry %} {% endif %} {% endfor %} {% endif %} {% endfor %} {% comment %}Second pass: Display remaining quantities for each unique variant{% endcomment %} {% assign displayed_variants = ',' %} {% for line_item in order.line_items %} {% assign bundle_items = line_item.variant.metafields.app--20787593217.bundle_items %} {% comment %}Check if this is a bundle item line item (has $0 price and Bundle Kit discount){% endcomment %} {% assign is_bundle_item_line = false %} {% if line_item.final_price == 0 and line_item.line_level_discount_allocations.size > 0 %} {% for discount_allocation in line_item.line_level_discount_allocations %} {% if discount_allocation.discount_application.title contains 'Bundle Kit' %} {% assign is_bundle_item_line = true %} {% break %} {% endif %} {% endfor %} {% endif %} {% unless bundle_items and bundle_items.size > 0 or is_bundle_item_line %} {% assign variant_check = ',' | append: line_item.variant_id | append: ',' %} {% unless displayed_variants contains variant_check %} {% comment %}Calculate total quantity for this variant (excluding bundle products and bundle item lines){% endcomment %} {% assign total_quantity = 0 %} {% for all_line_items in order.line_items %} {% assign check_bundle = all_line_items.variant.metafields.app--20787593217.bundle_items %} {% assign check_is_bundle_item_line = false %} {% if all_line_items.final_price == 0 and all_line_items.line_level_discount_allocations.size > 0 %} {% for discount_allocation in all_line_items.line_level_discount_allocations %} {% if discount_allocation.discount_application.title contains 'Bundle Kit' %} {% assign check_is_bundle_item_line = true %} {% break %} {% endif %} {% endfor %} {% endif %} {% unless check_bundle and check_bundle.size > 0 or check_is_bundle_item_line %} {% if all_line_items.variant_id == line_item.variant_id %} {% assign total_quantity = total_quantity | plus: all_line_items.quantity %} {% endif %} {% endunless %} {% endfor %} {% comment %}Get nested quantity for this variant{% endcomment %} {% assign nested_quantity = 0 %} {% assign variant_key = line_item.variant_id | append: ':' %} {% assign nested_entries = nested_quantities | split: ',' %} {% for nested_entry in nested_entries %} {% if nested_entry contains variant_key %} {% assign entry_parts = nested_entry | split: ':' %} {% assign nested_quantity = entry_parts[1] | plus: 0 %} {% break %} {% endif %} {% endfor %} {% assign remaining_quantity = total_quantity | minus: nested_quantity %} {% if remaining_quantity > 0 %} <tr> <td>{{ remaining_quantity }}</td> <td>{{ line_item.title }} {% if line_item.line_level_discount_allocations.size > 0 %} <span class="subduedText"> {% for discount_allocation in line_item.line_level_discount_allocations %} <br>{{ discount_allocation.discount_application.title }} (-{{ discount_allocation.amount | money }}) {% endfor %} </span> {% endif %} </td> <td style="text-align: right;"> {% if line_item.original_price != line_item.final_price %} <span class="subduedText"><s>{{ line_item.original_price | money }}</s></span> {% endif %} {{ line_item.final_price | money }} </td> </tr> {% endif %} {% assign displayed_variants = displayed_variants | append: line_item.variant_id | append: ',' %} {% endunless %} {% endunless %} {% endfor %} <tr> <td colspan="2" style="text-align: right;">{{ "invoice_template.subtotal_label" | t }}</td> <td style="text-align: right;">{{ order.line_items_subtotal_price | money }}</td> </tr> {% assign has_shipping_discount = false %} {% for discount_application in order.discount_applications %} {% if discount_application.target_type == 'shipping_line' %} {% assign has_shipping_discount = true %} {% endif %} {% if discount_application.target_selection == 'all' and discount_application.target_type != 'shipping_line' %} <tr> <td colspan="2" style="text-align: right;">{% if discount_application.title %}<span class="subduedText">{{ discount_application.title }}</span>{% endif %}</td> <td style="text-align: right;">-{{ discount_application.total_allocated_amount | money }}</td> </tr> {% endif %} {% endfor %} <tr> <td colspan="2" style="text-align: right;">{{ "invoice_template.tax_label" | t }}</td> <td style="text-align: right;">{{ order.tax_price | money }}</td> </tr> {% if order.shipping_address %} <tr> <td colspan="2" style="text-align: right;">{{ "invoice_template.shipping_label" | t }}</td> <td style="text-align: right;">{% if has_shipping_discount %}{{ "invoice_template.free_shipping" | t }}{% else %}{{ order.shipping_price | money }}{% endif %}</td> </tr> {% endif %} <tr> <td colspan="2" style="text-align: right;"><strong>{{ "invoice_template.total_label" | t }}</strong></td> <td style="text-align: right;"><strong>{{ order.total_price | money }}</strong></td> </tr> {% if order.net_payment != order.total_net_amount %} <tr> <td colspan="2" style="text-align: right;">{{ "invoice_template.total_paid_label" | t }}</td> <td style="text-align: right;">{{ order.net_payment | money }}</td> </tr> {% endif %} {% if order.total_refunded_amount > 0 %} <tr> <td colspan="2" style="text-align: right;">{{ "invoice_template.total_refunded_label" | t }}</td> <td style="text-align: right;">-{{ order.total_refunded_amount | money }}</td> </tr> {% endif %} {% if order.net_payment != order.total_net_amount %} <tr> <td colspan="2" style="text-align: right;"><strong>{{ "invoice_template.outstanding_amount_label" | t }}</strong></td> <td style="text-align: right;"><strong>{{ order.total_price | minus: order.net_payment | money }}</strong></td> </tr> {% endif %} </tbody>
Â
4. Preview and Save
Â
Original version:

Â
Modified version:

Â