Webhooks are server callbacks to your server from Cashfree. Webhooks are event-based and are sent when specific events related to the transaction happen.

Configure Webhook

  1. Add your webhook through the merchant dashboard for the first time. Write to [email protected] to edit your Webhook endpoint.
  2. Ensure you do not process duplicate events.
  3. Below is the list of events for which we will be notifying on your webhook and a list of parameters being sent.

We support webhooks in both encoded and JSON formats.

Amount Collected

The AMOUNT_COLLECTED webhook notifies that money has been received in your Cashfree Virtual account through Auto Collect.

Webhook parameters and descriptions are available below:

ParameterDescription
eventIt contains the name of the event which just occurred. Value = AMOUNT_COLLECTED.
amountSpecifies the amount collected.
vAccountIdThe virtual account ID of the customer who made the payment.
virtualVpaIdThe virtual account ID of the customer who made the payment (if received via VPA).
isVpaValue is 1 if the amount is paid via VPA transfer.
vAccountNumberThe virtual bank account number (if received to Virtual Bank Account).
referenceIdThe reference number generated by Cashfree to track the transaction.
utrUnique transaction reference number provided by the bank.
remitterVpaPayer's VPA details in case of UPI transactions.
emailCustomer email address.
phoneCustomer phone number.
creditRefNoReference number generated by the bank.
remitterAccountPayer's bank account number.
remitterNamePayer's name.
paymentTimeTime at which the payment was made.
signatureA unique string that helps distinguish that the request is genuine and initiated by Cashfree.
transferType(Applicable from Feb 4th, 2022)

Indicates the mode through which the transaction was made to your Auto Collect Virtual account, such as NEFT, RTGS, UPI, or IMPS.
remarks(Applicable from Feb 4th, 2022)

Remarks that the customer enters when the transaction is initiated.

📘

Note:

With effect from Feb 4, 2022, we will be adding two new parameters to the ‘Amount Collected’ Webhook i.e ‘transferType’ and ‘remarks.’
transferType’ will notify the mode through which the transaction was made to your Auto Collect Virtual account, such as NEFT, RTGS, UPI, or IMPS.
remarks’ will be the remarks that the customer passes when the transaction is initiated.


Transfer Rejected

The TRANSFER_REJECTED webhook notifies that the transfer request was received, but has been rejected due to some reason (mentioned in the field reason).

ParameterDescription
eventIt contains the name of the event which just occurred.
Value = TRANSFER_REJECTED.
amountSpecifies the amount collected.
vAccountIdThe virtual account ID of the customer who made the payment.
rejectIdThe transfer rejected transaction ID.
utrUnique transaction reference number provided by the bank.
remitterAccountPayer's bank account number.
transferTimeTime at which the transfer was made.
reasonSpecifies the reason for rejecting the transfer.
signatureA unique string which helps distinguish that the request is genuine and initiated by Cashfree.

Amount Settled

The AMOUNT_SETTLED webhook notifies that the settlement has been made.

ParameterDescription
eventIt contains the name of the event which just occurred.
Value = AMOUNT_SETTLED.
amountSpecifies the amount settled.
(SettlementAmount + adjustment = amount)
countNo. of transactions that are settled.
utrUnique transaction reference number provided by the bank.
settlementIdReference number of the settlement made.
settlementAmountThe settlement amount will be the total transaction amount minus the service charges and taxes.
adjustmentThe differential amount that was deducted or added in the current settlement cycle.
(SettlementAmount + adjustment = amount)
signatureA unique string that helps distinguish that the request is genuine and initiated by Cashfree.

Example - AMOUNT_COLLECTED webhook

{
    "event":"AMOUNT_COLLECTED",
    "amount":"400",
    "vAccountId":"abcd123",
    "virtualVpaId":"[email protected]",
    "isVpa":"1",
    "email":"[email protected]",
    "phone":"9876543210",
    "referenceId":87654,
    "utr":"N123456789",
    "creditRefNo":"0976541123",
    "remitterAccount":"123455666778",
    "remitterName":"CASHFREE PAYMENTS",
    "paymentTime":"2019-07-20 15:27:37",
    "signature":"8uV792gBZaasJHBFSsfaMHLuqnZKkoBFjw9gEJ8Sx85V+jgbpg4ME="
}

Refunds

For refunds, we support the following three webhooks:

Refund Success

The REFUND_SUCCESS webhook notifies whenever a refund attempted is successful at the bank (the account is debited), and the beneficiary bank has deposited the money and confirmed it.

Webhook parameters and descriptions are available below:

ParameterDescription
eventIt contains the name of the event which just occurred. Value = REFUND_SUCCESS.
cacRefundIdThe Refund ID that Cashfree Autocollect generated and shared with the merchant during the creation of the refund.
referenceIdThe reference number provided by Cashfree Payments for the transaction.
amountSpecifies the refund amount
noteNote that the merchant enters when the refund is initiated.
merchantRefIdMerchantRefId that the merchant enters when the refund is initiated.
refundUtrUnique transaction reference number provided by the bank.
refundStatusStatus of the refund. Possible statuses are:

- ACKNOWLEDGED
- PROCESSING
- SUCCESS
- FAILED
- REVERSED
createdAtTime at which the refund was initiated.
updatedAtTime of the last update
refundRemarks-
fundStatusDEBITED_FROM_MERCHANT
signatureA unique string that helps distinguish that the request is genuine and initiated by Cashfree Payments.

Refund Failed

The REFUND_FAILED webhook notifies whenever a refund attempt fails.
Webhook parameters and descriptions are available below:

ParameterDescription
eventIt contains the name of the event which just occurred. Value = REFUND_FAILED.
cacRefundIdThe Refund ID that Cashfree Autocollect generated and shared with the merchant during the creation of the refund.
referenceIdThe reference number provided by Cashfree Payments for the transaction.
amountSpecifies the refund amount
noteNote that the merchant enters when the refund is initiated.
merchantRefIdMerchantRefId that the merchant enters when the refund is initiated.
refundUtrUnique transaction reference number provided by the bank.
refundStatusStatus of the refund. Possible statuses are:

- ACKNOWLEDGED
- PROCESSING
- SUCCESS
- FAILED
- REVERSED
createdAtTime at which the refund was initiated.
updatedAtTime of the last update
refundRemarksReason for failure
fundStatusRETURNED_TO_MERCHANT
signatureA unique string that helps distinguish that the request is genuine and initiated by Cashfree Payments.

Refund Reversed

The REFUND_REVERSED webhook notifies whenever the beneficiary bank reverses the refund.

Webhook parameters and descriptions are available below:

ParameterDescription
eventIt contains the name of the event which just occurred. Value = REFUND_REVERSED.
cacRefundIdThe Refund ID that Cashfree Autocollect generated and shared with the merchant during the creation of the refund.
referenceIdThe reference number provided by Cashfree Payments for the transaction.
amountSpecifies the refund amount
noteNote that the merchant enters when the refund is initiated.
merchantRefIdMerchantRefId that the merchant enters when the refund is initiated.
refundUtrUnique transaction reference number provided by the bank.
refundStatusStatus of the refund. Possible statuses are:

- ACKNOWLEDGED
- PROCESSING
- SUCCESS
- FAILED
- REVERSED
createdAtTime at which the refund was initiated.
updatedAtTime of the last update
refundRemarksReason for reversal.
fundStatusRETURNED_TO_MERCHANT
signatureA unique string that helps distinguish that the request is genuine and initiated by Cashfree Payments.

Webhook Sample

{
   "amount": "250.12",
   "referenceId": "100",
   "cacRefundId": "98",
   "createdAt": "2022-03-13 22:30:38",
   "event": "REFUND_SUCCESS",
   "fundStatus": "CREDITED_TO_CUSTOMER",
   "merchantRefId": "test100",
   "note": "test",
   "refundRemarks": "Transfer completed successfully",
   "refundStatus": "SUCCESS",
   "refundUtr": "1647190899292747",
   "signature": "1WP7Pm5CQ1XpLLO+0zups2E6ae/VyMq4MMPAWpC8syE=",
   "updatedAt": "2022-03-13 22:31:39"
}

Vendor Settlement

The VENDOR_SETTLEMENT_WEBHOOK notifies when a settlement has been made to the vendor.

ParameterDescription
vendorRefIdUnique reference ID of the vendor.
signatureA unique string that helps distinguish that the request is genuine and initiated by Cashfree Payments.
amountThe aggregated amount in the settlement time period.
(SettlementAmount + adjustment = amount)
adjustmentAny debit or credit amount due to pending ledger balance or any other adjustment.
(SettlementAmount + adjustment = amount)
settlementAmountSum of the net settlement amount for the payments part of this settlement.
vendorSettlementRefIdUnique reference ID for the vendor settlement.
utrUnique transaction reference number provided by the bank.
countNumber of payments considered in the settlement.
eventIt contains the name of the event which just occurred.
Value = VENDOR_SETTLEMENT_WEBHOOK.

Verify Signature

Verifying the signature (passed along with the POST parameters) is mandatory before you process any response. We also recommend whitelisting only our IP address on your webhook endpoint.

Follow the steps below to calculate and verify the signature passed:

  1. Get all the POST parameters except ‘signature’ and assign it to an array as key-value pair.
  2. Sort the array based on keys.
  3. Concatenate all the values in this array and the resultant is the post data (say, postData).
  4. postData needs to be encrypted using SHA-256 and then base64 encoded.
  5. Now verify if the signature calculated and the signature received a match. Proceed further if it matches.

Do not go live without verifying the signature.

The following code snippets show you how to generate and verify the signature. This should not be assumed production-ready, kindly consider adding necessary validation before processing.

$data = $_POST;
  $signature = $_POST["signature"];
  unset($data["signature"]);
  // $data now has all the POST parameters except signature
  ksort($data);  // Sort the $data array based on keys
  $postData = "";
  
  foreach ($data as $key => $value){
    if (strlen($value) > 0) {
      $postData .= $value;
    }
  }
  $hash_hmac = hash_hmac('sha256', $postData, $clientSecret, true) ;
  // Use the clientSecret from the oldest active Key Pair.
  $computedSignature = base64_encode($hash_hmac);
  if ($signature == $computedSignature) {
    // Proceed based on $event 
  } else {
    // Reject this call 
  }
?>
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;
import org.apache.commons.codec.binary.Base64;
public class ComputedSignature {
    public static String generateHMAC(String clientSecret, String data) {
        String hash = null; //data is a string which has the json sorted through keys and concatenated values
        try {
            String secret = clientSecret;
            String message = data;
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(),"HmacSHA256");
            sha256_HMAC.init(secret_key);
            hash = Base64.encodeBase64String(sha256_HMAC.doFinal(message.getBytes()));
        }
        catch (Exception e){ //Log it
        }
        return hash;
    }
}