Skip to content

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

FieldWhat it holds
amount, currencyThe price you charged, in minor units of your currency.
fee_payer, customer_feeWho pays 402pay's fee, business or customer, and what the customer pays toward it, in the same currency: 0 when you pay it, and until the customer picks how to pay.
amount_receivedWhat arrived, in the same currency at the quoted rate. 0 until funds arrive, and amount plus customer_fee once it's paid in full.
reportingamount, fee, transaction_fee, customer_fee and net in US cents, for totals across currencies. fee is the rate and transaction_fee the flat fee, and net is what you keep after them: amount plus customer_fee less fee and transaction_fee. fee and net are final once the payment succeeds.
fee_rate_bpsThe rail's rate in basis points: 0 for crypto (0%) and 300 for cards (3%).
methodHow 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.
settlementWhere the funds went: destination is wallet for the deposit that reached your wallet, whole, or fees when the payment went to 402pay to pay fees you owed. Then the asset, network, amount, address and transaction.
confirmed_atWhen 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 less any customer_fee, and the fee is taken on that.
  • A payment finished by a remainder landed in more than one transfer. settlement.amount adds them up, and settlement.tx_hash names the latest.

Fees

reporting.transaction_fee and reporting.net stay 0 until the payment succeeds.reporting.fee is the rate on the payment and reporting.transaction_fee the $0.25 flat fee, both on the pricing page. Neither comes out of the deposit: every payment, by card or crypto, lands in your wallet whole (the price, plus the fee when your customer pays it). What you owe, the rate, the flat fee and your wallet's monthly plan, goes on your fee statement, which 402pay collects by sending some whole payments to its own address. Those payments have settlement.destination set to fees and no wallet transaction. See fees and billing.

Passing fees on

In the dashboard, under Settings, Payments, you choose who pays 402pay's fees. With your customers paying, the hosted checkout adds a processing fee to each customer's total: the rate for the method they pick, plus the $0.25 flat fee, in the price's currency. It's worked out on the price, never on a total that already includes it, so the payment lands at the price plus the whole fee, and the same fee owed on your fee statement as usual leaves you the whole price. A payment you create with POST /payments follows the setting unless its own fee_payer says otherwise.

A $49.00 card paymentAmount
Price$49.00
Processing fee (3% plus $0.25)$1.72
The customer pays$50.72
Lands in your wallet$50.72
The rate plus $0.25, on your fee statement-$1.72
You keep$49.00

A crypto customer sends the price plus the fee in their coin. A card customer reviews the final total, including any additional fees, on the secure payment page. The payment says who paid in fee_payer and how much in customer_fee, while amount stays the price.

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. A payment collected as fees has none, since its funds went to 402pay. 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 "https://dash.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"

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.mjsNode.js
// Every payment created in September 2026, oldest first, as CSV.const API = "https://dash.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", "usd_fee", "usd_net", "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.reporting.fee, p.reporting.net, 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.

Match records

To matchUse
An order to its paymentreference, or your own metadata. Both filter GET /payments.
A payment to the chainmethod.tx_hash and method.explorer_url.
A payment to your walletsettlement.tx_hash, and the payment_id on each wallet transaction.
A payment to a customercustomer_id.
A send to its purposeIts 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, except on a simulated business, where they're fixed.