# The sale line

> Report the sale with a single line of HTML on the receipt page – no JavaScript, and Danish amounts are parsed correctly.

The sale line is the simplest way to report a sale: a hidden element on the receipt page that [track.js](https://www.affilyflow.com/en/docs/reference/track-js) finds and reports. There is no JavaScript to write, so a template variable can't break the code.

## The line

```html title="Receipt page"
<div hidden data-affilyflow-order="1008" data-affilyflow-total="499,00"></div>
```

Replace `1008` and `499,00` with your template variables – the order number and the goods amount after discount, excluding VAT and shipping. Which variables those are on your system is covered in [Custom-built store](https://www.affilyflow.com/en/docs/store/custom-built).

The line only works when track.js is on the same page. Add the script to every page, including the receipt.

## Attributes

| Attribute | Required | Value |
|---|---|---|
| `data-affilyflow-order` | Yes | The order number – or `?parameter` to read it from the page URL. |
| `data-affilyflow-total` | Yes | The amount – or `#id` to read the text of the element with that ID. |
| `data-affilyflow-vat` | No | The VAT percentage included in the amount (e.g. `25`). It is subtracted. |
| `data-affilyflow-currency` | No | Currency code, e.g. `EUR`. Without it, the store's settlement currency is used. |
| `data-affilyflow-coupon` | No | The customer's discount code(s), e.g. `ANNA10`. Separate several with commas. See [Discount codes](#discount-codes). |

Use `hidden` so the element isn't shown. It makes no difference to tracking.

## Values from the page

If the site builder has no template variables (e.g. Webflow), the line can read the values from the page itself:

- `data-affilyflow-order="?orderId"` reads the `orderId` parameter in the URL (`/order-confirmation?orderId=WF-55` gives `WF-55`).
- `data-affilyflow-total="#af-total"` reads the text of the element with `id="af-total"`.
- `data-affilyflow-vat="25"` subtracts 25 % VAT when the amount on the page includes VAT.

```html title="Receipt page · Webflow"
<div hidden data-affilyflow-order="?orderId" data-affilyflow-total="#af-total" data-affilyflow-vat="25"></div>
```

With `1.249,00 kr.` in `#af-total`, 999.20 is reported (1,249 without 25 % VAT).

## How the amount is read

- Danish amounts are parsed: `499,00`, `1.249,00`, `1.249,-`, `499,00 kr.` and `kr. 499`.
- `1.249` is read as 1249 – in the line, a dot followed by three digits is always a thousands separator, because the value comes from page text.
- Machine numbers such as `1249.5` and `89.90` are used as is.
- With `data-affilyflow-vat` the amount is divided by 1 + VAT/100 and rounded to two decimals. The value must be above 0 and below 100.

The amount must be what commission is calculated on: goods after discount, excluding VAT and shipping.

## Discount codes

Put the customer's discount code in `data-affilyflow-coupon`, and a [personal discount code](https://www.affilyflow.com/en/docs/store/personal-discount-codes) the store has given an affiliate earns that affiliate commission – even without a click:

```html title="Receipt page · with a discount code"
<div hidden data-affilyflow-order="1008" data-affilyflow-total="499,00" data-affilyflow-coupon="ANNA10"></div>
```

- If the customer has a valid click, the click always wins. The code is sent along, so a personal code can still attribute the sale if the click has expired.
- Without a click the sale is only sent when one of the codes is a personal code. The script compares with a list of one-way fingerprints of the store's personal codes, so an order with a general code or no code never leaves the page.
- A general code for all affiliates earns no commission on its own – only the link does.
- If there is no code, leave the attribute out or empty.

## Timing

Many pages render the receipt after load (Livewire, React, Webflow). The line handles it:

- track.js looks for the element when the page has loaded and watches for new elements for as long as the page lives – also when the receipt is only rendered by in-page navigation (Next, Nuxt, React, Livewire) minutes later.
- If the order number is missing or the amount has no digits yet, the script waits up to 20 seconds for them.
- Each element is reported once: it is marked with the order number in `data-affilyflow-sent` when read. If the same element later gets a new order number, it is reported again.

A reloaded receipt is not sent again: the browser remembers the order number for 30 days, and the server never counts the same order number twice in the same program.

## When nothing is sent

- **No affiliate click in the browser** – and no personal discount code. A normal purchase without an affiliate is not sent, and no error is logged. Test with the test link from the store dashboard – see [Testing and troubleshooting](https://www.affilyflow.com/en/docs/store/testing-and-troubleshooting).
- **No consent yet.** With `data-consent="required"` the sale waits until consent is settled. See [Consent and cookies](https://www.affilyflow.com/en/docs/store/consent-and-cookies).
- **The order number is missing or a placeholder.** The line requires an order number. `ORDRE_ID`, `{{ $order->id }}`, `[OrderID]`, `<…>` and `%OrderID%` that weren't filled in are rejected.
- **The amount is empty or 0.**

The last two write an error to the browser console:

```text title="Browser console"
Affilyflow: data-affilyflow-order must be the order number – the sale was not recorded.
Affilyflow: data-affilyflow-total must be the amount (goods excl. VAT and shipping) – the sale was not recorded.
```

> [!TIP]
> The live test under Setup in the store dashboard shows the amount that arrived and asks whether it matches your test order. It catches both VAT and shipping that slipped in.

## The line or JavaScript?

The line and [`affilyflow.conversion()`](https://www.affilyflow.com/en/docs/reference/track-js#affilyflow-conversion) report the same sale. Use the line unless you already have a script that works – the old call works unchanged. Use only one of them on the same receipt, or send the same order number in both, so the duplicate guard stops the second.

Source: https://www.affilyflow.com/en/docs/reference/sale-line
