Amounts
Every amount is an integer number of USDC atoms. USDC has 6 decimals.
Every amount in the API is an integer in USDC atoms, with currency: "usdc". USDC has 6 decimals: one USDC is 1000000 atoms.
| Atoms | USDC |
|---|---|
1 | 0.000001 |
10000 | 0.01 |
1000000 | 1.00 |
2500000 | 2.50 |
125000000 | 125.00 |
USDC is a dollar stablecoin, so 1.00 USDC is displayed as $1.00 in ZyloPay's apps.
Convert without floating point
Never convert with floating-point arithmetic. 0.1 + 0.2 is not 0.3 in binary floating point, and the error ends up in your books.
// "12.34" → 12340000n (reject more than 6 decimals)
export function toAtoms(usdc: string): bigint {
const m = /^(\d+)(?:\.(\d{1,6}))?$/.exec(usdc);
if (!m) throw new Error(`Invalid USDC amount: ${usdc}`);
return BigInt(m[1]) * 1_000_000n + BigInt((m[2] ?? '').padEnd(6, '0'));
}
// 12340000 → "12.34"
export function formatUsdc(atoms: number | bigint): string {
const a = BigInt(atoms);
const whole = a / 1_000_000n;
const frac = (a % 1_000_000n).toString().padStart(6, '0').replace(/0+$/, '').padEnd(2, '0');
return `${whole}.${frac}`;
}Amounts fit in a JavaScript number up to 9,007,199,254 USDC, far above any single payment (the API caps a payment intent at 1,000,000 USDC). Use bigint when you sum large volumes.
Which amount is which
On a payment:
| Field | Meaning |
|---|---|
amount | The sale amount. You receive all of it. |
fees.acquirer, fees.protocol | Network fees, paid by the customer on top of amount. |
fees.cashback | The part of the fees returned to the customer as cashback. |
total_charged | What left the customer's wallet: amount + fees − instant cashback. |
net | What you received. Equals amount. |
amount_refunded | Refunded so far. |
See Fees for a worked example.