Kushki sends webhook notifications to your server for every Card Present transaction event — charges, authorizations, captures, voids, reverses, and refunds. Your endpoint receives the event payload immediately after the terminal confirms the operation.Card Present webhooks are configured from the Kushki Console under Developers → Webhooks. Webhook configuration via API is not supported for Card Present.
Supported events#
| Event | Trigger |
|---|
approvedTransaction | A charge, authorization, or capture is approved |
declinedTransaction | A transaction is declined by the issuer or network |
initializedTransaction | A two-step authorization is initialized |
voidTransaction | A void or reverse is completed |
refundTransaction | A refund is completed |
Webhook payload#
All events share a common envelope. The transactionType and transactionStatus fields identify the specific event.{
"transactionType": "SALE",
"transactionStatus": "APPROVAL",
"transactionId": "1234567890abcdef",
"ticketNumber": "987654321",
"clientTransactionId": "ae6dd41a-9173-4ec7-8734-3178454ef341",
"amount": 500.00,
"currency": "PEN",
"responseCode": "000",
"responseText": "APPROVED",
"approvalCode": "123456",
"cardType": "credit",
"paymentBrand": "VISA",
"maskedCard": "XXXXXXXXXXXX1234",
"binCard": "411111",
"isDeferred": false,
"merchantId": "<your-merchant-id>",
"created": "2026-01-01T14:32:00.000Z",
"processorBankName": "BCP",
"transactionReference": "718fa526-6f41-405f-a1f5-a71db52dfdd2",
"posDetails": {
"brand": "SUNMI",
"model": "P2-EU",
"serialNumber": "SN71652",
"terminalId": "TID001"
}
}
Key fields#
| Field | Description |
|---|
transactionType | SALE, AUTHORIZATION, CAPTURE, VOID, REVERSE, REFUND |
transactionStatus | APPROVAL, DECLINED, INITIALIZED |
ticketNumber | Kushki-assigned transaction ticket — use for reconciliation |
clientTransactionId | The UUID you sent in the original request |
transactionReference | Acquirer-level reference — required for void, capture, and refund |
approvalCode | Issuer approval code (present on approved transactions) |
responseCode | ISO 8583 response code — 000 means approved |
posDetails.serialNumber | Serial number of the terminal that processed the transaction |
Transaction types reference#
Charge (SALE)#
Triggered when a one-time payment completes.{
"transactionType": "SALE",
"transactionStatus": "APPROVAL",
"amount": 500.00,
"currency": "PEN",
"isDeferred": false
}
For deferred (instalment) charges, isDeferred is true and a deferred object is included:{
"transactionType": "SALE",
"transactionStatus": "APPROVAL",
"isDeferred": true,
"deferred": {
"months": "6",
"monthlyAmount": 83.33
}
}
Authorization (AUTHORIZATION)#
Triggered when a two-step pre-authorization is placed.{
"transactionType": "AUTHORIZATION",
"transactionStatus": "INITIALIZED",
"amount": 500.00,
"transactionReference": "718fa526-6f41-405f-a1f5-a71db52dfdd2"
}
Capture (CAPTURE)#
Triggered when an authorization is captured.{
"transactionType": "CAPTURE",
"transactionStatus": "APPROVAL",
"amount": 500.00,
"transactionReference": "718fa526-6f41-405f-a1f5-a71db52dfdd2"
}
Void (VOID)#
Triggered when an authorization or same-day charge is cancelled.{
"transactionType": "VOID",
"transactionStatus": "APPROVAL",
"transactionReference": "718fa526-6f41-405f-a1f5-a71db52dfdd2"
}
Reverse (REVERSE)#
Triggered when a transaction is reversed at the acquirer level.{
"transactionType": "REVERSE",
"transactionStatus": "APPROVAL",
"transactionReference": "718fa526-6f41-405f-a1f5-a71db52dfdd2"
}
Refund (REFUND)#
Triggered when a settled transaction is refunded — full or partial.{
"transactionType": "REFUND",
"transactionStatus": "APPROVAL",
"amount": 250.00,
"transactionReference": "718fa526-6f41-405f-a1f5-a71db52dfdd2"
}
Signature verification#
Kushki signs every webhook request with an HMAC-SHA256 signature. Verify it before processing the payload to ensure authenticity.| Header | Value |
|---|
X-Kushki-Signature | Base64-encoded HMAC-SHA256 of the raw request body |
X-Kushki-Timestamp | Unix timestamp in milliseconds when the event was sent |
Verification (Node.js example)#
Always verify the signature before trusting the payload. Reject any request where verification fails.
Retry policy#
If your endpoint does not return HTTP 2xx within the timeout window, Kushki retries the delivery with exponential backoff:| Attempt | Delay |
|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 8 hours |
After 5 failed attempts the event is marked as undelivered. You can replay it from the Console → Developers → Webhooks → Event Log.
Best practices#
| Practice | Reason |
|---|
Respond immediately with 200 | Avoid timeouts — process asynchronously |
| Persist the raw payload before processing | Enables replay if processing fails |
Use ticketNumber as the idempotency key | Protect against duplicate delivery |
Verify X-Kushki-Signature on every request | Reject forged or tampered payloads |
Check X-Kushki-Timestamp | Reject events older than 5 minutes to prevent replay attacks |
Configuration#
Configure your webhook endpoints in the Kushki Console:1.
Go to Developers → Webhooks
4.
Select the Card Present events to subscribe to
5.
Copy the Signing Secret and store it securely in your environment
Your webhook URL must be publicly accessible over HTTPS. HTTP endpoints are not accepted.
Got a suggestion on this documentation? Contact us.