Initialise a payment
const url = 'https://api.paywithnablr.com/v1/payments';const options = { method: 'POST', headers: { 'Idempotency-Key': 'order_1042_attempt_1', Authorization: 'Bearer <token>', 'Content-Type': 'application/json' }, body: '{"amount":500000,"currency":"NGN","reference":"order_1042","customer":{"email":"ada@example.com","name":"Ada Obi"},"callback_url":"https://shop.example/thanks","metadata":{"order_id":1042}}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.paywithnablr.com/v1/payments \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --header 'Idempotency-Key: order_1042_attempt_1' \ --data '{ "amount": 500000, "currency": "NGN", "reference": "order_1042", "customer": { "email": "ada@example.com", "name": "Ada Obi" }, "callback_url": "https://shop.example/thanks", "metadata": { "order_id": 1042 } }'Creates a payment and its hosted checkout. Send the customer to
checkout_url, or open the checkout inline with checkout_token.
The fee is fixed now, from your pricing and your fee bearer setting.
The checkout stays open for one hour (expires_at).
Idempotency-Key is required: a retry with the same key and the same
body returns the first response (status, body and Location, with
Idempotent-Replay: true) instead of creating a second payment.
The smallest payment is ₦100 (10000), as on payment links.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”16 to 255 characters, unique per payment you mean to create (an order id plus an attempt number works well). Kept for 24 hours, per mode.
Example
order_1042_attempt_1Request Bodyrequired
Section titled “Request Bodyrequired”object
What you are charging for, in kobo, at least ₦100 (10000). 500000 is ₦5,000.00.
Your unique reference for this payment, per mode. Letters, digits,
., :, - and _, up to 100. If you leave it out we make one
(PWN…).
object
Limit the checkout to these methods. Omitted: every method you have turned on in Settings. Methods you have turned off are dropped; if none is left the request is refused.
Where the checkout sends the customer when the payment ends, with
?reference=<your reference> added. Absolute http or https.
Anything you want back on the payment and its webhooks. At most 20 keys and 8 KB.
object
Shown to the customer at checkout.
Example
{ "amount": 500000, "currency": "NGN", "reference": "order_1042", "customer": { "email": "ada@example.com", "name": "Ada Obi" }, "callback_url": "https://shop.example/thanks", "metadata": { "order_id": 1042 }}Responses
Section titled “Responses”The payment, with its checkout URL and token.
object
object
pending: waiting for the customer. processing: the payment network
has the payment and has not confirmed it. succeeded: paid. failed: the
checkout closed after the last attempt failed. abandoned: the
checkout closed with nothing tried. refunded and
partially_refunded are reserved for refunds, which are not yet
available.
The amount you asked for, in kobo.
Our fee, in kobo. Each method’s price is fixed when the payment is created; once succeeded this is the paying method’s fee, before that a quote (see above).
merchant: the fee comes out of amount. customer: the fee is added to what the customer pays.
What the customer pays, in kobo. amount, plus fee when the customer bears it. A quote until the payment succeeds.
What you receive, in kobo. A quote until the payment succeeds.
The methods the checkout offers.
object
What you sent. {} if you sent nothing.
object
The payment link this payment came through, if any.
Why the last attempt failed, in words you can show the customer. null once succeeded.
When the checkout closes.
The settlement (stl_…) that paid this out, once settled.
The hosted checkout. Redirect the customer here.
For the inline checkout. Only in this response.
object
This request’s id, also in the X-Request-Id header.
Example
{ "data": { "id": "pay_01M3XX8PCBFA5VZ3PQZQ0S78BP", "object": "payment", "reference": "order_1042", "status": "pending", "mode": "test", "amount": 500000, "currency": "NGN", "fee": 7500, "fee_bearer": "merchant", "charged_amount": 500000, "net": 492500, "channel": "card", "channels": [ "card" ], "customer": { "id": "cus_01M3XX8ERVFY9A1FAQ2EGHYZWT", "email": "ada@example.com", "name": "Ada Obi" }, "failure_reason": "Your bank declined the card: insufficient funds.", "authorization": { "brand": "visa", "last4": "4081", "exp_month": 12, "exp_year": 2030, "bank": "Nablr Test Bank", "nablr_handle": "ada" }, "checkout_url": "https://checkout.paywithnablr.com/c/ck_test_by1k2G3kGkaUO5UMHGYUAWqZAha3uAM8pozrWeozlcq", "checkout_token": "ck_test_by1k2G3kGkaUO5UMHGYUAWqZAha3uAM8pozrWeozlcq" }}Headers
Section titled “Headers”The payment’s URL, /v1/payments/{id}.
true when this response is a replay of an earlier request with the same Idempotency-Key.
This request’s id. Quote it when you contact support.
Requests allowed in the current one-minute window.
Requests left in the current window.
VALIDATION_FAILED: a field is wrong; details says which. A value
of the wrong JSON type has detail code type and a message saying
what to send (Send a whole number., Send text., Send true or false., Send an object., Send a list.).
MALFORMED_REQUEST: the body is not valid JSON.
object
object
A sentence for a person. Safe to show to your user.
The code in words, for example Validation failed.
A quotable reference for some failures.
One entry per field that is wrong.
object
For example required, invalid, format, length, unknown, type.
Extra context, such as retry_after_seconds on RATE_LIMITED.
object
object
This request’s id, also in the X-Request-Id header.
Example
{ "error": { "message": "Send a positive amount in minor units (500000 = ₦5,000.00).", "code": "VALIDATION_FAILED", "title": "Validation failed", "details": [ { "field": "amount", "code": "invalid", "message": "Send a positive amount in minor units (500000 = ₦5,000.00)." } ] }, "meta": { "request_id": "01a0fbd4-3b18-7181-9149-8dbcae100085" }}UNAUTHENTICATED: no Authorization: Bearer header. The message
says what to send: your secret key (Bearer sk_test_… or
sk_live_…).
INVALID_API_KEY: the key is unknown, malformed or revoked.
object
object
A sentence for a person. Safe to show to your user.
The code in words, for example Validation failed.
A quotable reference for some failures.
One entry per field that is wrong.
object
For example required, invalid, format, length, unknown, type.
Extra context, such as retry_after_seconds on RATE_LIMITED.
object
object
This request’s id, also in the X-Request-Id header.
Example
{ "error": { "message": "The API key provided is not valid.", "code": "INVALID_API_KEY", "title": "Invalid API key" }, "meta": { "request_id": "01a0fbd4-3b68-75e0-bd33-0b950ddc99a5" }}SECRET_KEY_REQUIRED: you sent a publishable key.
LIVE_MODE_NOT_ENABLED: a live key before your business is verified.
ACCOUNT_RESTRICTED: the account is suspended.
object
object
A sentence for a person. Safe to show to your user.
The code in words, for example Validation failed.
A quotable reference for some failures.
One entry per field that is wrong.
object
For example required, invalid, format, length, unknown, type.
Extra context, such as retry_after_seconds on RATE_LIMITED.
object
object
This request’s id, also in the X-Request-Id header.
Example
{ "error": { "message": "This request needs your secret key. Publishable keys can only be used from a checkout.", "code": "SECRET_KEY_REQUIRED", "title": "Secret key required" }, "meta": { "request_id": "01a0fbd4-3b68-75e0-bd33-0b950ddc99a5" }}DUPLICATE_REFERENCE: you already used this reference in this
mode. IDEMPOTENCY_KEY_REUSED: this Idempotency-Key was used
with a different body. REQUEST_IN_PROGRESS: the first request
with this key has not finished; retry shortly.
object
object
A sentence for a person. Safe to show to your user.
The code in words, for example Validation failed.
A quotable reference for some failures.
One entry per field that is wrong.
object
For example required, invalid, format, length, unknown, type.
Extra context, such as retry_after_seconds on RATE_LIMITED.
object
object
This request’s id, also in the X-Request-Id header.
Example
{ "error": { "message": "A payment with this reference already exists. Use a new reference for a new payment.", "code": "DUPLICATE_REFERENCE", "title": "Duplicate reference" }, "meta": { "request_id": "01a0fbd4-3b18-7181-9149-8dbcae100085" }}PAYLOAD_TOO_LARGE: the body is over 2 MB.
object
object
A sentence for a person. Safe to show to your user.
The code in words, for example Validation failed.
A quotable reference for some failures.
One entry per field that is wrong.
object
For example required, invalid, format, length, unknown, type.
Extra context, such as retry_after_seconds on RATE_LIMITED.
object
object
This request’s id, also in the X-Request-Id header.
Example
{ "error": { "code": "VALIDATION_FAILED", "details": [ { "field": "amount" } ] }}UNSUPPORTED_MEDIA_TYPE: the body is not application/json.
object
object
A sentence for a person. Safe to show to your user.
The code in words, for example Validation failed.
A quotable reference for some failures.
One entry per field that is wrong.
object
For example required, invalid, format, length, unknown, type.
Extra context, such as retry_after_seconds on RATE_LIMITED.
object
object
This request’s id, also in the X-Request-Id header.
Example
{ "error": { "code": "VALIDATION_FAILED", "details": [ { "field": "amount" } ] }}RATE_LIMITED: wait Retry-After seconds, then retry.
object
object
A sentence for a person. Safe to show to your user.
The code in words, for example Validation failed.
A quotable reference for some failures.
One entry per field that is wrong.
object
For example required, invalid, format, length, unknown, type.
Extra context, such as retry_after_seconds on RATE_LIMITED.
object
object
This request’s id, also in the X-Request-Id header.
Example
{ "error": { "message": "Too many attempts. Please wait a moment and try again.", "code": "RATE_LIMITED", "title": "Rate limited", "meta": { "retry_after_seconds": 12 } }, "meta": { "request_id": "01a0fbd4-3b68-75e0-bd33-0b950ddc99a5" }}Headers
Section titled “Headers”Seconds to wait.
Unix time when a request will be allowed again.
INTERNAL_ERROR: our fault. Retry with backoff; it is safe for requests with an Idempotency-Key.
object
object
A sentence for a person. Safe to show to your user.
The code in words, for example Validation failed.
A quotable reference for some failures.
One entry per field that is wrong.
object
For example required, invalid, format, length, unknown, type.
Extra context, such as retry_after_seconds on RATE_LIMITED.
object
object
This request’s id, also in the X-Request-Id header.
Example
{ "error": { "code": "VALIDATION_FAILED", "details": [ { "field": "amount" } ] }}