Create payment processors and payment options, and assign them to locations and workstations.
You must make all API calls to InStore from a secure server.
Configure payments
Complete the payments setup in the following order:
Authenticate InStore APIs
Authenticate to the InStore APIs with an administrator account and obtain an access token for the following steps.
You must configure the environment you are setting up to be your default environment in the InStore Center. If it isn't your default environment, do one of the following:
-
Access the InStore Center and set this environment as the administrator's default; or
-
Use the InStore
/switchtenantendpoint to get a new token:{ "client_id": "67e6976a0803e100127e311c", "tenant_id": "1ac0-9cd8-eb98-c521" }
A valid token is required each time you switch tenant environments.
Create a payment processor
Create a payment processor using the following endpoint:
POST https://api.instore.{region}.gcp.commercetools.com/{projectKey}/instore-tenants/{tenantKey}/payment-processors
Construct a separate call body for each tender type that this processor handles. The response of the request contains the payment processor's ID you will use in subsequent steps when developing for that tender type.
Sample payment processor payloads
Use the following sample payloads as a starting point. Replace placeholder values and adapt fields to your integration.
{
"key": "processor-cash-1",
"name": { "en-US": "Pay with cash", "es-MX": "Pago con efectivo" },
"description": {
"en-US": "Pay with cash"
},
"integrationConfiguration": {
"type": "Cash"
}
}
{
"key": "processor-bankcard-1",
"name": { "en-US": "Pay with card" },
"description": {
"en-US": "Pay with card"
},
"integrationConfiguration": {
"type": "BankCard",
"url": "https://api.example.com/bankcard",
"timeout": 15000,
"connectionTimeout": 15000,
"setupSteps": ["Initialization", "Connection"]
}
}
{
"key": "processor-poa-99",
"name": { "en-US": "Pay on account" },
"description": { "en-US": "Pay On Account" },
"integrationConfiguration": {
"type": "PayOnAccount",
"url": "https://integration.example.com/pay-on-account",
"apiKey": "YourSecureApiKeyHere",
"timeout": 15000,
"enableFields": [
"PaymentAccountIDs",
"PurchaseOrder",
"CompanyName",
"AuthorizedPurchaser"
],
"accountMethod": "Cart"
}
}
{
"key": "processor-wallet",
"name": { "en-US": "Digital Wallet" },
"description": { "en-US": "Digital Wallet" },
"integrationConfiguration": {
"type": "Wallet",
"url": "https://integration.example.com/wallet",
"apiKey": "YourSecureApiKeyHere",
"timeout": 15000
}
}
{
"key": "processor-giftcard-ped-1",
"name": {
"en-US": "Gift card (PED)",
"es-MX": "Tarjeta de regalo (PED)"
},
"description": {
"en-US": "Gift card paid via a payment terminal",
"es-MX": "Tarjeta de regalo pagada mediante terminal"
},
"integrationConfiguration": {
"type": "GiftCard",
"url": "https://integration.example.com/gift-card",
"apiKey": "YourSecureApiKeyHere",
"timeout": 15000,
"connectionTimeout": 15000,
"setupSteps": ["Initialization", "Connection"],
"cardNumberMethod": "Requested",
"cardBalanceMethod": "Requested"
}
}
{
"key": "processor-giftcard-manual-1",
"name": {
"en-US": "Gift card (scan or manual entry)",
"es-MX": "Tarjeta de regalo (escanear o ingresar)"
},
"description": {
"en-US": "Gift card paid by scanning or entering the card number",
"es-MX": "Tarjeta de regalo pagada al escanear o ingresar el número"
},
"integrationConfiguration": {
"type": "GiftCard",
"url": "https://integration.example.com/gift-card",
"apiKey": "YourSecureApiKeyHere",
"timeout": 15000,
"connectionTimeout": 15000,
"cardNumberMethod": "Manual",
"cardBalanceMethod": "Requested"
}
}
{
"id": "6918ee77f412799d8ef33ee8",
"key": "processor-bank-card-1",
"name": {
"en-US": "Pay with card"
},
"description": {
"en-US": "Pay with card"
},
"integrationConfiguration": "<omitted>",
"createdAt": "2025-11-15T21:19:51.306Z",
"updatedAt": "2025-11-15T21:19:51.306Z"
}
The fields are defined as follows:
| Element | Data type | Description |
|---|---|---|
| key | String | An identifier that you specify (for example, processor-poa-99). This string must be globally unique among processors, not just unique within your tenant or organization. If you receive an error due to duplicate keys, choose a different key. |
| name | Object<String, String> | A name that you specify for your own convenience during development. |
| description | Object<String, String> | Optional. Not in use. |
| integrationConfiguration | Object | The payment processor configuration. The fields in this object depend on integrationConfiguration.type. |
| integrationConfiguration.type | String | The payment type. The value can be Cash, BankCard, GiftCard, Wallet, or PayOnAccount. This value determines which other integrationConfiguration fields apply. |
| integrationConfiguration.url | String | The callback URL where InStore sends the payment request. This field applies to BankCard, Wallet, PayOnAccount, and GiftCard processor configurations. |
| integrationConfiguration.apiKey | String | The payment service key used for signature verification between InStore and your payment service provider. Use the same value that you configured in your payment service integration. This field applies when your processor configuration requires request signing, such as Wallet, PayOnAccount, and GiftCard. |
| integrationConfiguration.enableFields | Array<String> | For PayOnAccount, the fields to display to the store associate during checkout. Options are PaymentAccountIDs, PurchaseOrder, CompanyName, and AuthorizedPurchaser. Only enable fields for which values can be called. |
| integrationConfiguration.accountMethod | String | For PayOnAccount, how the processor receives Customer account information. The only available option is Cart. InStore makes a dynamic API call based on screen input. |
| integrationConfiguration.timeout | Integer | The request and read timeout. This value is the maximum time to wait for the entire HTTP request to complete, including receiving the response. Default is 10000 milliseconds (10 seconds). |
| integrationConfiguration.connectionTimeout | Integer | The timeout for establishing the TCP connection to the server. Specify the maximum time to wait before the connection handshake times out. Default is 10000 milliseconds (10 seconds). This field applies to configurations that connect to an external payment service, such as BankCard and some GiftCard integrations. |
| integrationConfiguration.setupSteps | Array<String> | Optional. This field applies to configurations that require setup checks before payment, such as BankCard and some GiftCard integrations. Use this element to specify Initialization or Connection. With Initialization, InStore makes a request to the initialize_credit_processor endpoint to verify that the payment service provider (PSP) can be reached. With Connection, InStore makes a request to the connect_card_reader endpoint to verify that the PED is available for communication. These endpoints are configured on your integration server and appended to the payment processor base url. If you don't need these steps to enable the payment method, leave setupSteps undefined. Depending on your implementation, you can define setupSteps for only one processor, with other processors sharing the definition. |
| integrationConfiguration.cardNumberMethod | String | For GiftCard, specifies how InStore acquires the unique number of the stored value account or gift card. Options are Requested for stored value via PED or Manual for stored value via scan or manual entry. |
| integrationConfiguration.cardBalanceMethod | String | For GiftCard, specifies how InStore acquires the available balance for the stored value account or gift card. The option is Requested. If Requested is set, InStore attempts to retrieve the balance from the payment processor. |
Create a payment option
Create a payment option using the following endpoint:
POST https://api.instore.{region}.gcp.commercetools.com/{projectKey}/instore-tenants/{tenantKey}/payment-options
Construct a separate request body for each payment option you want to make available. The response contains the payment option ID, which you will use in subsequent steps.
Sample payment option payloads
Use the following sample payload as a starting point. Replace placeholder values and adapt fields to your requirements.
{
"key": "option-cash-1",
"name": {
"en-US": "Pay with cash",
"es-MX": "Pagar con efectivo"
},
"description": {
"en-US": "Pay with cash",
"es-MX": "Pagar con efectivo"
},
"displayHint": "BuildOutlined",
"allowSplit": false,
"allowRepeat": true,
"minCentAmount": 0,
"maxCentAmount": 0,
"default": true,
"sortOrder": 0.5,
"paymentModes": ["Online"],
"allowedOperations": ["Sale"],
"method": "Cash",
"paymentProcessorId": "691bb93ff14fd895922ceb16"
}
{
"id": "691bbaa4f1add2fda55a3950",
"key": "option-cash-1",
"name": {
"es-MX": "Pagar con efectivo",
"en-US": "Pay with cash"
},
"description": {
"es-MX": "description",
"en-US": "description"
},
"displayHint": "BuildOutlined",
"allowSplit": false,
"allowRepeat": true,
"minCentAmount": 0,
"maxCentAmount": 0,
"default": true,
"sortOrder": 0.5,
"paymentModes": ["Online"],
"allowedOperations": ["Sale"],
"method": "Cash",
"paymentProcessorId": "691bb93ff14fd895922ceb16",
"createdAt": "2025-11-18T00:15:32.908Z",
"updatedAt": "2025-11-18T00:15:32.908Z"
}
The fields are defined as follows:
| Element | Data type | Description |
|---|---|---|
| key | String | An identifier that you specify (for example, option-cash-us-1). This string must be globally unique among payment options, not just unique within your tenant or organization. If you receive an error due to duplicate keys, choose a different key. |
| name | Object<String, String> | A name that you specify for your own convenience during development. |
| description | Object<String, String> | Optional. Not in use. |
| displayHint | String | The identifier for a supported Material UI icon. InStore supports a subset of icons. The list is available upon request. No default. |
| allowSplit | Boolean | If true, a payment using this method may be shared with other payment options. If false, this payment option may only be used to pay for the entire checkout amount. Default is false. |
| allowRepeat | Boolean | If true, repeated or additional calls to this payment option within the same session don't change the state beyond the first successful call. Default is true. This setting is recommended to prevent multiple identical charges. |
| minCentAmount | Integer | The minimum amount that can be paid for using this payment option. Expressed in the equivalent of cents for that currency. For example, 10000 in a tenant environment that uses euros = 100 euros. Default is 0. |
| maxCentAmount | Integer | The maximum amount that can be paid for using this payment option. Expressed in the equivalent of cents for that currency. For example, 10000 in a tenant environment that uses euros = 100 euros. Default is 0. |
| default | Boolean | If true, this payment option is available to all locations and workstations in the environment where it is created. The true setting is designed to be used when adding payment options to multiple workstations or locations in bulk mode. The default is false. |
| sortOrder | Number | A number value between 0 and 1 inclusive that you specify to indicate this payment option button's display position on the tender selection page if default is true. A 1 appears at the top of the list and 0 at the bottom. Use a preceding 0 and a period (.) when specifying the decimal. For example, 0.5, 0.1234, and 0.77. A button whose value is 0.44 will appear above one whose value is 0.4. If two payment options have the same value for sortOrder, the tie is broken by order of creation, with later created buttons appearing below earlier created ones. Default is 0. |
| paymentModes | Array<String> | The payment modes supported by this payment option. Only Online is supported. |
| allowedOperations | Array<String> | The payment operations supported by this payment option. Only Sale is supported. |
| method | String | The payment method. The value can be Cash, Credit, PayOnAccount, Wallet, or GiftCard, depending on the payment type selected during payment processor setup. |
| paymentProcessorId | String | The ID of the corresponding payment processor created during Create a payment processor. |
default: true setting, you must assign sortOrder to all payment options the next time you access the API to work with payment options. If you specify a blank, null, or invalid value for sortOrder when default: true, the API returns an error and the payment option creation fails.sortOrder value is ignored for the workstation or location if InStore encounters a payment option assignment there.Assign payment options to locations and workstations
Assign to a location
POST https://api.instore.{region}.gcp.commercetools.com/{projectKey}/instore-tenants/{tenantKey}/location/{locationId}
locationId is the database identifier of the location, for example 682eebe13717b1001237e7ae.Assign to a workstation
POST https://api.instore.{region}.gcp.commercetools.com/{projectKey}/instore-tenants/{tenantKey}/workstation/{workstationId}
workstationId is the database identifier of the workstation, for example 683ec8c5f71306095b351b14.Sample payment assignment payloads
Use the following sample payloads as a starting point. Replace placeholder values and adapt fields to your requirements.
{
"actions": [
{
"action": "addPaymentOptionAssignment",
"paymentOptionId": "68b1a9b06281bcbc94d503f7"
}
]
}
{
"actions": [
{
"action": "setPaymentOptionAssignments",
"paymentOptionIds": [
"68b1a9b06281bcbc94d503f7",
"691bbaa4f1add2fda55a3950",
"691bbac4f1add2fda55a3952"
]
}
]
}
{
"actions": [
{
"action": "removePaymentOptionAssignment",
"paymentOptionId": "691bbaa4f1add2fda55a3950"
}
]
}
{
"paymentOptionAssignments": ["68b1a9b06281bcbc94d503f7"]
}
SET action for a location or workstation controls the button order that colleagues see. Otherwise, buttons are listed in the order in which they were added, with the most recently added payment option at the bottom of the button list.
If you set the default key to true, you can use the sortOrder field to control the order of the payment options. See Sample payment option payloads.Send a separate call for each payment option you want to remove.