Skip to content
Loading keys…
Authorization<token>

A public key (pk./pk_test.) is accepted on /payments, /customers, /links, /invoices and the catalogue reads (/channels, /providers, /countries, /currencies); anything that moves money out, reads the balance or manages the account answers 406 to it. It is an identifier, never an authorization. Use a secret key (sk./sk_test.) for sensitive operations (transfers, refunds, balance), or a restricted key (rk./rk_test.) scoped to specific permissions. The _test. variant of any key selects the sandbox environment, there is no separate sandbox URL. Never expose your secret key in client-side code.

In: header

Header Parameters

Idempotency-Keystring

Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).

Request Body

application/json

deferredboolean

Prepare the payment without creating it, for Components shown before your order exists. The customer then comes with `POST /payments/{id}/activate`.

amountnumberrequired

Amount to collect in the major unit of the currency (e.g. 25000 = 25,000 XAF). Minimum: 0.01.

currencystringrequired

ISO 4217 currency code (XAF, XOF, NGN, GHS, KES…).

emailstring | null

The payer's email. One of `email`, `phone`, `customer_id` or `customer` is required, unless `deferred` is `true`.

customer_idstring | null

One of your customers, by its `cus_` id. One of `email`, `phone`, `customer_id` or `customer` is required, unless `deferred` is `true`.

phonestring | null

The payer's phone number, international format. One of `email`, `phone`, `customer_id` or `customer` is required, unless `deferred` is `true`.

namestring | null

The payer's full name, shown on the payment page.

descriptionstring | null

A label shown to the customer on the payment page.

referencestring | null

Your own reference for this payment, such as an order number (max 128 chars). Free and not unique: two payments may carry the same one. Find them with `GET /payments?reference=`; to make a retry safe, send an `Idempotency-Key` header.

callbackstring | null

Where the customer is sent back once the payment ends, whatever the outcome, with `status` in the query string (`succeeded`, `failed`, `cancelled`, `expired`). Must be HTTPS; in sandbox, `http://localhost` and `http://127.0.0.1` are accepted too. Any other address answers `422`.

expiresobject

When the payment ends on its own if nobody pays it.

ininteger | null

Session expiry in minutes (5–43200). Defaults to 1440 (24h).

customerobject | null

Customer information. Not required itself: at least one of `email`, `phone`, `customer_id` or `customer` is, unless `deferred` is true.

emailstring

Customer email address.

phonestring

Customer phone number (international format).

namestring

Customer full name displayed on the payment page.

themingobject | null

Colours and logo of the payment page for this payment, over your account branding. Stored and returned; the page does not read it today.

addressobject | null

Accepted for older integrations and not used.

shippingobject | null

Accepted for older integrations and not used.

itemsarray | null

Lines shown on the payment page. Display only: they carry no price and never change `amount`.

telemetryobject | null

Free-form data about the integration that created the payment, such as your SDK and app versions. Kept with the payment, not returned.

metadataobject | null

Free-form key-value data attached to the transaction.

bearer"merchant" | "customer"

Who bears the platform fee: `merchant` (default) or `customer`.

"merchant""customer"
acceptobject | null

What this payment may be paid with. Each list narrows the payment page and the charge; a channel outside them answers `422` `channel_not_accepted`.

countriesarray<string>

Two-letter country codes: only the channels of these countries. Cards and crypto belong to no country and stay; name them under `types` or `channels` to exclude them.

channelsarray<string>

Only these channels: slugs such as `cm.mtn`, `cm.mobile` for every mobile operator of Cameroon, or `mobile` for every mobile operator.

typesarray<string>

Channel types accepted, such as `mobile_money` or `card`.

currencies"payment" | "any"

`payment`: only channels that settle in the payment's currency. `any` or absent: no currency filter.

"payment""any"

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://api.wajub.com/payments" \  -H "Idempotency-Key: order-1042" \  -H "Content-Type: application/json" \  -d '{    "amount": 25000,    "currency": "XAF"  }'
POST
/payments
{  "code": 201,  "status": "Created",  "message": "Payment initiated",  "authorization_url": "https://pay.wajub.com/test_7Yh2Mp4kQ9xL4vR8tB3nW6yC1dF5sJ0aG…",  "authorization_token": "test_7Yh2Mp4kQ9xL4vR8tB3nW6yC1dF5sJ0aG…",  "transaction": {    "id": "trx_test_CSUGajfv9xh0XQ5wu2lx",    "reference": "order-4172",    "amount": 25000,    "currency": "XAF",    "status": "pending",    "description": "Order #4172",    "sandbox": true,    "created_at": "2026-01-15T10:30:00+00:00"  }}

Payment initialized

What did you think of this content?