Back to How-To Guides
HOW-TO12 min read2025-06-23

How to Integrate a Crypto Payment Gateway — Three Options by Technical Complexity

Adding crypto payment to your website takes 1–3 days with a third-party processor, or 5–8 weeks for a custom integration. Here is the complete technical guide for each option.

ClickMasters Team
Step-by-step implementation
Expert Assistance

Ready to Integrate Crypto Payments?

Get expert guidance on setting up crypto payment acceptance for your business.

Complete Guide

Quick Answer

Integrating crypto payments offers 3 options: Third-Party Processor (1-3 days, 0% dev cost, 1% fee — Coinbase Commerce, BitPay), API Integration (5-8 weeks, $15,000–$40,000 — custom checkout with webhooks), and Full Custom Gateway (8-14 weeks, $40,000–$80,000 — direct blockchain integration with HD wallet address management). Auto-conversion to USD eliminates price volatility risk. Break-even vs. custom: ~3 years at $1M/year volume.

Option 1: Third-Party Processor (1–3 days, $0 dev cost)

Coinbase Commerce or BitPay provides a hosted checkout page. You embed a payment button; customers pay with crypto; you receive USD in your bank account within 1–3 business days.

Example
<!-- Coinbase Commerce button -->
<script src="https://commerce.coinbase.com/v1/checkout.js?version=201807"></script>
<button class="buy-with-crypto"
  data-custom="Your-Order-ID"
  data-code="YOUR-CHECKOUT-CODE">
  Pay with Crypto
</button>

Fee: 1% per transaction (Coinbase Commerce).

Break-even vs. custom: At $1M/year in crypto payments, 1% = $10,000/year in fees. Custom integration (no ongoing fees) pays back in ~3 years.

Option 2: API Integration (5–8 weeks, $15,000–$40,000)

Build your own payment flow using crypto payment APIs:

Example
// Create payment request (Coinbase Commerce API example)
async function createPayment(orderId, amount, currency = 'USD') {
    const response = await fetch('https://api.commerce.coinbase.com/charges', {
        method: 'POST',
        headers: {
            'X-CC-Api-Key': process.env.COINBASE_COMMERCE_KEY,
            'X-CC-Version': '2018-03-22',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            name: 'Order Payment',
            description: 'Order ' + orderId,
            local_price: { amount: amount.toFixed(2), currency },
            pricing_type: 'fixed_price',
            metadata: { orderId }
        })
    });
    
    const charge = await response.json();
    return charge.data.hosted_url; // Redirect user to this URL
}

// Webhook handler for payment confirmation
app.post('/webhooks/coinbase', express.raw({ type: 'application/json' }), (req, res) => {
    const signature = req.headers['x-cc-webhook-signature'];
    const payload = req.body.toString('utf8');
    
    // Verify webhook signature
    const hmac = crypto.createHmac('sha256', process.env.COINBASE_WEBHOOK_SECRET);
    const digest = hmac.update(payload).digest('hex');
    
    if (digest !== signature) {
        return res.status(401).send('Invalid signature');
    }
    
    const event = JSON.parse(payload);
    
    if (event.type === 'charge:confirmed') {
        const orderId = event.data.metadata.orderId;
        fulfillOrder(orderId); // Your order fulfillment logic
    }
    
    res.status(200).send('OK');
});

Option 3: Full Custom (8–14 weeks, $40,000–$80,000)

Direct blockchain integration with your own wallet infrastructure:

Example
// Generate unique deposit address per order using HD wallet
const { ethers } = require('ethers');

class PaymentAddressManager {
    constructor(hdWalletMnemonic) {
        this.wallet = ethers.HDNodeWallet.fromPhrase(hdWalletMnemonic);
        this.provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
    }
    
    async generateDepositAddress(orderId) {
        // Derive unique child address for each order
        const orderIndex = await this.db.orders.getIndex(orderId);
        const childWallet = this.wallet.derivePath(`m/44'/60'/0'/0/${orderIndex}`);
        
        await this.db.depositAddresses.create({
            orderId,
            address: childWallet.address,
            privateKey: childWallet.privateKey, // Encrypted at rest
            createdAt: new Date(),
            expiresAt: new Date(Date.now() + 3600000) // 1 hour expiry
        });
        
        return childWallet.address;
    }
    
    async monitorForPayment(address, expectedAmount) {
        // Poll for incoming transactions
        const filter = {
            address: USDC_CONTRACT_ADDRESS,
            topics: [
                ethers.id('Transfer(address,address,uint256)'),
                null,
                ethers.zeroPadValue(address, 32)
            ]
        };
        
        return new Promise((resolve) => {
            this.provider.on(filter, (log) => {
                const amount = ethers.toBigInt(log.data);
                if (amount >= BigInt(expectedAmount * 1e6)) { // USDC has 6 decimals
                    resolve({ confirmed: true, txHash: log.transactionHash });
                }
            });
        });
    }
}

Frequently Asked Questions

Common questions before following this guide

Clear answers to the most common practical, technical, and implementation questions.

1

Answers

How do we handle crypto price volatility when accepting payments?

Auto-conversion to USD on receipt eliminates price risk. The customer pays with crypto; your payment processor or custom integration sells it immediately (within seconds) and credits you in USD. Your business is never exposed to crypto price movements.

Expert Assistance

Ready to Integrate Crypto Payments?

Get expert guidance on setting up crypto payment acceptance for your business.