CryptoCheckout runs on testnet. No contracts are deployed to any mainnet yet — deliberately, not as an oversight.
Payment, settlement, distribution, claiming, webhooks, and the dashboard work end to end on all eight networks, and a full payment cycle has been verified on seven of them. BNB testnet is wired the same way and quoting, but a complete cycle has not been signed off there yet. Paying by sending to an invoice address works everywhere; paying from a connected wallet is available on the seven EVM networks, not on TRON.Integrate now on testnet and you’ll be ready the day your chains switch on.
Stated plainly, because you’d find them eventually and it’s better you plan around them.
A deposit-rail order nets slightly less than 99%
The platform fee is a flat 1% of the gross on every pool — 0.75% to us, 0.25% to a partner if one referred you — and that’s the whole cost on the connect rail: you net 99%. A deposit-rail order starts from a slightly smaller base, because the one-time forwarder holds back a network fee before the pool ever sees the money.That fee is capped on-chain at 10% of what arrives, fixed into the forwarder’s address before the customer is ever shown it, and verified by their own browser before they pay — it recovers the gas of deploying that address and sweeping it, and it’s shown against the specific order in surchargeUnits. On a cheap chain it’s a small fraction of a percent; nothing you’d notice against the flat 1%.Affects: deposit-rail orders only — the connect rail has no equivalent. Workaround: price it in, or steer higher-value orders to the connect rail where a wallet is available. Fees.
Per-network minimums are a published table, not a live reading
Each network carries a minimum order below which a payment costs more to settle than it recovers, and below it that network disappears from the checkout. That minimum is a fixed per-network value we ship and update by hand — it is not computed from current network conditions at quote time. So it can be conservative when a network is quiet and thin when it is busy.Treat the published figures as indicative rather than as ceilings. When they are computed live they are expected to come out higher than today’s table on several networks, and a congestion spike can push one up steeply for as long as it lasts — enough to take pay-by-address off an expensive network for a while. The TRON row is the least settled of all: settling costs more there than anywhere else, so that figure is provisional and we expect to re-publish it before TRON mainnet opens.Affects: small orders, most visibly on Ethereum, where the minimum is highest. Workaround: none downward — your own settings can only raise a minimum, not lower it. Limits.
Cost control is an absolute amount per network, not a share of the order
Your own minimums are set as absolute amounts in your settlement currency, one per network and per way of paying. There is no way to say “never spend more than 1% of the order on settling it” and have the per-network figures follow from that.Note that these settings are transitional. When the percentage control described under Coming ships, the absolute figures are migrated and retired, so anything you tune now will not survive as a stored setting.Affects: anyone selling across a wide range of order values. Workaround: set the absolute figures by hand and revisit them whenever your price points move. Settings.
Your payout contract is deployed by us, not signed by you
We deploy your payout contract on each network at first use and pay that network fee. Your payout address is baked into its immutable code from the message you signed at setup, and no admin or owner function exists that could change it — but the deploy transaction is ours, not yours, and there is no fee estimate shown for it because there is no transaction of yours to price.Affects: anyone who wants the deployment to be provably their own action, and anyone who wants integration gated on the contract already existing. Workaround: none today; the deployed contract is still readable on-chain and checkable against the address you signed. The pool.
A TRON payout wallet must be a plain single-key wallet
TRON sign-in verifies plain key signatures only, so a TRON multisig or smart-contract wallet cannot be used as a payout wallet. On the EVM networks a contract or multisig payout wallet works normally.This decision is irreversible for you: the payout wallet is the wallet you sign in with, and it is frozen into the contract when your pool is provisioned. If your treasury is a TRON multisig, decide up front to receive TRON proceeds into a single-key wallet you control and move them on from there. Whether TRON contract-wallet sign-in becomes supported is undecided — plan on the asymmetry lasting. Payout wallet.
Linking a second wallet works one way, and must be finished in one sitting
Accepting on both the EVM networks and TRON needs two wallets on one account, and the order you first sign in decides whether that is possible. Sign in with an EVM wallet first and you can attach a TRON wallet afterwards from Account. Sign in with a TRON wallet first and there is no way to attach an EVM wallet — you end up with two unconnected accounts, two dashboards, two sets of networks, tokens and pools, and no single view of your money.Linking is also a two-wallet co-signature that has to be completed in one go. Connect the second wallet, then walk away or reload before co-signing, and that wallet is left unlinked. Sign in with it later and you can land in a fresh, empty account rather than yours — no payments, no pool, as though your data vanished. The header only ever shows the wallet you are currently connected with, so there is no at-a-glance way to confirm a second wallet is attached.Workaround: sign in with your EVM wallet first, attach TRON from Account, and finish the co-signature in one sitting. If you have already ended up with two accounts, contact support — merging them is not self-serve. Settings.
BNB Chain mainnet is gated on a decimals fix
On BNB Smart Chain mainnet these stablecoins are 18-decimal rather than the 6 used everywhere else, and our pay-by-address path doesn’t yet handle that consistently. Enabling it before the fix risks a scaling error, so it stays a mainnet gate.BNB testnet is unaffected and available today. Affects: BNB Chain at mainnet only.
USDT on Ethereum mainnet needs an approval fix
Mainnet USDT rejects changing a non-zero allowance to another non-zero value. A repeat customer with a leftover allowance would have their wallet payment fail.Testnet is unaffected. This is a mainnet go-live gate. Pay-by-address is unaffected either way.
A late payment to an already-settled address isn't picked up
If a customer pays an address whose order already settled — usually by reusing an old one — it currently isn’t detected automatically.The funds are safe: that address can only pay your pool. Recovery needs us to intervene, so contact support.There is one chain-family difference worth knowing. On the EVM networks, a top-up arriving while the order is still being watched is picked up on its own. On TRON nothing is: a second transfer to an already-settled address sits there, and once a quote expires that address stops being watched at all, so a late payment is not observed in the first place.Affects: repeat customers who save addresses, and slow exchange withdrawals — which on TRON need reconciling by hand.
Underpaid and wrong-token orders need a manual conversation, and never clear
There’s no automatic prompt asking the customer to top up. While the order is still open the address stays valid and a second transfer that brings it up to the full amount is picked up — but you have to ask for it.Until the invoice is fully covered nothing is swept, so a partial amount sits at that address, and there is no action you can trigger yourself to sweep it back out and refund the customer. That is a deliberate choice rather than a missing piece: we won’t settle an order the customer never completed, and won’t hand over money for goods that weren’t shipped. So don’t wait for an automatic sweep — it isn’t coming.Once you’ve settled it with the customer off-chain — refunded from your own wallet, or written off a few cents — there is no way to mark the order done. The row stays under Needs you permanently, so that list only accumulates and the weekly review we recommend gets less useful over time. A control to close a resolved row is intended.Workaround: contact support if a customer walks away from an underpaid invoice. Edge cases.
No view for money that arrived without a matching order
There is no surface listing these, and scanning Payments will not reveal them either — Payments lists the orders you created. Once an order has settled, or an unfunded one passes the end of its monitoring window, we stop watching its address, so a later arrival creates no record at all: no status, no webhook, no automatic sweep.Two related traps. An order showing expired is not proof nothing happened — the expired label currently outranks a shortfall, so money may have arrived against it. And a payment sent on a network you don’t accept is never observed at all; detection for that case is intended, recovery tooling is not.Affects: anyone reconciling by hand. Workaround: if a customer says they paid and you have no record of it, contact support for a manual sweep. Note that recovering a stranded deposit runs it forward through normal settlement, so the platform fee applies even though the order never completed — worth weighing before chasing a small balance. Edge cases.
Dashboard figures need reconciling before you report on them
Two places to be careful. The claimable balance on Pool counts only money that has already been released, so fresh sales can show as zero or sit on “settling…” while the money is genuinely in your pool. Nothing is missing; the figure is behind.Analytics is coarser than it looks. If you accept both euro-pegged and dollar-pegged stablecoins, the headline volume adds them together as if they were one unit. Time-series charts date a settlement by when the order was created rather than when the money settled, so daily and monthly bars shift and month-end totals won’t tie out. The success-rate figure is labelled as something other than what it measures. And converted display-currency totals run on a fixed placeholder rate with no marker saying so.Workaround: reconcile from the Payments CSV and the transaction hashes, and read the per-token chips rather than any converted total. Corrections are planned. Reading the numbers.
Quoted amounts can carry more decimal places than a price normally would
A quoted amount is derived from the price and the rate, so it can come out with three or more decimals. Anyone paying by copying the figure into a wallet or an exchange withdrawal screen has to retype it exactly, which is awkward.Rounding at quote time, described under Coming, changes the value the quote endpoint returns, so if you reconcile your own order total against it, or re-derive base units from it, expect it to move — it will be announced before it ships. Amount formats.
What your customer sees after paying is coarse
Three rough edges in the same few seconds.There is no per-confirmation progress. Once a customer has paid, the screen says only that it is confirming — never “3 of 20”. Against the published confirmation depths (around 20 blocks on Ethereum, 64 on Polygon, 19 on TRON) that is a long time staring at something that doesn’t move, and it produces the “did it go through?” ticket. A granular progress indicator is intended.On the wallet-connect path, the customer’s payment is irreversible the moment their transaction confirms — but the success screen and the onPaymentConfirmed callback wait for our settlement step afterwards. If settlement is slow they sit on a spinner after paying, and your thank-you redirect doesn’t run. Nothing is at risk; the money is already final and can only reach your pool. Fulfil from webhooks, not the browser callback.The checkout also shows two countdowns — the price lock and how long the address stays valid — whose copy implies they’re the same clock, so customers ask why the timers disagree.Checkout states.
Payment-link enforcement fails open if the resolver is unreachable
A link generated from Payment links is single-use and price-locked on the server: a paid, voided or expired link is refused with link_not_open, and an amount, currency, token or network edited into the URL is refused with link_params_mismatch. The residual is what happens when that lookup itself fails — both the page and the quote endpoint fail open rather than blocking, and the checkout proceeds on the values in the URL.Separately, the quick links generated from the Pool tab are not payment links: there is no link record behind them, so they are neither single-use nor price-enforced.One more reason not to hand-edit a checkout URL: a ?currency= value the checkout doesn’t recognise fails the page outright rather than falling back to your default currency.Affects: anyone relying on a link being unusable twice. Workaround: generate from Payment links, not the Pool tab, send the link exactly as generated, and reconcile against your dashboard, which stays authoritative for what actually arrived. Payment links.
On-chain verification is EVM-only
A registry contract is deployed on TRON and listed on the verify page, but nothing in the TRON payment path reads it yet: no TRON payout wallet is attested there, and the checkout can’t recompute a TRON settlement address in the browser, so the browser-side check doesn’t extend there. TRON payments settle correctly; they don’t carry that specific verification. Verification.
A held payment has no self-service release
If a payment is frozen — because a screening check flagged the sending address, or because a configuration check didn’t line up — it leaves automatic reconciliation and stays where it is: never swept, never settled. The funds are not lost; they stay at an address that can only ever pay your pool. But there is no release control in the dashboard, and release tooling is not built on our side yet either, so a hold is a one-way state today and lifting one is something we do case by case.Affects: merchants with screening switched on, and anyone hitting a configuration mismatch. Workaround: contact support — a hold is recoverable, just not by you and not on its own. Edge cases.
Fees are not returned on refunds — and you can only refund what you already hold
This is a settled policy (CRY-274), not an open question: the fee is taken on-chain when your pool distributes, before you’d typically refund, and it never comes back. Refunding a customer in full means absorbing that yourself — on a connect-rail €100 order you received €99.00 and would be refunding €100.Less obvious, and worth checking before you promise a customer a same-day refund: you can only refund from money you physically hold. That means the pool must have been released and your share withdrawn to your wallet first — settle → distribute → claim → refund, in that order. If you need to refund urgently, look for an unreleased or unwithdrawn balance before anything else. Refunds.
TRON wallet payments. TRON supports pay-by-address only today, which means we front the network cost of settling every TRON payment — which is why TRON carries the highest minimum order. Paying from a connected wallet puts that cost inside the customer’s own transaction instead, as it already is on the EVM networks. That makes small TRON orders viable: an order under the pay-by-address minimum will be offered wallet-only on TRON rather than removing the network from the checkout. Two caveats — your TRON payout contract has to exist on-chain first, so the path is unavailable on a network you haven’t deployed on, and TRON wallet coverage is not uniform, so which wallets are supported will be published alongside it.Cheaper settlement. A more efficient contract pattern, plus cheaper sourcing of the network resources a settlement consumes, cuts what it costs to settle a pay-by-address payment substantially — lowering minimum order sizes on every network, with the largest drop where settling costs most.That change alters how the one-time address behind a pay-by-address order is derived, on both chain families. At cutover, addresses are computed a different way, so invoices quoted under the old scheme have to be paid or expired first and a short pause on new quotes is possible. If you log, whitelist, display or reconcile against pay-to addresses, or run the default seven-day monitoring window, plan for a drain window — it will be announced ahead of time.Quoted amounts rounded at source. Amounts will be rounded to two decimals when the quote is made, so what is displayed, what is expected and what the customer sends are the same figure. Internal accounting keeps full precision — only the quoted and displayed numbers round.
Deployment as a prerequisite for API keys and the embed. You already sign and pay for your own pool deployment, once per network, from your own wallet — that shipped. What’s still planned is gating checkout on it up front: today you can integrate and the connect rail simply refuses (pool_not_deployed) on a chain you haven’t activated; the plan is for undeployed chains to never be offered in the first place, and for API keys and the embed to require at least one deployed network to exist at all. The pool.Percentage-based cost controls. Cap settlement cost as a share of order value instead of setting an absolute minimum per chain, with the implied minimum per network shown live as you adjust it. Below your tolerance, pay-by-address quietly disappears for that network rather than erroring; wallet payment is unaffected. A quote already issued is honoured even if network costs rise before it settles.It is a narrowing as well as a simplification: today’s controls are per network and per way of paying, while the replacement is a single percentage governing the pay-by-address option only. The absolute figures you set today are migrated and retired.Unsettled deposits surface. One place showing every way money can arrive and not reach you — an arrival with no matching order, an underpayment, a wrong token — with what came in, why it stalled, the network fee to recover it, and one button, signed and paid by you. A late arrival is recorded against you as a deposit that matched no order, rather than reopening an order that already completed.Customer top-up prompt for underpayments, and a merchant-side sweep-and-refund action. That sweep is a transaction you sign and pay for, and putting an underpaid deposit through it settles it like any other payment, so the platform fee applies.Late-payment re-quoting. A payment arriving long after expiry is currently honoured at the original amount however stale, anywhere inside the seven-day monitoring window. That is narrowing sharply: automatic settlement will be limited to roughly an hour past expiry.Past that hour nothing is lost or refused — the payment simply stops settling on its own and waits for you to accept it from the unsettled-deposits surface. Plan for it on the pay-by-address rail in particular, where exchange withdrawals routinely take longer than an hour under review or congestion, so a share of perfectly legitimate payments will start needing a click. Two details worth knowing: orders priced in the same currency as your settlement token are not re-priced at all, so re-quoting affects a minority of orders; and a re-priced payment is re-checked against tolerance, so a customer who paid in full can land slightly short and become an underpayment. Lengthening your quote lifetime in settings eats into the automatic window one-for-one. Automatic reconciliation of TRON late payments lands alongside it.Release tooling for held payments, so a hold can be lifted rather than only applied.Specific checkout messages for three refusal reasons the API already returns with distinct codes — a token not available on that network, and two payment-link mismatches — which the checkout shows as a generic failure today.Settlement cadence as a real choice, once you pay for the settlement transaction yourself and the timing becomes an economic decision rather than ours. Read the trade-off honestly: today you do nothing and still get paid — we release your pool, claim your share for you on the EVM networks, and pay the network fee for both, in practice at least daily. Afterwards, releasing is something you trigger and pay for, we stop claiming your share on your behalf, and the safety net that runs if you never press anything drops from every few minutes to roughly monthly — and it fires only when releasing is economically worth doing, so a small balance in a quiet pool can sit longer than the cadence suggests. In plain terms, “we push your money to you” becomes “you collect your money”. Claiming.A completion signal tied to finality. The customer’s success screen and the browser callback move to the moment their payment is final, independent of when settlement runs. Fulfil from webhooks either way.Confirmation progress at checkout, so a customer waiting on a slow network can see how far along they are.Wallet linking made safe to interrupt, with a first-run prompt offering both chain families and a header that shows both linked addresses.Corrections to Analytics — per-peg totals rather than mixed sums, settlement-dated time series, an honest caption on the success-rate figure, and a visible marker on any placeholder conversion.
Volatile asset acceptance. Letting customers pay in ETH or similar with conversion to your settlement token at checkout. The contract path exists but is not enabled — accepting volatile assets means someone bears price risk between payment and settlement, and that needs to be right rather than fast.Multi-token checkout. A wider set of tokens than you’ve explicitly enabled.Per-customer deposit addresses. One permanent address per customer instead of one per invoice — much cheaper for repeat deposits, so it suits subscriptions, balance top-ups, and marketplaces. The trade-off: the address identifies who, not which order, so matching relies on amount and timing. Right for balance models, wrong for one-shot e-commerce, and it would be opt-in.The design was reopened and is not currently in development — don’t sequence a subscription launch around it. What happens when a customer with a permanent address pays while none of their orders is open — a balance credit, or an unattributed arrival — is genuinely undecided. Payment rails.
Four gates before any chain goes live. Each chain is reviewed and enabled separately.
Third-party security audit
Independent review of the settlement contracts.
Public bug bounty
Live before real money moves, so the contracts have been adversarially tested by people paid to break them.
Legal sign-off
Counsel review of the custody position and every public claim — and of who may be onboarded, so if you operate in a regulated line of business, expect your own eligibility to form part of the gate.
Per-chain approval
Each chain reviewed and enabled individually rather than all at once.
Contracts on mainnet are not the go signal. The first mainnet run on any chain is deliberately done with our own money as a live test, so contracts will be deployed — and visible on the verify page — while the audit is still open and no merchant may go live. Merchant onboarding onto mainnet is a second, later switch. If you see a mainnet address listed, that is not your cue to start taking real money; your go-live switch is.
Chains open one at a time, in the order their per-chain work and demand allow rather than in any published sequence — the network you built on may open well before or well after another. What you can accept on a chain at open is not necessarily what you can accept on it in testing: euro settlement in particular will reach far fewer networks than dollar settlement, because Circle’s euro stablecoin exists natively on only two of the seven EVM mainnets (Ethereum and Base), while dollar settlement is available across all of them. If you intend to price in euros, plan your network list around that.Alongside the four gates there is per-chain technical and operational work: the USDT approval fix for Ethereum, the decimal fix for BNB Chain, a re-verification of TRON’s address derivation against real mainnet USDT, and funding plus balance alerting for the settlement wallet on every chain we switch on. On Ethereum, non-urgent payouts may be deliberately deferred while network costs spike, so an Ethereum payout can arrive later than the cadence suggests; getting a customer’s money into your pool is never delayed for that reason.Pay-by-address on TRON carries more than the shared checklist. Because it is the path that lets a customer withdraw USDT straight out of an exchange, it gets its own security review and its own legal review of the address-based deposit model, and we expect to enable it merchant by merchant rather than automatically when TRON opens. If your business depends on exchange withdrawals on TRON, treat “TRON mainnet approved” and “I can take exchange withdrawals on TRON” as two separate events.
We’d rather be late than be the crypto payment company that lost merchant funds to an unaudited contract. The gates are the product.
Changes that affect integrations are announced before they ship. Breaking changes to the API or webhook format come with notice and a migration path.That promise is not limited to formats. A change to how one-time deposit addresses are derived, or to the precision of quoted amounts, is announced ahead of time too — with a window to let in-flight invoices drain, and warning if new quotes have to pause briefly during a cutover.
Get set up now
Testnet integration carries straight over to mainnet.