Skip to content

Explore Nexus Pay

Payments, integrations, and help in one place.

Developers

A small, versioned REST API and signed webhooks. Every account starts in test mode with its own keys; nothing you do in test mode touches real funds.

Step 1

Authenticate

Create an API key in Dashboard → Settings (shown once). Send it as a bearer token from your server only — never from a browser.

Authorization: Bearer nxp_test_…

Step 2

Create an invoice

Amounts are decimal strings. Send an Idempotency-Key so a retried request returns the same invoice instead of a duplicate.

curl -X POST https://api.example/v1/invoices   -H "Authorization: Bearer nxp_test_…"   -H "Idempotency-Key: order-1001"   -H "Content-Type: application/json"   -d '{"amount":"75.00","currency":"USD","merchant_order_id":"1001","description":"Order 1001"}'

# → 201 { "id": "…", "public_id": "chk_…", "status": "pending", "checkout_url": "https://…/pay/chk_…", … }

Redirect the customer to checkout_url. Poll GET /v1/invoices/{id} if you need status, but rely on webhooks to fulfil.

Step 3

Receive webhooks

Register an endpoint (Dashboard → Developers). Every event is signed over the raw body. Verify, then deduplicate on the event id inside the same transaction that credits the order — deliveries are at-least-once and you will see duplicates.

X-NexusPay-Signature: t=<unix seconds>,v1=<hex>
signature = HMAC_SHA256(secret, "<t>." + raw_body)   # reject if |now − t| > 300s

{ "id": "…", "type": "invoice.paid", "version": 1, "environment": "test",
  "data": { "invoice_id": "…", "merchant_order_id": "1001", "status": "paid", "amount": "75.00",
            "payment": { "asset_symbol": "USDT", "network_id": "bsc-testnet", "tx_hash": "0x…", … } } }

Event types: invoice.confirming, invoice.paid, invoice.partial, invoice.expired, invoice.late_review, invoice.cancelled, refund.*, ping. Only invoice.paid should credit an order.

Step 4

Errors and references

Errors are JSON with a stable machine code.

{ "error": { "code": "idempotency_conflict", "message": "Idempotency-Key reused with a different payload" } }
401 invalid key · 403 suspended / forbidden · 404 not found (also for other tenants&apos; objects) · 409 conflict · 422 invalid · 429 rate limited · 503 pricing_unavailable / platform_paused
  • Complete receivers with signature verification and transactional deduplication in Python, Node, and PHP: examples/merchant/ in the repository.
  • OpenAPI document: GET /openapi.json on the API host; interactive docs at /docs.
  • Event schema: packages/contracts/events/webhook.v1.schema.json.
  • Sandbox: every account is in test mode until live activation; test-network tokens have no value. How to get test tokens →

Framework stack

Node.js / Laravel ecommerce

For Node or Laravel stores, the flow is identical: create invoice on checkout, save merchant_order_id, and mark paid only from verified webhook callback.

// Laravel route idea
Route::post('/checkout', [CheckoutController::class, 'create']);
Route::post('/nexuspay/webhook', [WebhookController::class, 'handle']);

// Node webhook: verify with raw body
app.post('/nexuspay/webhook', express.raw({type: 'application/json'}), (req, res) => {
  const ok = verifyNexusPaySignature(req.headers['x-nexuspay-signature'], req.body);
  if (!ok) return res.status(400).send('invalid signature');
  // if event.id not processed, update order inside single transaction, then 200
});

Need starter files? Use examples/merchant/node/server.js for raw Node and examples/merchant/laravel/ README + controllers for Laravel.