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.amountat the price, whileamount_receivedandsettlement.amountinclude the excess. - An accepted payment reports what actually arrived:
reporting.amountis its value. - A payment finished by a remainder landed in more than one transfer.
settlement.amountadds them up, andsettlement.tx_hashnames 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.
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.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"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();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.
// 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.
In the dashboard: Search, filter and export payments.
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 returns. Those rates follow the market.