Kushki ONE is currently in Beta for Perú 🇵🇪. Do not deploy to production without coordinating with the Kushki integration team.
Kushki ONE Connect is a semi-integrated API that lets your POS system control a Kushki SmartPOS terminal (Sunmi P3 / P2 SE) — triggering card payments, managing pre-authorizations, adding tips, and printing receipts from your own application.Your POS stays in control of the transaction flow. The terminal handles all card interaction and cryptographic processing.
Two connection modes#
| Mode | How it works | Best for |
|---|
| Cloud | Your POS calls Kushki's cloud, which pushes the command to the terminal | POS running in the cloud, or on a different network from the terminal |
| Local Network | Your POS calls the terminal's local IP directly over LAN or Wi-Fi | POS and terminal on the same local network |
The two modes cover the same operations, but they are not interchangeable. Beyond the base URL, these differ: | Cloud | Local Network |
|---|
| Terminal addressing | terminalSerial in the path | The terminal's IP and port |
| Abort | POST, sync only | GET, sync and async |
| Transaction search | One unified endpoint | Two: acquirer-side and on-device |
| Print status | POST .../print_job, ID in the body | GET .../print_job?print_job_id= |
| Recommended HTTP timeout | 90 s (relay latency) | 15 s |
| Endpoints | 17 | 20 |
Sync and async#
Every payment operation exists twice, under two path prefixes, in both modes:| 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 | On the webhook you register |
Async exists because card-present flows wait on a human and routinely exceed the ~15 second timeout budget of most POS architectures.The async response is an acknowledgement, not a result. To learn whether the transaction was approved you must consume the events webhook — supply events_webhook_url in the request body.
Refund and transaction search are sync-only in both modes.
Terminal models#
| Model | Description |
|---|
| Sunmi P3 | Handheld SmartPOS with thermal printer |
| Sunmi P2 SE | Compact countertop SmartPOS |
Base URLs#
| Environment | URL |
|---|
| Production | https://cloudt.kushkipagos.com |
| UAT | https://uat-cloudt.kushkipagos.com |
POST /terminal/v1/{terminalSerial}/{sync|async}/{operation}
Local Network — the terminal exposes an HTTP server on its local IP:http://{terminalIp}:{port}/terminal/v1/{sync|async}/{operation}
| 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) |
Print operations keep their own paths in both modes — see each Print folder.Before using Try it, pick the matching environment at the top right: Kushki ONE Cloud — UAT, Kushki ONE Cloud — Producción or Kushki ONE Local. The default UAT Testing Env points at the Online Payments host, where Kushki ONE does not answer.
Authentication#
Kushki ONE uses HMAC-SHA256 request signing — not the Private-Merchant-Id header used in Online Payments.| Header | Description |
|---|
Authorization | Base64( HMAC-SHA256( rawRequestBody, businessCode ) ) |
timestamp | Unix timestamp in milliseconds, within ±5 min of server time |
Both headers are required on every endpoint, Payment and Print alike. On bodyless requests such as Abort, the signature is computed over an empty string.Never expose your Business-Code in client-side code or logs.
Amounts are integers in céntimos and the terminal is provisioned in PEN or USD, both with two decimal places. Send 1200 to charge S/ 12.00 — never drop the céntimos, never send separators. There is no currency field; the terminal's DMS configuration decides it.Requests take integers, but event and webhook payloads echo amounts back as decimals (12000.0). Do not re-send an echoed value as an amount.
Key integration notes#
Save rawResponse.transaction_reference from every charge or authorization — required for capture, re-authorization, void and refund.
client_transaction_id is your idempotency key. Retry with the same UUID; the terminal deduplicates.
Wait at least 1 minute after a transaction before calling void. Cutoff in Peru is around 20:59 local on the same business day; after that, use refund.
The terminal handles one transaction at a time. Do not send another command until the current one completes.
APPROVAL_REQUESTED is the point of no return — once the transaction reaches the acquirer, abort returns 409.
Where to go next#
Cloud Services
Control the terminal through Kushki's cloud. No direct network access required.
Local Network Services
Call the terminal's local IP directly. Lowest latency, no cloud dependency.
Got a suggestion on this documentation? Contact us.