Webhooks

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:

Parameter

Description

event

It contains the name of the event which just occurred. Value = AMOUNT_COLLECTED.

amount

Specifies the amount collected.

vAccountId

The virtual account ID of the customer who made the payment.

virtualVpaId

The virtual account ID of the customer who made the payment (if received via VPA).

isVpa

Value is 1 if the amount is paid via VPA transfer.

vAccountNumber

The virtual bank account number (if received to Virtual Bank Account).

referenceId

The reference number generated by Cashfree to track the transaction.

utr

Unique transaction reference number provided by the bank.

email

Customer email address.

phone

Customer phone number.

creditRefNo

Reference number generated by the bank.

remitterAccount

Payer's bank account number.

remitterName

Payer's name.

paymentTime

Time at which the payment was made.

signature

A unique string that helps distinguish that the request is genuine and initiated by Cashfree.

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).

Parameter

Description

event

It contains the name of the event which just occurred.
Value = TRANSFER_REJECTED.

amount

Specifies the amount collected.

vAccountId

The virtual account ID of the customer who made the payment.

rejectId

The transfer rejected transaction ID.

utr

Unique transaction reference number provided by the bank.

remitterAccount

Payer's bank account number.

transferTime

Time at which the transfer was made.

reason

Specifies the reason for rejecting the transfer.

signature

A 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.

Parameter

Description

event

It contains the name of the event which just occurred.
Value = AMOUNT_SETTLED.

amount

Specifies the amount settled.

count

No. of transactions that are settled.

utr

Unique transaction reference number provided by the bank.

settlementId

Reference number of the settlement made.

settlementAmount

The settlement amount will be the total transaction amount minus the service charges and taxes.

adjustment

The differential amount that was deducted or added in the current settlement cycle.
(SettlementAmount + adjustment = amount)

signature

A 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="
}

Verify Signature

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

Follow 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.

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;
    }
}