---
title: Producer Invoices
date: 2026-06-13T16:10:00+01:00
author: John Henry Donovan
canonical_url: "https://johnhenry.ie/plugins/container-deposits/docs/guide/producer-invoices"
section: Plugins
---
esc

↑↓ to navigate↵ to selectesc to close

Menu On this page 

- [Return to top](#)

Documentation

Documentation

# Invoices &amp; Receipts

## Example Templates

Example templates are available in the root of the plugin. Get them [here](https://github.com/john-henry/craft-container-deposits/tree/craft-5/example-templates).

## Re-turn Compliance

Re-turn's [Producer Invoice Guidance](https://www.re-turn.com/en/products/producer-invoice-guidance/) is a fair bit more involved than the standard Re-turn invoice format.

Re-turn publishes two separate layout specs that affect Craft Commerce stores:

DocumentAudiencePlugin partial**Producer invoice**B2B - wholesalers to retailers`store/_partials/invoice-block`**Retailer receipt**B2C - retailers to consumers`store/_partials/receipt-block`

Both partials self-suppress when no deposits exist on the order, so they're safe to include unconditionally.

### Retailer Receipt (B2C)

This is the format mandated for the receipt a consumer receives at the till or via email:

```twig
Milk ................. €2.50
Bread ................ €3.20
Water bottle 2 litre . €1.80
Orange can 330ml ..... €1.20
Total Net ............ €8.70

Deposit
25c × 1 Unit ......... €0.25
15c × 1 Unit ......... €0.15
TOTAL ................ €9.10
(Total NET + Deposit)
```

#### Drop-in usage

```twig
{% include 'store/_partials/receipt-block' ignore missing with {
    order: order,
} only %}
```

Renders the whole products → Total Net → Deposit section → TOTAL block. The mandatory disclosure notice ("*Deposit is mandatory under the Re-turn DRS scheme and cannot be discounted*") gets added automatically at the bottom.

### Producer invoice (B2B)

Re-turn's *Producer Invoice Guidance* requires that deposits be shown on a separate line item, with each deposit tier (€0.15 and €0.25) on its own row, followed by a deposit subtotal and a grand total that includes both products and deposit. The plugin ships everything needed to produce that exact layout.

### The required structure

```twig
1,500 'in scope' Products  @ €X/unit ..................... €XX
VAT @ XX% ................................................ €XX
                                          Subtotal ..... €XXXX

┌─────────────────────────────────────────────────────────┐
│ Re-turn Deposit         No. Units    Per unit    Total  │
│ Deposit 150–500ml          500         15c        €75   │
│ Deposit >500ml–3L        1,000         25c       €250   │
│ Total Re-turn Deposit                            €325   │
└─────────────────────────────────────────────────────────┘

                                          Subtotal ..... €XXXX
                                          + Deposit ...... €325
                                          Total invoice .. €XXXX
```

### Drop-in partial

The plugin ships a Twig partial that renders the dashed block exactly the way Re-turn shows it. Include it anywhere an `order` (or cart) is in scope:

```twig
{% include 'store/_partials/invoice-block' ignore missing with {
    order: order,
} only %}
```

The `ignore missing` flag means your template won't break if the plugin gets uninstalled - the block just disappears. The block itself self-suppresses for any order with no deposits, so it's fine to leave it permanently in your invoice template.

## Twig helpers

Whether you use the partial or not, the `craft.containerDeposits` variable gives you everything you need to build a custom layout:

CallReturns`craft.containerDeposits.lineItemsFor(order)`Array of deposit `LineItem`s on the order`craft.containerDeposits.productLineItemsFor(order)`Array of non-deposit `LineItem`s`craft.containerDeposits.totalFor(order)`Sum of price × qty across all deposit line items`craft.containerDeposits.productSubtotalFor(order)`Sum of subtotals for product line items`craft.containerDeposits.isDeposit(lineItem)``true` if the given line item is a deposit`craft.containerDeposits.allTypes()`Every deposit type configured in the CP

### Example - custom invoice layout

```twig
<table>
  {# Products only #}
  {% for item in craft.containerDeposits.productLineItemsFor(order) %}
    <tr>
      <td>{{ item.description }}</td>
      <td>{{ item.qty }}</td>
      <td>{{ item.subtotalAsCurrency }}</td>
    </tr>
  {% endfor %}

  <tr>
    <td colspan="2">Products subtotal</td>
    <td>{{ craft.containerDeposits.productSubtotalFor(order)|commerceCurrency(order.currency) }}</td>
  </tr>

  {# Deposits in their own block #}
  {% set deposits = craft.containerDeposits.lineItemsFor(order) %}
  {% if deposits|length %}
    {% for item in deposits %}
      <tr class="deposit">
        <td>{{ item.description }}</td>
        <td>{{ item.qty }} × {{ item.price|commerceCurrency(order.currency) }}</td>
        <td>{{ (item.price * item.qty)|commerceCurrency(order.currency) }}</td>
      </tr>
    {% endfor %}
    <tr class="deposit-total">
      <td colspan="2"><strong>Total Re-turn Deposit</strong></td>
      <td>{{ craft.containerDeposits.totalFor(order)|commerceCurrency(order.currency) }}</td>
    </tr>
  {% endif %}

  <tr class="grand-total">
    <td colspan="2"><strong>Total (incl. deposit)</strong></td>
    <td><strong>{{ order.totalPriceAsCurrency }}</strong></td>
  </tr>
</table>
```

## VAT placement

Re-turn deposits sit outside the scope of VAT. The plugin's `bottleDeposit` tax category keeps Commerce from applying VAT to the deposit line items - your VAT row will only reflect the product subtotal, exactly as the Re-turn guidance requires. See [VAT Treatment](https://johnhenry.ie/plugins/container-deposits/docs/guide/vat-treatment) for details.

On this page
