Skip to content

Initialise a payment

POST
/payments
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.

Idempotency-Key
required
string
>= 16 characters <= 255 characters

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_1
Media typeapplication/json
object
amount
required

What you are charging for, in kobo, at least ₦100 (10000). 500000 is ₦5,000.00.

integer format: int64
>= 10000
currency
string
default: NGN
Allowed values: NGN
reference

Your unique reference for this payment, per mode. Letters, digits, ., :, - and _, up to 100. If you leave it out we make one (PWN…).

string
/^[A-Za-z0-9._:-]{1,100}$/
customer
required
object
email
required
string format: email
name
string
<= 200 characters
phone
string
<= 20 characters /^[+0-9 -]*$/
channels

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.

Array<string>
Allowed values: card bank_transfer ussd nablr
callback_url

Where the checkout sends the customer when the payment ends, with ?reference=<your reference> added. Absolute http or https.

string format: uri
<= 2000 characters
metadata

Anything you want back on the payment and its webhooks. At most 20 keys and 8 KB.

object
<= 20 properties
key
additional properties
any
description

Shown to the customer at checkout.

string
<= 140 characters
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
}
}

The payment, with its checkout URL and token.

Media typeapplication/json
object
data
required
object
id
required
string
object
required
string
Allowed value: payment
reference
required
string
status
required

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.

string
Allowed values: pending processing succeeded failed abandoned refunded partially_refunded
mode
required
string
Allowed values: test live
amount
required

The amount you asked for, in kobo.

integer format: int64
currency
required
string
Allowed values: NGN
fee
required

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).

integer format: int64
fee_bearer
required

merchant: the fee comes out of amount. customer: the fee is added to what the customer pays.

string
Allowed values: merchant customer
charged_amount
required

What the customer pays, in kobo. amount, plus fee when the customer bears it. A quote until the payment succeeds.

integer format: int64
net
required

What you receive, in kobo. A quote until the payment succeeds.

integer format: int64
channel
required
One of:

A payment method. nablr is Pay with Nablr.

string
Allowed values: card bank_transfer ussd nablr
channels
required

The methods the checkout offers.

Array<string>
Allowed values: card bank_transfer ussd nablr
customer
required
object
id
required
string | null
email
required
string
name
required
string | null
phone
required
string | null
metadata
required

What you sent. {} if you sent nothing.

object
key
additional properties
any
description
required
string | null
callback_url
required
string | null
payment_link_id
required

The payment link this payment came through, if any.

string | null
failure_reason
required

Why the last attempt failed, in words you can show the customer. null once succeeded.

string | null
authorization
required
One of:

How the payment was made, safe to show. Only the fields that apply are present.

object
brand

Card brand: visa, mastercard or verve.

string
last4
string
exp_month
integer
exp_year
integer
bank
string
nablr_handle
string
paid_at
required
string | null format: date-time
expires_at
required

When the checkout closes.

string format: date-time
settlement
required

The settlement (stl_…) that paid this out, once settled.

string | null
created_at
required
string format: date-time
checkout_url
required

The hosted checkout. Redirect the customer here.

string
checkout_token
required

For the inline checkout. Only in this response.

string
meta
required
object
request_id
required

This request’s id, also in the X-Request-Id header.

string
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"
}
}
Location
string

The payment’s URL, /v1/payments/{id}.

Idempotent-Replay
string
Allowed values: true

true when this response is a replay of an earlier request with the same Idempotency-Key.

X-Request-Id
string

This request’s id. Quote it when you contact support.

X-RateLimit-Limit
integer

Requests allowed in the current one-minute window.

X-RateLimit-Remaining
integer

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.

Media typeapplication/json
object
error
required
object
message
required

A sentence for a person. Safe to show to your user.

string
code
required
string
Allowed values: VALIDATION_FAILED MALFORMED_REQUEST UNAUTHENTICATED INVALID_API_KEY SECRET_KEY_REQUIRED LIVE_MODE_NOT_ENABLED ACCOUNT_RESTRICTED TEST_MODE_ONLY NOT_FOUND METHOD_NOT_ALLOWED CONFLICT DUPLICATE_REFERENCE IDEMPOTENCY_KEY_REUSED REQUEST_IN_PROGRESS INVALID_STATE_TRANSITION PAYLOAD_TOO_LARGE UNSUPPORTED_MEDIA_TYPE RATE_LIMITED INTERNAL_ERROR SERVICE_UNAVAILABLE
title
required

The code in words, for example Validation failed.

string
reference

A quotable reference for some failures.

string
details

One entry per field that is wrong.

Array<object>
object
field
required
string
code
required

For example required, invalid, format, length, unknown, type.

string
message
required
string
meta

Extra context, such as retry_after_seconds on RATE_LIMITED.

object
key
additional properties
any
meta
required
object
request_id
required

This request’s id, also in the X-Request-Id header.

string
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.

Media typeapplication/json
object
error
required
object
message
required

A sentence for a person. Safe to show to your user.

string
code
required
string
Allowed values: VALIDATION_FAILED MALFORMED_REQUEST UNAUTHENTICATED INVALID_API_KEY SECRET_KEY_REQUIRED LIVE_MODE_NOT_ENABLED ACCOUNT_RESTRICTED TEST_MODE_ONLY NOT_FOUND METHOD_NOT_ALLOWED CONFLICT DUPLICATE_REFERENCE IDEMPOTENCY_KEY_REUSED REQUEST_IN_PROGRESS INVALID_STATE_TRANSITION PAYLOAD_TOO_LARGE UNSUPPORTED_MEDIA_TYPE RATE_LIMITED INTERNAL_ERROR SERVICE_UNAVAILABLE
title
required

The code in words, for example Validation failed.

string
reference

A quotable reference for some failures.

string
details

One entry per field that is wrong.

Array<object>
object
field
required
string
code
required

For example required, invalid, format, length, unknown, type.

string
message
required
string
meta

Extra context, such as retry_after_seconds on RATE_LIMITED.

object
key
additional properties
any
meta
required
object
request_id
required

This request’s id, also in the X-Request-Id header.

string
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.

Media typeapplication/json
object
error
required
object
message
required

A sentence for a person. Safe to show to your user.

string
code
required
string
Allowed values: VALIDATION_FAILED MALFORMED_REQUEST UNAUTHENTICATED INVALID_API_KEY SECRET_KEY_REQUIRED LIVE_MODE_NOT_ENABLED ACCOUNT_RESTRICTED TEST_MODE_ONLY NOT_FOUND METHOD_NOT_ALLOWED CONFLICT DUPLICATE_REFERENCE IDEMPOTENCY_KEY_REUSED REQUEST_IN_PROGRESS INVALID_STATE_TRANSITION PAYLOAD_TOO_LARGE UNSUPPORTED_MEDIA_TYPE RATE_LIMITED INTERNAL_ERROR SERVICE_UNAVAILABLE
title
required

The code in words, for example Validation failed.

string
reference

A quotable reference for some failures.

string
details

One entry per field that is wrong.

Array<object>
object
field
required
string
code
required

For example required, invalid, format, length, unknown, type.

string
message
required
string
meta

Extra context, such as retry_after_seconds on RATE_LIMITED.

object
key
additional properties
any
meta
required
object
request_id
required

This request’s id, also in the X-Request-Id header.

string
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.

Media typeapplication/json
object
error
required
object
message
required

A sentence for a person. Safe to show to your user.

string
code
required
string
Allowed values: VALIDATION_FAILED MALFORMED_REQUEST UNAUTHENTICATED INVALID_API_KEY SECRET_KEY_REQUIRED LIVE_MODE_NOT_ENABLED ACCOUNT_RESTRICTED TEST_MODE_ONLY NOT_FOUND METHOD_NOT_ALLOWED CONFLICT DUPLICATE_REFERENCE IDEMPOTENCY_KEY_REUSED REQUEST_IN_PROGRESS INVALID_STATE_TRANSITION PAYLOAD_TOO_LARGE UNSUPPORTED_MEDIA_TYPE RATE_LIMITED INTERNAL_ERROR SERVICE_UNAVAILABLE
title
required

The code in words, for example Validation failed.

string
reference

A quotable reference for some failures.

string
details

One entry per field that is wrong.

Array<object>
object
field
required
string
code
required

For example required, invalid, format, length, unknown, type.

string
message
required
string
meta

Extra context, such as retry_after_seconds on RATE_LIMITED.

object
key
additional properties
any
meta
required
object
request_id
required

This request’s id, also in the X-Request-Id header.

string
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.

Media typeapplication/json
object
error
required
object
message
required

A sentence for a person. Safe to show to your user.

string
code
required
string
Allowed values: VALIDATION_FAILED MALFORMED_REQUEST UNAUTHENTICATED INVALID_API_KEY SECRET_KEY_REQUIRED LIVE_MODE_NOT_ENABLED ACCOUNT_RESTRICTED TEST_MODE_ONLY NOT_FOUND METHOD_NOT_ALLOWED CONFLICT DUPLICATE_REFERENCE IDEMPOTENCY_KEY_REUSED REQUEST_IN_PROGRESS INVALID_STATE_TRANSITION PAYLOAD_TOO_LARGE UNSUPPORTED_MEDIA_TYPE RATE_LIMITED INTERNAL_ERROR SERVICE_UNAVAILABLE
title
required

The code in words, for example Validation failed.

string
reference

A quotable reference for some failures.

string
details

One entry per field that is wrong.

Array<object>
object
field
required
string
code
required

For example required, invalid, format, length, unknown, type.

string
message
required
string
meta

Extra context, such as retry_after_seconds on RATE_LIMITED.

object
key
additional properties
any
meta
required
object
request_id
required

This request’s id, also in the X-Request-Id header.

string
Example
{
"error": {
"code": "VALIDATION_FAILED",
"details": [
{
"field": "amount"
}
]
}
}

UNSUPPORTED_MEDIA_TYPE: the body is not application/json.

Media typeapplication/json
object
error
required
object
message
required

A sentence for a person. Safe to show to your user.

string
code
required
string
Allowed values: VALIDATION_FAILED MALFORMED_REQUEST UNAUTHENTICATED INVALID_API_KEY SECRET_KEY_REQUIRED LIVE_MODE_NOT_ENABLED ACCOUNT_RESTRICTED TEST_MODE_ONLY NOT_FOUND METHOD_NOT_ALLOWED CONFLICT DUPLICATE_REFERENCE IDEMPOTENCY_KEY_REUSED REQUEST_IN_PROGRESS INVALID_STATE_TRANSITION PAYLOAD_TOO_LARGE UNSUPPORTED_MEDIA_TYPE RATE_LIMITED INTERNAL_ERROR SERVICE_UNAVAILABLE
title
required

The code in words, for example Validation failed.

string
reference

A quotable reference for some failures.

string
details

One entry per field that is wrong.

Array<object>
object
field
required
string
code
required

For example required, invalid, format, length, unknown, type.

string
message
required
string
meta

Extra context, such as retry_after_seconds on RATE_LIMITED.

object
key
additional properties
any
meta
required
object
request_id
required

This request’s id, also in the X-Request-Id header.

string
Example
{
"error": {
"code": "VALIDATION_FAILED",
"details": [
{
"field": "amount"
}
]
}
}

RATE_LIMITED: wait Retry-After seconds, then retry.

Media typeapplication/json
object
error
required
object
message
required

A sentence for a person. Safe to show to your user.

string
code
required
string
Allowed values: VALIDATION_FAILED MALFORMED_REQUEST UNAUTHENTICATED INVALID_API_KEY SECRET_KEY_REQUIRED LIVE_MODE_NOT_ENABLED ACCOUNT_RESTRICTED TEST_MODE_ONLY NOT_FOUND METHOD_NOT_ALLOWED CONFLICT DUPLICATE_REFERENCE IDEMPOTENCY_KEY_REUSED REQUEST_IN_PROGRESS INVALID_STATE_TRANSITION PAYLOAD_TOO_LARGE UNSUPPORTED_MEDIA_TYPE RATE_LIMITED INTERNAL_ERROR SERVICE_UNAVAILABLE
title
required

The code in words, for example Validation failed.

string
reference

A quotable reference for some failures.

string
details

One entry per field that is wrong.

Array<object>
object
field
required
string
code
required

For example required, invalid, format, length, unknown, type.

string
message
required
string
meta

Extra context, such as retry_after_seconds on RATE_LIMITED.

object
key
additional properties
any
meta
required
object
request_id
required

This request’s id, also in the X-Request-Id header.

string
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"
}
}
Retry-After
integer

Seconds to wait.

X-RateLimit-Reset
integer

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.

Media typeapplication/json
object
error
required
object
message
required

A sentence for a person. Safe to show to your user.

string
code
required
string
Allowed values: VALIDATION_FAILED MALFORMED_REQUEST UNAUTHENTICATED INVALID_API_KEY SECRET_KEY_REQUIRED LIVE_MODE_NOT_ENABLED ACCOUNT_RESTRICTED TEST_MODE_ONLY NOT_FOUND METHOD_NOT_ALLOWED CONFLICT DUPLICATE_REFERENCE IDEMPOTENCY_KEY_REUSED REQUEST_IN_PROGRESS INVALID_STATE_TRANSITION PAYLOAD_TOO_LARGE UNSUPPORTED_MEDIA_TYPE RATE_LIMITED INTERNAL_ERROR SERVICE_UNAVAILABLE
title
required

The code in words, for example Validation failed.

string
reference

A quotable reference for some failures.

string
details

One entry per field that is wrong.

Array<object>
object
field
required
string
code
required

For example required, invalid, format, length, unknown, type.

string
message
required
string
meta

Extra context, such as retry_after_seconds on RATE_LIMITED.

object
key
additional properties
any
meta
required
object
request_id
required

This request’s id, also in the X-Request-Id header.

string
Example
{
"error": {
"code": "VALIDATION_FAILED",
"details": [
{
"field": "amount"
}
]
}
}