This walks through onboarding one merchant end-to-end on the Service API — same authentication as
before, nothing to set up differently. If you are still integrating against the legacy /api/v2
API, use the legacy quickstart instead of this page.
1. Get your group ID
Used to look things up — you don't need to send it in any request body, it's read from your Bearer token. See PBO Owner for the full endpoint.
This call stays on /api/v2/* rather than /api/openapi/v1/* — group/PBO lookup is shared
infrastructure that both versions use, so it isn't duplicated under the new base path.
GET /api/v2/current
Authorization: Bearer {jwt}2. Create the EMV configs
emvList on the acquirer profile (next step) and emvs on the payment binding (step 5) both
reference EMV configs by ID — create them first. See EMV Config for all fields.
POST /api/openapi/v1/emv
Authorization: Bearer {jwt}
Content-Type: application/json
{
"emvName": "l3-visa",
"paymentMethod": "01",
"currency": "SGD",
"params": "{\"aid\":\"A0000000031010\",\"appVersion\":\"0002\",\"clFloorLimit\":0,\"clTransLimit\":99999999,\"clCVMLimit\":100000}"
}HTTP/2 200 OK
{ "msg": "SUCCESS", "code": 0, "data": { "id": 1675 } }Repeat for payment method 02 (e.g. "emvName": "l3-mastercard") — this walkthrough assumes it
comes back as "id": 1676.
3. Create the acquirer profiles
If the merchant uses a single acquirer, create one profile here and list every payment method it accepts — steps 4 and 5 work the same way, you just bind one profile instead of two.
This walkthrough creates a separate profile per payment method to show what the API makes
possible: VISA settles through one acquirer, MASTERCARD through another. methodList/emvList are JSON-encoded strings, scoped to just the
one method each profile handles. enablerParams declares which per-acquirer fields (here
acqMid/acqTid) the device step below must supply for this profile. See
Acquirer Profile for all fields.
POST /api/openapi/v1/acquirer
Authorization: Bearer {jwt}
Content-Type: application/json
{
"profileName": "Visa - SG",
"currency": "SGD",
"connUrl": "https://acquirer-host.example.com/gateway",
"enablerMsgFormat": "MOCK",
"enablerParams": "acqMid,acqTid",
"methodList": "{\"01\":[]}",
"emvList": "{\"01\":[1675]}"
}HTTP/2 200 OK
{ "msg": "SUCCESS", "code": 0, "data": { "id": 316 } }POST /api/openapi/v1/acquirer
Authorization: Bearer {jwt}
Content-Type: application/json
{
"profileName": "Mastercard - SG",
"currency": "SGD",
"connUrl": "https://acquirer-host.example.com/gateway",
"enablerMsgFormat": "MOCK",
"enablerParams": "acqMid,acqTid",
"methodList": "{\"02\":[]}",
"emvList": "{\"02\":[1676]}"
}HTTP/2 200 OK
{ "msg": "SUCCESS", "code": 0, "data": { "id": 317 } }4. Create the merchant
country and currency are new in this version. See Merchant for all fields.
POST /api/openapi/v1/mchInfo
Authorization: Bearer {jwt}
Content-Type: application/json
{
"mchName": "ACME Café",
"country": "SG",
"currency": "SGD",
"contactName": "John Doe",
"contactEmail": "[email protected]",
"timeZone": "Asia/Singapore",
"providerReference": "my-reference",
"mcc": "5814"
}HTTP/2 200 OK
{
"msg": "SUCCESS",
"code": 0,
"data": {
"mchId": "M1721816099",
"mchName": "ACME Café",
"country": "SG",
"currency": "SGD",
"state": 1,
"acquirers": [],
"supportedPayments": []
}
}5. Bind the merchant to each acquirer profile
Call this once per acquirer, each time naming the payment method that profile handles — this is what actually routes VISA to one acquirer and MASTERCARD to the other on the same merchant. See Merchant payment config for details.
POST /api/openapi/v1/mchInfo/payment/M1721816099
Authorization: Bearer {jwt}
Content-Type: application/json
{
"acquirerProfileId": "316",
"currency": "SGD",
"mid": "12345",
"paymentMethods": [
{ "paymentMethodCode": "01", "emvs": [{ "emvId": 1675 }] }
]
}HTTP/2 200 OK
{ "msg": "SUCCESS", "code": 0 }POST /api/openapi/v1/mchInfo/payment/M1721816099
Authorization: Bearer {jwt}
Content-Type: application/json
{
"acquirerProfileId": "317",
"currency": "SGD",
"mid": "56787",
"paymentMethods": [
{ "paymentMethodCode": "02", "emvs": [{ "emvId": 1676 }] }
]
}HTTP/2 200 OK
{ "msg": "SUCCESS", "code": 0 }6. Create an activation code for the SoftPOS app
Now that the merchant has two acquirers bound, extParams.acquirers on the device must carry one
entry per acquirer profile ID, each with the fields that profile's enablerParams declared
(acqMid/acqTid here) — this is how the Enabler knows which MID/TID to use per acquirer at
transaction time. See Device for all fields.
POST /api/openapi/v1/device
Authorization: Bearer {jwt}
Content-Type: application/json
{
"mchId": "M1721816099",
"deviceType": "COTS",
"deviceAlias": "Code name",
"deviceAdmin": "passcode",
"extParams": {
"acquirers": {
"316": { "acqMid": "12345", "acqTid": "234" },
"317": { "acqMid": "56789", "acqTid": "44" }
}
}
}HTTP/2 200 OK
{
"msg": "SUCCESS",
"code": 0,
"data": {
"id": "CD-017241045101",
"activationCode": "017241045101",
"profileId": "316"
}
}Use the activationCode to log in on the SoftPOS app.