Merchant Onboarding
Create a merchant, understand the pending-until-activated lifecycle, and the status transitions a partner may and may not make.
Creating a merchant through the API mirrors the backoffice onboarding flow exactly. The most important thing to understand up front: a merchant you create cannot process payments until Ops activates it, and you cannot activate it yourself.
The lifecycle
create ──▶ pending (-1) ──▶ [Ops reviews & activates] ──▶ active (1)
│
suspend ◀──────┤──────▶ reactivate
▼
suspended (0)| Status | Value | Meaning | Who sets it |
|---|---|---|---|
| Pending | -1 | Created, awaiting Ops review. Cannot transact. | Set automatically on create. |
| Active | 1 | Live and able to transact. | Ops only (from pending). Partner may reactivate from suspended. |
| Suspended | 0 | Temporarily halted. | Partner or Ops. |
| Draft / Deleted | -2 / -3 | Internal states. | Never exposed — reported as 404. |
Create a merchant
POST /v1/merchants. The owning master comes from your token — there is no resellerid field, and
one in the body is ignored. The merchant is always created at status = -1 (pending).
curl -s -X POST https://dev.boapi.ppgw.net/v1/merchants \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"businessname": "Acme Online",
"businesslegalname": "Acme Online (Pty) Ltd",
"businessaddress1": "12 Long Street",
"businesscity": "Cape Town",
"businesspostalcode": "8001",
"businessstate": "Western Cape",
"businesscountryid": 197,
"businesstelephone": "+27215550100",
"businessemail": "accounts@acme.example",
"contactfirstname": "Jane",
"contactsurname": "Doe",
"contactcountryid": 197,
"contacttelephone": "+27215550101",
"contactmobile": "+27825550102",
"contactemail": "jane.doe@acme.example"
}'{
"merchantid": 10544,
"merchantcode": "ME10544",
"status": -1,
"statuslabel": "pending",
"settingscopied": null,
"opsnotified": true
}Two response fields deserve attention:
opsnotified— creating a merchant sends an onboarding notification to the Ops team, which is what prompts them to review and activate it. If this isfalse, the merchant was created, but the notification did not go out — so nobody has been told to activate it. Treatfalseas an action item: follow up with your platform contact quoting themerchantid.settingscopied— the number of settings copied when you supplycopy_settings_from(see below);nullwhen you didn't.
The full request field set matches the backoffice onboarding form. See the create endpoint for every field and which are required.
Seed settings from a sibling merchant
If you already have a configured merchant and want the new one to start from the same EFT gateway
settings, pass copy_settings_from with that merchant's id. It must be a merchant in your own
scope; the copy is applied after the default seed.
{
"businessname": "Acme Wholesale",
"businesslegalname": "Acme Wholesale (Pty) Ltd",
"businessaddress1": "12 Long Street",
"businesscity": "Cape Town",
"businesspostalcode": "8001",
"businessstate": "Western Cape",
"businesscountryid": 197,
"businesstelephone": "+27215550100",
"businessemail": "accounts@acme.example",
"contactfirstname": "Jane",
"contactsurname": "Doe",
"contactcountryid": 197,
"contactemail": "jane.doe@acme.example",
"copy_settings_from": 10231
}Only the partner-writable settings are copied — the same set you could write directly. Naming a
merchant that isn't yours returns source_out_of_scope (a 400), distinct from not_found because
you named it explicitly and deserve to know the reference was rejected.
Update profile fields
PATCH /v1/merchants/{merchantId}. Every field is optional; only the fields you send are written.
There are no fee or billing fields — billing is out of scope for this API.
curl -s -X PATCH https://dev.boapi.ppgw.net/v1/merchants/10544 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "contactemail": "ops@acme.example", "contacttelephone": "+27215550190" }'Suspend and reactivate
The status field on PATCH permits only Active (1) ↔ Suspended (0), and only when the
merchant is already at status ≥ 0.
{ "status": 0 }What you cannot do:
- Activate a pending merchant (
-1 → 1). That is Ops-only — it is the whole point of the pending gate. - Move a merchant to draft or deleted.
Attempting a disallowed transition returns a validation_failed 400; the merchant is unchanged.
Next steps
- Gateway settings — configure the merchant's EFT behaviour.
- Receiving accounts and Payment routing — where funds settle.