# Receipt Data

**WP admin:** templates are edited in `WP Admin → POS → Templates`; this page lists the fields they can print.

To print or email a receipt, see [Receipts and the Paid Screen](/zh-CN/sell/print-email-receipts.md); to pick a template, or have AI change one for you, see [Customise Your Receipt](/zh-CN/settings/receipt-templates/customise-receipt.md).

This page is for editing a template's code by hand. Every template, HTML or thermal, prints from the same receipt data: the store, the order, the items, the totals and the payments. The page shows how to print a field, gives three common examples, and lists every field.

**Jump to:** [Find a field](#field-reference) · [Common examples](#common-recipes) · [If something goes wrong](#if-something-goes-wrong)

## Print a field[​](#print-a-field "直接链接到 Print a field")

1. Open the template in **WP Admin → POS → Templates** ([Edit it by hand](/zh-CN/settings/receipt-templates/customise-receipt.md#option-3--edit-it-by-hand) has the details).
2. Where the field should print, type its path between double braces, such as `{{store.name}}`, `{{order.number}}` or `{{totals.total_display}}`, or insert it from the field list beside the code.
3. Check the preview below the code, then click **Update** to save.

For a list, such as the items, wrap the row in a section and it repeats once per item:

```
{{#lines}}

  {{name}} x {{qty}} —

  {{line_total_display}}

{{/lines}}
```

A section also leaves its contents out when the field is empty, zero or false, so `{{#customer.id}}…{{/customer.id}}` prints only for a named customer. To print money, use the field that ends in `_display`; see [Currency fields](#currency-fields).

Receipts print offline too: the app builds a copy of the receipt data from the order on the device.

Why receipts can differ

### Where the data comes from[​](#where-the-data-comes-from "直接链接到 Where the data comes from")

Your store's server builds the receipt data for each order, and the app builds a shorter copy from the order on the device: it has no `cashier`, no store opening hours, notes or policies, and no `totals.paid_total` or `totals.change_total`. An HTML or thermal template opens at once from the device's copy and switches to the server's when it arrives; offline, the device's copy is the one that prints, so those fields print empty. With WCPOS Pro, the device's copy carries the store logo too; without Pro, the logo arrives with the server's copy. A legacy PHP template is always rendered by the server. That's why a template uses the fields below and never PHP order methods. A few fields print only when the server renders the template, as it does for a PDF download; [If something goes wrong](#if-something-goes-wrong) lists them.

## The receipt, mapped[​](#receipt-map "直接链接到 The receipt, mapped")

Each part of a printed receipt comes from one section of the receipt data. Point at a part of the receipt or at its card to light up the pair; click or tap either one to jump to that section's fields. On a phone, the cards follow the receipt in the same order, top to bottom.

The receipt below, the first two recipes and the price breakdown use the same sample order. Its item amounts are before the coupon (`line_subtotal_display`); the gallery's receipt templates print them after it (`line_total_display`, 26.10 for the espresso).

[COFFEE MONSTER](#store)

[12 Roast Lane, Portland OR](#store)

[VAT: US-998877](#store)

***

[Receipt #1042Jul 13, 2026](#order)

[Cashier: AdaCustomer: Nia](#order)

***

[2 × Espresso Beans29.00](#lines)

[~~34.00~~ · Savings −5.00](#lines)

[1 × Ceramic Mug18.00](#lines)

[1 × Croissant5.75](#lines)

[Item amounts before coupon: `line_subtotal_display`](#lines)

***

[Subtotal52.75](#totals)

[Coupon SUMMER10−5.28](#totals)

[Gift wrap2.50](#totals)

[Shipping10.00](#totals)

[TOTAL59.97](#totals)

[Total saved10.28](#totals)

***

[Card59.97](#payments)

***

[Thank you for your purchase!](#store)

[店铺抬头](#store)

[`store.name` · `store.address_lines` · `store.tax_ids` · `store.logo`](#store)

[订单与人员](#order)

[`order.number` · `order.created` · `cashier.name` · `customer.name`](#order)

[商品明细](#lines)

[`lines[]` · `line_savings` · `savings_in_discounts`](#lines)

[合计区](#totals)

[`totals.*` · `discounts[]` · `fees[]` · `shipping[]` · `totals.total_saved`](#totals)

[付款](#payments)

[`payments[]`](#payments)

[页脚](#store)

[`store.personal_notes` · `store.policies_and_conditions` · `i18n.thank_you_purchase`](#store)

## Common recipes[​](#common-recipes "直接链接到 Common recipes")

Most hand edits are one of these two, shown for an HTML template, and a third under them covers reprinting older orders. Each card shows the new rows on a receipt, then their code, then where to add it in your template. The item name, amount and TOTAL come from the rest of your template.

Using these in a thermal template

The same fields and sections work unchanged: put each printed line in a `<text>` element and leave out `<s>`, because thermal XML has no strike-through and prints the price plain ([Thermal Templates](/zh-CN/settings/receipt-templates/thermal-templates.md#text-and-formatting)).

2 × Espresso Beans26.10

~~34.00~~ · Savings −5.00

Strike through the regular price

```
{{#lines}}
{{#line_savings}}
  <s>{{line_regular_total_display}}</s>
  {{i18n.savings}}:
  -{{line_savings_display}}
{{/line_savings}}
{{/lines}}
```

Inside your template's existing `{{#lines}}` section, add the `{{#line_savings}}` block after the item row. 34.00 regular price − 5.00 sale saving − 2.90 coupon = 26.10 paid. The block leaves out both rows on orders with no recorded price history.

TOTAL59.97

Total saved10.28

Add a Total saved row

```
{{#totals.total_saved_complete}}
{{#totals.total_saved}}
  {{i18n.total_saved}}:
  {{totals.total_saved_display}}
{{/totals.total_saved}}
{{/totals.total_saved_complete}}
```

Add these lines after your TOTAL row. Two sections: the row is left out when the price history is incomplete, or when nothing was saved.

Reprint an order made before WCPOS 1.9.0

1 × Espresso Beans14.50

~~17.00~~ Discount −2.50

Reprint a pre-v1.9 order safely

```
{{#lines}}
{{#line_savings}}
  <s>{{line_regular_total_display}}</s>
  {{^savings_in_discounts}}
    {{i18n.savings}}:
    -{{line_savings_display}}
  {{/savings_in_discounts}}
{{/line_savings}}
{{#discounts}}
  {{i18n.discount}}:
  -{{discounts_display}}
{{/discounts}}
{{/lines}}
```

For an order made before WCPOS 1.9.0, not the sample order. Inside your template's existing `{{#lines}}` section, add the `{{#line_savings}}` and `{{#discounts}}` blocks after the item row. The saving is already inside the discount, so this prints the discount and leaves the saving out.

## Field reference[​](#field-reference "直接链接到 Field reference")

Expand a section to see its fields. The first item lists every section and its type.

All sections and their types

### Top-level sections[​](#top-level-sections "直接链接到 Top-level sections")

| Section                       | What it holds                                                                                                    |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `order` (object)              | Order identity, status, dates, note, and payment URL information                                                 |
| `store` (object)              | Store identity, address, contact details, tax IDs, logo, hours, and footer text                                  |
| `cashier` (object)            | User who processed the order                                                                                     |
| `customer` (object)           | Customer display name, addresses, and tax IDs                                                                    |
| `lines` (array)               | Product line items                                                                                               |
| `fees` (array)                | Fee rows                                                                                                         |
| `shipping` (array)            | Shipping rows                                                                                                    |
| `discounts` (array)           | Coupon/discount rows                                                                                             |
| `totals` (object)             | Order totals, payment totals, refund summary, and item counts                                                    |
| `tax` (object)                | Tax display mode flags for section guards                                                                        |
| `tax_summary` (array)         | Per-rate tax summary rows                                                                                        |
| `has_tax_summary` (boolean)   | Convenience guard for `tax_summary`                                                                              |
| `payments` (array)            | Payment rows                                                                                                     |
| `refunds` (array)             | Refund records applied to the order                                                                              |
| `fiscal` (object)             | Fiscal snapshot fields populated by fiscal integrations                                                          |
| `register` (object)           | The register that took the sale: `id` and `name`. Empty strings when unknown                                     |
| `software` (object)           | The software that issued the receipt: `name` (`WCPOS`), `plugin_version`, `app_version`, `app_build`, `platform` |
| `presentation_hints` (object) | Formatting and renderer hints                                                                                    |
| `i18n` (object)               | Translated labels for bundled and custom templates                                                               |

Order number, status and dates — order

### order[​](#order "直接链接到 order")

| Field                 | Type        | Example / description                             |
| --------------------- | ----------- | ------------------------------------------------- |
| `order.id`            | number      | `1042`                                            |
| `order.number`        | string      | Human-facing order number, e.g. `"1042"`          |
| `order.currency`      | string      | ISO currency code, e.g. `"USD"`                   |
| `order.customer_note` | string      | Customer/order note                               |
| `order.wc_status`     | string      | Raw WooCommerce status slug, e.g. `"processing"`  |
| `order.status_label`  | string      | Localised status label, including custom statuses |
| `order.created_via`   | string      | Source/channel, e.g. `"woocommerce-pos"`          |
| `order.needs_payment` | boolean     | Whether a payment section should be shown         |
| `order.payment_url`   | string      | Order payment URL when available                  |
| `order.created`       | date object | Order creation date                               |
| `order.paid`          | date object | Paid date, empty strings when not paid            |
| `order.completed`     | date object | Completed date, empty strings when incomplete     |
| `order.printed`       | date object | Render-time print/reprint timestamp               |

Store name, address, contact and hours — store

### store[​](#store "直接链接到 store")

| Field                           | Type        | Example / description                                                                                                                           |
| ------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `store.id`                      | number      | Store ID, or historical ID for deleted stores                                                                                                   |
| `store.name`                    | string      | Store display name                                                                                                                              |
| `store.address.address_1`       | string      | Street address line 1                                                                                                                           |
| `store.address.address_2`       | string      | Suite/unit line                                                                                                                                 |
| `store.address.city`            | string      | City/locality                                                                                                                                   |
| `store.address.state`           | string      | State/region                                                                                                                                    |
| `store.address.postcode`        | string      | Postal code                                                                                                                                     |
| `store.address.country`         | string      | ISO country code                                                                                                                                |
| `store.address_lines`           | array       | Preformatted address lines; recommended for most templates                                                                                      |
| `store.tax_ids`                 | array       | Structured business tax IDs; loop this instead of using a single tax ID                                                                         |
| `store.phone`                   | string      | Store phone                                                                                                                                     |
| `store.email`                   | string      | Store email                                                                                                                                     |
| `store.logo`                    | string/null | Store logo URL or data URI: the store's own logo, or else the WordPress site logo unless the store turns that off. `null` when there is neither |
| `store.opening_hours`           | string/null | Compact opening-hours text                                                                                                                      |
| `store.opening_hours_vertical`  | string/null | Multi-line opening-hours block                                                                                                                  |
| `store.opening_hours_inline`    | string/null | Comma-separated opening-hours text                                                                                                              |
| `store.opening_hours_notes`     | string/null | Free-text opening-hours notes                                                                                                                   |
| `store.personal_notes`          | string/null | Receipt footer/personal note                                                                                                                    |
| `store.policies_and_conditions` | string/null | Refund, returns, or terms text                                                                                                                  |
| `store.footer_imprint`          | string/null | Legal footer imprint                                                                                                                            |

### Tax ID objects[​](#tax-id-objects "直接链接到 Tax ID objects")

`store.tax_ids` and `customer.tax_ids` contain objects with the same shape:

| Field     | Type        | Description                                                                              |
| --------- | ----------- | ---------------------------------------------------------------------------------------- |
| `type`    | string      | Identifier such as `eu_vat`, `de_steuernummer`, `au_abn`, `br_cpf`, `us_ein`, or `other` |
| `value`   | string      | Tax ID value to print                                                                    |
| `country` | string/null | ISO country code; null for `eu_vat` and `other`                                          |
| `label`   | string      | Localised display label, resolved before rendering                                       |

Example:

```
{{#store.tax_ids}}

  {{label}}: {{value}}

{{/store.tax_ids}}
```

Who served the customer — cashier

### cashier[​](#cashier "直接链接到 cashier")

| Field          | Type   | Example / description               |
| -------------- | ------ | ----------------------------------- |
| `cashier.id`   | number | WordPress user ID, `0` when unknown |
| `cashier.name` | string | Cashier display name                |

Customer name, addresses and tax IDs — customer

### customer[​](#customer "直接链接到 customer")

| Field                         | Type        | Example / description                                                                      |
| ----------------------------- | ----------- | ------------------------------------------------------------------------------------------ |
| `customer.id`                 | number/null | Customer ID, or `null` for guests                                                          |
| `customer.name`               | string      | Customer display name, or guest label                                                      |
| `customer.first_name`         | string      | The billing first name, for a greeting such as "Thanks, Nia". Empty for guests without one |
| `customer.billing_address.*`  | object      | WooCommerce billing address fields                                                         |
| `customer.shipping_address.*` | object      | WooCommerce shipping address fields                                                        |
| `customer.tax_ids`            | array       | Structured customer tax IDs snapshotted from the order                                     |

Common address keys include `first_name`, `last_name`, `company`, `address_1`, `address_2`, `city`, `state`, `postcode`, `country`, `email`, and `phone`.

Items sold — lines

### lines[​](#lines "直接链接到 lines")

Loop with `{{#lines}}...{{/lines}}`. Sample values are the espresso line from [the sample order](#receipt-map).

Every money field comes in two: the number, for a `{{#…}}` section (zero and `null` hide it, and a `null` field has no `_display` field at all), and the `_display` text, for printing. Fields marked incl/excl also come with `_incl` and `_excl` versions, each with its own `_display`.

筛选字段…试试 “stable”, “product”

key字符串

Stable line key / order item ID.

key"412"

sku字符串

Product SKU.

sku"ESP-500"

name字符串

Product or line display name.

name"Espresso Beans"

qty数字

Quantity sold.

qty2

qty\_refunded数字

Quantity refunded for this line.

qty\_refunded0

regular\_price数字金额可为空含税/不含税

Recorded regular unit price. `null` on orders without POS price history — wrap it in a section.

regular\_price17

regular\_price\_display"$17.00"

selling\_price数字金额可为空含税/不含税

Pre-coupon selling unit price — the recorded POS price when available, otherwise derived from the stored line subtotal.

selling\_price14.5

selling\_price\_display"$14.50"

unit\_savings数字金额可为空含税/不含税

Regular minus selling, clamped to zero. Zero is falsy, so guarded rows hide themselves.

unit\_savings2.5

unit\_savings\_display"$2.50"

line\_regular\_total数字金额可为空含税/不含税

Recorded regular price multiplied by quantity.

line\_regular\_total34

line\_regular\_total\_display"$34.00"

line\_selling\_total数字金额可为空含税/不含税

Pre-coupon selling price multiplied by quantity.

line\_selling\_total29

line\_selling\_total\_display"$29.00"

line\_savings数字金额可为空含税/不含税

Total regular-to-selling-price savings for this line.

line\_savings5

line\_savings\_display"$5.00"

savings\_in\_discounts布尔值

True when the line's saving is already inside `discounts`, as on orders made before v1.9.0. Use it so a saving isn't printed twice.

savings\_in\_discountsfalse

unit\_subtotal数字金额含税/不含税

WooCommerce pre-discount unit value. Do not use this as the regular price.

unit\_subtotal14.5

unit\_subtotal\_display"$14.50"

unit\_price数字金额含税/不含税

Final unit value after WooCommerce discounts.

unit\_price13.05

unit\_price\_display"$13.05"

line\_subtotal数字金额含税/不含税

Before coupon: WooCommerce's pre-discount line subtotal, the amount beside each item on the sample receipt above.

line\_subtotal29

line\_subtotal\_display"$29.00"

discounts数字金额含税/不含税

Native WooCommerce line discount as a positive value — coupons only on current orders.

discounts2.9

discounts\_display"$2.90"

line\_total数字金额含税/不含税

After coupon: the final line total, what the gallery's receipt templates print beside each item.

line\_total26.1

line\_total\_display"$26.10"

total\_refunded数字金额

Total refunded for this line as a positive value.

total\_refunded0

total\_refunded\_display""

taxes数组

Per-rate tax rows for this line.

—

meta数组

Order item meta as `{key, value}` pairs.

—

attributes数组

Product/variation attributes as `{key, value}` pairs.

—

### Displaying regular price and savings[​](#displaying-regular-price-and-savings "直接链接到 Displaying regular price and savings")

For a unit-price layout, show the recorded regular price, selling price, and saving like this:

```
{{#lines}}

  {{#unit_savings}}

    <span style="text-decoration: line-through;">{{regular_price_display}}</span>

    <span>{{selling_price_display}}</span>

    <span>{{i18n.savings}}: -{{unit_savings_display}}</span>

  {{/unit_savings}}

{{/lines}}
```

Use the line-total fields when quantity matters:

```
{{#lines}}

  {{#line_savings}}

    <span style="text-decoration: line-through;">{{line_regular_total_display}}</span>

    <span>{{i18n.savings}}: -{{line_savings_display}}</span>

  {{/line_savings}}

{{/lines}}
```

`selling_price` is the price before coupons. Use `unit_price` or `line_total` for the final amount after WooCommerce discounts.

Reprinting orders created before v1.9.0

Older WCPOS orders may already include the regular-to-selling-price reduction in `discounts`. If your custom template prints both line savings and line discounts, use `savings_in_discounts` to avoid showing the same reduction twice:

```
{{#lines}}

  {{#line_savings}}

    <span style="text-decoration: line-through;">{{line_regular_total_display}}</span>

    {{^savings_in_discounts}}

      <span>{{i18n.savings}}: -{{line_savings_display}}</span>

    {{/savings_in_discounts}}

  {{/line_savings}}

  {{#discounts}}

    <span>{{i18n.discount}}: -{{discounts_display}}</span>

  {{/discounts}}

{{/lines}}
```

If the template does not print a line-level `discounts` row, keep showing `line_savings` even when `savings_in_discounts` is true. The bundled templates handle this distinction automatically.

Fees and shipping — fees, shipping

### fees and shipping[​](#fees-and-shipping "直接链接到 fees and shipping")

Loop with `{{#fees}}...{{/fees}}` and `{{#shipping}}...{{/shipping}}`.

| Field                       | Type   | Description                                   |
| --------------------------- | ------ | --------------------------------------------- |
| `label`                     | string | Fee label or shipping method name             |
| `method_id`                 | string | Shipping method ID (shipping only)            |
| `total` / `_incl` / `_excl` | number | Display-side, inclusive, and exclusive totals |
| `taxes`                     | array  | Per-rate tax rows                             |
| `meta`                      | array  | `{key, value}` meta pairs                     |

Formatted variants: `total_display`, `total_incl_display`, and `total_excl_display`.

Coupons and discounts — discounts

### discounts[​](#discounts "直接链接到 discounts")

Loop with `{{#discounts}}...{{/discounts}}`.

| Field                       | Type   | Description                                                                                                                    |
| --------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `label`                     | string | Coupon description or code fallback. A discount added in the POS cart reads `Discount`, or `Discount (10%)` for a percentage   |
| `code`                      | string | Coupon code                                                                                                                    |
| `discount_type`             | string | WooCommerce coupon type slug, for example `fixed_cart`, `percent`, or `fixed_product`. Empty when the coupon no longer exists. |
| `total` / `_incl` / `_excl` | number | Discount amount as a positive value                                                                                            |

Formatted variants: `total_display`, `total_incl_display`, and `total_excl_display`. Add your own minus sign in the template if you want discounts shown as negative rows.

`discount_type` was added in Receipt Data v1.2. Fiscal receipt snapshots captured before then do not carry it.

Totals, amounts paid, refunds and item counts — totals

### totals[​](#totals "直接链接到 totals")

Sample values are from [the sample order](#receipt-map), which later received a $7.25 partial refund.

Money fields follow the same pairing as line items: a bare number for guards and a `_display` string for printing, with `_incl`/`_excl` variants where marked.

筛选字段…试试 “discounts”, “discount”

subtotal数字金额含税/不含税

Order subtotal before discounts.

subtotal52.75

subtotal\_display"$52.75"

discount\_total数字金额含税/不含税

Order discount total as a positive value — coupons only on current orders.

discount\_total5.28

discount\_total\_display"$5.28"

sale\_savings\_total数字金额可为空含税/不含税

Total recorded regular-to-selling-price savings across product lines, including catalogue sales and till price changes.

sale\_savings\_total5

sale\_savings\_total\_display"$5.00"

total\_saved数字金额可为空含税/不含税

Combined WooCommerce discounts and regular-price savings, with legacy overlap removed. The one customer-facing figure for everything saved.

total\_saved10.28

total\_saved\_display"$10.28"

total\_saved\_complete布尔值

Whether the receipt has enough recorded price data to calculate the complete savings totals.

total\_saved\_completetrue

tax\_total数字金额

Total tax amount.

tax\_total0

tax\_total\_display"$0.00"

total数字金额含税/不含税

Order grand total, following the tax display setting: with prices shown excluding tax it is the total minus tax. `total_incl` is always the amount charged.

total59.97

total\_display"$59.97"

paid\_total数字金额

Amount paid / applied.

paid\_total59.97

paid\_total\_display"$59.97"

change\_total数字金额

Change returned to the customer.

change\_total0

change\_total\_display""

refund\_total数字金额

Total refunded as a positive value.

refund\_total7.25

refund\_total\_display"$7.25"

net\_total数字金额

Total minus refunds, clamped to zero. `0` when nothing was refunded, so guard it with `refund_total`.

net\_total52.72

net\_total\_display"$52.72"

total\_qty数字

Sum of line item quantities.

total\_qty4

line\_count数字

Count of product line rows.

line\_count3

Use `total_saved` when you want one customer-facing figure for everything saved. Do not calculate it by adding `discount_total` and `sale_savings_total` in the template: orders created before v1.9.0 may already include their POS price saving in WooCommerce's discount total. The canonical `total_saved` field detects and removes that overlap.

Savings totals are `null` and `total_saved_complete` is false when any product line lacks enough recorded price data for a reliable aggregate. Guard the row with `total_saved_complete`, then use `total_saved` to hide a zero value:

```
{{#totals.total_saved_complete}}

  {{#totals.total_saved}}

    <span>{{i18n.total_saved}}: {{totals.total_saved_display}}</span>

  {{/totals.total_saved}}

{{/totals.total_saved_complete}}
```

The bundled templates print **Total saved** from the tax-inclusive variant, `totals.total_saved_incl_display`, inside a single `{{#totals.total_saved_incl}}` guard. That one guard is enough because the value is `null` when the price history is incomplete and zero when nothing was saved.

Tax rows — tax, tax\_summary

### tax and tax\_summary[​](#tax-and-tax_summary "直接链接到 tax and tax_summary")

Use `tax` for display-mode guards and `tax_summary` for itemized rate rows.

| Tax field                | Type    | Description                               |
| ------------------------ | ------- | ----------------------------------------- |
| `tax.display`            | string  | `incl` or `excl`                          |
| `tax.display_incl`       | boolean | True when prices display inclusive of tax |
| `tax.display_excl`       | boolean | True when prices display exclusive of tax |
| `tax.breakdown`          | string  | `hidden`, `single`, or `itemized`         |
| `tax.breakdown_hidden`   | boolean | True when tax rows should be hidden       |
| `tax.breakdown_single`   | boolean | True when a single tax total is preferred |
| `tax.breakdown_itemized` | boolean | True when per-rate rows are preferred     |
| `has_tax_summary`        | boolean | True when `tax_summary` contains rows     |

Loop `tax_summary` with `{{#tax_summary}}...{{/tax_summary}}`.

| Field                 | Type        | Description                    |
| --------------------- | ----------- | ------------------------------ |
| `code`                | string      | Tax rate ID/code               |
| `rate`                | number/null | Rate percentage when resolved  |
| `label`               | string      | Tax rate label                 |
| `compound`            | boolean     | Whether the rate is compounded |
| `taxable_amount_excl` | number/null | Taxable base excluding tax     |
| `tax_amount`          | number      | Tax collected                  |
| `taxable_amount_incl` | number/null | Taxable base including tax     |

Formatted variants: `taxable_amount_excl_display`, `tax_amount_display`, and `taxable_amount_incl_display`.

Payments taken — payments

### payments[​](#payments "直接链接到 payments")

Loop with `{{#payments}}...{{/payments}}`.

| Field            | Type   | Description                       |
| ---------------- | ------ | --------------------------------- |
| `method_id`      | string | Payment method identifier         |
| `method_title`   | string | Payment method display title      |
| `amount`         | number | Amount applied to the order       |
| `transaction_id` | string | Gateway transaction ID            |
| `tendered`       | number | Cash amount tendered when present |
| `change`         | number | Cash change returned when present |

Formatted variants: `amount_display`, `tendered_display`, and `change_display`.

Refunds — refunds

### refunds[​](#refunds "直接链接到 refunds")

Loop with `{{#refunds}}...{{/refunds}}`. Refund amounts are positive numbers: the template adds a minus sign, or prints them in their own returned-items block.

| Field              | Type        | Description                                                                                                    |
| ------------------ | ----------- | -------------------------------------------------------------------------------------------------------------- |
| `id`               | number      | Refund record ID                                                                                               |
| `date`             | date object | Refund creation date                                                                                           |
| `amount`           | number      | Refund total                                                                                                   |
| `subtotal`         | number      | Refunded line subtotal                                                                                         |
| `tax_total`        | number      | Tax refunded                                                                                                   |
| `shipping_total`   | number      | Shipping amount refunded                                                                                       |
| `shipping_tax`     | number      | Shipping tax refunded                                                                                          |
| `reason`           | string      | Refund reason                                                                                                  |
| `refunded_by_id`   | number/null | User ID that issued the refund                                                                                 |
| `refunded_by_name` | string      | User display name that issued the refund                                                                       |
| `refunded_payment` | boolean     | Whether the payment was refunded through the gateway                                                           |
| `destination`      | string      | Where the money went back: `original_method`, `cash` or `manual` for a refund made in the POS; empty otherwise |
| `gateway_id`       | string      | Gateway ID used for the refund                                                                                 |
| `gateway_title`    | string      | Gateway display title                                                                                          |
| `processing_mode`  | string      | Provider/manual processing mode                                                                                |
| `lines`            | array       | Refunded product rows                                                                                          |
| `fees`             | array       | Refunded fee rows                                                                                              |
| `shipping`         | array       | Refunded shipping rows                                                                                         |

Refund line fields include `name`, `sku`, `qty`, `total`, `total_incl`, `total_excl`, and `taxes`; templates rendered in the POS app also get `line_total` and `unit_total`. Refund fee and shipping rows use `label`, `total`, `total_incl`, `total_excl`, and `taxes`, and shipping rows add `method_id`. Display variants are added for totals and tax amounts.

Fiscal records — fiscal

### fiscal[​](#fiscal "直接链接到 fiscal")

Fiscal integrations and WCPOS Pro fill in the identity fields, such as the receipt number, hash and QR payload. The document fields say what kind of document is printing, so a template can print a refund or a register report differently from a sale.

| Field                             | Type             | Description                                                                                  |
| --------------------------------- | ---------------- | -------------------------------------------------------------------------------------------- |
| `fiscal.document_type`            | string           | `sale` by default; also `refund`, `void`, `cancellation`, `closure`, `xreport` or `handover` |
| `fiscal.is_sale_document`         | boolean          | True for a sale. Use the `is_…` flags as section guards                                      |
| `fiscal.is_refund_document`       | boolean          | True for a refund                                                                            |
| `fiscal.is_void_document`         | boolean          | True for a void: a sale cancelled before it was completed                                    |
| `fiscal.is_cancellation_document` | boolean          | True for a cancellation: a completed sale cancelled later                                    |
| `fiscal.is_closure_document`      | boolean          | True for a register closure                                                                  |
| `fiscal.is_x_report`              | boolean          | True for an X-report                                                                         |
| `fiscal.is_handover`              | boolean          | True for a hand-over slip                                                                    |
| `fiscal.corrects`                 | string           | On a refund, the identity of the sale it corrects                                            |
| `fiscal.sale_time`                | date object/null | When the till recorded the sale, in the till's timezone                                      |
| `fiscal.sale_tz`                  | string           | The till's timezone, e.g. `"Europe/Berlin"`                                                  |
| `fiscal.received_at`              | date object/null | When the store's server received the sale                                                    |
| `fiscal.sale_counter`             | number/null      | The till's own sale counter                                                                  |
| `fiscal.immutable_id`             | string           | Immutable fiscal identifier                                                                  |
| `fiscal.receipt_number`           | string           | Fiscal receipt number                                                                        |
| `fiscal.sequence`                 | number/null      | Sequence counter                                                                             |
| `fiscal.hash`                     | string           | Hash/signature value                                                                         |
| `fiscal.qr_payload`               | string           | QR payload for fiscal verification                                                           |
| `fiscal.tax_agency_code`          | string           | Tax authority code                                                                           |
| `fiscal.signed_at`                | string           | Fiscal signing timestamp                                                                     |
| `fiscal.signature_excerpt`        | string           | Truncated signature for display                                                              |
| `fiscal.document_label`           | string           | Document label, e.g. Tax Invoice                                                             |
| `fiscal.is_reprint`               | boolean          | Whether this render is a reprint                                                             |
| `fiscal.reprint_count`            | number           | Reprint count                                                                                |
| `fiscal.extra_fields`             | array/object     | Jurisdiction-specific values, usually a list of `{label, value}` rows                        |

Print the extra fields with a loop:

```
{{#fiscal.extra_fields}}

  {{label}}: {{value}}

{{/fiscal.extra_fields}}
```

Formatting — presentation\_hints

### presentation\_hints[​](#presentation_hints "直接链接到 presentation_hints")

These fields are mostly for the app and the server, which use them to format the receipt. Templates rendered by the server can print all of them; templates rendered in the POS app get only `display_tax`, `prices_entered_with_tax`, `rounding_mode`, `locale` and `order_barcode_type`.

| Field                                         | Type         | Description                                                                                                                                                                                                               |
| --------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `presentation_hints.display_tax`              | string       | `incl` or `excl`. Filled in by the app; the server leaves it out                                                                                                                                                          |
| `presentation_hints.hour12`                   | boolean/null | True when the store's time format uses a 12-hour clock                                                                                                                                                                    |
| `presentation_hints.hour_token`               | string/null  | The hour pattern from the store's time format: `h`, `hh`, `H` or `HH`                                                                                                                                                     |
| `presentation_hints.prices_entered_with_tax`  | boolean      | Whether catalogue prices include tax                                                                                                                                                                                      |
| `presentation_hints.rounding_mode`            | string       | WooCommerce tax rounding setting                                                                                                                                                                                          |
| `presentation_hints.locale`                   | string       | Locale used for formatting                                                                                                                                                                                                |
| `presentation_hints.timezone`                 | string       | Receipt timezone                                                                                                                                                                                                          |
| `presentation_hints.currency_position`        | string       | Currency symbol position                                                                                                                                                                                                  |
| `presentation_hints.currency_symbol`          | string       | Currency symbol                                                                                                                                                                                                           |
| `presentation_hints.price_thousand_separator` | string       | Thousands separator                                                                                                                                                                                                       |
| `presentation_hints.price_decimal_separator`  | string       | Decimal separator                                                                                                                                                                                                         |
| `presentation_hints.price_num_decimals`       | number       | Decimal places                                                                                                                                                                                                            |
| `presentation_hints.price_display_suffix`     | string       | WooCommerce price display suffix                                                                                                                                                                                          |
| `presentation_hints.order_barcode_type`       | string       | Barcode type for a template that reads it: `code128` (the default), `qrcode`, `ean13`, `ean8` or `upca`. Filled in by the app; the server leaves it out, and the gallery templates set their barcode type in the template |

The pre-formatted money fields (the `*_display` values such as `totals.total_display`) render amounts with the **currency symbol** in the order's currency, using the position and separators above — so receipts show `$12.00`, not `USD 12.00`. The raw `order.currency` field remains the ISO code for any logic in your template.

Receipt wording — i18n

### i18n[​](#i18n "直接链接到 i18n")

Use `i18n` labels instead of hardcoding text where possible:

```
{{i18n.order}} #{{order.number}}

{{i18n.cashier}}: {{cashier.name}}

{{i18n.total}}: {{totals.total_display}}
```

Common keys include `order`, `date`, `cashier`, `customer`, `item`, `sku`, `qty`, `unit_price`, `regular_price`, `selling_price`, `savings`, `discount`, `subtotal`, `total_saved`, `total`, `tax`, `paid`, `tendered`, `change`, `tax_summary`, `refunded`, `net_total`, `customer_note`, `thank_you_purchase`, `opening_hours`, the fiscal labels `copy` (prints COPY), `reprint`, `register`, `sale_time`, `software`, `document_refund`, `document_void` and `document_cancellation`, and the tax-ID label keys such as `store_tax_id_label_eu_vat` and `customer_tax_id_label_other`. Extra keys may be added by extensions.

## How the prices relate[​](#price-model "直接链接到 How the prices relate")

One item on the receipt carries several prices, and the names are easiest to follow on the amounts themselves. This is the espresso line from the sample order — a $17.00 product on sale for $14.50, with a 10% coupon on top:

Espresso Beans — one unit (the order has two)

13.05 paid

1.45

2.50

0regular price 17.00

顾客支付金额`unit_price → 13.05 · line_total → 26.10`

优惠券折扣（SUMMER10）`lines[].discounts → 此商品行优惠 2.90`

较原价节省的金额`unit_savings → 2.50 · line_savings → 5.00`

Sale savings across the orde&#x72;**`totals.sale_savings_total` = 5.00**

All coupon discounts across the orde&#x72;**`totals.discount_total` = 5.28**

Savings + discounts, legacy overlap remove&#x64;**`totals.total_saved` = 10.28**

A sale saving is the gap between the regular price and the selling price. A discount is what a coupon took off, as WooCommerce works it out. WooCommerce's order totals and reports hold only the discounts, so `total_saved` adds the two into one figure for the customer.

## Rendering rules[​](#rendering-rules "直接链接到 Rendering rules")

How money, prices with or without tax, and dates print. Open the one you need.

Print money, and hide zero amounts

### Currency fields[​](#currency-fields "直接链接到 Currency fields")

Money fields stay numbers, and each one gets a `_display` field formatted in the store's language and currency:

| Numeric field              | Display field                      |
| -------------------------- | ---------------------------------- |
| `totals.total`             | `totals.total_display`             |
| `lines[].line_total`       | `lines[].line_total_display`       |
| `payments[].amount`        | `payments[].amount_display`        |
| `tax_summary[].tax_amount` | `tax_summary[].tax_amount_display` |

Print the `_display` field. Use the number only for a section or for machine-readable output: `{{#totals.change_total}}…{{/totals.change_total}}` leaves its row out when the amount is zero.

Print prices with or without tax

### Tax display-aware fields[​](#tax-display-aware-fields "直接链接到 Tax display-aware fields")

Several fields come in three versions: with tax (`_incl`), without tax (`_excl`), and a plain one that follows the store's setting for showing prices in the cart with or without tax.

| Convenience field            | Inclusive field                   | Exclusive field                   |
| ---------------------------- | --------------------------------- | --------------------------------- |
| `lines[].regular_price`      | `lines[].regular_price_incl`      | `lines[].regular_price_excl`      |
| `lines[].selling_price`      | `lines[].selling_price_incl`      | `lines[].selling_price_excl`      |
| `lines[].unit_savings`       | `lines[].unit_savings_incl`       | `lines[].unit_savings_excl`       |
| `lines[].line_regular_total` | `lines[].line_regular_total_incl` | `lines[].line_regular_total_excl` |
| `lines[].line_selling_total` | `lines[].line_selling_total_incl` | `lines[].line_selling_total_excl` |
| `lines[].line_savings`       | `lines[].line_savings_incl`       | `lines[].line_savings_excl`       |
| `lines[].unit_price`         | `lines[].unit_price_incl`         | `lines[].unit_price_excl`         |
| `lines[].unit_subtotal`      | `lines[].unit_subtotal_incl`      | `lines[].unit_subtotal_excl`      |
| `lines[].line_subtotal`      | `lines[].line_subtotal_incl`      | `lines[].line_subtotal_excl`      |
| `lines[].discounts`          | `lines[].discounts_incl`          | `lines[].discounts_excl`          |
| `lines[].line_total`         | `lines[].line_total_incl`         | `lines[].line_total_excl`         |
| `fees[].total`               | `fees[].total_incl`               | `fees[].total_excl`               |
| `shipping[].total`           | `shipping[].total_incl`           | `shipping[].total_excl`           |
| `discounts[].total`          | `discounts[].total_incl`          | `discounts[].total_excl`          |
| `totals.subtotal`            | `totals.subtotal_incl`            | `totals.subtotal_excl`            |
| `totals.discount_total`      | `totals.discount_total_incl`      | `totals.discount_total_excl`      |
| `totals.sale_savings_total`  | `totals.sale_savings_total_incl`  | `totals.sale_savings_total_excl`  |
| `totals.total_saved`         | `totals.total_saved_incl`         | `totals.total_saved_excl`         |
| `totals.total`               | `totals.total_incl`               | `totals.total_excl`               |

Print dates and times

### Date objects[​](#date-objects "直接链接到 Date objects")

Each date comes ready-formatted in several ways, so a template never has to format a date itself.

| Field                                               | Description                    |
| --------------------------------------------------- | ------------------------------ |
| `datetime`, `date`, `time`                          | Default date/time strings      |
| `datetime_short`, `datetime_long`, `datetime_full`  | Locale-aware combined formats  |
| `date_short`, `date_long`, `date_full`              | Locale-aware date-only formats |
| `date_ymd`, `date_dmy`, `date_mdy`                  | Fixed-order date formats       |
| `weekday_short`, `weekday_long`                     | Day names                      |
| `day`, `month`, `month_short`, `month_long`, `year` | Individual date parts          |

Available date objects: `order.created`, `order.paid`, `order.completed`, `order.printed`, `refunds[].date`, `fiscal.sale_time`, and `fiscal.received_at`. `order.printed` is refreshed at render time, which is useful for reprints. The two `fiscal` dates are `null` when the receipt has no fiscal record, so wrap them in a section.

## Extending receipt data[​](#extending "直接链接到 Extending receipt data")

A plugin can add its own fields to the receipt data through the `wcpos_receipt_data` filter.

The filter — its arguments, the six modes and an example

WCPOS keeps the fields above free of any one plugin's data. When a plugin needs the receipt to know something WooCommerce does not model, it adds that itself through the `wcpos_receipt_data` filter, the same way plugins filter WooCommerce's own order totals. The filter runs on every receipt the server builds: live receipts, fiscal snapshots at payment time, PDF downloads, and legacy PHP templates. Before WCPOS 2.0 this filter was named `woocommerce_pos_receipt_data`; that name still works but is deprecated since 2.0 and is removed in 2.2 at the earliest (see [Hook naming](/zh-CN/manage-store/add-ons.md#hook-naming)).

The third argument, `$mode`, says which document is being built: `live`, `fiscal`, `refund`, `preview` (sample receipts in the template editor and gallery), `closure` or `xreport` (register closure and X-report documents). In `preview`, `closure` and `xreport` the order is an unsaved one whose ID is `0`; a plugin that needs a saved order should return `$data` unchanged when `$order->get_id()` is `0`.

```
add_filter( 'wcpos_receipt_data', function ( array $data, WC_Abstract_Order $order, string $mode ) {

    foreach ( $data['discounts'] as &$row ) {

        if ( 'smart_coupon' === $row['discount_type'] ) {

            $row['gift_card'] = true;

        }

    }

    return $data;

}, 10, 3 );
```

A template can then guard on the new key like any other section:

```
{{#discounts}}

  {{#gift_card}}Gift Card{{/gift_card}}{{^gift_card}}{{i18n.discount}}{{/gift_card}}{{#label}}: {{label}}{{/label}}

{{/discounts}}
```

Keys defined in the schema should keep their documented types. Added keys are not part of the schema, so they do not appear in the template editor's field picker, and fiscal snapshots only carry what the filter added at the time the order was paid. The filter is available from WCPOS 1.10.8.

Which receipts print an added key

Every added key reaches the receipts the server renders itself: PDF downloads and legacy PHP templates. HTML and thermal templates rendered in the POS app rebuild the data first: a key added inside `order`, `store`, `cashier` or `customer` comes through, but a key added anywhere else, such as on the discounts row above, is left out. <!-- -->On a live receipt with a fiscal snapshot, the fiscal identity, `register` and `software` are copied from the snapshot after the filter runs, so changing them in this filter has no effect; enrich the snapshot instead.

## If something goes wrong[​](#if-something-goes-wrong "直接链接到 If something goes wrong")

**A row prints `$0.00` on one receipt and nothing on another.** Some `_display` fields, such as `totals.change_total_display`, `totals.refund_total_display` and `payments[].tendered_display`, are empty at zero when the server renders the receipt, and `$0.00` when the app does. Put the row inside a section on the number instead, so it is left out of both: `{{#totals.change_total}}…{{/totals.change_total}}`.

**The Total saved row is missing.** `totals.total_saved_complete` is false: at least one item has no recorded regular price, so the saving can't be worked out. Orders rung up before WCPOS 1.9.0 are the usual case.

**The total is less than the customer paid.** The store shows prices excluding tax, so `totals.total` is the total before tax. Print `totals.total_incl_display` for the amount charged. The legacy PHP receipt that ships with WCPOS prints that amount.

**A field prints in the PDF download but not in the POS.** Templates rendered in the app rebuild the data first and leave out a few fields, which print only in PDF downloads and legacy PHP templates. Print a field from the list below only in those, or guard it with a section so the POS receipt leaves it out.

Fields that differ between PDF and POS receipts

* `lines[].attributes`, `lines[].total_refunded_display` and `lines[].unit_subtotal_display` (with its `_incl` and `_excl` twins)
* `software.platform`
* `presentation_hints` other than `display_tax`, `prices_entered_with_tax`, `rounding_mode`, `locale` and `order_barcode_type`
* customer tax IDs of the German, Dutch, French, UK company and Swiss types
* keys a plugin adds outside `order`, `store`, `cashier` and `customer`; see [Extending receipt data](#extending)

## Versions[​](#versions "直接链接到 Versions")

The receipt data has its own version number, separate from the plugin's. Newer fields are missing from older receipts, such as a fiscal snapshot taken before the field existed, so guard them with a section.

| Version | Added                                                                                                                                                                                    |
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1.1     | Regular price, selling price and savings for each item, and the order's savings totals, including **Total saved**. None of them change the order totals or WooCommerce reports           |
| 1.2     | `discounts[].discount_type`                                                                                                                                                              |
| 1.3     | `customer.first_name` and the customer display labels in `i18n`                                                                                                                          |
| 1.4     | `register`, `software`, the fiscal document fields (`fiscal.document_type`, the `is_…` flags, `sale_time`, `received_at`, `sale_tz`, `sale_counter`, `corrects`) and their `i18n` labels |

## Related Documentation[​](#related-documentation "直接链接到 Related Documentation")

[HTML TemplatesWrite a receipt template in HTML and Mustache.](/zh-CN/settings/receipt-templates/html-templates.md)

[Thermal TemplatesWrite a template for a receipt printer.](/zh-CN/settings/receipt-templates/thermal-templates.md)

[Customise Your ReceiptPick a template, or have AI change one for you.](/zh-CN/settings/receipt-templates/customise-receipt.md)
