The purpose of this document is to lay down the payment integration with Cashfree that is required for a merchant or Solution Partner that has setup a chatbot using WhatsApp Business APIs and needs to receive payments from WhatsApp users.
This document covers the set of APIs that need to be integrated and how the integration works in tandem with the WhatsApp Business API integration. For additional details regarding Cashfree payment integration, please refer to the Cashfree documentation.
Where this fits into the entire flow in terms of integration to the WA P2M product : The following document covers the requests, responses in red in the flow diagram below.
Cashfree Payment Integration
Setup
Obtain credentials (client id and secret) from Cashfree dashboard after setting up the account.
Obtain the merchant vpa, mcc and purpose code from Cashfree. This will be used to set up the payment configuration on WhatsApp. Multiple vpas are supported and hence multiple payment configurations can be set up. Each payment configuration should have one VPA.
This API returns the UPI intent url that contains the parameters required for the WhatsApp APIs.
Reference doc
Request
curl --request POST \
--url https://sandbox.cashfree.com/pg/orders/sessions \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'x-api-version: 2022-09-01' \
--data '
{
"payment_method": {
"upi": {
"channel": "link",
"upi_id": "rajnandan1@okhdfcbak",
"upi_expiry_minutes": 10
}
},
"payment_session_id": "session_364o8HjN0-gc6n_n4EBEPOXriJUJvCeVIdy9u8ihOhwvpNg9F1wMorWmkVxUR90kTe473bpbotNxyZ6Fze8M0w42_BpTxoEWsbBR21y7i0nh" // this is from the create order API response
}
Response
{
"action": "custom",
"cf_payment_id": 885899755, // is the transaction ID, is also present in UPI url
"channel": "link",
"data": {
"url": null,
"payload": {
"bhim": "https://payments-test.cashfree.com/pgbillpayuiapi/simulator/885899755?txnId=885899755&amount=200.50&pa=cashfree@testbank&pn=Cashfree&tr=885899755&am=200.50&cu=INR&mode=00&purpose=00&mc=5732&tn=Cashfree%20Simulator%20Payment",
"default": "https://payments-test.cashfree.com/pgbillpayuiapi/simulator/885899755?txnId=885899755&amount=200.50&pa=cashfree@testbank&pn=Cashfree&tr=885899755&am=200.50&cu=INR&mode=00&purpose=00&mc=5732&tn=Cashfree%20Simulator%20Payment",
"gpay": "https://payments-test.cashfree.com/pgbillpayuiapi/simulator/885899755?txnId=885899755&amount=200.50&pa=cashfree@testbank&pn=Cashfree&tr=885899755&am=200.50&cu=INR&mode=00&purpose=00&mc=5732&tn=Cashfree%20Simulator%20Payment",
"paytm": "https://payments-test.cashfree.com/pgbillpayuiapi/simulator/885899755?txnId=885899755&amount=200.50&pa=cashfree@testbank&pn=Cashfree&tr=885899755&am=200.50&cu=INR&mode=00&purpose=00&mc=5732&tn=Cashfree%20Simulator%20Payment",
"phonepe": "https://payments-test.cashfree.com/pgbillpayuiapi/simulator/885899755?txnId=885899755&amount=200.50&pa=cashfree@testbank&pn=Cashfree&tr=885899755&am=200.50&cu=INR&mode=00&purpose=00&mc=5732&tn=Cashfree%20Simulator%20Payment",
"web": "https://sandbox.cashfree.com/pg/view/upi/qcrgfb.session_364o8HjN0-gc6n_n4EBEPOXriJUJvCeVIdy9u8ihOhwvpNg9F1wMorWmkVxUR90kTe473bpbotNxyZ6Fze8M0w42_BpTxoEWsbBR21y7i0nh.c252cd27-c877-4a51-8352-837d04a2f4c2"
},
"content_type": null,
"method": null
},
"payment_amount": 200.5,
"payment_method": "upi"
}
Parsing the response
Store the cf_payment_id as a unique identifier of the payment at Cashfree end. As Cashfree supports multiple payments for a given order_id (or cf_order_id), storing the cf_payment_id is important for deduping multiple/duplicate payments (if they occur due to a bug or otherwise).
Extract the key-value pairs in data.payload.default
Verify “am” to be the same as the amount that was set.
Use the value in “tr” as the reference_id while setting up the Parameters object to send the payment message using WhatsApp API.
The value of “pa” is the merchant vpa that will be used for this transaction. The payment configuration name corresponding to the vpa returned should be used as payment_configuration while setting up the Parameters object to send the payment message using WhatsApp API.
In case the merchant vpa obtained from above does not match with any of the vpas set in the WhatsApp payment configuration, payment should be discontinued. Please reach out to Cashfree to confirm the updated vpa and update the WhatsApp payment configuration accordingly.
Also check whether the “mode” and “purpose” values are the same as those set in the payment configuration. In case of mismatch, log the mismatch to follow up with Cashfree about the right/updated values. Do not block the payment due to this mismatch.
Once the user completes the payment on WhatsApp, Cashfree will send a webhook about payment completion. Please note that while WhatsApp also shares a payment completion signal, please rely on the signal from Cashfree for the final payment status to avoid reconciliation issues.
Based on the payment_status in the webhook, update the order status for the user using the WhatsApp API.
Status api can be used as an alternative in case the webhook isn’t received within a certain timeframe. Based on the payment_status in the response, update the order status for the user using the WhatsApp API.
Cashfree allows setting the expiry time for an order in the Create Order API. Use that to set preferred expiry time.
Post order expiry, if no webhook was received, do a status check to ensure that the order expired and then cancel the order at WhatsApp to update the user.
Handling failed payments
The Payment message sent to the user via WhatsApp allows for multiple retries upon failure (ie the Pay button is available until successful payment). However Cashfree requires the reference id (“tr” field in the url received in Order Pay response) to be unique for each payment.
So when a failed payment response is received from Cashfree, update the status of order at WhatsApp to cancelled. Post that a new payment message can be sent to the user to retry the payment.
In case, there is a delay in cancellation and the user ends up making a successful payment, Cashfree will not send a webhook to the merchant but does an auto-refund, without any additional action required by the merchant. In the case of a customer query in such a scenario (where they claim the transaction was successful but the payment cannot be found at Cashfree), suggest to the user that refund will be processed in a few days.
Canceling Order for successful transaction
There may arise a scenario where Cashfree shared a successful payment signal but the order cannot be fulfilled by the merchant. In such scenario, process refund for the payment via one of the following mechanisms: