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 and 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. All fields are required except businessaddress2, contactaddress2, and
copy_settings_from. The merchant is created at status = -1 (pending), or status = 1 (active) when
it is auto-activated (on DEV, or when your master is in the auto-activate list).
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",
"businesscountrycode": "ZA",
"businesstelephone": "+27215550100",
"businessemail": "accounts@acme.example",
"contactfirstname": "Jane",
"contactsurname": "Doe",
"contactcountrycode": "ZA",
"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.
Retrieving the merchant's gateway token
GET /v1/merchants/{merchantId} returns the full merchant record, including its apitoken. This is
the merchant's gateway API token, returned in full, and it is what you use to route that merchant's
transactions through the gateway.
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 can be any non-deleted merchant in your
own scope, at any status; 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",
"businesscountrycode": "ZA",
"businesstelephone": "+27215550100",
"businessemail": "accounts@acme.example",
"contactfirstname": "Jane",
"contactsurname": "Doe",
"contactcountrycode": "ZA",
"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) or Suspended (0), and only when the merchant
is already at status 0 or 1.
{ "status": 0 }What you cannot do:
- Activate a pending merchant (
-1to1). 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.