Accepting Payments

Learn how to accept cryptocurrency payments with ZEUSXPAY

Accepting Payments

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

Payment Flow Overview

Here’s how a typical payment works:

  1. Customer initiates payment on your website/app
  2. Your server creates an order via our API
  3. Customer is redirected to ZEUSXPAY checkout
  4. Customer sends crypto to the provided address
  5. Payment is confirmed on the blockchain
  6. Webhook notification sent to your server
  7. You fulfill the order for your customer

Creating a Payment

Basic Payment

const order = await zeusxpay.orders.create({
	amount: 99.99,
	currency: 'USD',
	crypto_currency: 'BTC',
	description: 'Premium Subscription',
	customer_email: 'customer@example.com'
});

Advanced Options

const order = await zeusxpay.orders.create({
	// Required fields
	amount: 99.99,
	currency: 'USD',
	crypto_currency: 'BTC',

	// Customer information
	customer_email: 'customer@example.com',
	customer_name: 'John Doe',

	// Order details
	description: 'Premium Subscription - Annual',
	reference_id: 'order_12345', // Your internal ID

	// URLs
	return_url: 'https://yoursite.com/success',
	cancel_url: 'https://yoursite.com/cancel',
	webhook_url: 'https://yoursite.com/webhooks/zeusxpay',

	// Metadata (optional custom data)
	metadata: {
		plan: 'premium',
		period: 'annual',
		user_id: '12345'
	},

	// Expiration
	expires_in: 3600 // 1 hour
});

Supported Cryptocurrencies

ZEUSXPAY supports 100+ cryptocurrencies. Popular options include:

  • Bitcoin (BTC)
  • Ethereum (ETH)
  • USDT (Tether - ERC20, TRC20, BEP20)
  • USDC (USD Coin)
  • BNB (Binance Coin)
  • Litecoin (LTC)
  • Dogecoin (DOGE)
  • And many more…

Let Customer Choose

Don’t specify crypto_currency to let customers choose:

const order = await zeusxpay.orders.create({
	amount: 99.99,
	currency: 'USD',
	// crypto_currency not specified - customer chooses
	description: 'Premium Subscription'
});

Payment States

Orders go through several states:

pending → confirming → completed
   ↓           ↓
expired     failed
  • pending: Waiting for customer to send crypto
  • confirming: Transaction detected, waiting for confirmations
  • completed: Payment confirmed and successful
  • expired: Payment window expired
  • failed: Payment failed or was cancelled

Handling Payment Confirmation

Receive real-time notifications:

app.post('/webhooks/zeusxpay', async (req, res) => {
	const event = req.body;

	// Verify signature
	const signature = req.headers['x-zeusxpay-signature'];
	const isValid = zeusxpay.webhooks.verify(
		JSON.stringify(event),
		signature,
		process.env.WEBHOOK_SECRET
	);

	if (!isValid) {
		return res.status(401).send('Invalid signature');
	}

	switch (event.type) {
		case 'order.created':
			console.log('Order created:', event.data.id);
			break;

		case 'order.confirming':
			console.log('Payment detected:', event.data.id);
			break;

		case 'order.completed':
			// Payment successful! Fulfill the order
			await fulfillOrder(event.data);
			break;

		case 'order.failed':
			console.log('Payment failed:', event.data.id);
			break;
	}

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

Option 2: Polling

Poll the API to check payment status:

async function checkPaymentStatus(orderId) {
	const order = await zeusxpay.orders.retrieve(orderId);

	if (order.status === 'completed') {
		// Payment successful
		await fulfillOrder(order);
	} else if (order.status === 'expired' || order.status === 'failed') {
		// Payment failed
		console.log('Payment not completed');
	} else {
		// Still pending, check again later
		setTimeout(() => checkPaymentStatus(orderId), 10000);
	}
}

Pricing and Currency Conversion

Fixed Crypto Amount

Charge a specific amount of cryptocurrency:

const order = await zeusxpay.orders.create({
	crypto_amount: 0.001, // 0.001 BTC
	crypto_currency: 'BTC',
	description: 'Fixed crypto payment'
});

Fiat to Crypto Conversion

Charge in fiat, we handle conversion:

const order = await zeusxpay.orders.create({
	amount: 100.0,
	currency: 'USD',
	crypto_currency: 'BTC',
	// We calculate the BTC amount automatically
	description: 'Fiat-based payment'
});

The crypto amount is locked when the order is created and remains valid for the expiration period.

Checkout Options

Hosted Checkout

Redirect customers to our hosted page:

// Create order
const order = await zeusxpay.orders.create({ ... });

// Redirect to checkout
window.location.href = order.payment_url;

Embedded Checkout

Display checkout on your site:

<div id="zeusxpay-checkout"></div>

<script>
	zeusxpay.checkout({
		containerId: 'zeusxpay-checkout',
		orderId: 'ord_1234567890',
		onSuccess: (order) => {
			window.location.href = '/success';
		},
		onCancel: () => {
			window.location.href = '/cancel';
		}
	});
</script>

QR Code

Generate QR codes for mobile payments:

const qrCode = await zeusxpay.orders.getQRCode(orderId);
// Returns a data URL or SVG

Refunds

Issue full or partial refunds:

// Full refund
const refund = await zeusxpay.refunds.create({
	order_id: 'ord_1234567890',
	reason: 'Customer request'
});

// Partial refund
const partialRefund = await zeusxpay.refunds.create({
	order_id: 'ord_1234567890',
	amount: 50.0, // Refund $50 of $100 order
	reason: 'Partial refund'
});

Metadata and Custom Data

Store custom data with orders:

const order = await zeusxpay.orders.create({
	amount: 99.99,
	currency: 'USD',
	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 return URLs as users might not return to your site.

2. Idempotency

Use idempotency keys to safely retry requests:

const order = await zeusxpay.orders.create(
  { ... },
  {
    idempotencyKey: 'order_12345_' + Date.now()
  }
);

3. Set Expiration Times

Set reasonable expiration times:

const order = await zeusxpay.orders.create({
	amount: 99.99,
	currency: 'USD',
	expires_in: 1800 // 30 minutes
});

4. Handle All States

Handle all possible order states in your application:

switch (order.status) {
	case 'pending':
		// Show "waiting for payment"
		break;
	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;
}

5. Verify Webhook Signatures

Always verify webhook signatures:

const isValid = zeusxpay.webhooks.verify(payload, signature, webhookSecret);

if (!isValid) {
	throw new Error('Invalid webhook signature');
}

Testing

Test payments in sandbox mode:

// Use test API keys
const zeusxpay = new ZeusXPay('sk_test_...');

// Create test order
const order = await zeusxpay.orders.create({
	amount: 1.0,
	currency: 'USD',
	crypto_currency: 'BTC'
});

// Test payments auto-complete after 1 minute

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 order = await zeusxpay.orders.create({
		amount: total,
		currency: 'USD',
		description: `Order #${Date.now()}`,
		customer_email: req.body.email,
		metadata: {
			cart_items: JSON.stringify(cart),
			customer_id: req.user.id
		},
		return_url: `https://mystore.com/order-confirmation`,
		webhook_url: 'https://mystore.com/webhooks/payment'
	});

	res.json({ checkoutUrl: order.payment_url });
});

Subscription Payment

// Monthly subscription
async function chargeSubscription(subscription) {
	const order = await zeusxpay.orders.create({
		amount: subscription.price,
		currency: 'USD',
		crypto_currency: 'USDT',
		description: `${subscription.plan} - Monthly`,
		customer_email: subscription.customer_email,
		metadata: {
			subscription_id: subscription.id,
			period_start: Date.now(),
			period_end: Date.now() + 30 * 24 * 60 * 60 * 1000
		}
	});

	// Send payment link to customer
	await sendEmail(subscription.customer_email, {
		subject: 'Subscription Payment',
		paymentLink: order.payment_url
	});
}

Next Steps

Need Help?

If you have questions about accepting payments: