Skip to main content

Payment Flow Guide

This guide walks you through the complete payment flow from creating a payment order to receiving confirmation. Understanding this flow helps you provide the best experience for your customers.

Overview

The CryptoPay payment flow consists of these main steps:

  1. Create Payment Order - Generate a payment request
  2. Customer Payment - Customer sends cryptocurrency
  3. Detection - Our system detects the blockchain transaction
  4. Confirmation - Wait for required block confirmations
  5. Notification - Receive webhook notification
  6. Fulfillment - Complete the order

Step 1: Create Payment Order

Using the Dashboard

  1. Navigate to Payments > Create Order

  2. Fill in details:

    • Amount: 100.00
    • Currency: USDC
    • Blockchain: Base
    • Order Info: Product details in JSON format
    • Expiration: Optional expiration time
  3. Click Create Order to generate the payment link

Using the API

const order = await fetch('/api/payment-orders/', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: '100.00',
currency: 'USDC',
blockchain: 'base',
order_info: JSON.stringify({
product: 'Premium Plan',
customer_id: 'user_123',
quantity: 1
}),
nonce: Date.now() + Math.floor(Math.random() * 1000000),
webhook_url: 'https://your-site.com/webhooks/cryptopay'
})
});

const paymentOrder = await order.json();
console.log('Payment URL:', paymentOrder.data.payment_url);

Payment Order Response

{
"success": true,
"data": {
"id": 123,
"order_id": "ORD-abc123def456",
"amount": "100.00",
"currency": "USDC",
"blockchain": "base",
"status": "pending",
"receiving_address": "0x1234567890123456789012345678901234567890",
"payment_url": "https://pay.cryptopay.com/order/ORD-abc123def456",
"qr_code_url": "/qr/ORD-abc123def456",
"expires_at": "2024-01-01T12:00:00Z",
"created_at": "2024-01-01T10:00:00Z"
}
}

Step 2: Customer Payment

Payment Options

Customers can pay using:

1. Payment Page

  • Direct them to payment_url
  • Mobile-optimized interface
  • Supports all major wallets
  • QR code for mobile wallets

2. Direct Wallet Transfer

  • Show the receiving address
  • Display exact amount and token
  • Include QR code for easy scanning

3. Embedded Widget

<iframe 
src="https://pay.cryptopay.com/order/ORD-abc123def456"
width="400"
height="600"
frameborder="0">
</iframe>

Customer Experience

  1. Choose Wallet: MetaMask, Coinbase Wallet, etc.
  2. Connect Wallet: Authorize wallet connection
  3. Review Payment: Confirm amount, token, and recipient
  4. Send Transaction: Submit blockchain transaction
  5. Wait for Confirmation: Transaction processes on blockchain

Payment Instructions

Provide clear instructions to customers:

<div class="payment-instructions">
<h3>Complete Your Payment</h3>
<p>Send exactly <strong>100.00 USDC</strong> to:</p>
<code>0x1234567890123456789012345678901234567890</code>
<p>Network: <strong>Base</strong></p>
<p>⚠️ Only send USDC on Base network to this address</p>
</div>

Step 3: Payment Detection

How Detection Works

Our system continuously monitors blockchains for incoming transactions:

  1. Real-time Monitoring: We scan new blocks every few seconds
  2. Address Matching: Check if transactions match your wallet addresses
  3. Amount Verification: Verify the payment amount and token
  4. Initial Detection: Payment status changes to "processing"

Detection Timeline

BlockchainDetection TimeBlock Time
Ethereum15-30 seconds~12 seconds
Base5-10 seconds~2 seconds
Polygon5-10 seconds~2 seconds
BSC10-15 seconds~3 seconds
Arbitrum2-5 seconds~0.25 seconds

What We Check

  • Correct Address: Payment sent to your wallet address
  • Correct Token: Right cryptocurrency (USDC, ETH, etc.)
  • Sufficient Amount: At least the required amount
  • Valid Transaction: Transaction succeeded on blockchain

Step 4: Confirmation Process

Confirmation Requirements

Different confirmation thresholds based on your settings:

// Example confirmation thresholds
const confirmationSettings = {
'low_value': 1, // < $100
'medium_value': 6, // $100-$1000
'high_value': 12, // > $1000
'custom': 24 // Custom setting
};

Confirmation Timeline

Example: Base Network (2-second blocks, 12 confirmations)

  • Block 1: Transaction included (0 confirmations)
  • Block 2: 1 confirmation (2 seconds later)
  • Block 6: 5 confirmations (10 seconds later)
  • Block 12: 11 confirmations (22 seconds later)
  • Block 13: 12 confirmations ✅ CONFIRMED (24 seconds later)

Status Updates

Payment status progresses through these stages:

  1. pending - Waiting for payment
  2. processing - Payment detected, waiting for confirmations
  3. confirmed - Required confirmations reached
  4. failed - Payment failed or insufficient

Step 5: Webhook Notifications

Webhook Events

You'll receive webhooks for each status change:

payment.pending - Initial detection

{
"event": "payment.pending",
"data": {
"order_id": "ORD-abc123def456",
"transaction_hash": "0xabcdef...",
"amount": "100.00",
"currency": "USDC",
"blockchain": "base",
"confirmations": 1,
"status": "processing"
}
}

payment.confirmed - Final confirmation

{
"event": "payment.confirmed",
"data": {
"order_id": "ORD-abc123def456",
"transaction_hash": "0xabcdef...",
"amount": "100.00",
"currency": "USDC",
"blockchain": "base",
"confirmations": 12,
"status": "confirmed",
"confirmed_at": "2024-01-01T10:15:00Z"
}
}

Webhook Handler Example

app.post('/webhooks/cryptopay', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-webhook-signature'];
const payload = req.body;

// Verify signature
if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}

const webhookData = JSON.parse(payload);
const { event, data } = webhookData;

switch (event) {
case 'payment.pending':
// Update UI to show payment detected
updatePaymentStatus(data.order_id, 'processing');
notifyCustomer(data.order_id, 'Payment detected, waiting for confirmation');
break;

case 'payment.confirmed':
// Fulfill the order
fulfillOrder(data.order_id);
updatePaymentStatus(data.order_id, 'confirmed');
notifyCustomer(data.order_id, 'Payment confirmed! Order processing');
break;

case 'payment.failed':
// Handle failed payment
updatePaymentStatus(data.order_id, 'failed');
notifyCustomer(data.order_id, 'Payment failed: ' + data.reason);
break;
}

res.status(200).send('OK');
});

Step 6: Order Fulfillment

Fulfillment Process

Once payment is confirmed:

  1. Verify Payment: Double-check payment details
  2. Update Database: Mark order as paid
  3. Fulfill Order: Deliver product/service
  4. Send Confirmation: Email receipt to customer
  5. Update Analytics: Record successful payment

Example Fulfillment

async function fulfillOrder(orderId) {
try {
// Get order details
const order = await getOrderFromDatabase(orderId);
const orderInfo = JSON.parse(order.order_info);

// Update order status
await updateOrderStatus(orderId, 'paid');

// Fulfill based on product type
switch (orderInfo.product) {
case 'Premium Plan':
await activatePremiumSubscription(orderInfo.customer_id);
break;

case 'Digital Download':
await sendDownloadLink(orderInfo.customer_id, orderInfo.product_id);
break;

case 'Physical Product':
await createShippingLabel(orderInfo.customer_id, orderInfo.shipping_address);
break;
}

// Send confirmation email
await sendOrderConfirmation(orderInfo.customer_id, order);

console.log(`Order ${orderId} fulfilled successfully`);

} catch (error) {
console.error(`Error fulfilling order ${orderId}:`, error);
// Handle fulfillment errors
}
}

Payment Flow Monitoring

Dashboard Monitoring

Track payments in real-time through your dashboard:

  1. Live Feed: See payments as they happen
  2. Status Updates: Watch confirmations accumulate
  3. Transaction Details: View blockchain transaction info
  4. Customer Information: See payment source addresses

API Monitoring

Check payment status programmatically:

// Poll for payment updates
async function monitorPayment(orderId) {
const maxAttempts = 60; // 5 minutes with 5-second intervals
let attempts = 0;

while (attempts < maxAttempts) {
const response = await fetch(`/api/payment-orders/${orderId}/`, {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});

const order = await response.json();

if (order.data.status === 'confirmed') {
console.log('Payment confirmed!');
return order.data;
} else if (order.data.status === 'failed') {
console.log('Payment failed');
return order.data;
}

// Wait 5 seconds before next check
await new Promise(resolve => setTimeout(resolve, 5000));
attempts++;
}

console.log('Payment monitoring timeout');
return null;
}

Handling Edge Cases

Common Issues

1. Insufficient Amount

{
"event": "payment.failed",
"data": {
"reason": "insufficient_amount",
"expected_amount": "100.00",
"received_amount": "50.00"
}
}

2. Wrong Token

{
"event": "payment.failed",
"data": {
"reason": "invalid_token",
"expected_token": "USDC",
"received_token": "USDT"
}
}

3. Expired Order

{
"event": "order.expired",
"data": {
"order_id": "ORD-abc123def456",
"expired_at": "2024-01-01T12:00:00Z"
}
}

Recovery Actions

function handlePaymentIssue(webhookData) {
const { event, data } = webhookData;

switch (data.reason) {
case 'insufficient_amount':
// Contact customer about partial payment
sendPartialPaymentNotification(data.order_id, data);
break;

case 'invalid_token':
// Guide customer to send correct token
sendTokenCorrectionNotification(data.order_id, data);
break;

case 'expired':
// Offer to create new payment order
sendOrderRenewalNotification(data.order_id);
break;
}
}

Best Practices

Customer Communication

  1. Set Expectations: Explain confirmation times
  2. Provide Updates: Show payment progress
  3. Clear Instructions: Specify exact amount and token
  4. Support Contact: Offer help if issues arise

Error Handling

  1. Graceful Degradation: Handle API failures
  2. Retry Logic: Implement exponential backoff
  3. Logging: Record all payment events
  4. Monitoring: Alert on unusual patterns

Security

  1. Verify Webhooks: Always check HMAC signatures
  2. Validate Amounts: Confirm payment matches order
  3. Monitor Addresses: Watch for suspicious activity
  4. Secure Storage: Protect customer data

Next Steps