Dispute Webhooks
Learn in detail about dispute webhooks.
Dispute webhooks can be configured to receive automated notifications when disputes are created, updated and closed.
The webhook notification will be sent on all the URLs added and enabled under the dispute webhook. Merchants can add new URLs and enable or disable existing URLs for refund webhook at any point in time and it will be reflected instantaneously.
Webhook | Description |
---|---|
DISPUTE_CREATED | Dispute_created webhook will be triggered when a new dispute is created. |
DISPUTE_UPDATED | Dispute_updated webhook will be triggered when a dispute is updated, for example when a comment is added by the Cashfree team, when the dispute moves into further stages like Pre-arbitration, Arbitration, or when the status of the dispute changes. |
DISPUTE_CLOSED | This webhook will be triggered when a dispute is closed. |
Click here to know how to configure webhooks.
Dispute Created
Sample Payload
"{
"data": {
"dispute": {
"dispute_id": "433475258",
"dispute_type": "DISPUTE",
"reason_code": "1402",
"reason_description": "Duplicate Processing",
"dispute_amount": 3,
"created_at": "2023-06-15T21:49:48+05:30",
"updated_at": "2023-06-15T21:49:48+05:30",
"respond_by": "2023-06-18T23:59:59+05:30",
"dispute_status": ""DISPUTE_CREATED"",
"cf_dispute_remarks": "Dispute is created, please take action",
"dispute_action_on": "MERCHANT"
},
"order_details": {
"order_id": "order_1944392DR1kMTFYdIf8bI2awAcC3i9FTa",
"order_amount": 3,
"order_currency": "INR",
"cf_payment_id": 885473311,
"payment_amount": 3,
"payment_currency": "INR"
},
"customer_details": {
"customer_name": "Dileep Kumar s",
"customer_phone": "8000000000",
"customer_email": "[email protected]"
}
},
"event_time": ""2023-06-15T21:50:04+05:30",
"type": "DISPUTE_CREATED"
}"
Dispute Updated
Sample Payload
"{
"data": {
"dispute": {
"dispute_id": "433475257",
"dispute_type": "PRE_ARBITRATION",
"reason_code": "13.1",
"reason_description": "Merchandise / Services Not Received",
"dispute_amount": 40000,
"created_at": "2023-06-15T21:16:03+05:30",
"updated_at": "2023-06-15T21:19:15+05:30",
"respond_by": "2023-06-19T23:59:59+05:30",
"dispute_status": "PRE_ARBITRATION_CREATED",
"cf_dispute_remarks": "Pre Arbitration request has been raised for this case.\nTarget Date :: 2023-06-18T00:00 -> 2023-06-19T23:59:59.",
"dispute_update": "TYPE_UPDATE",
"dispute_action_on": "MERCHANT"
},
"order_details": {
"order_id": "order_1944392D4jHtCeVPPdTXkaUwg5cfnujQe",
"order_amount": 40000,
"order_currency": "INR",
"cf_payment_id": 885457437,
"payment_amount": 40000,
"payment_currency": "INR"
},
"customer_details": {
"customer_name": "Dileep Kumar s",
"customer_phone": "8000000000",
"customer_email": "[email protected]"
}
},
"event_time": "2023-06-15T21:20:24+05:30",
"type": "DISPUTE_UPDATED"
}"
Dispute Closed
Sample Payload
"{
"data": {
"dispute": {
"dispute_id": "433475257",
"dispute_type": "CHARGEBACK",
"reason_code": "4855",
"reason_description": "Goods or Services Not Provided",
"dispute_amount": 4500,
"created_at": "2023-06-15T21:16:03+05:30",
"updated_at": "2023-06-15T21:16:51+05:30",
"respond_by": "2023-06-18T00:00:00+05:30",
"resolved_at": "2023-06-15T21:16:51.682836678+05:30",
"dispute_status": "CHARGEBACK_MERCHANT_WON",
"cf_dispute_remarks": "Chargeback won by merchant"
},
"order_details": {
"order_id": "order_1944392D4jHtCeVPPdTXkaUwg5cfnujQe",
"order_amount": 4500,
"order_currency": "INR",
"cf_payment_id": 885457437,
"payment_amount": 4500,
"payment_currency": "INR"
},
"customer_details": {
"customer_name": "Dileep Kumar s",
"customer_phone": "8000000000",
"customer_email": "[email protected]"
}
},
"event_time": "2023-06-15T21:17:14+05:30",
"type": "DISPUTE_CLOSED"
}"
Payload Field Description
Field | Description | Example | Type |
---|---|---|---|
dispute_id | Cashfree’s unique ID to identify a dispute. | 433475257 | Long |
dispute_type | Type of dispute created. Possible values: - DISPUTE - RETRIEVAL - CHARGEBACK - PRE_ARBITRATION - ARBITRATION | Chargeback | String |
reason_code | Condition for which the customer is filing the case. Click here to know more about dispute reason codes. | 13.6 | String |
reason_description | Description of the reason code. Codes for Chargeback cases are specified by Card networks/NPCI. | Credit not processed | String |
dispute_amount | The amount for which the dispute has been created. | 4500 | BigDecimal |
created_at | Time on which the dispute was registered on Cashfree’s system. | 2023-06-15T21:16:03+05:30 | LocalDateTime |
updated_at | Time on which the dispute was updated. | 2023-06-15T21:16:51+05:30 | LocalDateTime |
respond_by | Time by which the merchant is expected to respond to the dispute. | 2023-06-18T00:00:00+05:30 | LocalDateTime |
dispute_status | Status of Dispute. All possible values are listed in the table below. | CHARGEBACK_CREATED | String |
cf_dispute_remarks | Any remarks specified by Cashfree on the dispute. | Please submit documents. | String |
dispute_update | Specifies what has been updated on the dispute. Possible Values: - STATUS_UPDATE - TYPE_UPDATE - COMMENT_UPDATE | TYPE_UPDATE | String |
dispute_action_on | Specifies whether the action is on Cashfree or Merchant at a time. Possible Values: - MERCHANT - CASHFREE | MERCHANT | String |
resolved_at | Time on which the dispute was resolved/closed. | 2023-06-15T21:16:51.682836678+05:30 | LocalDateTime |
event_time | Time at which dispute webhook was initiated. | 2023-06-15T21:16:51+05:30 | LocalDateTime |
type | Type of webhook. Possible Values: - DISPUTE_CREATED - DISPUTE_UPDATED - DISPUTE_CLOSED | DISPUTE_CREATED | String |
List of Dispute Status |
---|
DISPUTE_CREATED |
DISPUTE_DOCS_RECEIVED |
DISPUTE_UNDER_REVIEW |
DISPUTE_MERCHANT_WON |
DISPUTE_MERCHANT_LOST |
DISPUTE_MERCHANT_ACCEPTED |
DISPUTE_INSUFFICIENT_EVIDENCE |
RETRIEVAL_CREATED |
RETRIEVAL_DOCS_RECEIVED |
RETRIEVAL_UNDER_REVIEW |
RETRIEVAL_MERCHANT_WON |
RETRIEVAL_MERCHANT_LOST |
RETRIEVAL_MERCHANT_ACCEPTED |
RETRIEVAL_INSUFFICIENT_EVIDENCE |
CHARGEBACK_CREATED |
CHARGEBACK_DOCS_RECEIVED |
CHARGEBACK_UNDER_REVIEW |
CHARGEBACK_MERCHANT_WON |
CHARGEBACK_MERCHANT_LOST |
CHARGEBACK_MERCHANT_ACCEPTED |
CHARGEBACK_INSUFFICIENT_EVIDENCE |
PRE_ARBITRATION_CREATED |
PRE_ARBITRATION_DOCS_RECEIVED |
PRE_ARBITRATION_UNDER_REVIEW |
PRE_ARBITRATION_MERCHANT_WON |
PRE_ARBITRATION_MERCHANT_LOST |
PRE_ARBITRATION_MERCHANT_ACCEPTED |
PRE_ARBITRATION_INSUFFICIENT_EVIDENCE |
ARBITRATION_CREATED |
ARBITRATION_DOCS_RECEIVED |
ARBITRATION_UNDER_REVIEW |
ARBITRATION_MERCHANT_WON |
ARBITRATION_MERCHANT_LOST |
ARBITRATION_MERCHANT_ACCEPTED |
ARBITRATION_INSUFFICIENT_EVIDENCE |
Signature Verification
The signature must be used to verify if the request has not been tampered with. To verify the signature at your end, you will need your Cashfree PG secret key along with the payload. Timestamp is present in the header x-webhook-timestamp
timestamp := 1617695238078;
signedPayload := $timestamp.$payload;
expectedSignature := Base64Encode(HMACSHA256($signedPayload, $merchantSecretKey));
Compute Signature and Verify
function verify(ts, rawBody){
const body = ts + rawBody
const secretKey = "<your secret key>";
let genSignature = crypto.createHmac('sha256',secretKey).update(body).digest("base64");
return genSignature
}
func VerifySignature(expectedSig string, ts int64, body string) (string, error) {
t := time.Now()
currentTS := t.Unix()
if currentTS-ts > 1000*300 {
return "", errors.New("webhook delivered too late")
}
signStr := strconv.FormatInt(ts, 10) + body
fmt.Println("signing String: ", signStr)
key := ""
h := hmac.New(sha256.New, []byte(key))
h.Write([]byte(signStr))
b := h.Sum(nil)
return base64.StdEncoding.EncodeToString(b), nil
}
function computeSignature($ts, $rawBody){
$signStr = $ts . $rawBody;
$key = "";
$computeSig = base64_encode(hash_hmac('sha256', $signStr, $key, true));
return $computeSig;
}
public String generateSignature() {
String payload = "json payload in string";
String timestamp = "x-webhook-timestamp";
String data = timestamp+payload;
String secretKey = "SECRET-KEY"; // Get secret key from Cashfree Merchant Dashboard;
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key_spec = new SecretKeySpec(secretKey.getBytes(),"HmacSHA256");
sha256_HMAC.init(secret_key_spec);
String computed_signature = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(data.getBytes()));
return computed_signature; // compare with "x-webhook-signature"
}
import base64
import hashlib
import hmac
def generateSignature():
timestamp = "timestamp data"
payload = 'json data in string'
signatureData = timestamp+payload
message = bytes(signatureData, 'utf-8')
secretkey=bytes("Secret_Key",'utf-8') #Get Secret_Key from Cashfree Merchant Dashboard.
signature = base64.b64encode(hmac.new(secretkey, message, digestmod=hashlib.sha256).digest())
computed_signature = str(signature, encoding='utf8')
return computed_signature #compare with "x-webhook-signature"
Updated about 1 year ago