1. Kushki One
Kushki Docs
English
  • Español
  • English
  • Home
  • Quick Start
    • Frequently Asked Questions
    • Moving to Production
    • Policy for Important API Changes
    • Test Data
    • Error Codes
    • Latest Features
  • Payment Glossary
    • Payments Glossary
  • One-time card payments (Online)
    • Supported card brands
    • Functionalities by business model
    • How do third party commissions work?
    • Integration guide Third Party Commissions
    • Network Tokens
    • One-step Payments
      • How do Card Payments Work?
      • Accept a Card Payment
      • Direct charge (without token)
      • Accept One-Time Payments with OTP
      • OTP Authentication Error Codes
      • Error codes for single card payments
    • Two-steps Payments
      • How do single payments with authorization and capture work?
      • Receive payments with authorization and capture
    • Refunds
      • Returns, cancellations, and refunds
    • 3DS Authentication
      • Introduction to 3DS
      • 3DS API integration
      • 3DS integration with kushki.js library
      • 3DS API integration plus kushki.js library
      • 3DS Error Codes
    • Apple Pay Payments
      • Apple Pay Configuration
      • Apple Pay Sandbox testing
  • Recurring Card Payments (Online)
    • Functionalities by business model
    • External subscriptions to Kushki
    • Authenticate your subscriptions with 3DS
    • Accept one-click payments with 3DS
    • Error codes in recurring charges
    • Apple Pay for Subscriptions
    • Scheduled payments
      • How do Credit or Debit Card Payment Recurring Charges Work?
      • Create a recurring charge
      • Manage your Scheduled Charges
    • OneClick Payments
      • Accepting One-Click Payments
      • How do OneClick payments with authorization and capture work?
      • Receive one-click payments with authorization and capture
  • Card-present payments
    • Card present payments
    • Accept card present payments
    • Test data
    • Webhooks for card present
    • Cloud Terminal API
      • Cloud terminal API overview
      • Take payments
      • Cancel a payment request
      • Check the status of a payment request
      • How to print a customized ticket?
    • App-to-app
      • App-to-app overview
      • Take payments
    • Terminal SDK
      • Terminal SDK Introduction
      • Take payments
    • Raw card-present API
      • Raw card-present API overview
      • Cryptographic key exchange
      • Sample script to encrypt information
      • Take Payments
      • Frequently Asked Questions
      • Error codes for card-present transactions
    • Transactions
      • Transactions
      • Cancel payments
    • Kushki One
      • First Steps
      • Autenticación y Cifrado de Requests
      • Accept payments with Kushki One
      • Amount Format
      • Async services and webhooks
      • Printing on SmartPOS terminal
      • Unified Error Catalog — Kushki ONE Connect
    • Kushki One Payment App
      • Overview
      • Process a payment
      • Split payment on the terminal
      • Refunds and PreAuth & Capture
      • Review Your Transactions
      • Terminal Setup
  • Wire Transfers
    • How do Payments by Wire Transfers Work?
    • Banks and transaction details for bank transfer payments
    • Receive Wire Transfers
    • Check the Status of a Transaction
  • Money Disbursement
    • Wire Transfer
      • How Does a Payment Distribution by Wire Transfer Work?
      • Payment Distribution to Bank Accounts
      • Error codes for transfer dispersions
  • Payment Links
    • Smartlinks
  • Plugins
    • Shopify
      • Shopify
      • Plugin Operation
    • VTEX
      • VTEX Integration Guide
  • Payment forms and buttons
    • Kajita
      • How Does it Work?
      • Payment Kajitas
    • Payment Button
      • Overview
      • Generate a payment button
  • Branch Offices Management
    • How to Onboard Submerchants via API
  • Notifications
    • Webhooks
    • Good Practices
    • Check your Webhooks
    • One-time Payments Webhooks
      • Webhook for One-Time Payments made with a card
      • Webhook for One-Time Payments by Wire Transfer
      • Webhook for One-Time Payments in Cash
    • Recurring Payments Webhooks
      • Webhook for Recurring Payments Made with Card
    • Payment Distribution Webhooks
      • Webhook for payment disbursement through wire transfer
    • Payment button Webhooks
      • Webhooks with Payment Button
    • Smartlinks Webhooks
      • Webhooks with Smartlinks
    • Refunds Webhooks
      • Webhook for Voids and Refunds
      • Chargeback Webhooks
HomeMexico 🇲🇽
Ecuador 🇪🇨Chile 🇨🇱Colombia 🇨🇴Peru 🇵🇪
HomeMexico 🇲🇽
Ecuador 🇪🇨Chile 🇨🇱Colombia 🇨🇴Peru 🇵🇪
Status
Soporte / Support
English
  • Español
  • English
  1. Kushki One

Accept payments with Kushki One

🚧 Early Release — Beta
This product is in early access. Parameters, response structures and behaviors may change without prior notice. Do not use this version in production without coordinating with the Kushki integrations team first.
The Payment API lets you process card-present payments from your POS system to a Kushki ONE terminal running in semi-integrated mode. The terminal handles the entire cardholder interaction and the EMV chip: your system sends the amount and receives the result.

Requirements#

Before you start
A Sunmi P3 or P2 SE terminal linked to your merchant account and running in semi-integrated mode.
Your Business-Code, provided by the integrations team.
Each device's terminalSerial. The integrations team hands it over during onboarding.
Your connection topology decided: Cloud, Local Network or Localhost.

How it works#

The payloads and the headers are identical between topologies. The routes are not — three things change, and they are listed under the base URLs.
TopologyBase URL
Local Network (LAN / Wi-Fi)http://{TERMINAL_IP}:6868/terminal/v1 or https://{TERMINAL_IP}:6869/terminal/v1
Cloud (Internet) — UAThttps://uat-cloudt.kushkipagos.com/terminal/v1/{terminalSerial}
Cloud (Internet) — Productionhttps://cloudt.kushkipagos.com/terminal/v1/{terminalSerial}
What changes between Cloud and the local network, beyond the base URL:
DifferenceLocal NetworkCloud
/abort methodGET, in both modesPOST, sync only
Async abortAvailableDoes not exist
Print routes/terminal/v1/print/{terminalSerial}/sync/print
Not sure which topology to use?
Read Integration topologies in Getting started before you continue.

Sync and async modes#

Every operation that requires terminal interaction exists in two variants, under separate path prefixes.
ModePrefixBehaviorWhere the result arrives
Sync/sync/Holds the connection open until the acquirer answersIn the HTTP response
Async/async/Returns immediately with a TERMINAL_ACKNOWLEDGED acknowledgement. Never blocksWebhook only
When to use async mode
A card-present payment depends on a person's interaction and frequently exceeds the 15 seconds most POS architectures tolerate. If your system cannot hold a connection open that long, use async mode and consume the events over webhook.

Available operations#

OperationPathSyncAsyncWhat it does
Sale/charge✅✅Immediate charge: authorizes and captures in a single step
Authorization/authorization✅✅Reserves funds without capturing them
Capture/capture✅✅Charges the funds from an approved authorization
Re-authorization/re_authorization✅✅Extends the amount or the validity of an active authorization
Post-tip/pos_tip✅✅Adds a tip to an already-authorized transaction
Reversal/void✅✅Reverses a transaction: cancellation within the calendar day, refund after the cut-off
Abort/abort✅✅Cancels an operation in progress on the terminal
Online search/transaction_search_online✅—Queries transaction history at the acquirer
Local search/transaction_search_local✅—Queries the history stored on the terminal
/abort differs between topologies
On Local Network, /abort uses the GET method and is available in both modes. On Cloud it uses POST and only exists in sync mode.

Key concepts#

client_transaction_id#

A UUID v4 identifier that your POS system generates. It works as an idempotency key: if the terminal already processed that identifier, it detects the duplicate and prevents a double charge.
Generate a new one for every sale. Reuse it only when you are retrying the exact same operation after a network failure.

transaction_reference#

An identifier that Kushki generates and returns in the response of every approved transaction, inside rawResponse. It is the link between operations in the same lifecycle.
Persist this value
Store the transaction_reference in your database the moment you receive the response. Without it you cannot capture, re-authorize, void or refund that transaction.

Amount structure#

The amount object is sent in the currency's minor units, as an integer. The number of decimals depends on the country.
Build the amount correctly
A badly built amount is the most common cause of incorrect charges. Read Amount format in Kushki ONE before your first integration.

Optional fields, by operation#

These are the only optional fields, and each one belongs to specific operations. They behave the same in sync and async.
FieldTypeApplies toWhat it does
amount.tipinteger/charge and /authorizationAdds a tip. The tip can be set at pre-authorization time, not only when charging
cashback_amountinteger/chargeCash withdrawal on top of the purchase. Send 0 if it does not apply
deferred / query_deferredobject / boolean/chargeInstallments. The field and its shape change by country — see below
omit_cardboolean/capture, /re_authorization and /voidWith true the operation runs without asking for the card
metadataobject/charge, /authorization and /pos_tipFree-form traceability: reference, customer_email, device
On /pos_tip, amount.tip is not an optional field — it is the amount of the operation.
omit_card is what makes the hotel case work: extending or capturing a pre-authorization after the guest has left the desk.

Installments change by country#

The two fields are mutually exclusive and never travel together:
CountryFieldShapeMaximum
Mexicoquery_deferredBoolean. The terminal offers Meses Sin Intereses to the cardholder after reading the card; your POS does not choose the months—
Chiledeferredmonths, plus credit_type: "03" for cuotas comercio — a string, not a number12 with credit_type, 48 without it
Colombiadeferredmonths only. credit_type does not apply48
Perudeferredmonths only. credit_type does not apply2–48, every network
If a capability is not enabled for your terminal, the terminal ignores the field instead of rejecting the request — so a 200 does not prove the tip was applied. To have it enabled, write to soporte@kushkipagos.com.
Beta coverage
Only /charge has been exercised end-to-end with these fields, in sync and async. amount.tip on /authorization and omit_card on its six combinations are defined but not yet exercised — expect to be the first to run them.

Reading the HTTP status#

On payment endpoints the status is always 200
Whatever happened, payment endpoints answer 200. The status confirms that the terminal processed your request — not that the operation succeeded. Always evaluate the response body. A POS that branches on response.ok treats a busy terminal, an expired PIN and a cardholder cancellation as successes.
The print endpoints are the exception: they return real codes, 404 when the job does not exist and 409 while the queue is busy.

Payment flows#

Direct sale#

The most common retail flow. The terminal activates the reader when it receives the request and waits for the cardholder to complete the interaction.
POST /sync/charge  →  200 OK (approved: true)

Pre-authorization and capture#

Use this when the final amount is unknown at the time of the interaction: hotels, fuel stations, open-tab restaurants.
POST /sync/authorization  →  store transaction_reference
        ↓  (hours or days later)
POST /sync/capture  →  with the stored transaction_reference
You can insert /re_authorization to raise the reserved amount or extend the window before capturing. Send subtotal_iva0: 0 to extend the validity only.
A re-authorization can be canceled
Once you cancel a re-authorization, the transaction accepts no further re-authorizations.

Authorization validity#

Card typeValidity from authorization
Debit (Visa / Mastercard)7 days
Credit (Visa / Mastercard)28 days
The capture can reach up to 110% of the total authorized, adding the authorization and every non-canceled re-authorization. Only one capture is allowed per cycle.

Post-tip#

Adds a tip to an already-authorized transaction. Use it when the cardholder decides the amount after the initial charge. Send the value in amount.tip alongside the original transaction_reference.

Reversal#

There is a single reversal endpoint, /void, and the system decides what the operation becomes based on when you call it. The cut-off is 23:59 local time in every country: within the same calendar day the reversal is a cancellation; from midnight onwards it enters the refund cycle and takes business days.
Wait at least 1 minute
Wait at least 1 minute after the original transaction before reversing it, or it fails for no apparent reason.
The type returned by transaction search tells you what actually happened:
TypeWhat it means
VOIDYou called /void on the same calendar day. Cancellation — the cardholder never sees the charge
REFUNDYou called /void after the cut-off. It entered the refund cycle and takes business days
REVERSEYou did not ask for it. The platform generates it on its own when communication with the terminal fails
A REVERSE you never requested is not an error
Your POS can find a REVERSE in transaction search without having called anything. It is how the platform resolves a charge whose communication was cut mid-flight — the scenario where the POS charges, the link drops, and nobody knows whether the transaction landed.

Authentication#

Kushki ONE uses one mechanism — hash + encryption — and it is the same in Cloud, on the local network and on localhost: Authorization: Basic <SHA512>, timestamp in seconds, and the body as the encrypted envelope {"data":"<iv_hex>:<cipher_hex>"}.
Every payload shown on this page is the plaintext you encrypt, not what travels on the wire. The full flow, the key derivation chain and the diagnostic tree are on Authentication and request encryption.
Local Network and Localhost: send the encrypted_http_communication header
In Local Network and Localhost, every request also carries the header encrypted_http_communication: true, in UAT and in production. Cloud does not require it. Details in Authentication and request encryption.
Do not confuse Business-Code with private_credential_id
The signing key is your Business-Code. The private_credential_id is a terminal configuration field and is not used to sign requests.
Set a long client timeout
Card-present flows wait on a person. Use at least 90 seconds on Cloud, where the relay adds latency on top of the terminal's own processing time, and 15 seconds on the local network. A 30-second timeout on Cloud produces phantom failures on charges that were in fact approved.

Direct sale example#

A charge of 12000 minor units with no tax breakdown. What that represents depends on the country's decimals — check Amount format in Kushki ONE before your first integration.
JavaScript
Python

Best practices#

Generate a unique client_transaction_id per sale and reuse it only when retrying the same operation.
Persist the transaction_reference as soon as you receive the authorization or charge response.
Check that the amount fields add up to the expected total before you send the request.
Log the client_transaction_id and the HTTP code of every operation to make reconciliation and support easier.
Call /abort only while a transaction is active on the terminal. Calling it afterwards returns 409 Conflict.
Sign exactly the same bytes you send: serialize once, sign that string and send that same string.
Async services and webhooks
Integrate async mode: lifecycle states, event structure and the delivery retry policy.
Error catalog
Look up the error models, the codes by category and the corrective actions for every endpoint.
Modificado en 2026-10-07 14:31:58
Anterior
Autenticación y Cifrado de Requests
Siguiente
Amount Format
Built with