Skip to main content

Webhooks

Whenever a payout is initiated, we update the merchant on the status of the transaction with the help of webhooks. Our onboarding team will share the IP address from which webhook calls will be made to the merchant endpoints. We advise the merchant to whitelist only these IP addresses from which legitimate calls from Zamp will be delivered.


IP addresses to whitelist

EnvironmentIP address
Stage34.87.148.68
Prod35.240.227.82

Signature validation

Once the merchant receives the webhook call, we first request the merchant to validate if the call is truly made by Zamp. To validate, extract the header key X-ZAMP-Signature and validate against the logic below. The message consists of a comma-separated string with values id and status of payoutSession. The result of the code block below and the value present in the X-ZAMP-Signature header 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 consists of transaction_type and transaction_id. The data passed in the request body is the 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 is the same result as API GET https://api.zamplabs.com/api/v1/transfer/payouts/{payouts-session-id}.

FieldTypeDescription
transaction_typeStringType of entity for which the webhook is sent.
transaction_idStringUnique ID of the entity for which the webhook is sent.
idStringUnique ID of the entity for which the webhook is sent (same as transaction_id).
reference_idStringCustomer reference ID sent while executing the payout.
statusStringPayout status.
merchant_idStringMerchant ID to which the payout belongs.
quote_idStringQuote ID of the quote created for the payout.
corridor_idStringCorridor ID (source to destination currency mapping ID).
source_currency_codeStringSource account currency code.
destination_currency_codeStringDestination currency code.
beneficiary_idStringBeneficiary ID of the beneficiary to whom the payout is made.
source_amountFloatSource amount in source currency.
receiving_amountFloatReceiving amount in destination currency code.
exchange_rateFloatExchange rate from source to destination currency at the time when the quote was created.
total_feesFloatTotal fees charged for that transaction.
fixed_cost_currencyStringCurrency code in which fees are deducted.
unique_transaction_referenceStringUnique transaction reference. Transaction hash for crypto payout and bank reference ID for fiat payout.
created_atTimestampPayout created timestamp.
updated_atTimestampPayout updated timestamp.

For example, if the transaction is of type payout_session, the response in the data parameter is the same result as API GET https://api.zamplabs.com/transfer/v1/payouts/{payouts-session-id}.


Example payloads

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 and retries

We expect the merchant to return an HTTP 200 OK status when the message has been received. In the absence of an HTTP 200 OK response, Zamp retries the webhook with exponential backoff and doubling delay. Retries continue for a maximum of 24 hours.