Structure of webhooks
General information
Tranzzo uses webhooks to promptly notify you of any changes in payment statuses in real-time.
It's important to note that in specific circumstances (such as network or server-side delays), webhook notifications may be duplicated.
We send webhooks using the POST
HTTP method and the following content type: Content-Type:application/x-www-form-urlencoded
.
Webhook parameters:
Parameter | Type | Description |
---|---|---|
data | String | Base64Url-encoded JSON |
signature | String | data signed with ${SECRET_KEY} |
Webhook example:
data=AIzaSyDKS9CnQoCY0NpeSbXYsmu5c3thaEi1b5A
signature=AIzaSyDKS9CnQoCY0NpeSbXYsmu5c3thaEi1b5A
Tranzzo uses the following IP addresses to send webhooks:
- 35.187.74.148
Note: typically we send webhooks to 443 and 8443 ports. However, if you require webhooks to be sent to other ports, please inform Tranzzo Support.
Verification of webhooks
Webhook verification requires forming a signature using the following method: signature=base64url_encode(sha1($API_SECRET + base64url_encode($data) + $API_SECRET))
The sha1
function returns raw bytes rather than a hex-encoded string, and the signature is 28 characters in length.
Signature calculation example:
raw_data='{"name":"Joe","age":20}' # {"name":"Joe","age":20}
data='eyJuYW1lIjoiSm9lIiwiYWdlIjoyMH0=' # base64url_encode(raw_data)
secret='changeme' # should be changed to ${API_SECRET}
signature='Bcj3hb-h00HrEMIoJ5nPW5ZHlVQ=' # base64url_encode(sha1($secret + $data + secret))
# Bash one-liner:
# 1. calculate sha1 as raw bytes
# 2. encode raw bytes with base64
# 3. replace [+]->[-],[/]->[_]
echo -n 'changemeeyJuYW1lIjoiSm9lIiwiYWdlIjoyMH0=changeme' | \
openssl dgst -binary -sha1 | \
base64 | \
tr '/+' '_-'
Webhooks parameters
Webhooks contain different sets of parameters depending on whether they are primary or secondary operations.
The parameters for webhooks of primary transactions including purchase, auth, credit, p2p, and lookup, are as follows:
Parameter | Type | Required | Description |
---|---|---|---|
payment_id | String | ✅ | Unique Tranzzo payment identifier |
order_id | String | ✅ | Unique identifier of order |
gateway_order_id | String | Unique order identifier in bank acquirer system. | |
billing_order_id | String | Unique Tranzzo billing identifier | |
transaction_id | String | Unique Tranzzo transaction identifier | |
pos_id | String | ✅ | Merchant's identifier (POS_ID ) |
mode | String | ✅ | Payment mode |
method | String | ✅ | Payment method |
amount | Number | ✅ | Transaction amount |
currency | String | ✅ | Transaction currency |
payway | String | Optional payway | |
eci | String | Electronic Commerce Indicator (ECI) - authentication result of credit card payment on 3D Secure | |
status | String | ✅ | Transaction status |
status_code | String | Tranzzo payment status code | |
status_description | String | Tranzzo payment status code description | |
cc_mask | String | Card number mask | |
cc_token | String | Tranzzo card token | |
cc_token_expiration | String | Token expiration timestamp | |
customer_id | String | Customer identifier in merchant's system | |
customer_phone | String | Customer phone | |
fee | Object | Amount and currency of commission | |
fixed_fee | Object | Amount and currency of fixed commission (fee), which constitutes a portion of the total commission (fee) | |
percent_fee | Object | Amount and currency representing the interest commission (fee), which constitutes a portion of the total commission (fee) | |
created_at | String | ✅ | Timestamp when transaction was created |
processed_at | String | Timestamp when transaction was updated last time | |
payload | String | Payment request payload |
Here is an example of a webhook for the auth primary transactions:
{
"payment_id": "c4939398-1dad-4b92-1c34-7f6802379180",
"order_id": "111999991",
"gateway_order_id": "6320ac9a-aaaa-4912-adb3-5bca2dd560fe",
"billing_order_id": "123",
"transaction_id": "4f98dc46-ffff-4ba7-a267-286fe7669894",
"pos_id": "6eb070d5-7fbe-1176-9488-c152b60dd346",
"mode": "direct",
"method": "auth",
"amount": 0.28,
"currency": "UAH",
"payway": "privat24",
"eci": "7",
"status": "success",
"status_code": "1000",
"status_description": "Transaction is successful.",
"cc_mask": "424242******4242",
"cc_token": "N2U0ZWExZjU5ZDEzNDqkZjg2YjBaOGYdN2VgZWFcOTYaT2FBaFBUekt6R3hzeDBPU2hO",
"cc_token_expiration": "2020-10-10T10:10:22",
"customer_id": "123",
"customer_phone": "+380999999999",
"fee": {
"amount": 136,
"currency": "UAH"
},
"percent_fee": {
"amount": 126,
"currency": "UAH"
},
"fixed_fee": {
"amount": 10,
"currency": "UAH"
},
"created_at": "2018-10-10T10:10:10.100",
"processed_at": "2018-10-10T10:10:22.100",
"payload": ""
}
When utilizing certain alternative payment methods, there may be instances where the payer can make partial payments, leading to changeable transaction amounts. In such scenarios, the webhook will also include the following parameters:
Parameter | Type | Description |
---|---|---|
processed_amount | Number | The amount that was actually paid by the customer and processed by the payment system. It applies to payments where the final payment amount can be changed by the payer. |
processed_currency | String(≤256) | Actual currency of payment with processed_amount. It applies to payments where the final payment amount can be changed by the payer. |
Webhook example for the purchase transaction with changeable amount:
{
"payment_id": "c4939398-1dad-4b92-1c34-7f6802379180",
"order_id": "111999991",
"gateway_order_id": "6320ac9a-aaaa-4912-adb3-5bca2dd560fe",
"billing_order_id": "123",
"transaction_id": "4f98dc46-ffff-4ba7-a267-286fe7669894",
"pos_id": "6eb070d5-7fbe-1176-9488-c152b60dd346",
"mode": "direct",
"method": "purchase",
"amount": 1000,
"currency": "UAH",
"payway": "privat24",
"eci": "7",
"status": "success",
"status_code": "1000",
"status_description": "Transaction is successful.",
"cc_mask": "424242******4242",
"cc_token": "N2U0ZWExZjU5ZDEzNDqkZjg2YjBaOGYdN2VgZWFcOTYaT2FBaFBUekt6R3hzeDBPU2hO",
"cc_token_expiration": "2020-10-10T10:10:22",
"customer_id": "123",
"customer_phone": "+380999999999",
"fee": {
"amount": 136,
"currency": "UAH"
},
"percent_fee": {
"amount": 126,
"currency": "UAH"
},
"fixed_fee": {
"amount": 10,
"currency": "UAH"
},
"created_at": "2018-10-10T10:10:10.100",
"processed_at": "2018-10-10T10:10:22.100",
"processed_amount": 980,
"processed_currency": "UAH",
"payload": ""
}
The parameters of webhooks for secondary transactions vary based on the transaction type.
The parameters for webhooks of a Capture transaction are as follows:
Parameter | Type | Required | Description |
---|---|---|---|
operation_id | String | ✅ | Unique Tranzzo capture identifier |
payment_id | String | ✅ | Tranzzo payment identifier of primary operation |
order_id | String | ✅ | Merchant's order_id of primary operation |
transaction_id | String | Unique Tranzzo transaction identifier | |
pos_id | String | ✅ | Merchant's identifier (POS_ID ) |
mode | String | ✅ | direct |
method | String | ✅ | capture |
amount | Number | ✅ | Actual capture amount |
currency | String | ✅ | Transaction currency |
status | String | ✅ | Transaction status |
status_code | String | Tranzzo payment status code | |
status_description | String | Tranzzo payment status code description | |
fee | Object | Amount and currency of commission | |
created_at | String | ✅ | Timestamp when transaction was created |
processed_at | String | Timestamp when transaction was updated last time |
Example:
{
"operation_id": "edf7605c-99a8-43be-a1a5-2e96ebac8512",
"payment_id": "c4939398-1dad-4b92-1c34-7f6802379180",
"order_id": "123",
"transaction_id": "4f98dc46-ffff-4ba7-a267-286fe7669894",
"pos_id": "6eb070d5-7fbe-1176-9488-c152b60dd346",
"mode": "direct",
"method": "capture",
"amount": 100,
"currency": "UAH",
"status": "success",
"status_code": "1000",
"status_description": "Transaction is successful.",
"fee": {
"amount": 1.0,
"currency": "UAH"
},
"created_at": "2018-10-10T10:10:10.100",
"processed_at": "2018-10-10T10:10:12.000"
}
The parameters for webhooks of a Void transaction are as follows:
Parameter | Type | Required | Description |
---|---|---|---|
operation_id | String | ✅ | Unique Tranzzo void identifier |
payment_id | String | ✅ | Tranzzo payment identifier of primary operation |
order_id | String | ✅ | Merchant's order_id of primary operation |
transaction_id | String | Unique Tranzzo transaction identifier | |
pos_id | String | ✅ | Merchant's identifier (POS_ID ) |
mode | String | ✅ | direct |
method | String | ✅ | void |
amount | Number | ✅ | Actual void amount |
currency | String | ✅ | Transaction currency |
status | String | ✅ | Transaction status |
status_code | String | Tranzzo payment status code | |
status_description | String | Tranzzo payment status code description | |
fee | Object | Amount and currency of commission | |
created_at | String | ✅ | Timestamp when transaction was created |
processed_at | String | Timestamp when transaction was updated last time |
Example:
{
"operation_id": "edf7605c-99a8-43be-a1a5-2e96ebac8512",
"payment_id": "c4939398-1dad-4b92-1c34-7f6802379180",
"order_id": "123",
"transaction_id": "4f98dc46-ffff-4ba7-a267-286fe7669894",
"pos_id": "6eb070d5-7fbe-1176-9488-c152b60dd346",
"mode": "direct",
"method": "void",
"amount": 100,
"currency": "UAH",
"status": "success",
"status_code": "1000",
"status_description": "Transaction is successful.",
"fee": {
"amount": 1.0,
"currency": "UAH"
},
"created_at": "2018-10-10T10:10:10.100",
"processed_at": "2018-10-10T10:10:12.000"
}
The parameters for webhooks of a refund transaction are as follows:
Parameter | Type | Required | Description |
---|---|---|---|
operation_id | String | ✅ | Unique Tranzzo refund identifier |
payment_id | String | ✅ | Tranzzo payment identifier of primary operation |
order_id | String | ✅ | Merchant's order_id of primary operation |
transaction_id | String | Unique Tranzzo transaction identifier | |
pos_id | String | ✅ | Merchant's identifier (POS_ID ) |
mode | String | ✅ | direct |
method | String | ✅ | refund |
amount | Number | ✅ | Actual refund amount |
currency | String | ✅ | Transaction currency |
status | String | ✅ | Transaction status |
status_code | String | Tranzzo payment status code | |
status_description | String | Tranzzo payment status code description | |
fee | Object | Amount and currency of commission | |
created_at | String | ✅ | Timestamp when transaction was created |
processed_at | String | Timestamp when transaction was updated last time |
Example:
{
"operation_id": "edf7605c-99a8-43be-a1a5-2e96ebac8512",
"payment_id": "c4939398-1dad-4b92-1c34-7f6802379180",
"order_id": "123",
"transaction_id": "4f98dc46-ffff-4ba7-a267-286fe7669894",
"pos_id": "6eb070d5-7fbe-1176-9488-c152b60dd346",
"mode": "direct",
"method": "refund",
"amount": 100,
"currency": "UAH",
"status": "success",
"status_code": "1000",
"status_description": "Transaction is successful.",
"fee": {
"amount": 1.0,
"currency": "UAH"
},
"created_at": "2018-10-10T10:10:10.100",
"processed_at": "2018-10-10T10:10:12.000"
}
Re-sending webhooks for operations
Receiving a webhook notification multiple times for a specific transaction can be done by sending a request using the GET
HTTP method.
Request parameters:
Parameter | Type | Required | Description |
---|---|---|---|
POS_ID | UUID | ✅ | Merchant's identifier (POS_ID ) |
ORDER_ID | String | ✅ | Merchant's order identifier |
OPERATION | String | ✅ | Payment method, e.g. purchase , void , etc. |
Request example:
$ curl "https://cpay.tranzzo.com/api/v1/pos/${POS_ID}/orders/${ORDER_ID}/${OPERATION}?callback=true" \
-H "X-API-AUTH: CPAY ${API_KEY}:${API_SECRET}" \
-H "X-API-KEY: ${ENDPOINTS_KEY}"
Query parameters:
Parameter | Type | Required | Description |
---|---|---|---|
callback | Boolean | ✅ | true |
It's important to note that webhooks may include additional information beyond the parameters listed above. If you need to configure the transmission of these additional parameters or learn about what they are, please contact Tranzzo Support.
Re-sending webhooks for recurring payments
To receive a repeated webhook for recurring payments, send a GET
request to the /api/v1/pos/:posId/orders/:orderId/purchase?callback=true&transactionId=:paymentId
endpoint, where the posId
is an ID of merchant’s project, the orderId
is an order ID, and the transactionId
is an ID of a specific transaction.
Request example:
curl "https://cpay.tranzzo.com/api/v1/pos/${POS_ID}/orders/${ORDER_ID}/purchase?callback=true" \
-H "X-API-AUTH: CPAY ${API_KEY}:${API_SECRET}" \
-H "X-API-KEY: ${ENDPOINTS_KEY}"
Optional query parameters:
Parameter | Type | Required | Description |
---|---|---|---|
callback | Boolean | ✅ | true |
transactionId | String | An identifier for one of the transactions within the corresponding recurring payment |
If the request lacks the transactionId
query parameter, the response will provide information on the latest transaction associated with the corresponding subscription.
Request example for specific transaction:
curl "https://cpay.tranzzo.com/api/v1/pos/${POS_ID}/orders/${ORDER_ID}/purchase?callback=true&transactionId=${TRANSACTION_ID}" \
-H "X-API-AUTH: CPAY ${API_KEY}:${API_SECRET}" \
-H "X-API-KEY: ${ENDPOINTS_KEY}"
Response example:
{
"payment_id": "c4939398-1dad-4b92-1c34-7f6802379180",
"order_id": "111999991",
"gateway_order_id": "6320ac9a-aaaa-4912-adb3-5bca2dd560fe",
"billing_order_id": "123",
"transaction_id": "4f98dc46-ffff-4ba7-a267-286fe7669894",
"pos_id": "6eb070d5-7fbe-1176-9488-c152b60dd346",
"mode": "direct",
"method": "auth",
"amount": 0.28,
"currency": "UAH",
"payway": "privat24",
"eci": "7",
"status": "success",
"status_code": "1000",
"status_description": "Transaction is successful.",
"cc_mask": "424242******4242",
"cc_token": "N2U0ZWExZjU5ZDEzNDqkZjg2YjBaOGYdN2VgZWFcOTYaT2FBaFBUekt6R3hzeDBPU2hO",
"cc_token_expiration": "2020-10-10T10:10:22",
"customer_id": "123",
"customer_phone": "+380999999999",
"fee": {
"amount": 1.0,
"currency": "UAH"
},
"created_at": "2018-10-10T10:10:10.100",
"processed_at": "2018-10-10T10:10:22.100",
"payload": "",
"recurring": {
"id": "n9W9kyytX2q62jBg7fu7V",
"status": "active"
}
}