Build customer balances
Provision persistent deposits and maintain exact chain-and-asset customer funds.
Customer balances are for products that hold a merchant-scoped ledger for each customer. They are not checkout addresses and they are not a promise that assets on different chains are fungible.
Integration sequence
- Create one Paybytoken Customer for the authenticated customer in your system.
- Read
/api/v1/deposit-assetsand show only currently enabled chains and assets. - Provision an EVM deposit account and an initial persistent address slot.
- Wait until the address watch is ready before displaying it.
- Consume signed
customer_deposit.*events and retrieve balances server-side. - Spend with a
customer_balancePayment Intent or create a customer withdrawal.
Use @paybytoken/node or the Customer deposits API. Store
Customer, deposit-account and address IDs in your backend. Never derive availability from a browser
poll alone.
Provision a customer and address
Create one merchant-scoped Customer for one durable customer identity in your system. Reuse that Customer across deposits and balance payments; do not create a new Customer for every checkout.
const customer = await paybytoken.customers.create(
{
reference: `user:${user.id}`,
email: user.email,
name: user.displayName,
metadata: { internal_user_id: user.id },
},
{ idempotencyKey: `customer:${user.id}` },
)
const assets = await paybytoken.depositAssets.list()
const supportsBaseUsdc = assets.data.some(
(asset) => asset.chain === 'base' && asset.asset === 'USDC' && asset.enabled,
)
if (!supportsBaseUsdc) throw new Error('Base USDC deposits are unavailable')
const account = await paybytoken.customerDepositAccounts.create(
customer.id,
{
address_family: 'evm',
initial_address: {
label: 'Primary deposit address',
chains: ['base'],
},
},
{ idempotencyKey: `deposit-account:${customer.id}:evm` },
)Provisioning can be asynchronous. If the result has status: "provisioning", wait for the
suggested retry interval and retrieve the account from your server. Display an address only after
the address and requested chain are active.
An EVM address slot may be activated on another supported EVM chain later. Activation changes which chain Paybytoken watches; it does not make balances fungible across those chains.
Exact-asset accounting
Every balance is scoped to merchant, customer, mode, chain and asset. Base USDC cannot silently pay an Ethereum USDC intent. Decimal values are strings; atomic values are integer strings. Use the asset discovery endpoints for contracts, precision, minimums, maximums and fees instead of hard-coding them.
Deposits can be detected before they are finalized. Credit spendable funds only after Paybytoken marks the deposit credited. Keep below-minimum, restricted and reversed states visible to support and reconciliation workflows.
Deposit lifecycle
| Status | Meaning | Customer-facing treatment |
|---|---|---|
detected / confirming | Transfer was observed but has not reached required finality. | Show pending; do not make funds spendable. |
confirmed | Chain confirmation policy passed and accounting is finishing. | Keep pending until credited. |
credited | Exact-asset available balance was updated. | Funds may be used for supported balance payments or withdrawals. |
below_minimum | Transfer does not meet current deposit policy. | Explain the limitation; do not ask for another transfer to the same transaction. |
restricted | Compliance or operational policy stopped crediting. | Route to support without exposing internal risk details. |
reversed | A previously observed chain outcome was reversed. | Freeze dependent business actions and reconcile. |
Persist the deposit ID and transaction hash for support, but use the Paybytoken deposit status as the accounting state. A block explorer is evidence of a transaction, not evidence that the merchant-scoped balance was credited.
Customer experience and controls
- Show the exact chain, asset, address and minimum before the customer transfers.
- Warn against sending from an exchange or bridge when refunds require control of the source.
- Never combine amounts across chain and asset rows into one spendable number.
- Keep retired addresses in history; do not silently present them as active.
- Restrict or close a Customer through an authorized backend workflow, not a browser-only action.
Continue with Pay and withdraw from customer balances.
Did this page answer your question?
Your feedback helps us improve the integration path.