Skip to content

Quickstart

Create a connection, get it authorised, and take your first payment on it.

Four steps, and the third one is not yours to do. A connection only becomes usable once the merchant signs in and accepts it, so plan for a round trip through a human before your first payment.

Everything here needs your platform's secret key and a Scale plan.

1. Create the connection

You declare what the connection may do and what you will retain on it. Capabilities are required and cannot be empty, pricing is optional.

curl https://api.wajub.com/accounts \
  -H "Authorization: sk.kZ3qP8mWvL2xR7tB5nY4hC6dF9jS1aG0eU3i…" \
  -H "Content-Type: application/json" \
  -d '{
    "reference": "shop-amina",
    "capabilities": ["read", "payments", "refunds"],
    "pricing": { "percentage_fee": 2.5, "currency": "XAF" },
    "callback": "https://example.com/sync-events"
  }'

The answer is 201 Created. Two fields matter more than the rest.

Response · 201 Created
{
"code": 201,
"status": "Created",
"message": "Account created",
"account": {
"id": "acc_7Yh2MpL4tRb3nP8sZcXv",
"reference": "shop-amina",
"sandbox": false,
"capabilities": [
"read",
"payments",
"refunds"
],
"status": "pending",
"payment_status": "inactive",
"authorization_url": "https://sync.wajub.com/oauth/v2/authorize?access_token=…",
"pricing": {
"percentage_fee": 2.5,
"fixed_fee": 0,
"max_fee": 0,
"currency": "XAF"
},
"created_at": "2026-09-13T10:24:11+00:00"
}
}

id is the value you will send as X-Sync. authorization_url is the link the merchant has to open, and this response is the only place it appears — send it or store it now, because reading the subaccount later will not give it back. POST /accounts/{id}/token mints a replacement.

Put authorization_url in front of the merchant however suits you: an email, a button in your own onboarding, a QR code. They open it, sign in to their Wajub account, review the capabilities you asked for, and accept.

The merchant brings their own account

There is nothing to create on their side through your integration. If they do not have a Wajub account yet, the authorisation page walks them through opening one, and the connection completes afterwards.

Once they accept, status flips to active and slave carries their business name and email. You find out either by polling the account or by receiving the account.updated webhook.

3. Wait for payments to be switched on

An active connection still cannot charge. payment_status stays inactive until the merchant's compliance check clears, and only then does Wajub activate it and fire account.payment_activated.

Activate payments on a sandbox connection
curl -X PUT https://api.wajub.com/accounts/acc_test_7Yh2MpL4tRb3nP8sZcXv \
  -H "Authorization: sk_test.kZ3qP8mWvL2xR7tB5nY4hC6dF9jS1aG0eU3i…" \
  -H "Content-Type: application/json" \
  -d '{ "payment_status": "active" }'

4. Take a payment on it

From here it is the ordinary payments API. One header decides who the payment belongs to.

curl https://api.wajub.com/payments \
  -H "Authorization: sk.kZ3qP8mWvL2xR7tB5nY4hC6dF9jS1aG0eU3i…" \
  -H "X-Sync: acc_7Yh2MpL4tRb3nP8sZcXv" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 50000,
    "currency": "XAF",
    "customer": { "email": "buyer@example.com" },
    "callback": "https://example.com/return"
  }'

The payment belongs to the merchant from this point on. It appears in their Dashboard, settles into their balance, and their webhooks fire. Yours fire too, with a copy of the same event.

What you get back when it succeeds

When the payment completes, Wajub reads the connection's pricing rules, computes your commission on the payment amount, and credits it to your platform. You are told by webhook.

fee.received
{
"event": "fee.received",
"data": {
"id": "fee_9Lq5RtVb2Kd8",
"amount": 1250,
"currency": "XAF",
"percentage": 2.5,
"fixed_amount": null,
"applied_to": "transaction",
"feeable_id": "trx_CSUGajfv9xh0XQ5wu2lx",
"account": {
"id": "acc_7Yh2MpL4tRb3nP8sZcXv",
"reference": "shop-amina"
}
}
}

The payload also carries a feeable_type, which is currently the internal class name of the object the fee was charged on rather than a public type. Match on feeable_id instead.

The merchant receives the mirror of it, fee.charged, on their own endpoints. Between the two, both sides of the commission are auditable without either of you asking the other.

What did you think of this content?