Skip to main content

Webhooks

Introduction

As soon as Customer initiates a deposit, Cashier will send a Notification Webhook to Merchant system.

Optionally, the Merchant can receive real-time notifications of transaction status changes via the Notification API. For that purpose, Merchant has to implement the Notification API on their end.

Cashier uses the Notification endpoint to notify Merchants about the result of payment processing.

When the Notification is sent to the Merchant’s URL, Cashier expects the Merchant’s server to respond with Status code 200 – OK. After that, the Notification is considered as successfully sent.

Notification retry policy

If the Notification is not successfully sent (does not receive HTTP 200 back), Cashier records the status of the transaction notification as In Retry and the Cashier attempts to resend the notification every 60, 120, 300, 3600, 14400 and 43200 seconds.

If it fails to send the notification in each retry attempt, Cashier stops attempting to resend the notification.

Signature verification

Every webhook request we send includes an HTTP header:

Signature: <hash>

This signature allows you to verify that the message really comes from our system and that its content hasn’t been modified during transmission.

To verify signature, you need to generate one using the instruction provided below.

Step 1. Get your API key

Each Merchant has their own API key that is used as a secret when generating the signature. You will receive this Merchant API key from our side.

For the purpose of this example, we’ll use the following API key:

secret12345

Step 2. Receive notification

Let’s say you receive the following notification:

{
"transactionId": "f7c26f04-39e6-4ad7-b5a2-a5e28e4a4071",
"relatedTransactionId": null,
"amount": 10000,
"currency": "USD",
"amountUSD": 10000,
"status": "SUCCESS",
"errors": [],
"transactionDate": "2025-02-11T10:03:24.844036+00:00",
"transactionType": "deposit",
"externalTransactionId": "67ab206d07598",
"originTransactionId": null,
"brandName": "Phantom360",
"customerID": "4",
"accountID": "94e0c2d3-bfc6-4188-8bad-9351a6008a5c",
"ip": "2a09:bac0:1000:645::84:8e",
"fakeIp": null,
"source": "WEB",
"paymentType": "CREDIT_CARD",
"processorName": "PHANTOM_2D",
"processorPaymentMethod": "Credit Card",
"midType": null,
"cardType": "MASTERCARD",
"cardBin": "507860",
"cardLast4Digits": "3448",
"cardExpMonth": "12",
"cardExpYear": "2036",
"bankName": "BANCO BNP PARIBAS BRASIL S.A.",
"ccType": "credit",
"ccLevel": null,
"convertedAmount": 10000,
"convertedCurrency": "USD",
"marketRate": 1,
"markUpDown": 100,
"exchangeRate": 1,
"depositCurrencyToUSDMarketRate": 1,
"depositCurrencyToEUROMarketRate": 0.9692,
"convertedCurrencyToUSDMarketRate": 1,
"convertedCurrencyToEUROMarketRate": 0.9692,
"publicTitle": null,
"userAgent": "Chrome 133.0 - desktop",
"binCountry": "BR",
"variable1": null,
"variable2": null,
"variable3": null,
"receivedAmount": 10000,
"receivedCurrency": "USD",
"depositedAmount": 10000,
"depositedCurrency": "USD"
}

Step 3. Generate the signature

Take the raw request body exactly as it is sent (no formatting changes, no extra spaces) and create a hash using the HMAC SHA-256 algorithm, where the API key is used as the secret.

Example in PHP:

<?php

// Your Merchant API key (used as the HMAC secret)
$apiKey = 'secret12345';

// The raw JSON body of the webhook notification
$requestBody = '{
"transactionId":"f7c26f04-39e6-4ad7-b5a2-a5e28e4a4071",
"relatedTransactionId":null,
"amount":10000,
"currency":"USD",
"amountUSD":10000,
"status":"SUCCESS",
"errors":[],
"transactionDate":"2025-02-11T10:03:24.844036+00:00",
"transactionType":"deposit",
"externalTransactionId":"67ab206d07598",
"originTransactionId":null,
"brandName":"Phantom360",
"customerID":"4",
"accountID":"94e0c2d3-bfc6-4188-8bad-9351a6008a5c",
"ip":"2a09:bac0:1000:645::84:8e",
"fakeIp":null,
"source":"WEB",
"paymentType":"CREDIT_CARD",
"processorName":"PHANTOM_2D",
"processorPaymentMethod":"Credit Card",
"midType":null,
"cardType":"MASTERCARD",
"cardBin":"507860",
"cardLast4Digits":"3448",
"cardExpMonth":"12",
"cardExpYear":"2036",
"bankName":"BANCO BNP PARIBAS BRASIL S.A.",
"ccType":"credit",
"ccLevel":null,
"convertedAmount":10000,
"convertedCurrency":"USD",
"marketRate":1,
"markUpDown":100,
"exchangeRate":1,
"depositCurrencyToUSDMarketRate":1,
"depositCurrencyToEUROMarketRate":0.9692,
"convertedCurrencyToUSDMarketRate":1,
"convertedCurrencyToEUROMarketRate":0.9692,
"publicTitle":null,
"userAgent":"Chrome 133.0 - desktop",
"binCountry":"BR",
"variable1":null,
"variable2":null,
"variable3":null,
"receivedAmount":10000,
"receivedCurrency":"USD",
"depositedAmount":10000,
"depositedCurrency":"USD"
}';

// Generate the signature
$signature = hash_hmac('sha256', $requestBody, $apiKey);

// Print the generated hash
echo "Signature: " . $signature . PHP_EOL;

Example output:

Signature: 9b5a83bb341a999f73a44c020a3f363ffec17d354f5f30210b7c913702ed98cf

How to verify the signature on your side

When your system receives a webhook:

  1. Read the raw request body exactly as received (don’t JSON-decode it).
  2. Generate your own signature using the algorithm described above.
  3. Compare it with the Signature header from the request.

If the two signatures match — the webhook is authentic.

Deposit event

URL: Merchant API Notification URL (value passed as notification_url in payment init request)

HTTP Method: POST

Headers:

  • Content-type: application/json
  • Signature: <signature>

Request fields:

NameTypeSize/FormatMandatoryDescription
customer_idstringChar (100)trueCustomer unique identifier
transaction_idstringUUIDtrueTransaction unique identifier
currencystringChar (3)/ISO currency code: wikitrueOriginal transaction currency of deposit requested by merchant
amountintIn minor units: wikitrueOriginal transaction amount requested by Merchant
amount_usdintIn minor units: wikitrueUSD equivalent of Original Amount
statusstringenumtrueTransaction status. Possible values: PENDING, SUCCESS, FAILED, AUTHORIZED
errorsArray of JSON objectsExample: errors: [ { {'code' : "INVALID", 'message': "Invalid transaction"}, {'code' : "INVALID2", 'message': "Invalid transaction2"}falseFailed reasons. Only for failed transactions
brand_namestringChar (60)/Latin chars with no spacestrueMerchant name provided as part of credentials
transaction_datestringDATETIME Example: "2020-09-25 07:17:39.821057"falseTransaction date
payment_typestringenumfalsePossible values: CREDIT_CARD, APM
processor_namestringChar (64)falsePayment Provider Company name. PSP/APM name defined by Cashier
processor_payment_methodstringChar (64) Example: IDeal, QiwifalsePayment Provider name. PSP/APM name defined by Merchant
card_typestringChar (30)falseCard type such as "Visa" or "Mastercard"
cc_typestringChar (255)falseCard type, such as credit, debit, corporate
cc_levelstringChar (255)falseCard type such as "GOLD" or "PLATINUM"
card_binstringChar (8)falseFirst 8 digits of Credit Card
card_last4_digitsstringChar (4)falseLast 4 digits of Credit Card
card_exp_monthstringChar (2)falseCredit Card Expiry Month
card_exp_yearstringChar (4)falseCredit Card Expiry Year
bank_namestringChar (255)falseCustomer’s bank name
account_idstringUUIDfalseMerchant ID of merchant in Cashier System. Provided by Cashier Customer Support Team
external_transaction_idstringChar (255)falsePSP/APM's transaction ID number
transaction_typestringenumfalsePossible values: "deposit", "refund"
ipstringIPv4 | IPv6falseCustomer's IP Address
sourcestringenumfalseSource of the transaction. Possible values: "MOBILE_WEB", "MOBILE_APP", "WEB"
deposit_currency_to_usd_market_ratenumericWith 4 places in decimal partfalseMarket rate between deposit currency and USD
deposit_currency_to_euro_market_ratenumericWith 4 places in decimal partfalseMarket rate between deposit currency and EUR
converted_currency_to_euro_market_ratenumericWith 4 places in decimal partfalseMarket rate between converted currency and EUR
converted_currency_to_usd_market_ratenumericWith 4 places in decimal partfalseMarket rate between converted currency and USD
converted_currencystringChar (3)/Currency ISO codefalseCurrency of deposit accepted by Payment provider
converted_amountintIn minor unitsfalseConverted amount of the deposit in converted currency (including configured markUp/Down) to be send to Provider
market_ratenumericWith 4 places in decimal partfalseMarket rate between converted currency and original deposit currency
mark_up_downintfalseMerchant’s markUp/Down impacts exchange rate from Original to Converted currency
exchange_ratenumericWith 4 places in decimal partfalseFinal exchange rate used to convert from original to converted currency Example: Market rate: 1.0 MarkUpDown: 105% ExchangeRate will be 1.05
public_titlestringChar (255)falseDisplayed name of APM payment method
user_agentstringChar (255)falseBrowser of the Customer
bin_countrystringChar (2)/ISO2 Country codefalseCustomer’s card bank country
received_amountintIn minor unitsfalseAmount , actually paid by the customer in converted currency
received_currencystringChar (3)/ISO currency code: wikifalseReceived currency
deposited_amountintIn minor unitsfalseFinal amount which will be deposited to the customer’s account in Original deposit currency
deposited_currencystringChar (3)/ISO currency code: wikifalseDeposited currency
variable1stringChar (256)falseCustom variable forwarded from Deposit page to Merchant system via Notifications Webhooks
variable2stringChar (256)falseCustom variable forwarded from Deposit page to Merchant system via Notifications Webhooks
variable3stringChar (256)falseCustom variable forwarded from Deposit page to Merchant system via Notifications Webhooks
related_transaction_idstringFormat: UUIDfalseParent original deposit transaction identifier. Applicable for refunds
origin_transaction_idstringChar (50)falseMerchant’s internal transaction id

SUCCESS Deposit. Notification body example:

{
"transaction_id": "f7c26f04-39e6-4ad7-b5a2-a5e28e4a4071",
"related_transaction_id": null,
"amount": 10000,
"currency": "USD",
"amount_usd": 10000,
"status": "SUCCESS",
"errors": [],
"transaction_date": "2025-02-11T10:03:24.844036+00:00",
"transaction_type": "deposit",
"external_transaction_id": "67ab206d07598",
"origin_transaction_id": null,
"brand_name": "Phantom360",
"customer_id": "4",
"account_id": "94e0c2d3-bfc6-4188-8bad-9351a6008a5c",
"ip": "2a09:bac0:1000:645::84:8e",
"fake_ip": null,
"source": "WEB",
"payment_type": "CREDIT_CARD",
"processor_name": "PHANTOM_2D",
"processor_payment_method": "Credit Card",
"mid_type": null,
"card_type": "MASTERCARD",
"card_bin": "507860",
"card_last4_digits": "3448",
"card_exp_month": "12",
"card_exp_year": "2036",
"bank_name": "BANCO BNP PARIBAS BRASIL S.A.",
"cc_type": "credit",
"cc_level": null,
"converted_amount": 10000,
"converted_currency": "USD",
"market_rate": 1,
"mark_up_down": 100,
"exchange_rate": 1,
"deposit_currency_to_usd_market_rate": 1,
"deposit_currency_to_euro_market_rate": 0.9692,
"converted_currency_to_usd_market_rate": 1,
"converted_currency_to_euro_market_rate": 0.9692,
"public_title": null,
"user_agent": "Chrome 133.0 - desktop",
"bin_country": "BR",
"variable1": null,
"variable2": null,
"variable3": null,
"received_amount": 10000,
"received_currency": "USD",
"deposited_amount": 10000,
"deposited_currency": "USD"
}

Refund event

URL: Merchant API Notification URL (value passed as notification_url in payment init request)

HTTP Method POST

Headers:

  • Content-type: application/json
  • Signature: <signature>

Request fields:

NameTypeSize/FormatMandatoryDescription
customer_idstringChar (100)trueCustomer unique identifier
transaction_idstringUUIDtrueTransaction unique identifier
currencystringChar (3)/ISO currency code: wikitrueOriginal transaction currency of deposit requested by merchant
amountintIn minor units: wikitrueOriginal transaction amount requested by Merchant
amount_usdintIn minor units: wikitrueUSD equivalent of Original Amount
statusstringenumtrueTransaction status. Possible values: PENDING, SUCCESS, FAILED, AUTHORIZED
errorsArray of JSON objectsExample: errors: [ { {'code' : "INVALID", 'message': "Invalid transaction"}, {'code' : "INVALID2", 'message': "Invalid transaction2"}falseFailed reasons. Only for failed transactions
brand_namestringChar (60)/Latin chars with no spacestrueMerchant name provided as part of credentials
transaction_datestringDATETIME Example: "2020-09-25 07:17:39.821057"falseTransaction date
payment_typestringenumfalsePossible values: CREDIT_CARD, APM
processor_namestringChar (64)falsePayment Provider Company name. PSP/APM name defined by Cashier
processor_payment_methodstringChar (64) Example: IDeal, QiwifalsePayment Provider name. PSP/APM name defined by Merchant
card_typestringChar (30)falseCard type such as "Visa" or "Mastercard"
cc_typestringChar (255)falseCard type, such as credit, debit, corporate
cc_levelstringChar (255)falseCard type such as "GOLD" or "PLATINUM"
card_binstringChar (8)falseFirst 8 digits of Credit Card
card_last4_digitsstringChar (4)falseLast 4 digits of Credit Card
card_exp_monthstringChar (2)falseCredit Card Expiry Month
card_exp_yearstringChar (4)falseCredit Card Expiry Year
bank_namestringChar (255)falseCustomer’s bank name
account_idstringUUIDfalseMerchant ID of merchant in Cashier System. Provided by Cashier Customer Support Team
external_transaction_idstringChar (255)falsePSP/APM's transaction ID number
transaction_typestringenumfalsePossible values: "deposit", "refund"
ipstringIPv4 | IPv6falseCustomer's IP Address
sourcestringenumfalseSource of the transaction. Possible values: "MOBILE_WEB", "MOBILE_APP", "WEB"
deposit_currency_to_usd_market_ratenumericWith 4 places in decimal partfalseMarket rate between deposit currency and USD
deposit_currency_to_euro_market_ratenumericWith 4 places in decimal partfalseMarket rate between deposit currency and EUR
converted_currency_to_euro_market_ratenumericWith 4 places in decimal partfalseMarket rate between converted currency and EUR
converted_currency_to_usd_market_ratenumericWith 4 places in decimal partfalseMarket rate between converted currency and USD
converted_currencystringChar 3)/Currency ISO codefalseCurrency of deposit accepted by Payment provider
converted_amountintIn minor unitsfalseConverted amount of the deposit in converted currency (including configured markUp/Down) to be send to Provider
market_ratenumericWith 4 places in decimal partfalseMarket rate between converted currency and original deposit currency
mark_up_downintfalseMerchant’s markUp/Down impacts exchange rate from Original to Converted currency
exchange_ratenumericWith 4 places in decimal partfalseFinal exchange rate used to convert from original to converted currency Example: Market rate: 1.0 MarkUpDown: 105% ExchangeRate will be 1.05
public_titlestringChar (255)falseDisplayed name of APM payment method
user_agentstringChar (255)falseBrowser of the Customer
bin_countrystringChar (2)/ISO2 Country codefalseCustomer’s card bank country
received_amountintIn minor unitsfalseAmount, actually paid by the customer in converted currency
received_currencystringChar (3)/ISO currency code: wikifalseReceived currency
deposited_amountintIn minor unitsfalseFinal amount which will be deposited to the customer’s account in Original deposit currency
deposited_currencystringChar (3)/ISO currency code: wikifalseDeposited currency
variable1stringChar (256)falseCustom variable forwarded from Deposit page to Merchant system via Notifications Webhooks
variable2stringChar (256)falseCustom variable forwarded from Deposit page to Merchant system via Notifications Webhooks
variable3stringChar (256)falseCustom variable forwarded from Deposit page to Merchant system via Notifications Webhooks
related_transaction_idstringFormat: UUIDfalseParent original deposit transaction identifier. Applicable for refunds
origin_transaction_idstringChar (50)falseMerchant’s internal transaction id. Applicable for refunds

SUCCESS Refund. Notification body example:

{
"transaction_id": "9540d2c1-3f79-4e24-9d39-250f9385389f",
"related_transaction_id": "65839fd4-946b-4097-b4f5-240d3c9c7acb",
"amount": 1288,
"currency": "USD",
"amount_usd": 1288,
"status": "SUCCESS",
"errors": [],
"transaction_date": "2025-04-10T08:36:03.291840+00:00",
"transaction_type": "refund",
"external_transaction_id": "payment_cb01f9e7630c10af159d2622851ceb68",
"origin_transaction_id": null,
"brand_name": "brand",
"customer_id": "185309",
"account_id": "21e84c6c-5e5d-4686-b9d0-3426e99181b1",
"ip": "2a09:bac0:1000:645::84:59",
"fake_ip": null,
"source": "WEB",
"payment_type": "CREDIT_CARD",
"processor_name": "Phantom",
"processor_payment_method": "Credit Card",
"mid_type": null,
"card_type": "MASTERCARD",
"card_bin": "424242",
"card_last4_digits": "4242",
"card_exp_month": "11",
"card_exp_year": "2032",
"bank_name": "STOCK COMMERCIAL BANK",
"cc_type": "debit",
"cc_level": null,
"converted_amount": 1000,
"converted_currency": "GBP",
"market_rate": 0.7766,
"mark_up_down": 100,
"exchange_rate": 0.7766,
"sca": null,
"deposit_currency_to_usd_market_rate": 1,
"deposit_currency_to_euro_market_rate": 0.9069,
"converted_currency_to_usd_market_rate": 1.2877,
"converted_currency_to_euro_market_rate": 1.1678,
"public_title": null,
"user_agent": null,
"bin_country": null,
"variable1": null,
"variable2": null,
"variable3": null,
"received_amount": null,
"received_currency": null,
"deposited_amount": null,
"deposited_currency": null
}