Base URL: https://api.nexuzpayz.com/api/v1

Introduction

The NexuzPayz Merchant Integration API is a REST API for accepting GHS payments from your server-side checkout or billing system.

Use it to:

  • Create payment links and redirect customers to a hosted checkout page
  • Initiate mobile money USSD collections (MTN, Telecel, AirtelTigo)
  • Issue permanent USSD payment IDs (*203*{id}#)
  • Receive signed webhooks when payments succeed or fail

All requests use JSON over HTTPS. API keys are created in the merchant portal; this reference covers only the endpoints your integration calls.

Authentication

Authenticate every request with a secret API key in the Authorization header:

Authorization: Bearer sk_test_xxxxxxxx
Key prefixEnvironment
sk_test_Sandbox — test without real money movement
sk_live_Live — real GHS collections after KYC approval

The environment is determined by the key prefix. There is no separate sandbox base URL.

Security requirements

  • Call the API from your server only — never embed keys in client-side code, mobile apps, or public repos
  • Store keys in a secrets manager or environment variables
  • Rotate keys via the merchant portal if compromised

Collections

Create and retrieve GHS collections. Payment links return a `paymentUrl`; USSD flows may return `REQUIRES_OTP` while the payer confirms on their device.

POST/api/v1/merchant/collections

Create collection

Initiate a GHS collection via payment link or mobile-money USSD.

Authentication: Bearer API key (`sk_test_…` or `sk_live_…`)

Request body

FieldTypeRequiredDescription
amountstringYesPositive decimal amount in GHS (e.g. `"99.00"`).
methodstringDefault `payment_link`. Use any other value for USSD mobile-money collection.
channelstringRequired for USSD: `13` (MTN), `6` (Telecel), `7` (AirtelTigo).
payerPhonestringRequired for USSD. E.164 format, e.g. `+233201234567`.
payerEmailstringOptional. Used for payment-link notifications.
merchantReferencestringYour order or checkout reference.
metadataobjectArbitrary key-value metadata stored with the collection.
expirationMinutesintegerPayment-link expiry in minutes.
Example request
curl -X POST https://api.nexuzpayz.com/api/v1/api/v1/merchant/collections \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "99.00",
    "method": "payment_link",
    "merchantReference": "ORD-10042",
    "payerEmail": "customer@example.com",
    "expirationMinutes": 60
  }'

`201 Created` — returns the collection object.

Example response
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "externalRef": "moolre-ref-abc123",
  "merchantReference": "ORD-10042",
  "amount": "99.00",
  "currency": "GHS",
  "method": "payment_link",
  "channel": null,
  "status": "PENDING",
  "paymentUrl": "https://pay.moolre.com/...",
  "environment": "SANDBOX",
  "createdAt": "2026-06-26T10:00:00Z",
  "completedAt": null
}

Notes

  • Merchant must have a GHS collection wallet configured.
  • LIVE collections require merchant status `ACTIVE`.
  • Statuses: `PENDING`, `REQUIRES_OTP`, `SUCCEEDED`, `FAILED`, `EXPIRED`.
GET/api/v1/merchant/collections/{id}

Retrieve collection

Retrieve a collection by ID.

Authentication: Bearer API key

Path parameters

FieldTypeRequiredDescription
iduuidYesCollection ID.
Example request
curl https://api.nexuzpayz.com/api/v1/api/v1/merchant/collections/{id} \
  -H "Authorization: Bearer sk_test_..."

`200 OK` — returns the collection object.

Example response
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "externalRef": "moolre-ref-abc123",
  "merchantReference": "ORD-10042",
  "amount": "99.00",
  "currency": "GHS",
  "method": "payment_link",
  "status": "SUCCEEDED",
  "paymentUrl": "https://pay.moolre.com/...",
  "environment": "LIVE",
  "createdAt": "2026-06-26T10:00:00Z",
  "completedAt": "2026-06-26T10:05:12Z"
}

Error responses

  • `404` — Collection not found or does not belong to this merchant.

Payment IDs

Permanent Moolre payment IDs for USSD checkout. Customers pay by dialling `*203*{paymentId}#`.

POST/api/v1/merchant/payment-ids

Create payment ID

Issue a permanent USSD payment ID for a checkout session.

Authentication: Bearer API key

Request body

FieldTypeRequiredDescription
labelstringHuman-readable label for your records.
payerPhonestringCustomer phone number (E.164).
merchantReferencestringYour order reference.
expectedAmountstringExpected GHS amount (decimal string).
metadataobjectArbitrary metadata.
Example request
curl -X POST https://api.nexuzpayz.com/api/v1/api/v1/merchant/payment-ids \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Order #10042",
    "payerPhone": "+233201234567",
    "merchantReference": "ORD-10042",
    "expectedAmount": "99.00"
  }'

`201 Created` — returns the payment ID object including `ussdCode`.

Example response
{
  "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "paymentId": "48291037",
  "ussdCode": "*203*48291037#",
  "merchantReference": "ORD-10042",
  "expectedAmount": "99.00",
  "currency": "GHS",
  "status": "AWAITING_PAYMENT",
  "environment": "LIVE",
  "createdAt": "2026-06-26T10:00:00Z"
}

Notes

  • Statuses: `AWAITING_PAYMENT`, `PAID`, `FAILED`.
GET/api/v1/merchant/payment-ids

List payment IDs

Paginated list of payment IDs for the authenticated merchant.

Authentication: Bearer API key

Query parameters

FieldTypeRequiredDescription
pageintegerZero-based page index. Default `0`.
sizeintegerPage size. Default `20`.

`200 OK` — paginated list.

Example response
{
  "items": [ /* Payment ID objects */ ],
  "total": 42
}
GET/api/v1/merchant/payment-ids/{id}

Retrieve payment ID

Retrieve a payment ID. When `sync=true` (default) and status is `AWAITING_PAYMENT`, NexuzPayz polls Moolre for the latest status.

Authentication: Bearer API key

Path parameters

FieldTypeRequiredDescription
iduuidYesPayment ID record UUID.

Query parameters

FieldTypeRequiredDescription
syncbooleanPoll Moolre for updates. Default `true`.

`200 OK` — returns the payment ID object.

Example response
{
  "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "paymentId": "48291037",
  "ussdCode": "*203*48291037#",
  "status": "PAID",
  "paidAmount": "99.00",
  "paidAt": "2026-06-26T10:08:00Z",
  "collectionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

Webhooks

NexuzPayz delivers signed HTTP POST requests to URLs you register in the merchant portal. Your server must verify signatures before updating order state.

Event typeDescription
collection.succeededA collection was confirmed as paid.
collection.failedA collection failed or was not completed.

Delivery headers

Content-Typeapplication/json
X-NexuzPayz-Eventcollection.succeeded | collection.failed
X-NexuzPayz-Signaturet={unix_timestamp},v1={hmac_sha256_hex}
Example payload
{
  "event": "collection.succeeded",
  "timestamp": "2026-06-26T10:05:12Z",
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "externalRef": "moolre-ref-abc123",
    "merchantReference": "ORD-10042",
    "amount": "99.00",
    "currency": "GHS",
    "status": "SUCCEEDED",
    "method": "payment_link",
    "channel": null,
    "environment": "LIVE",
    "completedAt": "2026-06-26T10:05:12Z"
  }
}

Compute HMAC-SHA256 with the signing key from webhook creation. Signed payload: `{timestamp}.{raw_json_body}`. Compare to the `v1` value using constant-time comparison. Reject stale timestamps to prevent replay attacks.

Errors

Failed requests return a JSON error body:

{
  "status": 400,
  "code": "VALIDATION_ERROR",
  "message": "Amount must be positive",
  "traceId": "b4a3d9c5-2c3f-4d0f-8f1b-6d1a1c1f2a3b",
  "timestamp": "2026-06-26T10:00:00Z"
}
StatusMeaning
400Invalid request or business rule violation
401Missing or invalid API key
403Key valid but not permitted for this resource
404Resource not found
409Conflict
429Rate limited

Include the traceId when contacting support.