Account capabilities
The seven capabilities, what each one reaches, and how your commission is computed.
The three modes
account_type says what the merchant owns at Wajub and where the money sits. Capabilities,
commission and the consent to a change of terms work the same way in the three; what follows from
the mode is listed below the table. It is chosen when you create the connection and never changes
afterwards: switching mode changes what the merchant agreed to, so it is a new connection they
accept again.
| Mode | The merchant | The money | Use it for |
|---|---|---|---|
direct (default) | A full Wajub account they run themselves | Wajub rail, or their own provider contracts | Merchants already set up |
lite | A light hosted portal | Wajub rail, always | Small sellers, the common case |
relay | No Wajub account: a payout destination | Yours: you collect and Wajub relays the payouts | Marketplaces that are merchant of record |
What follows from the mode:
- a
liteconnection refuses to start a payment while the merchant is not on the Wajub rail (409). It exists so the commission is taken at the source and the payout is automatic, and both need the money to pass through Wajub; - a
relayconnection has no onboarding: there is no merchant account to claim. It is created withPOST /accountsonly, since the Dashboard form refuses it, and it has no authorization link:authorization_urlisnull, andPOST /accounts/{id}/tokenanswers422. So nobody claims the connection: it stayspending, itspayment_statusstaysinactive, andX-Syncrefuses it with403, as it refuses any connection that is notactive. You run a Relay marketplace with your own key, paying your sellers from your own balance; - a
relayconnection carries no invitation date:expires_atisnulland it never readsexpired; - on a Relay account, each new seller's wallet is checked against the operator's registered name before the first payout. Sellers are checked before their first payout
These are not Standard, Express or Custom tiers
The mode is not a level of service and does not gate features. Two connections in different modes can hold exactly the same capabilities and the same pricing.
The seven capabilities
A connection is granted a subset of this list, and the list is closed. At least one is required at
creation, and an unknown value is refused with 422.
| Capability | What it names |
|---|---|
read | Reading the events of what the connection brought |
payments | Initiating payments and payment links |
withdrawals | Paying out, and the beneficiaries paid |
refunds | Issuing refunds |
disputes | Answering disputes |
customers | Managing customers |
invoices | Issuing invoices |
write, settings, subscriptions and analytics are no longer offered: they opened no resource.
Asking for one when you create or update a connection answers 422. A connection that already
holds one keeps working, and the value grants nothing.
Every resource states what it requires
Capabilities are a real boundary: each resource declares the capability it takes, and a request
carrying X-Sync without that capability is refused with 403.
| The request touches | The capability checked |
|---|---|
/payments, /links | payments |
/invoices | invoices |
/customers, /customers/{id}/tax_ids | customers |
/refunds | refunds |
/disputes | disputes |
/transfers, /beneficiaries, /identity | withdrawals |
/, /providers, /events | read |
/channels, /countries, /currencies | none: the catalogues answer the same to everyone |
/balance, /webhooks, /shield, /tax, /listen | cannot be called with X-Sync at all: they belong to the merchant's whole account |
/accounts, /keys/current | cannot be called with X-Sync at all: they are yours |
A resource that cannot be called with X-Sync answers 403 with This endpoint cannot be called on behalf of a Sync account, whatever the connection holds.
A capability covers what the connection brought
Capabilities say what a platform may touch; the connection says whose. With X-Sync, a platform
reaches what this connection brought and nothing else of the merchant's: not their direct sales,
not their own links, invoices or payees, and nothing another platform brought.
| Resource | What the platform reaches |
|---|---|
/payments, /refunds | Only those carrying this connection |
/disputes | Only disputes on this connection's payments |
/links, /invoices | Only those created with this connection's X-Sync |
/beneficiaries | Only those created with this connection's X-Sync, including a beneficiary given inline in a transfer |
/transfers | Only payouts this connection initiated, and only to its own beneficiaries |
/customers, /customers/{id}/tax_ids | Customers seen on this connection's payments |
/events | Only events about the payments, refunds, transfers, disputes, links, invoices and beneficiaries above |
Anything outside that answers 404, as if it did not exist. A beneficiary the merchant already pays
is no exception: creating one for the same account with X-Sync gives the connection its own, and
paying the merchant's answers 422.
Customers are shared with the merchant
A customer is the merchant's, not the connection's. Once a customer has bought through the
connection, the platform can read, update and block them, and the merchant sees the result. It
cannot delete them: DELETE /customers/{id} with X-Sync answers 403, because erasing a
customer is the merchant's decision.
The merchant's other customers stay out of reach, even when the platform knows their email or phone. A customer already seen on the connection is returned, or attached, as usual.
Links and invoices collect for the connection
A payment made on a link or an invoice the connection created carries the connection, like a
payment made with POST /payments and X-Sync: the commission applies and the platform sees it
on /payments. Once the connection may no longer collect (cancelled, its payments suspended, the
capability withdrawn, or Sync no longer on your plan), the link answers 404 to the payer and the
invoice cannot be paid. They collect again when the connection does.
Events, and replaying them
GET /events with X-Sync lists the events recorded about what the connection brought. Events
recorded before 2026-10-10 carry no connection, so they are not listed.
POST /events/{id}/resend with X-Sync sends the event to your endpoints, never to the
merchant's: it resends the copy you received at the time, carrying data.account, or makes that
copy once when the event was never copied to you, as links, invoices and beneficiaries are not.
Changing the terms of a live connection
Capabilities and pricing are what the merchant agreed to, so once a connection is active they are
proposed rather than changed. PUT /accounts/{id} answers 202 Accepted and returns the proposal
in pending_changes; the connection keeps running on its current terms until the merchant accepts
or declines in their own dashboard.
| Then | What happens |
|---|---|
| The merchant accepts | The new terms apply from that moment, and account.change_accepted fires |
| The merchant declines | Nothing changes, and account.change_declined fires |
| You propose again | The new proposal replaces the one still on the table |
Sales already made keep the terms they were made under: a pricing change never re-prices a
commission already charged. While the connection is still pending, nobody has agreed to anything
yet and PUT applies the change outright, answering 200.
Pricing
Pricing is what your platform retains on the connected account's activity. It is one rule attached
to the connection, created by POST /accounts from the pricing object and changed afterwards with
PUT /accounts/{id} or from the Dashboard.
percentage_feenumberoptionalfixed_feenumberoptionalmin_feenumberoptionalmax_feenumberoptionalcurrencystringoptionalThe two kinds combine rather than compete: a rule with both a percentage and a fixed fee charges the percentage of the amount plus the flat figure, then applies the floor and the cap in that order.
How a fee is computed
Reading this sequence once explains every figure you will see on a fee.received.
| Step | What happens |
|---|---|
| 1 | The payment succeeds and carries a connection |
| 2 | The connection's pricing applies |
| 3 | The fee currency is the rule's currency, or the payment's when the rule has none |
| 4 | Percentage and fixed fee are summed, then clamped by min_fee and max_fee |
| 5 | A fee of zero is not charged |
| 6 | The fee is charged once for the payment |
| 7 | The amount leaves the merchant's balance and lands on yours, held under the sale's own retention |
One payment carries at most one commission, whatever happens to the event that triggered it. The commission moves in the currency the sale settled in, converted when the rule uses another currency.
A commission is a share of a sale, so a sale that comes undone takes its share with it.
When the sale is refunded
commission_refund_policy, set on the connection, decides what comes back.
| Policy | On a refund |
|---|---|
prorata (default) | The commission is returned in proportion to the amount refunded |
full | The whole commission is returned on the first refund, partial or not |
none | Nothing is returned; the merchant carries the refund alone |
Set it with POST /accounts, and change it with PUT /accounts/{id} only while the connection is
still pending: it is a commercial term the merchant accepted. Nothing is ever given back twice, and
several refunds on one sale can never return more than was charged.
When a dispute on the sale is lost
A lost dispute undoes the sale as a refund does, and the same policy applies to the disputed amount: a chargeback the provider reports lost, a dispute your merchant accepts, or one closed past its deadline. Your merchant accepting a dispute pays the buyer back with a refund; the dispute and that refund return the commission once between them, whichever is recorded first. A dispute won returns nothing, since the sale stands.
In sandbox
A sandbox sale moves the commission between the two sandbox balances, and a sandbox refund or a lost sandbox dispute gives it back by the same policy, so you can check what your merchants will see. The reserve, the cover of a negative balance and the commissions a merchant owes when they collect on their own contract are live only.
The rule currency is the denomination, not a filter
currency says what the fee is expressed in, not which payments the rule applies to. Charging a
flat 500 XAF on a payment made in NGN converts at the active rate, and converts a second time if
your platform's own balance is in a third currency. The metadata on the fee records both rates.
One rule, for every payment
A connection carries one pricing rule, and it applies to every payment made on the connection. There is no way to charge a different commission on small baskets or to exempt a currency: no endpoint and no Dashboard form sets conditions on a rule.
Pricing needs consent on acceptance too
Like capabilities, pricing on a connected merchant is proposed rather than changed: PUT answers
202 and the merchant decides. Set the commission you mean before you send the authorisation
link, and you never have to ask.
What stays editable outright
Two fields survive acceptance without the merchant's say-so, and they are the only two.
| Field | Why it stays open |
|---|---|
callback | The page the merchant is sent back to once they have accepted, and the origin a redirect_uri on the authorisation link has to share. HTTPS only (http://localhost and http://127.0.0.1 with a sandbox key), or 422. No event is sent to it: a connection's events go to your webhook endpoints |
payment_status | active or suspended, your own switch on the connection's ability to charge. active answers 409 while the merchant's verification is pending or rejected |
Suspending a connection stops both inbound payments and outbound transfers on it, and fires
account.payment_suspended. It is the lever to reach for when you would otherwise want to revoke a
capability, and unlike a capability it is reversible.