> For the complete documentation index, see [llms.txt](https://developers.bead.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.bead.xyz/payments/receipts.md).

# Receipts

## Receipts

Bead payment methods require a small number of fields beyond what you already include on a standard card receipt. This page covers what's required, what's additionally available, and how delivery works.

### Required fields

The following fields must be included on all Bead payment receipts when applicable:

| Field                | When required                           | API source                                                                                      |
| -------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Payment method       | Always                                  | `amounts.paid.inPaymentCurrency.currency.name` on `GET /Payments/{id}` (e.g. Bitcoin Lightning) |
| Final payment status | Always                                  | `statusCode` on the payment object                                                              |
| Exchange rate        | When a crypto-to-fiat conversion occurs | `conversions[].executedExchangeRate` on `GET /Payments/{id}`                                    |

Fields your existing receipt already covers — date, time, amount, merchant name, taxes, support contact — do not need to change.

### The `conversions` array

The `conversions` field is returned as an array on `GET /Payments/{id}` and in the payment result webhook payload. It is present on completed crypto payments and absent on non-crypto payments.

**Array size:** By design, `conversions` will contain exactly one entry for any given payment today. The array type is forward-looking; the system mutates a single conversion entry through its lifecycle rather than appending new ones. You can safely treat it as single-entry, but the defensive pattern below is recommended so your integration is robust to any future changes.

#### Conversion `statusCode`

Each entry in `conversions` has its own `statusCode` field — this is separate from the payment's top-level `statusCode`. The conversion `statusCode` values are:

| Value       | Meaning                                                                    |
| ----------- | -------------------------------------------------------------------------- |
| `quoted`    | A rate has been locked for the payment, but the funds have not yet settled |
| `executed`  | The conversion has completed and the exchange rate is final                |
| `completed` | The conversion and settlement are fully resolved                           |
| `cancelled` | The conversion was cancelled (e.g. payment expired or was invalid)         |

**Only read `executedExchangeRate` once `statusCode` is `executed` or `completed`.** Before that state, this field is zero/default and does not reflect a real rate.

#### Reading the exchange rate

The recommended pattern for reading the exchange rate from the `conversions` array:

1. Check that `conversions` is non-empty.
2. Find the entry where `statusCode` is `"executed"` or `"completed"`. In practice there is only one entry, but keying off `statusCode` rather than position is the correct approach.
3. Read `executedExchangeRate` from that entry.

**Example (JavaScript):**

```javascript
const conversion = payment.conversions?.find(
  c => c.statusCode === "executed" || c.statusCode === "completed"
) ?? payment.conversions?.[0];

const exchangeRate = conversion?.executedExchangeRate;
```

#### Field reference

| Field                   | Notes                                                                                                                                                                                                                                                                                     |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `statusCode`            | Conversion lifecycle state. Read other fields only when this is `executed` or `completed`.                                                                                                                                                                                                |
| `quotedExchangeRate`    | The rate locked at the time the payment was created.                                                                                                                                                                                                                                      |
| `presentedExchangeRate` | The rate shown to the payer at checkout.                                                                                                                                                                                                                                                  |
| `executedExchangeRate`  | The realized settlement rate. **Use this for receipt display.** Today this matches the quoted/presented rate in all normal payment flows; it may differ in edge cases involving payment exceptions (underpaid, cancelled, expired) where funds convert before reaching a suspense wallet. |

### Additional fields available

The following fields are available from `GET /Payments/{id}` and are useful to include on receipts for crypto payments, but are not required by Bead.

| Field                   | API source                                            | Notes                             |
| ----------------------- | ----------------------------------------------------- | --------------------------------- |
| Payment code            | `paymentCode`                                         | Unique identifier for the payment |
| Payment date/time       | `receivedTime`                                        | ISO 8601 timestamp                |
| Crypto amount paid      | `amounts.paid.inPaymentCurrency.amount`               | Amount in the payment currency    |
| Crypto asset            | `amounts.paid.inPaymentCurrency.currency.code`        | e.g. BTC                          |
| Requested fiat amount   | `amounts.requested.inRequestedCurrency.amount`        | The amount the merchant requested |
| Requested fiat currency | `amounts.requested.inRequestedCurrency.currency.code` | e.g. USD                          |

### When to issue the receipt

Generate or finalize the receipt after the payment reaches a final state. All fields above are available from a single call: `GET /Payments/{id}`. The payment result webhook also includes `conversions[]`, so you can read the exchange rate directly from the webhook payload without a follow-up GET call. See [Payment Statuses](/payments/payment-statuses.md) for the complete list of final states.

### Receipt delivery

**Integrator-delivered (default):** You deliver the receipt to the consumer using your existing channels — printed, email, SMS, in-app, or portal.

**Bead-delivered (optional):** Enable `emailReceipt` and/or `smsReceipt` on the Create Payment request to have Bead send the receipt directly to the consumer. When enabled, you do not need to send a separate consumer receipt. You remain responsible for merchant-side records, back-office retrievability, and retaining receipt records and delivery evidence for at least 7 years.

### Retention

Retain receipts and evidence of delivery or access for at least 7 years and make them available on request for audit or regulatory review.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers.bead.xyz/payments/receipts.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
