Stores and terminals
Before you can take a payment, Boundless needs to know where it is taken — which store, and which device in that store. You register these once, using your own identifiers, and then name them on every payment.
Your business
└── Store "Orchard Road branch" → you get back a store id
└── Terminal "Counter 1" → you get back a terminal id
The identifiers Boundless returns are what you use everywhere else. You never need the acquirer's own device numbers — the link between your terminal and the physical Pine Labs device is set up with Boundless during onboarding.
Register a store
curl https://api-live.kcpboundless.com/api/merchants/{merchantExternalId}/stores \
-H "X-API-Key: bndl_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Orchard Road branch",
"addressLine1": "252 Orchard Road",
"city": "Singapore",
"postalCode": "238905",
"country": "SG"
}'
The response includes the store's externalId — keep it; it is how you address the store from now
on.
Optional store details
Beyond the address, a store can carry details that other parts of the platform read:
| Field | Meaning |
|---|---|
country | Two-letter ISO 3166-1 code (SG, KR, …). Forgiving on input (sg works), stored uppercase; anything that is not a country code is rejected rather than saved. |
timezone | IANA zone id, for example Asia/Singapore. This decides which calendar day the store's payments settle under, so it must be a real zone — invalid values are rejected. |
defaultCurrency | ISO 4217 code from the platform's supported currencies. Pre-fills payment creation for this store. |
mcc | Merchant category code — exactly 4 digits, for example 5812. |
metadata | A free-form JSON object for your own details (contact person, opening hours, …). Up to 50 entries with keys up to 100 characters; values are stored as sent and never interpreted. |
Register a terminal
Terminals live under a store:
curl https://api-live.kcpboundless.com/api/merchants/{merchantExternalId}/stores/{storeExternalId}/terminals \
-H "X-API-Key: bndl_live_..." \
-H "Content-Type: application/json" \
-d '{
"label": "Counter 1"
}'
The response includes the terminal's externalId. A store can have as many terminals as it has
devices.
Optional device details
Recording what the device physically is pays off the day one goes missing or needs support:
| Field | Meaning |
|---|---|
terminalType | POS (countertop), MPOS (mobile), SOFTPOS (app on a phone), KIOSK, or UNATTENDED. |
vendor, model | Device make and model, for example Pine Labs / Plutus Smart A910. |
serialNumber | The serial printed on the device. Unique across all your terminals (case-insensitive) — registering a serial already on another of your live terminals is rejected with 409, because two records answering to one physical sticker makes device recovery ambiguous. |
metadata | The same free-form object as on stores — lane placement, SIM number, install notes. |
Keeping them in step
- List, update, or remove stores and terminals at any time — see the API reference.
- A store or terminal marked inactive cannot take a payment. This is deliberate: a payment to a terminal Boundless does not recognise, or one that is switched off, is refused rather than sent to the wrong place.
Removing safely
Removal cascades: deleting a store takes its terminals (and their device links) with it. As a
safety net, a store or terminal that took payments in the last 24 hours refuses an ordinary
delete with 409 — add ?force=true once you are sure. If recent activity cannot be determined,
the unforced delete also refuses, erring toward keeping a live setup intact.
Once a store has an active terminal, you are ready to take a payment.