Accepting Payments

Learn how to accept cryptocurrency payments with BLAQPAY

Accepting Payments

This comprehensive guide covers everything you need to know about accepting cryptocurrency payments with BLAQPAY.

Payment Flow Overview

Here’s how a typical payment works:

  1. Customer initiates payment on your website/app
  2. Your server creates a transaction via our API
  3. Customer is redirected to BLAQPAY payment page
  4. Customer chooses their preferred token (USDC, USDT, ETH, etc.)
  5. Customer sends crypto to the payment address
  6. Payment is confirmed on the blockchain
  7. Webhook notification sent to your server
  8. You fulfill the order for your customer

Creating a Payment

Basic Payment

const response = await fetch('https://blaqpay.io/api/transactions/create', {
	method: 'POST',
	headers: {
		'Authorization': 'Bearer YOUR_API_KEY',
		'Content-Type': 'application/json'
	},
	body: JSON.stringify({
		amount: 99.99,
		customer_email: 'customer@example.com',
		order_description: 'Premium Subscription'
	})
});

const { transaction, payment_url } = await response.json();

// Redirect customer to payment_url
window.location.href = payment_url;

Advanced Options

const response = await fetch('https://blaqpay.io/api/transactions/create', {
	method: 'POST',
	headers: {
		'Authorization': 'Bearer YOUR_API_KEY',
		'Content-Type': 'application/json'
	},
	body: JSON.stringify({
		// Required
		amount: 99.99,
		
		// Customer information
		customer_email: 'customer@example.com',
		customer_name: 'John Doe',
		
		// Order details
		order_description: 'Premium Subscription - Annual',
		order_id: 'order_12345', // Your internal ID
		order_items: [
			{
				name: 'Premium Plan',
				quantity: 1,
				price: 99.99
			}
		],
		
		// Redirect URLs
		success_url: 'https://yoursite.com/success',
		cancel_url: 'https://yoursite.com/cancel',
		
		// Metadata (optional custom data)
		metadata: {
			plan: 'premium',
			period: 'annual',
			user_id: '12345'
		},
		
		// Expiration (default: 30 minutes)
		expires_in_minutes: 60,
		
		// Currency (defaults to USD)
		currency: 'USD',
		
		// Shipping (for physical goods)
		requires_shipping: false
	})
});

const { transaction, payment_url } = await response.json();

Multi-Currency Support

BLAQPAY supports multiple fiat currencies. Specify the currency and the amount will be converted to USD automatically:

const response = await fetch('https://blaqpay.io/api/transactions/create', {
	method: 'POST',
	headers: {
		'Authorization': 'Bearer YOUR_API_KEY',
		'Content-Type': 'application/json'
	},
	body: JSON.stringify({
		amount: 100.00,
		currency: 'EUR', // Euros
		customer_email: 'customer@example.com'
	})
});

Supported Currencies:

  • USD, EUR, GBP, JPY, AUD, CAD, CHF, CNY, and more…

Token Selection

Customers choose their preferred cryptocurrency on the payment page. Supported tokens include:

  • Stablecoins: USDC, USDT
  • Native Tokens: ETH, BNB, MATIC, AVAX
  • Wrapped Tokens: WETH, WBTC
  • Multiple Chains: Ethereum, Polygon, BSC, Arbitrum, Base, Avalanche

The system automatically calculates the token amount based on real-time prices.

Payment States

Transactions go through several states:

created → prepared → pending → processing → confirming → completed
   ↓          ↓          ↓           ↓            ↓
cancelled  expired   failed      failed       failed
  • created: Transaction created, customer hasn’t selected token yet
  • prepared: Customer selected token, payment address generated
  • pending: Waiting for customer payment
  • processing: Payment detected on blockchain
  • confirming: Waiting for blockchain confirmations
  • completed: Payment confirmed and successful
  • failed: Payment failed
  • expired: Payment window expired
  • cancelled: Transaction cancelled

Handling Payment Confirmation

Set up a webhook endpoint to receive real-time notifications:

app.post('/webhooks/blaqpay', async (req, res) => {
	const event = req.body;
	
	// Verify signature
	const signature = req.headers['x-blaqpay-signature'];
	const isValid = verifyWebhook(
		JSON.stringify(event),
		signature,
		process.env.WEBHOOK_SECRET
	);
	
	if (!isValid) {
		return res.status(401).send('Invalid signature');
	}
	
	switch (event.event) {
		case 'transaction.created':
			console.log('Transaction created:', event.transaction.id);
			break;
			
		case 'transaction.payment_received':
			console.log('Payment detected:', event.transaction.id);
			break;
			
		case 'transaction.completed':
			// Payment successful! Fulfill the order
			await fulfillOrder(event.transaction);
			break;
			
		case 'transaction.failed':
			console.log('Payment failed:', event.transaction.id);
			break;
			
		case 'transaction.expired':
			console.log('Payment expired:', event.transaction.id);
			break;
	}
	
	res.status(200).send('OK');
});

Learn more about webhooks.

Option 2: Polling

Poll the API to check transaction status:

async function checkPaymentStatus(transactionId) {
	const response = await fetch(
		`https://blaqpay.io/api/transactions/${transactionId}`,
		{
			headers: {
				'Authorization': 'Bearer YOUR_API_KEY'
			}
		}
	);
	
	const { transaction } = await response.json();
	
	if (transaction.status === 'completed') {
		// Payment successful
		await fulfillOrder(transaction);
	} else if (transaction.status === 'expired' || transaction.status === 'failed') {
		// Payment not completed
		console.log('Payment not completed');
	} else {
		// Still pending, check again later
		setTimeout(() => checkPaymentStatus(transactionId), 10000);
	}
}

Redirect URLs

Configure where customers are redirected after payment:

{
	success_url: 'https://yoursite.com/success?transaction_id={transaction_id}',
	cancel_url: 'https://yoursite.com/cancel'
}

The {transaction_id} placeholder will be replaced with the actual transaction ID.

Metadata and Custom Data

Store custom data with transactions:

{
	amount: 99.99,
	metadata: {
		customer_id: '12345',
		subscription_id: 'sub_67890',
		plan: 'premium',
		referral_code: 'FRIEND10',
		custom_field: 'any data you need'
	}
}

Metadata is returned in webhooks and API responses.

Best Practices

1. Use Webhooks

Always use webhooks for payment confirmation. Don’t rely solely on redirect URLs as users might not return to your site.

2. Set Expiration Times

Set reasonable expiration times (default is 30 minutes):

{
	amount: 99.99,
	expires_in_minutes: 60 // 1 hour
}

3. Handle All States

Handle all possible transaction states in your application:

switch (transaction.status) {
	case 'created':
	case 'prepared':
	case 'pending':
		// Show "waiting for payment"
		break;
	case 'processing':
	case 'confirming':
		// Show "payment detected, confirming..."
		break;
	case 'completed':
		// Show "payment successful"
		break;
	case 'expired':
		// Show "payment expired, please try again"
		break;
	case 'failed':
		// Show "payment failed"
		break;
}

4. Verify Webhook Signatures

Always verify webhook signatures to ensure they’re from BLAQPAY:

import crypto from 'crypto';

function verifyWebhook(payload, signature, secret) {
	const expectedSignature = crypto
		.createHmac('sha256', secret)
		.update(payload)
		.digest('hex');
	
	return signature === expectedSignature;
}

5. Use Test Mode

Test your integration using test API keys (sk_test_...) before going live.

Testing

Test payments using test mode:

// Use test API keys
const API_KEY = 'sk_test_...';

// Create test transaction
const response = await fetch('https://blaqpay.io/api/transactions/create', {
	method: 'POST',
	headers: {
		'Authorization': `Bearer ${API_KEY}`,
		'Content-Type': 'application/json'
	},
	body: JSON.stringify({
		amount: 1.0,
		customer_email: 'test@example.com'
	})
});

In test mode:

  • Transactions are marked as testing_mode: true
  • Use testnet tokens
  • No real funds are involved

See our Testing Guide for more details.

Examples

E-commerce Checkout

// Shopping cart checkout
app.post('/checkout', async (req, res) => {
	const cart = req.body.cart;
	const total = calculateTotal(cart);
	
	const response = await fetch('https://blaqpay.io/api/transactions/create', {
		method: 'POST',
		headers: {
			'Authorization': `Bearer ${process.env.BLAQPAY_API_KEY}`,
			'Content-Type': 'application/json'
		},
		body: JSON.stringify({
			amount: total,
			order_description: `Order #${Date.now()}`,
			customer_email: req.body.email,
			order_items: cart.items,
			metadata: {
				cart_items: JSON.stringify(cart),
				customer_id: req.user.id
			},
			success_url: `https://mystore.com/order-confirmation`,
			cancel_url: `https://mystore.com/cart`
		})
	});
	
	const { payment_url } = await response.json();
	res.json({ checkoutUrl: payment_url });
});

Invoice Payment

// Create payment for invoice
async function createInvoicePayment(invoice) {
	const response = await fetch('https://blaqpay.io/api/transactions/create', {
		method: 'POST',
		headers: {
			'Authorization': `Bearer ${process.env.BLAQPAY_API_KEY}`,
			'Content-Type': 'application/json'
		},
		body: JSON.stringify({
			amount: invoice.total,
			currency: invoice.currency,
			customer_email: invoice.customer_email,
			customer_name: invoice.customer_name,
			order_id: invoice.id,
			order_description: `Invoice #${invoice.number}`,
			metadata: {
				invoice_id: invoice.id,
				invoice_number: invoice.number,
				due_date: invoice.due_date
			},
			expires_in_minutes: 1440 // 24 hours
		})
	});
	
	const { payment_url } = await response.json();
	
	// Send payment link to customer
	await sendEmail(invoice.customer_email, {
		subject: `Invoice #${invoice.number}`,
		paymentLink: payment_url
	});
}

Next Steps

Need Help?

If you have questions about accepting payments: