Webhooks
Whenever a payout is initiated, we update the merchant on the status of the transaction with the help of webhooks. Our on boarding team will share the IP Address from which webhook calls will be made to the merchants endpoints. We advice the merchant to whitelist only these IP Addresses from which legitimate calls from Zamp will be delivered.
IP Addresses to be whitelisted by merchants
- Stage Env: 34.87.148.68
- Prod Env: 35.240.227.82
Once the merchant recevies the webhook call, we first request the merchant to validate if the call is truly made by Zamp. In order to validate that, we request you to extract the header key X-ZAMP-Signature and validate against the logic below. The message consists of comma seperated string with values id, status of payoutSession The result of the code block below and the value present in the X-ZAMP-Signature key should match.
const message = "merchant_uNR5Kc6a2zTdfqbLsDwxUZ_06_15,initiated;
const sha_message = CryptoJS.SHA256(`${message}:${ZAMP_SECRET}`);
const x_zamp_signature = CryptoJS.enc.Base64.stringify(sha_message);
Request Body : The request body will consist of the transaction_type and transaction_id. The data passed on the request body will be same as that particular transaction type's GET API.
For example, if the transaction is of type payout_session, the response in the data parameter will the same result of API GET https://api.zamplabs.com/api/v1/transfer/payouts/{payouts-session-id}.
Key | Value | Description |
---|---|---|
transaction_type | String | Type of entity for which webhook is sent |
transaction_id | String | Unique Id of the entity for which webhook is sent |
id | String | Unique Id of the entity for which webhook is sent (Same as transaction_id) |
reference_id | String | Customer reference Id, sent while executing the payout |
status | String | Payout status |
merchant_id | String | Merchant Id to which the payout belongs |
quote_id | String | Quote Id of the quote created for the payout |
corridor_id | String | Corridor Id (Source to destination currency mapping id |
source_currency_code | String | Source Account Currency Code |
destination_currency_code | String | Destination Currency Code |
beneficiary_id | String | Beneficiary Id of the Beneficiary to whom payout is made |
source_amount | Float | Source Amount in Source Currency |
receiving_amount | Float | Receiving amount in destination currency code |
exchange_rate | Float | Exchange rate from source to source currency at the time when quote was created |
total_fees | Float | Total fees charged for that transaction |
fixed_cost_currency | String | Currency code in which fees will be deducted |
unique_transaction_reference | String | Unique transaction reference. It is the transaction hash in case of Crypto payout and Bank reference Id in case of fiat payout |
created_at | time stamp | payout created time stamp |
updated_at | time stamp | payout updated time stamp |
For example, if the transaction is of type payout_session, the response in the data parameter will the same result of API GET https://api.zamplabs.com/transfer/v1/payouts/{payouts-session-id}.
- Succeeded Payout
{
"transaction_type": "payout_session",
"transaction_id": "iihr42_z9oFU3w5EQEtiZbVspr7WP_06_02",
"data": {
"id": "iihr42_z9oFU3w5EQEtiZbVspr7WP_06_02",
"reference_id": "ref_098fe343",
"status": "succeeded",
"merchant_id": "iihr42_2pyNY8ZxjZGLbU7i2HzNDf_04_03",
"quote_id": "iihr42_HVLTQgQJTSahdqSmSXrHeF_06_02",
"corridor_id": "iihr42_Vm6YbkiPJjuNySeoRdoBp8_05_17",
"source_currency_code": "USD",
"destination_currency_code": "USD",
"beneficiary_id": "iihr42_B9XkvSN47U9kW3UDZKVDcg_05_17",
"source_amount": 100.00,
"receiving_amount": 99.50,
"exchange_rate": 1,
"total_fees": 0.5,
"fixed_cost_currency":"USD",
"unique_transaction_reference": "4JLXHTvmYWy36CY51dCDYs1FjiTgcQys9eJabHPb27NofwZWmjKwXQD9akwWPJ6Z65n91Zue96txr5SQRWXP86kY",
"created_at": "2023-06-02T07:19:48.351663Z",
"updated_at": "2023-06-02T07:21:13.398543Z"
}
}
- Failed Payout
{
"transaction_type": "payout_session",
"transaction_id": "iihr42_z9oFU3w5EQEtiZbVspr7WP_06_02",
"data": {
"id": "iihr42_z9oFU3w5EQEtiZbVspr7WP_06_02",
"reference_id": "ref_098fe343",
"status": "failed",
"merchant_id": "iihr42_2pyNY8ZxjZGLbU7i2HzNDf_04_03",
"quote_id": "iihr42_HVLTQgQJTSahdqSmSXrHeF_06_02",
"corridor_id": "iihr42_Vm6YbkiPJjuNySeoRdoBp8_05_17",
"source_currency_code": "USD",
"destination_currency_code": "USD",
"beneficiary_id": "iihr42_B9XkvSN47U9kW3UDZKVDcg_05_17",
"source_amount": 100.00,
"receiving_amount": 99.50,
"exchange_rate": 1,
"total_fees": 0.5,
"fixed_cost_currency":"USD",
"unique_transaction_reference": "",
"created_at": "2023-06-02T07:19:48.351663Z",
"updated_at": "2023-06-02T07:21:13.398543Z"
}
}
Expected Response, Retries
We expect the merchant to return a HTTP 200 OK status in case they have received the message. In the absence of a HTTP 200 OK response, Zamp will retry the webook with backoff exponential logic with a doubling delay. Retries will be done for a maximum of 24 hours.