Adding a crypto payments option shouldn’t require a risky re-platform. The best approach is incremental, starting with a low-friction path (hosted checkout or plugin) and graduating to deeper server-to-server integrations once you’ve validated conversion lift, fee savings, and operational fit. This guide walks you through the integration choices, the architectural patterns that scale, and the reconciliation and compliance hooks your finance and risk teams expect to see.
Start with the right integration pattern
1) Hosted Checkout (fastest time-to-live)
A hosted page handles quoting, address display/QR, countdown timers, under/over-payment flows, and basic refund initiation. You redirect the buyer to the hosted checkout and receive signed webhooks when the quote is paid or expires.
When to choose: You want speed-to-market, minimal engineering effort, and a standardized UX.
2) E-commerce Plugins (WooCommerce, Shopify, Magento)
Plugins wrap hosted or embedded flows in your platform’s native checkout with minimal configuration. They often include basic refund triggers, order status updates, and webhook listeners.
When to choose: You run on a mainstream platform and need a repeatable, maintainable path without bespoke code.
3) Embedded UI + Web SDK (more control)
You keep users on your domain and UI while the gateway provides a UI component (address/QR + timer) and handles quoting and chain routing underneath.
When to choose: You care about brand-consistent UX but still want to avoid building payment logic from scratch.
4) Server-to-Server (S2S) / Custom APIs (maximum control)
You integrate directly with gateway endpoints to generate quotes, confirm payments, trigger refunds, and orchestrate treasury rules. You own the UI entirely and wire idempotent POSTs, webhook signatures, and reconciliation exports into your stack.
When to choose: You’re a marketplace/platform, or you need advanced policy control, multi-party settlements, and deep ERP hooks.
What a clean crypto checkout must do (regardless of pattern)
- Quote & timer: Display a fixed-rate crypto amount and a clear countdown.
- Network abstraction: Buyers shouldn’t pick chains; let the gateway route to the cheapest / fastest rail.
- Under/over-payment flows: Provide one-click top-up or a smart refund prompt for small overages.
- Refundable CX: Enable self-serve ticketing that ties order → tx hash → refund tx for auditability.
Key engineering considerations
Webhook reliability
- Verify HMAC signatures and timestamps.
- Implement retries + idempotency keys (e.g., store a hash of payloads and ignore duplicates).
- Keep webhook handlers fast—offload long work to a queue.
Idempotency & order state
- Mark orders with states like: PENDING_QUOTE, AWAITING_FUNDS, CONFIRMED, EXPIRED, REFUNDED.
- Make all payment-side operations idempotent by order ID + quote ID.
Error handling & observability
- Log every quote request/response, webhook event, and refund action with correlation IDs.
- Ship metrics: time to confirmation, fee %, expired quotes, under-payment rate, refund cycle time.
Security & access
- Store API keys in a secrets manager; rotate regularly.
- Restrict dashboard roles (RBAC), enforce SSO, and audit access logs.
- Maintain withdrawal allow-lists for treasury wallets.
WooCommerce & Shopify: quick wins
WooCommerce
- Install plugin, set API keys, define accepted assets (start with USDC; optionally BTC/ETH).
- Configure order status mapping: e.g., “Processing” on payment confirmed; “Cancelled” on quote expiry.
- Add webhook endpoint via plugin or your backend (preferred) and validate signatures.
Shopify
- Use the provider’s payments app / custom payment method (Shopify policy dependent).
- Keep refunds initiated from your dashboard or via API so Shopify order timelines remain accurate.
Common pitfalls to avoid
- Not surfacing the countdown clearly—drives under-payments.
- Mixing testnet and mainnet assets in one environment.
- Failing to reconcile fees (network + gateway) and quoted vs settled currency.
Custom S2S: reference flow
- Create Quote: POST /quotes with orderId, fiatAmount, fiatCurrency. Receive {quoteId, cryptoAmount, asset, destination, expiry}.
- Render UI: Show QR/address + timer from the response or via UI SDK.
- Listen for Webhooks: payment_confirmed, quote_expired, payment_underpaid, refund_processed.
- Acknowledge Webhooks: Return 2xx quickly; enqueue downstream tasks.
- Fulfill Order: Only after payment_confirmed + KYT pass.
- Refunds: POST /refunds with reason and validated destination; link to original orderId.
Idempotency example
- For all POSTs: set header Idempotency-Key: orderId:attemptN.
- If you re-send due to timeout, the gateway returns the same object—no duplicates.
Reconciliation & accounting
Normalized ledger
- Every payment entry includes: quote FX, network fee, gateway fee, asset paid, chain, tx hash, final settlement asset, timestamp.
- Export CSV/S3 daily and pull via API to your data warehouse/ERP.
- Keep a mapping table for refunds to original orders (required for audit).
Month-end checklist
- Compare ERP order totals to settlement exports net of fees.
- Review outstanding quotes, stale AWAITING_FUNDS orders, and partial top-ups.
- Verify refund log matches support tickets and bank/treasury movements.
Compliance hooks you’ll be asked for
- Pre-auth KYT: Run wallet screening before fulfillment; block or review high-risk.
- Logs & retention: Keep immutable logs of screening, decisions, and refunds.
- Incident response: Have playbooks for chain congestion, provider outages, and webhook failures.
FAQs
Do we need our own wallet infrastructure?
Not to start. A gateway manages addresses/quotes. For treasury, you can receive settlements in USDC/fiat to custodial or bank destinations.
Can we keep users on our domain?
Yes—use embedded components or S2S APIs. Start hosted, then move embedded for full UX control.
How do we avoid double-fulfillment?
Rely on signed webhooks + idempotent handlers; fulfill only after payment_confirmed and risk checks pass.