It's Not Just "Stripe but for Crypto"
If you're coming from traditional card payments, your first instinct will be to map crypto concepts onto what you already know. Resist that. The fundamental model is different in ways that affect every layer of your integration.
With card payments, you authorize first and capture later. There's an issuing bank, an acquiring bank, and a network in between. Transactions can be reversed through chargebacks for months. With crypto, the customer pushes funds directly to you (or your provider's address). Once a transaction has enough confirmations on the blockchain, it's final. No chargebacks. No disputes. No issuer to call.
(they don't exist)
block time
standard
finality
That sounds great until you realize: no chargebacks also means no safety net for your customers. If you accidentally overcharge someone, you need to handle refunds manually by sending crypto back — and the gas fees come out of your pocket. I learned this the hard way when a pricing bug caused double-charges on a Saturday night. With Stripe, I would have just batch-refunded through the dashboard. With crypto, I spent three hours manually sending USDC back to 47 wallets.
The Crypto Payment Flow
Before diving into providers, let's look at what actually happens when a customer pays with crypto. This flow tripped me up initially because there's no synchronous "charge succeeded" response like you'd get from a card processor.
The key difference: between "Payment Page" and "Fiat Payout," you're waiting on a decentralized network you don't control. Block times vary. Fees spike. Transactions can sit in the mempool for hours during congestion. Your integration needs to handle all of this gracefully.
Comparing Crypto Payment Providers
I've worked with all three of these in production. Here's the honest breakdown.
| Feature | BitPay | Coinbase Commerce | BTCPay Server |
|---|---|---|---|
| Type | Hosted (custodial) | Hosted (custodial) | Self-hosted (non-custodial) |
| Settlement | Fiat (next day) or crypto | Crypto only (manual convert) | Direct to your wallet |
| Chains supported | BTC, ETH, LTC, + stablecoins | BTC, ETH, USDC, + EVM tokens | BTC, LTC, + plugins for others |
| Fees | 1% processing | 1% on cash-out | Free (you pay hosting) |
| KYC required | Yes (merchant) | Yes (merchant) | No |
| API quality | Good, REST-based | Simple, webhook-driven | Greenfield API (excellent) |
| Best for | Fiat settlement needs | Quick integration | Full control, privacy |
My take: If you need fiat settlement (most businesses do), BitPay is the most straightforward path. If you want full control and don't mind running infrastructure, BTCPay Server's Greenfield API is genuinely well-designed — better than some traditional payment APIs I've used. Coinbase Commerce is fine for getting started fast, but you'll outgrow it.
Settlement: The Part Nobody Warns You About
In traditional payments, settlement is boring. Money shows up in your bank account on a predictable schedule. With crypto, you have a decision to make: do you convert to fiat immediately, or hold crypto?
Most businesses should convert immediately. I know that sounds obvious, but I've watched a startup lose 30% of a month's revenue because they held ETH for two weeks "to see if it goes up." It went down. Your treasury is not a trading desk.
With instant conversion (what BitPay calls "settlement"), the flow works like this: customer pays in BTC, the provider locks in the exchange rate at the moment of payment, and you receive USD/EUR in your bank account the next business day. You never touch crypto. The provider absorbs the volatility risk and bakes it into their 1% fee.
If you do hold crypto — maybe you're paying suppliers in stablecoins or have a specific treasury strategy — make sure your accounting team knows. Crypto-on-balance-sheet has tax implications that vary wildly by jurisdiction. In the US, it's treated as property, not currency. Every disposal is a taxable event.
Webhook Patterns: Confirmations Are Not Binary
This is where traditional payment engineers get tripped up the most. In card payments, a transaction either succeeds or fails. With blockchain payments, there's a spectrum of "how settled is this?"
- 0-conf (unconfirmed): Transaction is broadcast to the network but not yet in a block. For Bitcoin, this is risky — double-spend attacks are possible. For small amounts (<$50), some merchants accept 0-conf. I wouldn't.
- 1-conf: Transaction is in one block. For most EVM chains and stablecoins, this is sufficient. Coinbase Commerce sends their first webhook here.
- 6-conf (Bitcoin standard): The industry standard for Bitcoin finality. At ~10 minutes per block, that's roughly an hour. This is what BitPay waits for before marking a payment as complete.
Your webhook handler needs to be idempotent and stateful. You'll receive multiple callbacks for the same payment as confirmations accumulate. I structure it like this:
// Simplified webhook state machine
switch (event.status) {
case 'pending': // 0-conf — show "payment detected" to user
updateOrder(orderId, 'payment_detected');
break;
case 'confirming': // 1-3 conf — safe for digital goods
if (order.type === 'digital') fulfillOrder(orderId);
break;
case 'confirmed': // 6 conf — safe for everything
fulfillOrder(orderId);
settleToFiat(orderId);
break;
case 'expired': // payment window closed, no tx received
cancelOrder(orderId);
break;
}
Gotcha: Payment expiration windows are typically 15-20 minutes. If a customer sends crypto after the window closes but before the address is recycled, you'll receive funds with no matching order. Every provider handles this differently. Build a reconciliation job that catches orphaned payments — I run mine every 6 hours.
Multi-Chain Support: The Real Complexity
Supporting "crypto payments" in 2026 means supporting multiple chains, and they're all different. Bitcoin uses UTXO. Ethereum and EVM chains use an account model. Solana has sub-second finality but a completely different transaction structure.
The practical challenges I've hit:
- Address formats: Bitcoin has legacy (1...), SegWit (bc1q...), and Taproot (bc1p...) addresses. Ethereum addresses work across all EVM chains but the same address on Ethereum vs. Polygon vs. Arbitrum are different networks. Customers will send to the wrong chain. It happens weekly.
- Gas fees: On Ethereum mainnet, a simple USDC transfer can cost $2-15 depending on congestion. On Polygon, it's fractions of a cent. This affects which chains you should prioritize for smaller payments.
- Finality times: Bitcoin ~60 min (6 blocks), Ethereum ~13 min (64 slots since the Merge), Solana <1 second. Your UX needs to account for these differences.
My advice: start with Bitcoin + one EVM chain (Ethereum or Polygon) + USDC. That covers 80%+ of crypto payment volume. Add Solana and other chains only when you see demand. Every chain you add is another node to monitor, another set of edge cases, and another integration to maintain.
Compliance: It's Catching Up Fast
The regulatory landscape for crypto payments has matured significantly. If you're building this in 2026, you can't ignore compliance.
- Travel Rule (FATF): For transactions above $1,000 (threshold varies by jurisdiction), you need to collect and transmit originator and beneficiary information. This is straightforward with custodial providers like BitPay — they handle it. With self-hosted BTCPay Server, it's on you.
- MiCA (EU): The Markets in Crypto-Assets regulation is fully in effect. If you're accepting crypto from EU customers, your provider needs to be MiCA-compliant. BitPay and Coinbase both have EU licenses. Check before you integrate.
- KYC: You'll need KYC for your merchant account with custodial providers. Some jurisdictions also require you to collect customer identity for crypto payments above certain thresholds. This is a moving target — work with a compliance advisor.
Real Gotchas from Production
Let me save you some debugging sessions:
- Underpayments: Customers will send slightly less than the invoiced amount because they forget about network fees. BitPay has a configurable tolerance (default 1%). Set it, or you'll get support tickets daily.
- Overpayments: The opposite also happens. Your system needs a policy — auto-refund the difference, credit the account, or eat it. We credit the customer's account balance.
- Exchange rate drift: Between when you show the price and when the customer actually sends, the rate can move. Most providers lock the rate for 15 minutes. If the payment arrives late, the amount in crypto may no longer match. Handle this edge case explicitly.
- Testnet tokens are not free: Bitcoin testnet and Ethereum Sepolia faucets are unreliable. Stock up on testnet tokens before a sprint, not during. BTCPay Server's regtest mode is the best testing experience — it mines blocks on demand.
- Mempool congestion: During Bitcoin fee spikes, low-fee transactions can be stuck for days. Your UI needs a "payment pending" state that doesn't panic the customer. We show estimated confirmation time based on current mempool conditions.
References
- BitPay API Documentation
- Coinbase Commerce Documentation
- BTCPay Server Documentation
- NOWPayments API Documentation
- FATF Virtual Assets — Travel Rule Guidance
- ESMA — Markets in Crypto-Assets Regulation (MiCA)
- Bitcoin Developer Guide — Transactions
Disclaimer: This article reflects the author's personal experience and opinions. It is not financial or legal advice. Cryptocurrency regulations vary by jurisdiction and change frequently — consult qualified legal and compliance professionals before implementing crypto payment solutions. Product names, logos, and brands are property of their respective owners.