> For the complete index of the 402pay docs, see [llms.txt](https://402pay.co/docs/llms.txt).

# Reporting and reconciliation

Which amounts to report, how payments match your wallet, and how to export a period.

Every payment carries what you charged, what arrived, what it was worth in US dollars and where it landed, and every deposit is a transaction in your wallet. This page shows which field to use for what, and how to export a period.

## Amounts on a payment

| Field | What it holds |
| --- | --- |
| `amount, currency` | The price you charged, a decimal string in your currency, such as `"49.00"`. |
| `amount_received` | What arrived, in the same currency at the quoted rate. `"0.00"` until funds arrive, and `amount` once it's paid in full. |
| `reporting` | The payment's amounts as decimal strings in US dollars, for totals across currencies. `reporting.amount` is the price in US dollars. |
| `method` | How the customer paid: the coin, network and amount as decimal strings, the sending address and transaction, and `overpaid_amount`. For cards, the payment rail without card details, which the customer enters on the secure payment page. |
| `settlement` | Where the funds went: `destination` is `wallet` for the deposit that reached your wallet, whole. Then the asset, network, amount, address and transaction. |
| `confirmed_at` | When the payment succeeded. |

- An overpayment keeps `reporting.amount` at the price, while `amount_received` and `settlement.amount` include the excess.
- An accepted payment reports what actually arrived: `reporting.amount` is its value.
- A payment finished by a remainder landed in more than one transfer. `settlement.amount` adds them up, and `settlement.tx_hash` names the latest.

Network fees are separate: the customer's wallet pays them in the network's own coin on top of what it sends, so they're never in a payment's amounts. The hosted checkout shows an estimate beside the total.

## Wallet transactions

Every deposit is an `in` wallet transaction whose `payment_id` names the payment, with its `value_usd` at the time. Sends are `out` transactions with their `network_fee_usd` and a note of up to 280 characters.

> Funds from a payment that's `underpaid` or `needs_review` can already be in your wallet, as `in` transactions with its `payment_id`, before the payment succeeds. Match wallet transactions to payments by `payment_id`, not by status.

Money in during September, cURL:

```bash
curl "https://wallet.402pay.co/api/v1/wallet/transactions?direction=in&created_after=2026-09-01T00:00:00Z&created_before=2026-10-01T00:00:00Z&limit=100" \
  -H "Authorization: Bearer $PAY402_SECRET_KEY"
```

Money in during September, Node.js:

```js
const response = await fetch("https://wallet.402pay.co/api/v1/wallet/transactions?direction=in&created_after=2026-09-01T00:00:00Z&created_before=2026-10-01T00:00:00Z&limit=100", {
  headers: {
    Authorization: `Bearer ${process.env.PAY402_SECRET_KEY}`,
  },
});
const { data } = await response.json();
```

Money in during September, Python:

```python
import os

import requests

response = requests.get(
    "https://wallet.402pay.co/api/v1/wallet/transactions?direction=in&created_after=2026-09-01T00:00:00Z&created_before=2026-10-01T00:00:00Z&limit=100",
    headers={
        "Authorization": f"Bearer {os.environ['PAY402_SECRET_KEY']}",
    },
)
data = response.json()["data"]
```

## Export a period

List payments with `created_after` and `created_before`, follow `next_cursor` until it's `null`, and write a row per payment. The start is included and the end isn't, so back-to-back periods never overlap.

export.mjs, Node.js:

```js
// Every payment created in September 2026, oldest first, as CSV.
const API = "https://api.402pay.co/api/v1";
const headers = { Authorization: `Bearer ${process.env.PAY402_SECRET_KEY}` };
const csv = (cell) => `"${String(cell ?? "").replaceAll('"', '""')}"`;

const rows = [["id", "status", "reference", "currency", "amount", "usd_amount", "confirmed_at"]];
let cursor = null;
do {
  const query = new URLSearchParams({
    created_after: "2026-09-01T00:00:00Z",
    created_before: "2026-10-01T00:00:00Z",
    sort: "created_at",
    limit: "100",
  });
  if (cursor) query.set("cursor", cursor);
  const page = await (await fetch(`${API}/payments?${query}`, { headers })).json();
  for (const p of page.data) {
    rows.push([p.id, p.status, p.reference, p.currency, p.amount, p.reporting.amount, p.confirmed_at]);
  }
  cursor = page.next_cursor;
} while (cursor);

console.log(rows.map((row) => row.map(csv).join(",")).join("\n"));
```

The dates filter on `created_at`. To book payments by when they succeeded, filter the rows on `confirmed_at`, or list `payment.succeeded` events for the period with [`GET /events`](https://402pay.co/docs/api/events/list.md).

In the dashboard: [Search, filter and export payments](https://402pay.co/support/search-and-export-payments.md).

## Match records

| To match | Use |
| --- | --- |
| An order to its payment | `reference`, or your own `metadata`. Both filter `GET /payments`. |
| A payment to the chain | `method.tx_hash` and `method.explorer_url`. |
| A payment to your wallet | `settlement.tx_hash`, and the `payment_id` on each wallet transaction. |
| A payment to a customer | `customer_id`. |
| A send to its purpose | Its `note`. |

## Exchange rates

A crypto checkout locks the coin amount when it opens, and `reporting` converts your currency to US dollars at the rates [`GET /exchange-rates`](https://402pay.co/docs/api/exchange-rates.md) returns. Those rates follow the market.
