In Local Network mode, your POS sends HTTP requests directly to the terminal's local IP address over your LAN or Wi-Fi. Use this mode when your POS and terminal share the same network and you want the lowest latency with no cloud dependency.Kushki ONE Local Network is currently in Beta for México 🇲🇽. Do not deploy to production without coordinating with the Kushki integration team.
Base URL#
The terminal exposes an HTTP server on its local IP:http://{terminalIp}:{port}/terminal/v1
| Variable | Default | Description |
|---|
terminalIp | 192.168.1.50 | Static IP or DHCP reservation of the terminal |
port | 6868 | Configured in the Device Management System (DMS) |
Payment operations live under /sync/ and /async/, so a charge is POST http://192.168.1.50:6868/terminal/v1/sync/charge. Print keeps its own paths — see below.Select the Kushki ONE Local environment at the top right, then override terminalIp and port with your own terminal's values. The default UAT Testing Env points at api-uat.kushkipagos.com, which is the Online Payments host — a local terminal does not answer there.There is no UAT/production split in Local mode: you always call the same device on your network. Whether it settles against the UAT or the production acquirer is decided by the terminal's own DMS provisioning, not by the URL.
Local traffic is plain HTTP, unencrypted. Keep the terminal on a trusted, segmented network. The terminal still needs port 443 egress to reach Kushki's authorization servers.
Authentication#
Both headers are required on every endpoint, print included:| Header | Description |
|---|
Authorization | HMAC-SHA256 signature of the raw JSON request body, Base64-encoded. Key = your Business-Code |
timestamp | Current Unix timestamp in milliseconds (13 digits) |
Sync vs Async#
Every payment operation ships in two variants under two path prefixes.| Variant | Prefix | HTTP response | Where the outcome arrives |
|---|
| Sync | /sync/ | Blocks until the acquirer answers, then returns the full result | In the HTTP response |
| Async | /async/ | Returns immediately with a TERMINAL_ACKNOWLEDGED event | Webhook only |
Async exists because card-present flows wait on a human and routinely exceed the ~15 second timeout budget of most POS architectures. Supply events_webhook_url in the body to receive events; it is accepted on /async/ endpoints only.Refund and both transaction searches are sync-only. Everything else, abort included, exists in both variants.
Every amount field is an integer in cents. The currency is always MXN, which has two decimal places — the last two digits are always the cents, so amounts without a fraction still carry their trailing zeros:| To charge | Send |
|---|
| 12.44 MXN | 1244 |
| 12.00 MXN | 1200 |
This applies to subtotal_iva0, subtotal_iva, iva, tip, cashback_amount and every member of extra_taxes. There is no currency field — the terminal's DMS configuration decides it.
Payment operations#
| Operation | Sync | Async |
|---|
| Charge | POST /sync/charge | POST /async/charge |
| Authorization | POST /sync/authorization | POST /async/authorization |
| Capture | POST /sync/capture | POST /async/capture |
| Re-authorization | POST /sync/re_authorization | POST /async/re_authorization |
| Post-tip | POST /sync/pos_tip | POST /async/pos_tip |
| Void | POST /sync/void | POST /async/void |
| Abort | GET /sync/abort | GET /async/abort |
| Refund | POST /sync/refund | — |
| Transaction Search — Online | POST /sync/transaction_search_online | — |
| Transaction Search — Local | POST /sync/transaction_search_local | — |
Charge#
{
"amount": {
"subtotal_iva0": 10000,
"subtotal_iva": 0,
"iva": 0,
"extra_taxes": { "airport_tax": 0, "iac": 0, "ice": 0, "travel_agency": 0 }
},
"client_transaction_id": "c5a3f3be-9d6f-4d39-8af5-58dbb589af79",
"metadata": { "reference": "ORD-20240317-001", "customer_email": "user@example.com" }
}
⚠️ Save rawResponse.transaction_reference from the response — required for capture, re-authorization, void and refund.
There is no tip field on /sync/charge: the terminal collects the tip on screen when tipping is enabled in the DMS. /sync/pos_tip and the async endpoints take it explicitly.Two-step flow#
authorization ──→ re_authorization (0..n) ──→ capture ──→ refund
│ │
└──────────────→ void ←───────────────────┘
| Rule | Detail |
|---|
| Pre-auth validity | Debit 7 days, credit 28 days. Visa and Mastercard only |
| Capture ceiling | ≤ 110% of the authorization plus all non-canceled re-authorizations |
| Captures per cycle | Exactly one |
| Void window | Same business day, cutoff around 22:00 local |
Transaction Search#
Two endpoints, different backends: _online queries the Kushki acquirer and needs internet; _local reads what the terminal itself stored and works offline. Only _online filters by transaction_type.{
"page": 1,
"size": 10,
"filters": { "last_four_digits": "9130", "start_date": 0, "end_date": 0 }
}
Dates are 13-digit millisecond timestamps. Send 0 in both to disable date filtering.
Print operations#
| Operation | Endpoint |
|---|
| Create Print Job | POST /terminal/v1/print |
| Get Print Job Status | GET /terminal/v1/print_job?print_job_id={id} |
| Print Job Webhook | POST to your webhookUrl |
Printing is asynchronous — create returns 202 Accepted with PENDING. Write type in lowercase; every other enum (align, dividerType, algorithm, errorLevel) is UPPERCASE.{
"printJobId": "RECEIPT-20240317-001",
"webhookUrl": "https://pos.micomercio.com.mx/webhooks/print",
"commands": [
{ "type": "text", "text": "MI COMERCIO MÉXICO\n", "align": "CENTER", "size": 28, "bold": true },
{ "type": "divider", "dividerType": "SOLID", "offset": 8 },
{ "type": "columns", "columns": [
{ "text": "2x Combo Hamburguesa", "weight": 2, "align": "LEFT" },
{ "text": "$300.00", "weight": 1, "align": "RIGHT" }
]},
{ "type": "feed", "lines": 3 },
{ "type": "cut" }
]
}
| Status | Description |
|---|
PENDING | Queued, not yet printed |
IN_PROGRESS | The driver is sending commands to the printer |
COMPLETED | Printed and cut successfully |
FAILED | Hardware error — see errorCode |
Key differences from Cloud mode#
| Feature | Local Network | Cloud |
|---|
| Base URL | http://{terminalIp}:{port}/terminal/v1 | https://cloudt.kushkipagos.com |
| Terminal addressing | The terminal's IP | terminalSerial in the path |
| Abort method | GET /sync/abort, GET /async/abort | POST /sync/abort, sync only |
| Async abort | ✅ | ❌ |
| Transaction search | Two endpoints: _online and _local | One unified endpoint |
| Print create | POST /terminal/v1/print | POST /{terminalSerial}/sync/print |
| Print status | GET /terminal/v1/print_job?print_job_id= | POST /{terminalSerial}/sync/print_job with the ID in the body |
| Print webhook | Documented as its own endpoint | Modeled as a callback |
| Recommended HTTP timeout | 15 s | 90 s (relay latency) |
| Network requirement | Terminal and POS on the same LAN/Wi-Fi | Internet access |
Folders#
Payment
17 card operations, sync and async.
Print
Receipt printing on the terminal's thermal printer.
Got a suggestion on this documentation? Contact us.