payment_confirmed, not before.
Why “seen” isn’t “paid”
A transaction appearing on-chain is not the same as a transaction being permanent. Blocks can be reorganised, and a payment that existed a moment ago can cease to exist. The attack is simple and old: pay, take the goods, then get the block containing the payment reorganised away. Crediting on first sight is how operators lose money. We only tell you about the green state.What confirmed means per rail
- Connect rail
- Deposit rail
Final once the customer’s
deposit() transaction reaches the required confirmation depth for that chain.Today the
payment_confirmed signal waits a little longer than it strictly needs to — until our settlement step also confirms. Shortening it to the deposit confirmation is a known improvement. It makes confirmation slightly slower, never less safe. Roadmap.Confirmation depth
Depth scales with value — a €5 order and a €50,000 order don’t warrant the same wait. Defaults are per chain and account for each chain’s actual reorg behaviour, which differs a lot. TRON needs around 19 confirmations for practical finality; some L2s have a soft-versus-hard distinction that matters at large values. You can raise the thresholds in Settings. Consider it if you sell anything instantly consumable — account credit, digital keys, gambling chips — where a reversal can’t be recovered by withholding shipment.Ship from webhooks
The browser callback
onPaymentConfirmed fires only if the customer’s tab is still open. Close the tab, and it never fires — but the payment still completed.Fulfil from the webhook. Use the browser callback for the thank-you screen and nothing else.Once confirmed, it’s permanent
No chargebacks. No reversals. No disputes. Neither the payer, nor their bank, nor we can undo a confirmed payment. That cuts both ways: you’re protected from fraudulent reversals, and you cannot claw back a payment you’d rather not have taken. Refunds are something you send. Refunds.Late payments still count
Quotes expire. Payment addresses do not. If a customer’s exchange withdrawal takes six hours and arrives long after the quote lapsed, the funds still reach your pool and still get credited. A confirmed payment is never rejected because a timer ran out. What you’ll see is anexpired_paid_late status rather than a clean paid, so you can decide whether to honour the original order or contact the customer.
Edge cases.