Quick Start Guide
Accept your first BEP-20 token payment in under 10 minutes. This guide walks you through every step from account creation to confirmed payment.
Create your account
Register at /auth/register. Verify your email address — this is required before API keys can be used in production.
The Free plan is permanently free and gives you BSC Testnet access with 100 API calls/month — perfect for development and testing.
Create an API key
Navigate to Dashboard → API Keys and click Create New Key. Give it a descriptive label (e.g. Production App).
cpk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4
Keep this key secret. Never expose it in client-side JavaScript or commit it to source control. Use environment variables.
Whitelist your domain
Go to Dashboard → Domains and add your application origin. For local development, add http://localhost:3000.
Create a payment session
Call POST /api/v1/payment/create with your API key, the token ID, and the amount. USDT has tokenId: 1 by default.
const res = await fetch('https://paynovax.online/api/v1/payment/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': 'cpk_live_...' },
body: JSON.stringify({ tokenId: 1, amount: '49.99' }),
});
const { data } = await res.json();
// data.ephemeralAddress — show this BSC address to your customer
// data.qrCodeData — base64 PNG QR code, display as <img src=...>
// data.sessionId — store this to poll status
// data.expiresAt — show a countdown timer
Display the qrCodeData as an <img> tag and show the ephemeralAddress as fallback text for wallets that don't support QR scanning.
Poll payment status
Poll GET /api/v1/payment/:sessionId/status every 5 seconds until the status is terminal.
async function pollStatus(sessionId) {
const terminal = ['completed', 'failed', 'expired'];
while (true) {
await new Promise(r => setTimeout(r, 5000));
const r = await fetch(BASE + `/api/v1/payment/${sessionId}/status`, { headers });
const d = (await r.json()).data;
if (terminal.includes(d.status)) return d;
}
}
Handle the result
When the status reaches a terminal state, fulfill the order or show the appropriate message.
const result = await pollStatus(sessionId);
switch (result.status) {
case 'completed':
// ✓ Payment confirmed on-chain
fulfillOrder(result.txHash);
break;
case 'expired':
// ✕ Session TTL elapsed without payment
showMessage('Payment timed out. Please try again.');
break;
case 'failed':
// ✕ Forwarding failed after payment detected
notifyAdmin(result);
break;
}
You're live!
Your integration is complete. For production, make sure to use BSC Mainnet and upgrade to a paid plan to unlock mainnet access.