1. The non-custodial model
The most important thing to understand about xD Pay is what it doesn't do. xD Pay never holds crypto, never exchanges crypto, never transmits money, and never pays merchants. It is software only.
What xD Pay does
Creates payment orders, renders QR codes, tracks payment status in real time, stores your sales history, and manages your team's logins.
What CoinGate does
Receives the customer's crypto, converts it at the moment of payment, and settles regular money (fiat) to your bank account per your CoinGate settlement settings.
Because the customer pays CoinGate directly and CoinGate pays you directly, xD Pay is never in the money flow. You are never exposed to crypto price swings — the amount you charge is locked in your own currency the moment the customer pays.
2. Payment lifecycle
Here's exactly what happens when a cashier charges a customer:
Cashier enters the amount
The cashier types a price (e.g. $12.50) and an optional note. The app validates the input and sends it to the xD Pay backend over HTTPS.
xD Pay creates a CoinGate order
The backend calls CoinGate's order API using the merchant's own CoinGate key. A unique, single-use callback token is generated for this payment so that status updates can later be verified as authentic.
A QR code is shown to the customer
The customer scans it with any phone camera or wallet app. It opens CoinGate's hosted payment page, where the customer picks their coin (Bitcoin, Ethereum, USDT, and many more) and pays. The merchant never chooses coins, networks, or wallets.
CoinGate confirms the payment
As the payment progresses on-chain, CoinGate sends signed status callbacks to xD Pay's webhook endpoint. Each callback is verified against the payment's unique callback token before it's accepted.
The screen shows "Paid ✓"
The POS screen polls for status and flips to Paid the moment the callback lands — typically seconds after the customer sends the payment.
CoinGate settles fiat to your bank
CoinGate converts the crypto at the sale-time rate and pays out in your chosen currency (USD, EUR, and more) on your CoinGate payout schedule — just like card settlements. xD Pay records the transaction but never touches the money.
3. Payment statuses
Internally, every payment moves through a strict, forward-only state machine. A payment can never go "backwards" — a late or duplicate webhook can't downgrade a completed payment. Merchants see simplified labels; the underlying states are:
| Status | Meaning | Shown to merchant as |
|---|---|---|
| NEW | Order created; waiting for the customer to pay. | Waiting |
| PAID | Payment detected and confirming on the network. | Paid |
| COMPLETE | Fully confirmed and queued for fiat settlement. | Paid |
| EXPIRED | The customer didn't pay before the timer ran out. | Expired |
| CANCELED | The order was canceled. | Canceled |
| INVALID / REFUNDED | Terminal edge cases handled by CoinGate. | Failed / Refunded |
4. Webhooks & verification
Status updates arrive via server-to-server callbacks from CoinGate. Three safeguards apply:
- Per-payment callback tokens. Every payment gets its own random, single-purpose token when the order is created. CoinGate echoes it back with each callback, and xD Pay rejects any callback whose token doesn't match. A leaked or forged request for one payment can't affect any other payment.
- Idempotent, forward-only transitions. Callbacks can arrive late, duplicated, or out of order. The state machine only ever advances, so replaying an old callback is a no-op.
- Rate limiting and validation. All webhook payloads are schema-validated before processing, and the endpoint is rate-limited.
5. QR codes & wallets
By default, the QR code opens CoinGate's hosted payment page, which handles coin selection, exchange rates, and network fees for the customer. For merchants whose CoinGate account supports it, xD Pay can also render a direct wallet QR:
- For Bitcoin-style (UTXO) coins, the QR encodes a
BIP21URI with the address and exact amount, so compatible wallets pre-fill everything. - For Ethereum-style (EVM) coins, the QR encodes the payment address directly.
- If direct-wallet mode isn't available on the merchant's account, xD Pay automatically falls back to the hosted payment page — the cashier never sees an error.
6. Security
Encrypted credentials
Your CoinGate key is encrypted at rest with AES-256-GCM (authenticated encryption). It is never displayed back in full and never leaves the server.
Session security
Sign-in uses signed, HTTP-only session cookies. Passwords are stored only as salted hashes — never in plain text.
Transport security
All traffic — browser to app, app to CoinGate, and CoinGate callbacks — travels over HTTPS/TLS.
Audit trail
Security-relevant actions (sign-ins, settings changes, key updates) are recorded in an internal audit log.
Least-privilege roles
Cashier accounts can sell and view payments but can't change settings or see credentials. Only owners can.
No card data, no wallets
xD Pay stores no card numbers, no private keys, and no wallet seed phrases — there's nothing of that kind to steal.
7. Practice mode vs. real payments
Every merchant account can run in Practice mode, which connects to CoinGate's sandbox environment and uses test money. The entire flow — charging, QR scanning, status updates — behaves exactly like production, but no real value moves.
Switching to Real payments is a per-merchant setting: you connect a live CoinGate key and flip the environment. Practice and real payments are kept strictly separate, and every payment record shows which mode it was made in.
8. Accounts & roles
| Role | Can do |
|---|---|
| Owner | Everything: sell, view all payments, manage the CoinGate connection, switch modes, add and remove cashiers. |
| Cashier | Create sales and view payment history. No access to settings, keys, or team management. |
Each team member signs in with their own email and password, so your sales history shows who rang up each sale.
Questions we didn't answer?
Check the FAQ, or read our Privacy Policy and Terms of Service for the legal details.