Skip to content
Loading keys…

Payments

Initialize, retrieve, list and cancel payments via the Payments API.

The Payment (transaction) object represents a payment collection attempt. Its lifecycle goes from pending to succeeded (or failed). All routes share the base https://api.wajub.com.

Before you begin

Create a payment from your server with your private key (sk. or sk_test.), or from a browser with your public key (pk. or pk_test.). Both are in the Wajub dashboard.

Marketplaces: acting on behalf of a subaccount

Platforms can attribute a payment to a connected subaccount by sending an X-Sync header alongside their own key. See Subaccounts for the full contract and error cases.

Endpoints

MethodPathDescription
POST/paymentsInitialize a payment
POST/payments/{id}Charge a payment from your server
POST/payments/{id}/confirmConfirm a step of a charge (code, PIN, provider window)
POST/payments/{id}/splitsCharge the next instalment (Mobile Money in live)
POST/payments/{id}/closeClose a payment paid in part in instalments
GET/payments/{id}Retrieve a payment
GET/paymentsList payments
DELETE/payments/{id}Cancel a payment
GET/payments/{id}/refundsList refunds for a payment
PATCH/payments/{id}Change a prepared payment's amount
POST/payments/{id}/activateCreate a prepared payment once the order is placed

Prepared payments

A payment created with deferred: true is only prepared. It exists for payment fields mounted on your checkout before the order does, and it stays out of everything else until you activate it.

PreparedActivated
In GET /payments and the dashboardNoYes
GET /payments/{id}Reads as pending, then expired or cancelled; answers 404 an hour after it expired or was cancelledThe payment
payment.createdNot sentSent on activation
Amount and currencyPATCH /payments/{id}Fixed
Can be chargedNoYes
DELETE /payments/{id}Ends the session, no webhookCancels, sends payment.cancelled

Activation keeps the id and the session token you already handed to the browser. A prepared payment that is never activated expires with its session, and no trace of it reaches your payments or your webhook endpoint, as long as you sent no customer while preparing it: that customer is created, with its customer.created.

The Payment object

Create response vs. retrieval response

The POST /payments (create) response includes two additional fields, authorization_url and authorization_token. That are not present on subsequent retrieval responses. These are the two most important fields in the create response.

A field with no value is left out of the response rather than sent as null.

idstringoptional
Unique transaction identifier: trx_ followed by 20 characters, trx_test_ in sandbox. This is the identifier to use in every API call (GET /payments/{id}, POST /refunds body, etc.).
authorization_urlstringoptional
**Returned by POST /payments only.** The hosted payment page URL to redirect your customer to. An opaque session URL, do not parse or construct it manually.
authorization_tokenstringoptional
**Returned by POST /payments only.** Browser-safe session token scoped to this payment. Pass as sessionId to Wajub Components for embedded checkout. It works on every call of the payment page until the payment is final, then for 5 more minutes after a success and 1 minute after a failure.
referencestringoptional
The reference you sent on POST /payments: your own order reference, stored and returned as is. It is not an API identifier, and Wajub never checks that it is unique.
statusenumoptional
Current state: pending, processing, succeeded, failed, cancelled, expired, partial, refunded, partially_refunded. The last two are read from API version 2026-10-11: on an earlier version a refunded payment keeps reading succeeded.
amountnumberoptional
Amount in the major unit of the currency (e.g. 25000 = 25 000 XAF).
amount_paidnumberoptional
What the payer has paid so far. Below amount while a payment paid in instalments is partial, and on such a payment closed before its last instalment (POST /payments/{id}/close).
currencystringoptional
ISO 4217 code of any currency Wajub has active. Which channels can collect it, and in which currency they settle, is on [Coverage](/resources/coverage); Sierra Leone is SLL.
channelstring?optional
Payment channel used (e.g. cm.mtn, cm.orange, sn.wave).
payment_methodobject?optional
Resolved payment method: { channel, account }.
descriptionstring?optional
Label visible to the customer on the payment page.
itemsarray?optional
Line items passed at initialization, each with name, description and quantity. Displayed on the payment page, they carry no price and never change amount.
taxobject?optional
Tax details when tax was applied to a live payment: { amount, taxable_amount, rate, name, country, inclusive }. Never present in sandbox.
failure_reasonstring?optional
Why the payment failed: the code of the provider that refused the last attempt, passed through, or a code of Wajub's own (see [Failure Reasons](/api/failure-reasons#failed-payments)). Present only when status=failed.
failure_messagestring?optional
One sentence explaining failure_reason, for your logs and your support team. Present only when status=failed.
receipt_urlstring?optional
A permanent, signed link to the payer's receipt. Present once the payment has succeeded, unless you turned receipts off in the Dashboard.
customerobject?optional
The customer: { id, name, email, phone }.
shipping_addressobject?optional
The customer's shipping address: { address_line1, address_line2, city, state, postal_code, country }.
billing_addressobject?optional
The customer's billing address, same fields.
metadataobject?optional
Free-form data you passed at creation.
invoicestring?optional
The id of the invoice this payment settles, when it was made on an invoice's page. Absent otherwise.
callbackstring?optional
Redirect URL after payment.
bearerstringoptional
Who bears the Wajub fee: merchant, or customer when the payer pays it on top of amount.
expires_atdatetime?optional
Until when the payer can pay, set with expires.in at creation. Past it the payment turns expired.
themingobject?optional
The theming object passed at creation, given back as it was stored. Nothing reads it today: the payment page follows your Dashboard branding, and an embedded checkout its appearance ([Branding](/libraries/components/branding)).
sandboxbooleanoptional
true for test-mode transactions.
credited_atdatetime?optional
When the funds were credited to your balance.
created_atdatetimeoptional
ISO 8601 creation timestamp, in UTC (+00:00).
updated_atdatetimeoptional
ISO 8601 timestamp of the last change.

Lifecycle

Events

EventTrigger
payment.createdPayment initialized, or a prepared payment activated
payment.processingPayment submitted to the provider
payment.succeededPayment successfully validated
payment.failedPayment failed (see failure_reason)
payment.attempt_failedAn attempt was refused at once and the payment is pending again
payment.expiredThe payment's deadline (expires_at) passed before it was paid
payment.cancelledPayment cancelled with DELETE /payments/{id} or the Cancel button of the hosted page
payment.split.processingAn instalment was sent to the payer
payment.split.succeededAn instalment was paid, and credited to your balance
payment.split.failedAn instalment was declined; the next call charges it again

See the full event catalog for refund-specific events. A refund on a payment does not re-emit a payment.* event, it emits refund.* events instead.

What did you think of this content?