Architecture first: CoinGate is the payment rail, not your domain model
The cleanest CoinGate integration puts a payment-orchestration layer between your business domain and the provider. Your invoice or order should not become a CoinGate object. It should have its own lifecycle and reference a separate payment intent.
A practical data chain is:
Business Order → Payment Intent → CoinGate Order → Payment Callback → Product Ledger → Settlement/Reconciliation.
Step 1: create a product-owned payment intent
Before calling CoinGate, create an internal record containing the customer, business object, expected price amount/currency, allowed payment method, expiry policy and a stable idempotency/reference key.
Do not use the provider ID as your primary business identifier. Provider migrations and retries become much easier when your system owns the reference.
Step 2: create the CoinGate order
CoinGate’s Create Order endpoint accepts the order price and currency, the settlement receive_currency, callback URL, return URLs and a merchant-defined token. It returns a payment_url for the hosted checkout.
For a typical B2B implementation, the business price can remain EUR while the customer chooses USDC in the provider checkout. Settlement can then follow the merchant configuration and provider capabilities.
Recommended mapping
| Your field | CoinGate concept | Purpose |
|---|---|---|
| paymentIntentId | order_id/title/reference | Cross-system correlation |
| amountDue | price_amount | Commercial amount |
| currency | price_currency | Commercial source-of-truth currency |
| settlementPreference | receive_currency | Merchant settlement target |
| callbackSecret | token | Callback validation support |
Step 3: redirect to hosted checkout
Hosted checkout is usually preferable for the first production version because the provider owns the supported asset/network presentation and payment instructions. It also keeps your application from hardcoding network-specific address/amount UX that can become stale.
Step 4: process callbacks idempotently
CoinGate documents callbacks when object state changes and also documents retries until the merchant endpoint returns success. It additionally supports callback replay from the dashboard. This means duplicate delivery is an expected system property, not an edge case.
Your callback handler should:
- authenticate/validate the notification using the configured integration mechanism,
- store an external event identifier or deterministic deduplication key,
- lock or transactionally load the payment intent,
- verify provider order identity, state, amount and currency context,
- apply an idempotent state transition,
- record an audit event,
- return success only after durable processing.
Step 5: map CoinGate status to product state
CoinGate currently documents statuses including new, pending, confirming, paid, invalid, expired, canceled and refund states. Do not mirror these directly as your only product state.
A better mapping is:
| Provider | Product payment | Business action |
|---|---|---|
| new/pending | AWAITING_PAYMENT | No entitlement |
| confirming | PAYMENT_DETECTED | Show progress only |
| paid | PAID | Credit ledger / unlock according to policy |
| invalid | MANUAL_REVIEW or FAILED | Do not credit automatically |
| expired/canceled | CLOSED | Create a new intent if needed |
Step 6: verify before crediting
For critical payments, the callback should trigger state verification rather than blind trust. CoinGate’s Get Order endpoint provides detailed order information including payment amounts, conversion data, fees, refunds and blockchain transaction information. Use the data required by your risk model to verify the transition.
Step 7: update the internal ledger
When the business accepts the payment, create an immutable ledger event tied to the customer, invoice/order, payment intent and provider order. Keep provider status and product credit separate so support can tell whether a payment was received but not yet credited, credited but not settled, or refunded later.
Read the internal ledger guide for the data model.
Step 8: treat refunds as a separate lifecycle
A refund is not “set payment status back to unpaid”. It is a new financial event with its own amount, currency, destination, provider refund identifier, status and audit trail. CoinGate provides dedicated refund APIs and refund status callbacks.
Step 9: reconcile provider ledger and settlement
Callbacks tell you that state changed. Reconciliation proves that the financial movements match. CoinGate exposes ledger transactions with filters such as date, currency, transaction type and source, which makes them useful for scheduled reconciliation jobs.
A daily job should compare:
- product payments accepted during the window,
- CoinGate orders and ledger transactions,
- provider fees and refunds,
- withdrawal/settlement records,
- bank evidence where fiat settlement is used.
See the full stablecoin reconciliation guide.
Testing checklist
- normal USDC payment,
- duplicate callback delivery,
- callback arrives out of order,
- payment expires,
- provider marks payment invalid/manual review,
- application returns 500 and callback is replayed,
- amount/reference mismatch,
- full and partial refund,
- reconciliation mismatch,
- provider API temporarily unavailable.
Common anti-patterns
“Callback equals paid”
A callback is an input. Your system decides whether the business transition is valid.
“CoinGate status is our entire payment model”
Provider state is narrower than your business state. Your product may need separate entitlement, settlement, refund and manual-review states.
“No ledger because the provider has reporting”
Provider reporting cannot replace your own product record of why a customer was credited.
“Reconciliation later”
Later usually means after transaction volume is high enough to make missing references expensive.
Monitoring and observability
Expose metrics for orders created, checkout conversion, payments stuck in confirming, callback failures, callback processing latency, invalid payments, refund failures and settlement mismatches. Keep provider IDs searchable in the operator panel so support can move from a customer or invoice to the exact provider object without querying production databases manually.
Security boundary
Keep the CoinGate API token server-side, isolate it from browser code and scope access according to the provider configuration available to your account. Callback endpoints should be public HTTPS endpoints but should not accept business mutations from arbitrary payloads. Authentication, reference validation and idempotency must happen before any product credit.
Sandbox-to-production rollout
Use the provider sandbox to verify integration contracts, but create a production runbook before the first live payment. The runbook should cover callback replay, provider outage, failed refund, settlement delay, manual status verification and escalation ownership. Test with low-value live transactions before enabling the rail for all customers.
Where CoinGate fits best
CoinGate is a strong fit when the product wants managed crypto checkout and provider-side settlement capabilities while keeping business logic, entitlement and reconciliation inside the application. For the architecture decision itself, compare gateway vs custom wallet infrastructure.