Webhooks
Stitch will dispatch one or more transaction webhooks per transaction throughout the transaction lifecycle. The sections below provide a breakdown of the different scenarios.
See Transaction webhook definition for the transaction webhook payload. Take special note of the enum options for
transaction.transactionResult
in order to implement transaction state management in the webhook consumer as described in the Webhook Introduction section.
Approved Pre-Auth Transaction
For a Pre-Auth that is approved, two webhooks will be received initially:
- In the first webhook, the
transaction.transactionResult
will beauthorized
, indicating the acquirer has approved the transaction. - In the second webhook, the
transaction.transactionResult
will beauthorized_confirmed
, indicating the terminal has received the approved response and the transaction is now awaiting capture.
Once a Pre-Auth has been captured, a third webhook will be received indicating the final result of processing:
- In the third webhook, the
transaction.transactionResult
will beapproved_confirmed
, indicating the terminal has received the approved response and the transaction is now complete.
Approved Standard Transaction
For an approved transaction, two webhooks will be received:
- In the first webhook, the
transaction.transactionResult
will beapproved
, indicating the acquirer has approved the transaction. - In the second webhook, the
transaction.transactionResult
will beapproved_confirmed
, indicating the terminal has received the approved response and the transaction is now complete.
Declined Transaction
For a declined transaction, there would be a maximum of two webhooks sent:
- In the first webhook, the
transaction.transactionResult
will bedeclined
, and in general this will be the last webhook sent fordeclined
transactions. - In the second webhook, which occurs infrequently, the
declined
transaction may bereversed
. For some processing routes, a declined transaction may temporarily reserve cardholder funds. Stitch will determine in which cases declines may reserve funds and in these cases attempt a reversal. Should the reversal succeed, a second webhook withtransaction.transactionResult
ofreversed
will be sent.
Failed Transaction
A failed transaction means that the Stitch platform could not successfully send the request upstream to the acquirer for technical reasons (e.g., no network connectivity upstream, the acquirer times out, etc.).
For a failed transaction, there would be a maximum of two webhooks sent:
- In the first webhook, the
transaction.transactionResult
will befailed
, and in general this will be the last webhook sent forfailed
transactions. - In the second webhook, which occurs infrequently, the
failed
transaction may bereversed
. For some acquirer routes, a failed transaction may temporarily reserve cardholder funds. Stitch will determine in which cases failures may reserve funds and in these cases attempt a reversal. Should the reversal succeed, a second webhook withtransaction.transactionResult
ofreversed
will be sent.
Reversed Transaction
Reversed by Terminal
This can happen when the EMV chip on the card rejects the acquirer response.
For a reversed transaction, two webhooks will be received:
- In the first webhook, the
transaction.transactionResult
will beapproved
, indicating the acquirer has approved the transaction. - In the second webhook, the
transaction.transactionResult
will bereversed
.
Reversed by Stitch Platform
After a transaction has been approved, something can prevent the terminal from getting the response (a network issue, the terminal battery dies, or the app crashes).
In these cases, Stitch will reverse the transaction.
For a reversed transaction, you will receive two webhooks:
- In the first webhook, the
transaction.transactionResult
will beapproved
, indicating the acquirer has approved the transaction. - In the second webhook, the
transaction.transactionResult
will bereversed
. This will be received one to five minutes after the charge request.
Void Transaction
Transactions can be voided from the terminal app (if the feature is supported) or from the Stitch backend. The void can be requested either via a support email (support@exipay.co.za) or via a B2B API integration available to directly integrate into the Stitch void API.
A transaction can only be voided if the void instruction is sent before batch cutover for the day. The transaction webhook as well as
transaction lookup has an attribute (voidableUntilTime
) to indicate until when a void instruction can be accepted (see Void).
A void is essentially a reversal instruction, the difference being that the transaction.transactionResult
at the end will be voided
(as opposed to reversed
).
Single TAP & PIN
For supporting terminals, a contactless transaction may result in a decline with code 65
. Instead of requiring a new contact transaction, the terminal can prompt the cardholder for a PIN.
This flow is a combination of declined charge & approved charge,
but the transaction.referenceId
will be the same.
- In the first webhook, the
transaction.transactionResult
will bedeclined
. This is the first transaction and will prompt the cardholder to input their PIN. - In the second webhook, the
transaction.transactionResult
will beapproved
. This is the second transaction (assuming the PIN was correct) and it has the sametransaction.referenceId
as the first webhook and also contains atransaction.originalTransactionId
linking it to the first transaction. - In the third webhook, the
transaction.transactionResult
will beapproved_confirmed
. This is sent once the terminal approves the second transaction. It contains the sametransaction.referenceId
andtransaction.originalTransactionId
as above.
Transaction webhook definition
A typical webhook response can be seen below:
{
"webhookId": "d20826ae-928c-4e4e-8445-9a219124c4ff",
"webhookType": "transaction",
"webhookTime": "2025-07-23T07:06:14.255473514Z",
"terminal": {
"id": "42004b91-d54b-4b43-8574-43dd119522af",
"manufacturerSerialNumber": "terminal-reports-serial",
"manufacturer": "Sunmi",
"model": "P2 Mini"
},
"transaction": {
"transactionId": "d5aa4c31-4cd9-410b-b20e-bff5a735e4b0",
"referenceId": "74026ed3-f7f4-4f95-bb59-f6bfb0d9b16d",
"transactionResult": "approved_confirmed",
"transactionType": {
"value": 9,
"description": "Goods and Services with Cashback"
},
"responseCode": {
"value": "00",
"description": "Approved or completed successfully",
"isoCodeDescription": "Approved or completed successfully",
"terminalOutcomeString": "Approved",
"receiptString": "Approved",
"explanation": "The acquirer has approved the transaction. Other factors may impact the final outcome of the transaction."
},
"cardTransactionData": {
"rrn": "350069576949",
"stan": "777142",
"settlementDate": "2025-07-23",
"merchant": {
"name": "CI Merchant",
"city": "Cape Town",
"countryCode": "ZA"
},
"amount": {
"amount": 1600,
"currencyCode": "ZAR",
"displayValue": "R16.00"
},
"card": {
"maskedPan": "541333******0036",
"binNumber": "541333",
"scheme": "Mastercard",
"cardholderName": "",
"expiryYear": "25",
"expiryMonth": "12",
"applicationId": "A0000000041010",
"applicationName": "MASTERCARD",
"terminalVerificationResult": "0000008001",
"accountType": {
"value": 0,
"description": "Default"
},
"productType": "CREDIT",
"countryCode": "ZA",
"cardFingerprint": "C14CD4BD3C208D5312A2E16F518EF599F8089006DB9E6DC1EC1377D66BC2500B"
},
"mid": "000000001328",
"tid": "00001471",
"approvalCode": "421861"
},
"transactionTime": "2025-07-23T07:06:09.623172",
"voidableUntilTime": "2025-07-23T22:00:00Z",
"cardNotPresentRefundableStatus": "refundable",
"paymentMethod": "card"
}
}
Base information
Field Path | Type | Description | Notes / Example |
---|---|---|---|
webhookId | string | The unique webhook identifier. | "d20826ae-928c-4e4e-8445-9a219124c4ff" |
webhookType | string | The type of webhook being submitted. For transaction webhooks this will have the value transaction . | "transaction" |
webhookTime | date-time | The UTC time the webhook was generated in ISO 8601 format. | "2025-07-23T07:06:14.255473514Z" |
Terminal information
Field Path | Type | Description | Notes / Example |
---|---|---|---|
id | string | The Stitch unique identifier for the terminal used to process the transaction. | "42004b91-d54b-4b43-8574-43dd119522af" |
manufacturerSerialNumber | string | The internal serial number issued by the manufacturer for the terminal. | "terminal-reports-serial" |
manufacturer | string | The terminal manufacturer name. | "Sunmi" |
model | string | The terminal model name. | "P2 Mini" |
Transaction information
See REST API for more information on the transaction fields.