Create Payment
curl --request POST \
--url https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"transactionId": "0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07",
"amount": "99.99",
"currency": "USD",
"paymentMethod": "CARD",
"products": [
{
"id": "PROD-001",
"name": "Widget",
"price": "99.99",
"quantity": 1
}
],
"customerInfo": {
"customerId": "CUST-123",
"email": "customer@example.com"
},
"metadata": {
"orderId": "ORD-12345"
}
}
'import requests
url = "https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments"
payload = {
"transactionId": "0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07",
"amount": "99.99",
"currency": "USD",
"paymentMethod": "CARD",
"products": [
{
"id": "PROD-001",
"name": "Widget",
"price": "99.99",
"quantity": 1
}
],
"customerInfo": {
"customerId": "CUST-123",
"email": "customer@example.com"
},
"metadata": { "orderId": "ORD-12345" }
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
transactionId: '0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07',
amount: '99.99',
currency: 'USD',
paymentMethod: 'CARD',
products: [{id: 'PROD-001', name: 'Widget', price: '99.99', quantity: 1}],
customerInfo: {customerId: 'CUST-123', email: 'customer@example.com'},
metadata: {orderId: 'ORD-12345'}
})
};
fetch('https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'transactionId' => '0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07',
'amount' => '99.99',
'currency' => 'USD',
'paymentMethod' => 'CARD',
'products' => [
[
'id' => 'PROD-001',
'name' => 'Widget',
'price' => '99.99',
'quantity' => 1
]
],
'customerInfo' => [
'customerId' => 'CUST-123',
'email' => 'customer@example.com'
],
'metadata' => [
'orderId' => 'ORD-12345'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments"
payload := strings.NewReader("{\n \"transactionId\": \"0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07\",\n \"amount\": \"99.99\",\n \"currency\": \"USD\",\n \"paymentMethod\": \"CARD\",\n \"products\": [\n {\n \"id\": \"PROD-001\",\n \"name\": \"Widget\",\n \"price\": \"99.99\",\n \"quantity\": 1\n }\n ],\n \"customerInfo\": {\n \"customerId\": \"CUST-123\",\n \"email\": \"customer@example.com\"\n },\n \"metadata\": {\n \"orderId\": \"ORD-12345\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"transactionId\": \"0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07\",\n \"amount\": \"99.99\",\n \"currency\": \"USD\",\n \"paymentMethod\": \"CARD\",\n \"products\": [\n {\n \"id\": \"PROD-001\",\n \"name\": \"Widget\",\n \"price\": \"99.99\",\n \"quantity\": 1\n }\n ],\n \"customerInfo\": {\n \"customerId\": \"CUST-123\",\n \"email\": \"customer@example.com\"\n },\n \"metadata\": {\n \"orderId\": \"ORD-12345\"\n }\n}")
.asString();using RestSharp;
var options = new RestClientOptions("https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("x-api-key", "<api-key>");
request.AddJsonBody("{\n \"transactionId\": \"0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07\",\n \"amount\": \"99.99\",\n \"currency\": \"USD\",\n \"paymentMethod\": \"CARD\",\n \"products\": [\n {\n \"id\": \"PROD-001\",\n \"name\": \"Widget\",\n \"price\": \"99.99\",\n \"quantity\": 1\n }\n ],\n \"customerInfo\": {\n \"customerId\": \"CUST-123\",\n \"email\": \"customer@example.com\"\n },\n \"metadata\": {\n \"orderId\": \"ORD-12345\"\n }\n}", false);
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
{
"transactionId": "0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07",
"status": "SUCCESS",
"paymentResponse": {
"transactionId": "0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07",
"status": "SUCCESS",
"amount": "99.99",
"currency": "USD",
"paymentMethod": "CARD",
"authorizationCode": "AUTH123456",
"receiptData": "...",
"timestamp": "2024-01-15T10:37:30.000Z"
},
"timestamp": "2024-01-15T10:37:30.000Z"
}Terminal Gateway API
Create Payment
Initiate a payment to a specific terminal with long-polling up to 90 seconds
POST
/
v1
/
terminals
/
{terminalId}
/
payments
Create Payment
curl --request POST \
--url https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"transactionId": "0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07",
"amount": "99.99",
"currency": "USD",
"paymentMethod": "CARD",
"products": [
{
"id": "PROD-001",
"name": "Widget",
"price": "99.99",
"quantity": 1
}
],
"customerInfo": {
"customerId": "CUST-123",
"email": "customer@example.com"
},
"metadata": {
"orderId": "ORD-12345"
}
}
'import requests
url = "https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments"
payload = {
"transactionId": "0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07",
"amount": "99.99",
"currency": "USD",
"paymentMethod": "CARD",
"products": [
{
"id": "PROD-001",
"name": "Widget",
"price": "99.99",
"quantity": 1
}
],
"customerInfo": {
"customerId": "CUST-123",
"email": "customer@example.com"
},
"metadata": { "orderId": "ORD-12345" }
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
transactionId: '0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07',
amount: '99.99',
currency: 'USD',
paymentMethod: 'CARD',
products: [{id: 'PROD-001', name: 'Widget', price: '99.99', quantity: 1}],
customerInfo: {customerId: 'CUST-123', email: 'customer@example.com'},
metadata: {orderId: 'ORD-12345'}
})
};
fetch('https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'transactionId' => '0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07',
'amount' => '99.99',
'currency' => 'USD',
'paymentMethod' => 'CARD',
'products' => [
[
'id' => 'PROD-001',
'name' => 'Widget',
'price' => '99.99',
'quantity' => 1
]
],
'customerInfo' => [
'customerId' => 'CUST-123',
'email' => 'customer@example.com'
],
'metadata' => [
'orderId' => 'ORD-12345'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments"
payload := strings.NewReader("{\n \"transactionId\": \"0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07\",\n \"amount\": \"99.99\",\n \"currency\": \"USD\",\n \"paymentMethod\": \"CARD\",\n \"products\": [\n {\n \"id\": \"PROD-001\",\n \"name\": \"Widget\",\n \"price\": \"99.99\",\n \"quantity\": 1\n }\n ],\n \"customerInfo\": {\n \"customerId\": \"CUST-123\",\n \"email\": \"customer@example.com\"\n },\n \"metadata\": {\n \"orderId\": \"ORD-12345\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"transactionId\": \"0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07\",\n \"amount\": \"99.99\",\n \"currency\": \"USD\",\n \"paymentMethod\": \"CARD\",\n \"products\": [\n {\n \"id\": \"PROD-001\",\n \"name\": \"Widget\",\n \"price\": \"99.99\",\n \"quantity\": 1\n }\n ],\n \"customerInfo\": {\n \"customerId\": \"CUST-123\",\n \"email\": \"customer@example.com\"\n },\n \"metadata\": {\n \"orderId\": \"ORD-12345\"\n }\n}")
.asString();using RestSharp;
var options = new RestClientOptions("https://api.sbx.moduluslabs.io/v1/terminal-gateway/v1/terminals/{terminalId}/payments");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("x-api-key", "<api-key>");
request.AddJsonBody("{\n \"transactionId\": \"0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07\",\n \"amount\": \"99.99\",\n \"currency\": \"USD\",\n \"paymentMethod\": \"CARD\",\n \"products\": [\n {\n \"id\": \"PROD-001\",\n \"name\": \"Widget\",\n \"price\": \"99.99\",\n \"quantity\": 1\n }\n ],\n \"customerInfo\": {\n \"customerId\": \"CUST-123\",\n \"email\": \"customer@example.com\"\n },\n \"metadata\": {\n \"orderId\": \"ORD-12345\"\n }\n}", false);
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
{
"transactionId": "0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07",
"status": "SUCCESS",
"paymentResponse": {
"transactionId": "0191f6b2-7c4e-7a3b-9d52-3f8e1a6c4b07",
"status": "SUCCESS",
"amount": "99.99",
"currency": "USD",
"paymentMethod": "CARD",
"authorizationCode": "AUTH123456",
"receiptData": "...",
"timestamp": "2024-01-15T10:37:30.000Z"
},
"timestamp": "2024-01-15T10:37:30.000Z"
}This endpoint requires HMAC-SHA256 authentication. See Authentication for signature computation details.
Long-Polling Behavior
This endpoint uses long-polling and waits up to 90 seconds for the terminal to respond. Plan for this timeout in your HTTP client configuration.Terminal ID Resolution
TheterminalId parameter is resolved in the following order:
- Device ID (Recommended) - First checks if the ID matches a registered
deviceId - Connection ID (Fallback) - If no device ID match, treats it as a
connectionId
Always use
deviceId when available. It provides a stable reference that doesn’t change when terminals reconnect.Handling Timeouts
If you receive a504 Gateway Timeout response:
- Do not retry the payment immediately
- Use Get Transaction to check if the payment completed
- Only retry if the transaction record’s status is
FailedorCancelled
The payment may have completed on the terminal after the HTTP timeout. Always verify transaction status before retrying to avoid duplicate charges.
Authorizations
HMAC-SHA256 authentication. Requires three headers: x-api-key (your API key), x-timestamp (ISO 8601 timestamp, within 5 minutes of server time), and x-signature (Base64-encoded HMAC-SHA256 signature). The string to sign is METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + SHA256(BODY). PATH is the endpoint path WITHOUT the /v1/terminal-gateway gateway prefix, for example /v1/terminals. SHA256(BODY) is the hex hash of the exact body you send. See the Authentication documentation.
Path Parameters
Body
application/json
Payment request details
Was this page helpful?