NexaPay API Documentation
Everything you need to integrate NexaPay into your application. Accept payments and receive crypto settlements.
Quick Start
Get up and running in 5 minutes
Integration Steps
- 1Create an account and get your API keys from the dashboard
- 2Set your crypto wallet address in Settings
- 3Use the API to create a payment session
- 4Redirect customers to the hosted checkout page
- 5Receive crypto when payment completes
// Server-side JavaScript. Keep the secret key out of browser code.
const API_KEY = process.env.NEXAPAY_API_KEY;
const API_URL = 'https://nexapay.one/api/v1';
// Create a payment with webhook callback
async function createPayment() {
const response = await fetch(`${API_URL}/payments`, {
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: 99.00,
currency: 'USD',
crypto: 'USDC',
description: 'Order #123',
customer_email: '[email protected]',
success_url: 'https://yoursite.com/success',
cancel_url: 'https://yoursite.com/cancel',
callback_url: 'https://yoursite.com/webhooks/nexapay',
}),
});
if (!response.ok) throw new Error('Payment creation failed');
const data = await response.json();
// Return this URL to your frontend so the customer can continue.
return data.payment.checkout_url;
}Authentication
Secure your API requests
NexaPay uses API keys to authenticate requests. All API requests must include your API key in the request headers. You can manage your API keys from the dashboard.
X-API-Key: cg_live_your_api_key_hereAuthorization: Bearer cg_live_your_api_key_hereAll API keys are live keys used for both development and production. No charges occur until a customer completes the full checkout flow.
Prefix: cg_live_- Never expose API keys in client-side code or public repositories
- Use environment variables to store keys securely
- Rotate keys regularly and immediately if compromised
- Safe to develop with live keys — no charges until a customer completes checkout
Safe Testing
Develop and test without any risk
NexaPay uses a single live API key for both development and production. There is no separate test mode — and you don't need one. Creating a payment session via the API does not charge anyone. A real charge only occurs when a customer completes the full checkout and enters their payment details.
What you can safely test
- Create payment sessions and inspect the API response
- Test the full redirect flow (success_url and cancel_url)
- Verify webhook delivery to your endpoints
- Build and debug your checkout integration end-to-end
- No charges until a real customer completes payment
When you call the API to create a payment, NexaPay generates a checkout session and returns a checkout URL. No money moves at this point. The customer must visit the checkout page, enter their card details, and confirm the payment for any charge to occur. This means your developers can freely integrate, test redirects, and verify webhooks with zero risk.
Payments
Accept fiat, receive crypto
Create payment sessions to accept card payments from your customers. Payments are automatically converted to cryptocurrency and settled to your configured wallet address.
/api/v1/paymentsRequest Body
amountPayment amount (e.g., 99.00)
currencyThree-letter ISO 4217 code (USD, EUR, GBP, AUD, JPY, ILS, and 25+ more)
cryptoSettlement crypto (USDC, ETH, POL and more)
descriptionPayment description shown to customer
customer_emailCustomer email for receipts
success_urlURL to redirect after successful payment
cancel_urlURL to redirect on payment cancellation
callback_urlWebhook URL for payment notifications
{
"success": true,
"payment": {
"id": 123,
"order_id": "live_abc123def456...",
"amount": 99.00,
"currency": "USD",
"status": "created",
"checkout_url": "https://nexapay.one/checkout/live_abc123..."
}
}Webhooks
Real-time payment notifications
Webhooks allow you to receive real-time notifications on payment events. Provide a callback_url when creating a payment, or set a global URL in your dashboard Settings. NexaPay sends a webhook for each of the following events: payment completed and session expired.
Webhook Security
Configure your webhook secret in the dashboard to receive HMAC-SHA256 signed callbacks. Verify signatures to prevent spoofing. Reject requests without a valid signature, and make order fulfillment idempotent so retries cannot process an order twice.
X-NexaPay-SignatureHMAC-SHA256 signatureX-NexaPay-TimestampRequest timestamp (for replay protection){
"order_id": "live_abc123def456...",
"payment_id": "12345678",
"status": "completed",
"amount": 95.95,
"txid": "0xabc123...",
"timestamp": "2026-02-18T01:32:31.881Z"
}Delivery rules
Webhooks are sent as a POST to the exact URL you configured. Use a public HTTPS endpoint: redirects are not followed (a 3xx response counts as a failed delivery), private or internal addresses are rejected, and each delivery times out after 15 seconds. Failed deliveries are retried automatically.
Status Values
pendingPayment session was created. The customer has not yet completed payment.completedPayment was successfully processed. Fulfil the order.failedThe payment failed. Notify the customer and allow retry.expiredThe payment session timed out (24 hours) without a completed payment. Release any held inventory and notify the customer.Note: amount and txid are present for on-chain payments and may be omitted for card payments.
// Node.js / Express. Configure the same secret in your NexaPay dashboard.
const crypto = require('crypto');
const express = require('express');
const app = express();
const webhookSecret = process.env.NEXAPAY_WEBHOOK_SECRET;
if (!webhookSecret) throw new Error('NEXAPAY_WEBHOOK_SECRET is required');
// Register this route BEFORE app.use(express.json()). Verify the exact bytes.
app.post('/webhooks/nexapay', express.raw({ type: 'application/json' }), async (req, res) => {
const signature = req.get('x-nexapay-signature');
const timestamp = req.get('x-nexapay-timestamp');
if (!Buffer.isBuffer(req.body) || !/^sha256=[a-f0-9]{64}$/i.test(signature || '') ||
!/^\d+$/.test(timestamp || '')) {
return res.status(401).json({ error: 'Missing or invalid signature' });
}
const sentAt = Number(timestamp); // NexaPay timestamps are milliseconds.
if (!Number.isSafeInteger(sentAt) || Math.abs(Date.now() - sentAt) > 5 * 60 * 1000) {
return res.status(401).json({ error: 'Webhook expired' });
}
const expected = crypto.createHmac('sha256', webhookSecret)
.update(timestamp + '.').update(req.body).digest();
const received = Buffer.from(signature.slice(7), 'hex');
if (received.length !== expected.length || !crypto.timingSafeEqual(received, expected)) {
return res.status(401).json({ error: 'Invalid signature' });
}
let payment;
try { payment = JSON.parse(req.body.toString('utf8')); }
catch { return res.status(400).json({ error: 'Invalid JSON' }); }
if (!payment || typeof payment.order_id !== 'string' || typeof payment.status !== 'string') {
return res.status(400).json({ error: 'Invalid payment event' });
}
try {
// Implement these on your server. Atomically deduplicate by order + status.
// Check the expected amount and currency before fulfilling your own order.
if (payment.status === 'completed') {
await fulfillOrderOnce(payment.order_id, payment);
} else if (payment.status === 'expired') {
await cancelOrderOnce(payment.order_id);
}
res.json({ received: true });
} catch {
// A non-2xx response allows NexaPay to retry delivery.
res.status(500).json({ error: 'Event processing failed' });
}
});Crypto Settlement
Automatic fiat-to-crypto conversion
All fiat payments are automatically converted to cryptocurrency at the current market rate and settled to your configured wallet address. No manual intervention required.
Settlement Timeline
API Endpoints
Complete endpoint reference
https://nexapay.one/api/v1/paymentsCreate a new payment session/payments/:order_idGet payment status by order ID/paymentsList all payments (max 100)Error Handling
Handle API errors gracefully
The API uses standard HTTP status codes to indicate success or failure. All error responses include a JSON body with details about what went wrong.
Rate Limits
API usage limits
API requests are rate limited to ensure fair usage and maintain service quality. Rate limits are applied per API key.
Need higher limits? Contact our sales team for Enterprise plans with custom rate limits.
WooCommerce Plugin
One-click WordPress integration
Accept NexaPay payments on your WooCommerce store with our official plugin. HPOS compatible with full webhook support for automatic order updates.
Installation Steps
- 1Download the plugin from the NexaPay documentation page
- 2Upload to WordPress via Plugins → Add New → Upload Plugin
- 3Activate the plugin
- 4Go to WooCommerce → Settings → Payments → NexaPay
- 5Enter your API key and webhook secret
- 6Enable the payment method
SDKs & Libraries
Official client libraries
We provide official SDKs for popular programming languages. All SDKs are open source and available on GitHub.
