Merchant management

Create, list, update, suspend, and unsuspend merchants via the Portal API — the programmatic version of the Portal's merchant management UI.

The merchant-management endpoints are the programmatic way for PSPs and acquirers to onboard, update, and lifecycle-manage their merchants. They're the API behind the Portal UI's merchant screens.

For the conceptual walk-through and decision tree, see Merchant Onboarding. For auth setup, see Authentication.


Endpoints

MethodPathPurposeAllowed callers
GET/restful/merchant/listList merchants in your scopePSP, Acquirer
POST/restful/merchant/createOnboard a new merchantPSP, Acquirer
POST/restful/merchant/updateUpdate an existing merchantPSP, Acquirer
POST/restful/merchant/suspendSuspend an ACTIVE merchantPSP, Acquirer
POST/restful/merchant/unsuspendUnsuspend a SUSPENDED merchantPSP, Acquirer

All requests use Basic Auth with a ROLE_REMOTE-enabled profile — see Authentication.


List merchants

Returns every merchant in your scope. For a PSP, that's merchants where pspId matches the caller. For an acquirer, that's merchants where acquirer matches the caller.

Request:

curl -X GET https://qa.scantopay.io/portal/restful/merchant/list \
  -u 'PSP_42:yourPspApiPassword'

Response:

[
  {
    "merchantId": 25,
    "merchantName": "Acme Coffee Pty Ltd",
    "merchantCategoryCode": "5812",
    "cardAcceptorTerminalId": "12345678",
    "cardAcceptorIdentificationCode": "8765432",
    "cardAcceptorNameLocation": "ZA",
    "email": "[email protected]",
    "acquirer": "SBSA",
    "pspId": 42,
    "merchantStatus": "ACTIVE",
    "acceptedCards": ["master", "visa"],
    "acceptedPayments": "AMT,SECURE_CODE"
  }
]

Returns an empty array if you own no merchants. There's no pagination today — the full list comes back in one response.


Create a merchant

Onboards a new merchant on the platform. Returns the freshly-created merchant including its assigned merchantId.

Request body — ApiMerchantBean:

FieldRequiredDescription
merchantNameyesUp to 45 chars
merchantCategoryCodeyesExactly 4 chars (e.g. 5812 for eating places)
cardAcceptorTerminalIdyesAcquirer-issued terminal ID. SBSA requires exactly 8 chars.
cardAcceptorIdentificationCodeyesAcquirer-issued merchant code. SBSA requires 7-15 chars.
cardAcceptorNameLocationyes2-char country code (e.g. ZA)
emailyesValid email address
acquirerconditionalRequired when caller is PSP — the acquirer name (e.g. ABSA, SBSA, Nedbank, ECLIPSE). Ignored when caller is acquirer (taken from the caller).
pspIdconditionalRequired when caller is acquirer — assigns the merchant to a PSP. Ignored when caller is PSP (taken from the caller).
secureCodeMerchantIdoptionalIf supplied, the platform creates a Secure Code config using the acquirer's defaults
addressoptionalNested location object — see below
acceptedCardsoptionalList of card brands the merchant accepts — master, visa, maestro, amex, diners, cup
payShapInfooptionalNested PayShap config — supply if onboarding the merchant on PayShap as well

Nested address object:

FieldDescription
addressLine1Street address
addressLine2Optional
cityCity
suburbSuburb / district
countryCountry
postalCodePostal code
latitudeFloat, optional
longitudeFloat, optional

Sample request:

curl -X POST https://qa.scantopay.io/portal/restful/merchant/create \
  -u 'PSP_42:yourPspApiPassword' \
  -H 'Content-Type: application/json' \
  -d '{
    "merchantName": "Acme Coffee Pty Ltd",
    "merchantCategoryCode": "5812",
    "cardAcceptorTerminalId": "12345678",
    "cardAcceptorIdentificationCode": "8765432",
    "cardAcceptorNameLocation": "ZA",
    "email": "[email protected]",
    "acquirer": "SBSA",
    "acceptedCards": ["master", "visa"],
    "address": {
      "addressLine1": "1 Main Road",
      "city": "Cape Town",
      "country": "South Africa",
      "postalCode": "8001"
    }
  }'

Response:

The full ApiMerchantBean of the new merchant, including the assigned merchantId and current merchantStatus.

Common errors:

HTTPBodyCause
400"Invalid 'pspId' Field"Acquirer didn't supply pspId, or the supplied PSP doesn't exist
400"Invalid 'acquirer' Field"PSP supplied an acquirer name that isn't in the supported list
400"Invalid 'Terminal Id' Field, must be 8 length"SBSA-specific terminal ID validation
400"Invalid 'cardAcceptorIdentificationCode' Field, must be between 7 and 15 length"SBSA-specific identification code validation
400(PayShap validation message)payShapInfo was supplied but invalid

Update a merchant

Two modes:

ModeTriggerBehaviour
Full updateupdateOnlyPresentFields: false (default)Every required field must be supplied — missing fields fail validation
Selective updateupdateOnlyPresentFields: trueOnly fields present in the request body are changed; everything else is preserved

Selective update is the safer choice for most use cases.

Sample request — selective update changing only the email:

curl -X POST https://qa.scantopay.io/portal/restful/merchant/update \
  -u 'PSP_42:yourPspApiPassword' \
  -H 'Content-Type: application/json' \
  -d '{
    "merchantId": 25,
    "updateOnlyPresentFields": true,
    "email": "[email protected]"
  }'

Response: the updated ApiMerchantBean.

Update constraints:

  • merchantId is mandatory
  • Merchant must be in ACTIVE state
  • Ownership check applies (PSP/acquirer can only update merchants they own)
  • acquirer can be changed (PSP-only) provided the new acquirer is in the supported list

For the rules around mutating PayShap info, see PayShap management.


Suspend a merchant

Moves a merchant from ACTIVE to SUSPENDED. The merchant stops being able to accept new transactions until unsuspended.

Request:

curl -X POST https://qa.scantopay.io/portal/restful/merchant/suspend \
  -u 'PSP_42:yourPspApiPassword' \
  -H 'Content-Type: application/json' \
  -d '{
    "merchantId": 25,
    "reason": "Compliance hold pending document review"
  }'

Request fields:

FieldRequiredDescription
merchantIdyesMerchant to suspend
reasonyesFree-text reason — captured in the audit log

Response: HTTP 200 OK with no body.

Common errors:

HTTPBodyCause
400"Merchant not in 'ACTIVE' state"Merchant is already suspended, waiting activation, or terminated
400"Invalid 'merchantId'"Ownership check failed

Unsuspend a merchant

Reverses a suspension — moves from SUSPENDED back to ACTIVE.

Request:

curl -X POST https://qa.scantopay.io/portal/restful/merchant/unsuspend \
  -u 'PSP_42:yourPspApiPassword' \
  -H 'Content-Type: application/json' \
  -d '{
    "merchantId": 25,
    "reason": "Documents received and verified"
  }'

Same request body as suspend. The reason is captured in the audit log.

Common errors:

HTTPBodyCause
400"Merchant not in 'SUSPENDED' state"Merchant is already active, or in a non-suspended state
400"Invalid 'merchantId'"Ownership check failed

What about activation?

Newly-created merchants are activated automatically as part of the /restful/merchant/create flow — no separate activation step is required. The legacy /restful/merchant/activate/{merchantId} endpoint is deprecated and not documented here.

If a merchant ends up in WAITING ACTIVATION for some reason (typically a back-office configuration step), contact [email protected] to resolve.


What's next