Onboarding
The lifecycle of a connection, and what freezes the moment a merchant accepts it.
A connection carries two statuses that move independently. status says whether the merchant has
accepted, payment_status says whether the connection may move money. A connection can be active
and still refuse every payment, which is the single most common surprise in this section.
The lifecycle
status | What it means | How it got there |
|---|---|---|
pending | Created, nobody has accepted | POST /accounts |
active | A merchant signed in and authorised it | They opened the authorisation link |
cancelled | Ended, by you | DELETE /accounts/{id} |
expired | The invitation ran out before anyone accepted | Time |
There is no restricted and no intermediate state. The status you read is computed rather than
stored: a cancelled connection reads cancelled, an expired one reads expired, one with a
merchant attached reads active, and everything else reads pending.
The authorisation link
Creating a connection mints a single-use authorisation token and hands it back inside a URL.
The merchant opens it, signs in to their own Wajub account, sees the capabilities you asked for, and accepts. Your platform never handles their credentials and never creates anything on their side.
The link is a credential
Anyone holding that URL can attach an account to your platform. Send it over a channel you
control, and treat it like a secret. If it leaks, POST /accounts/{id}/token revokes the old
one and mints a replacement — refused with 400 once a merchant has claimed the connection,
whether it is still running or was disconnected, because that merchant stays attached to it and
the new link could never be used. Reaching them again means a new connection they accept again.
An invitation does not stay open forever: it expires 30 days after it is minted, and a reminder goes out three days before that to the address you gave for the merchant. Once it expires, the cleanup cancels it and revokes its token, so the link in the merchant's inbox stops working.
You see authorization_url once, in the answer to the call that minted it — creating the subaccount,
or regenerating its token. Reading the subaccount afterwards never returns it, claimed or not. Keep
it when you receive it; if you lose it, mint a new one. Once the connection is claimed, slave
appears in the response, carrying the merchant's business name and email.
What the link cannot do
A connection is claimed once, and the checks run at the moment of the claim, not when the merchant opened the link:
- a connection you cancelled stays cancelled — the link cannot revive it;
- a connection another merchant already claimed cannot be taken over;
- an expired invitation is refused;
- in live mode, the merchant cannot claim it before filing their KYC. Filing is enough to connect; verification is what releases payments (below);
- the link can carry a
redirect_uri, but only one sharing an origin with thecallbackregistered on the connection. Any other host is refused, and a connection with no callback accepts none.
A merchant who submits twice lands on their own finished connection, not on an error.
Then payments have to be switched on
Acceptance is not permission to charge. payment_status starts inactive and stays there.
payment_status | Effect on requests carrying X-Sync |
|---|---|
inactive | Payments and transfers refused with 403 |
active | Payments and transfers run |
suspended | Payments and transfers refused with 403 |
Wajub flips it to active on its own when the merchant's compliance check clears, fires
account.payment_activated, and that is the normal path in live mode.
Sandbox is the exception
Compliance verification does not run in sandbox, so a sandbox connection never activates by
itself. Set payment_status to active yourself with PUT /accounts/{id} once the connection is
claimed. The same call answers 400 while it is still pending.
Suspension is yours to use afterwards. Setting payment_status to suspended stops inbound
payments and outbound transfers together, deliberately: a connection frozen for a failed compliance
recheck should not be able to drain its balance while it is unable to earn.
A Lite seller's own portal
A lite seller has no merchant dashboard — that is the point of the mode. Their onboarding ends on
the Wajub rail application rather than on a dashboard, and afterwards they use a portal of their
own, carrying your branding.
| They do | Where |
|---|---|
| Sign in | A one-time code sent to the shop's email address — no password, and a short session |
| See their sales and payouts | Only those carrying this connection: never their other business, never another platform's |
| Apply for the Wajub rail | Hosted, during onboarding; the connection cannot charge until it is approved |
| Declare where their money goes | The portal's payout account page |
A new payout destination is held before it can be used
A destination the seller has just declared or changed cannot receive a payout for a cooling-off period (24 hours by default). Verification says the account exists and whose name is on it; the hold buys the time a notification needs to reach a human who can say no. A transfer to a held destination is refused until it elapses.
What the merchant has to agree to again
The moment a merchant accepts, two of the four editable fields stop being yours alone.
| Field | After acceptance |
|---|---|
capabilities | 202 Accepted — proposed to the merchant, returned in pending_changes |
pricing | 202 Accepted — proposed to the merchant, returned in pending_changes |
callback | Still editable outright |
payment_status | Still editable outright, and only editable from here |
The asymmetry is deliberate. What the merchant agreed to on the authorisation screen cannot be changed behind their back, so a wider connection or a higher commission is a proposal they accept or decline in their own dashboard — the connection keeps running on its current terms in the meantime. Suspension stays yours, with no proposal needed.
Ending a connection
DELETE /accounts/{id} revokes the tokens, sets status to cancelled, and fires
account.deauthorized. If the merchant had accepted, payment_status drops to inactive at the
same time and the response reads Account disconnected; on an unclaimed invitation it reads
Account cancelled.
curl -X DELETE https://api.wajub.com/accounts/acc_7Yh2MpL4tRb3nP8sZcXv \
-H "Authorization: sk.kZ3qP8mWvL2xR7tB5nY4hC6dF9jS1aG0eU3i…"Disconnecting does not touch anything that already happened. The merchant keeps their account, their payments and their balance, and the commissions you already earned stay earned. What stops is your ability to act on their behalf.
The events to listen for
Five webhooks describe a connection's life, and you receive them on your platform's endpoints.
| Event | Fired when |
|---|---|
account.created | You create a connection |
account.updated | Anything changes on it, acceptance included |
account.payment_activated | It becomes able to charge |
account.payment_suspended | You suspend it |
account.deauthorized | It is disconnected or cancelled |
On top of those, every payment, refund and transfer made on a connected account fires its normal webhook to the merchant and a copy to your platform. You do not need to poll a connection to know what it is doing.