NX NEXUSPAY DEVELOPER

Merchant API production guide

Create hosted checkout sessions, track transactions, and receive signed payment events from your own website.

Production v1PHP currencyServer-to-server onlyReal payments

Accept production payments

The Merchant API is called from your secure backend—not directly from browser JavaScript or a mobile app. NexusPay returns a hosted checkout URL that you send your customer to.

Production base URLhttps://api.nexus-core.app
Real money moves in this environment. Use only approved credentials and complete a controlled low-value transaction before opening access to customers.
  1. Request a merchant live key and register your HTTPS success and cancel origins.
  2. Create a checkout session from your backend with a unique idempotency key.
  3. Redirect the customer to the returned checkout_url.
  4. Fulfill the order only after a verified payment.paid event or authenticated status lookup.

Get production access

NexusPay creates an approved production profile before issuing credentials. Be ready to provide your business or website name, the HTTPS origins used by your success and cancel pages, and the payment methods you plan to accept.

  1. Submit your integration details to your NexusPay account contact.
  2. NexusPay registers the approved HTTPS redirect origins and live payment methods.
  3. Your server API key is delivered once. Copy it directly into an encrypted server environment variable.
  4. Complete the sandbox acceptance test and a controlled production smoke test before customer launch.
Production keys are issued only after separate live approval. They are permission-scoped and can be revoked immediately. If a key is lost, NexusPay cannot display it again; request a replacement.

Authentication and credentials

Send the live key in the HTTP Authorization header. Keys start with nx_live_ and are displayed only once when issued.

Authorization: Bearer nx_live_your_key_here
Keep keys server-side. Store them in an encrypted environment variable. Never place a key in HTML, browser JavaScript, a mobile package, screenshots, chat, source control, or an analytics event.

If a key is exposed, ask NexusPay to revoke it immediately and issue a replacement. Never reuse a sandbox key in production.

Create a hosted checkout

Amounts are integer Philippine centavos: 100000 means PHP 1,000.00. Reuse the same Idempotency-Key when safely retrying the same order.

cURL

curl https://api.nexus-core.app/v1/checkout-sessions \
  -X POST \
  -H "Authorization: Bearer $NEXUSPAY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: ORDER-1001-payment" \
  -d '{
    "amount": 100000,
    "currency": "PHP",
    "merchant_order_id": "ORDER-1001",
    "description": "Online store order",
    "payment_methods": ["qrph"],
    "success_url": "https://shop.example.com/pay/success",
    "cancel_url": "https://shop.example.com/pay/cancel"
  }'

Node.js

import { NexusPay } from "./sdk/node.mjs";

const nexuspay = new NexusPay({
  apiKey: process.env.NEXUSPAY_API_KEY
});

const checkout = await nexuspay.createCheckout({
  amount: 100000,
  currency: "PHP",
  merchant_order_id: "ORDER-1001",
  payment_methods: ["qrph"],
  success_url: "https://shop.example.com/pay/success",
  cancel_url: "https://shop.example.com/pay/cancel"
}, { idempotencyKey: "ORDER-1001-payment" });

console.log(checkout.checkout_url);

PHP

<?php
$payload = [
  "amount" => 100000,
  "currency" => "PHP",
  "merchant_order_id" => "ORDER-1001",
  "payment_methods" => ["qrph"],
  "success_url" => "https://shop.example.com/pay/success",
  "cancel_url" => "https://shop.example.com/pay/cancel"
];

$ch = curl_init("https://api.nexus-core.app/v1/checkout-sessions");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("NEXUSPAY_API_KEY"),
    "Content-Type: application/json",
    "Idempotency-Key: ORDER-1001-payment"
  ],
  CURLOPT_POSTFIELDS => json_encode($payload)
]);
$checkout = json_decode(curl_exec($ch), true);
header("Location: " . $checkout["checkout_url"]);

Redirect the customer

A successful create request returns a checkout session with id, transaction_id, status, checkout_url, and expires_at. Redirect the browser to checkout_url.

A success-page redirect is not proof of payment. Customers can close, replay, or modify browser navigation. Never ship goods or credit an account from a redirect alone.

Complete a customer payment

Open the returned checkout_url in the customer’s browser. The signed URL always loads NexusPay Hosted Checkout. NexusPay selects and operates the internal payment route; your integration never receives processor credentials, endpoints, or references.

  1. Create a new checkout from your backend.
  2. Redirect the customer to the complete checkout_url; do not remove its signature.
  3. The customer chooses an available payment method and completes the provider flow.
  4. NexusPay updates the transaction and redirects the browser to your registered success or cancel URL with the checkout ID, transaction ID, and status.
  5. Your backend independently retrieves the transaction before fulfilling the order.
A browser return is never proof of payment. Wait for a verified signed event or authenticated status lookup before fulfillment.

Confirm payment safely

Use either a signed payment.paid webhook or an authenticated transaction lookup. Provider completion can be asynchronous. Treat pending and processing as non-final.

GET /v1/transactions/txn_nxp_...
Authorization: Bearer nx_live_...

Terminal outcomes include paid, failed, expired, cancelled, and refund/dispute states. Make your fulfillment operation idempotent.

Register and verify webhooks

Register a public HTTPS endpoint from your backend. The signing secret is returned only on the first successful registration response.

POST /v1/webhook-endpoints
Authorization: Bearer nx_live_...
Idempotency-Key: webhook-primary-001
Content-Type: application/json

{
  "url": "https://shop.example.com/webhooks/nexuspay",
  "events": ["payment.pending", "payment.paid", "payment.failed"]
}

Receiver rules

  1. Read the exact raw UTF-8 request body before JSON parsing.
  2. Verify the NexusPay signature and timestamp using the one-time signing secret.
  3. Reject invalid or stale signatures.
  4. Store the event ID with a unique constraint before fulfillment.
  5. Return a 2xx response to already-processed retries.

Delivery format

NexusPay sends an HTTP POST with Content-Type: application/json. The X-NexusPay-Event-Id and X-NexusPay-Event-Type headers identify the event. X-NexusPay-Signature contains t=UNIX_TIME,v1=HMAC_SHA256, calculated over UNIX_TIME.raw_request_body.

{
  "id": "evt_nxp_...",
  "type": "payment.paid",
  "created_at": "2026-09-24T00:05:00.000Z",
  "data": {
    "object": {
      "transaction_id": "txn_nxp_...",
      "merchant_order_id": "ORDER-1001",
      "status": "paid",
      "amount": 100000,
      "currency": "PHP"
    }
  }
}

NexusPay attempts delivery immediately and records non-2xx responses as failed. A protected worker checks for due deliveries every five minutes. Retries become eligible after approximately 1 minute, 5 minutes, 30 minutes, 2 hours, and 12 hours. After six unsuccessful attempts the event becomes dead_letter. Use GET /v1/webhook-events to inspect delivery state and POST /v1/webhook-events/{event_id}/retry for an immediate attempt after correcting a receiver problem. Delivery never follows redirects, times out quickly, and revalidates the destination hostname before every attempt.

API endpoints

MethodPathPurpose
POST/v1/checkout-sessionsCreate an idempotent hosted checkout.
GET/v1/checkout-sessions/{checkout_id}Retrieve the current checkout state.
POST/v1/checkout-sessions/{checkout_id}/expireExpire an unpaid checkout.
GET/v1/transactionsList cursor-paginated merchant transactions.
GET/v1/transactions/{transaction_id}Retrieve one transaction.
POST/v1/webhook-endpointsRegister a signed webhook destination.
GET/v1/webhook-eventsInspect recent webhook deliveries.
POST/v1/webhook-events/{event_id}/retryImmediately retry an unsuccessful delivery.

Download the complete OpenAPI 3.1 specification.

Errors and request IDs

Errors use a stable JSON envelope. Record the request_id when contacting NexusPay support.

{
  "error": {
    "code": "unauthorized",
    "message": "A Bearer API key is required.",
    "request_id": "req_nxp_..."
  }
}

Each API key may make 120 total requests per minute. State-changing requests also have a 30-per-minute ceiling. Use RateLimit-Remaining and RateLimit-Reset to pace requests; after HTTP 429, wait for Retry-After seconds.

StatusMeaningMerchant action
400Invalid requestCorrect fields, formats, or redirect origins.
401Missing or invalid keyCheck the server environment and key status.
403Scope or method unavailableConfirm merchant approval and enabled payment methods.
404Resource not foundCheck that the ID belongs to the same merchant.
409Idempotency or state conflictDo not reuse a key for a different request.
429Rate limitedWait for Retry-After, then retry safely.
5xxTemporary platform errorRetry safely with the same idempotency key.

Merchant integration checklist

  1. API key is stored only on the backend and excluded from source control.
  2. Each order uses a stable, unique idempotency key.
  3. Only registered HTTPS success and cancel origins are used.
  4. Amounts are integer centavos and currency is PHP.
  5. Orders are fulfilled only from a verified event or authenticated lookup.
  6. Webhook signature verification uses the exact raw body.
  7. Event IDs and merchant order IDs are uniquely enforced.
  8. Timeouts, retries, duplicate events, expiry, and failure states are tested.
Production access can be revoked immediately. Monitor signed events, reconciliation, refunds, and provider incidents from the first transaction.