Parameters
The POST request to the return URL includes the following parameters:| Parameter | Type | Description |
|---|---|---|
| cf_subReferenceId | Long | Unique numeric ID generated when the subscription was created. |
| cf_subscriptionId | String | ID of the subscription. |
| cf_authAmount | Float | The amount charged to authorise the subscription. |
| cf_referenceId | Long | The reference ID or transaction ID of authorisation in PG. |
| cf_status | String | Status of the subscription. In the returnUrl, the response should be ACTIVE or BANK_APPROVAL_PENDING if the authorisation was successful, or INITIALIZED if the authorisation failed. |
| cf_message | String | A brief note about the payment. |
| signature | String | The hash of all parameters in the request generated using Secret Key. |
| cf_umrn | String | The unique identifier associated with a mandate. Applicable if the payment mode is eMandate. |
| cf_checkoutStatus | String | The subscription checkout status. The status can be SUCCESS, FAILED, SUCCESS_DEBIT_PENDING, or SUCCESS_TOKENIZATION_PENDING. |
| cf_mode | String | The checkout payment mode. Modes: NPCI_SBC, SBC_UPI, SBC_CREDIT_CARD, SBC_DEBIT_CARD. |
| cf_subscriptionPaymentId | String | The subscription payment ID. |
| cf_umn | String | The unique identifier associated with a mandate. Applicable if the payment mode is UPI. |
Sample Payload
Once the authorisation is complete, Cashfree will send a POST request to yourreturn_url with the following payload:
{
"cf_subReferenceId": 1234567,
"cf_subscriptionId": "sub_test_123",
"cf_authAmount": 1.00,
"cf_referenceId": 987654321,
"cf_status": "ACTIVE",
"cf_message": "Subscription authorised successfully",
"signature": "calculated_signature_here",
"cf_umrn": "UMRN1234567890",
"cf_checkoutStatus": "SUCCESS",
"cf_mode": "SBC_UPI",
"cf_subscriptionPaymentId": "pay_test_123",
"cf_umn": "UMN1234567890"
}
Sample Code
Below are examples of how to receive and process the redirection payload in your backend.const express = require('express');
const app = express();
// Middleware to parse POST bodies
app.use(express.urlencoded({ extended: true }));
app.post('/return-url', (req, res) => {
const payload = req.body;
console.log('Received Redirection Payload:', payload);
const status = payload.cf_status;
if (status === 'ACTIVE' || status === 'BANK_APPROVAL_PENDING') {
// Handle success
res.send('Subscription Authorised Successfully');
} else {
// Handle failure
res.send('Authorization Failed');
}
});
from flask import Flask, request
app = Flask(__name__)
@app.route('/return-url', methods=['POST'])
def return_url():
# Capture the POST payload
payload = request.form.to_dict()
print("Received Redirection Payload:", payload)
status = payload.get('cf_status')
if status in ['ACTIVE', 'BANK_APPROVAL_PENDING']:
return "Subscription Authorised Successfully", 200
else:
return "Authorisation Failed", 400
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class SubscriptionController {
@PostMapping("/return-url")
public String handleRedirection(HttpServletRequest request) {
// Collect parameters from the POST request
Map<String, String[]> parameterMap = request.getParameterMap();
String status = request.getParameter("cf_status");
if ("ACTIVE".equals(status) || "BANK_APPROVAL_PENDING".equals(status)) {
return "Subscription Authorised Successfully";
} else {
return "Authorisation Failed";
}
}
}
package main
import (
"fmt"
"net/http"
)
func returnURLHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// Parse the POST form
r.ParseForm()
status := r.FormValue("cf_status")
fmt.Printf("Subscription Status: %s\n", status)
if status == "ACTIVE" || status == "BANK_APPROVAL_PENDING" {
fmt.Fprint(w, "Subscription Authorised Successfully")
} else {
fmt.Fprint(w, "Authorisation Failed")
}
}
func main() {
http.HandleFunc("/return-url", returnURLHandler)
http.ListenAndServe(":8080", nil)
}
<?php
// Receive the POST data from Cashfree redirection
$payload = $_POST;
$status = $payload['cf_status'] ?? '';
if ($status === 'ACTIVE' || $status === 'BANK_APPROVAL_PENDING') {
echo "Subscription Authorised Successfully";
} else {
echo "Authorisation Failed";
}
?>
Return URL
-
After the customer completes the checkout on the OTP page, they are redirected to your
return_url. This redirection is link-based. For example, if you provide areturn_urlin the formathttps://b8af79f41056.eu.ngrok.io?order_id={order_id}, the customer is redirected tohttps://b8af79f41056.eu.ngrok.io?order_id=order_271vfuhh1o4h6bQIigqyOx74YiJ1T. -
In production,
cf_statusandcf_messagemay not be included in thereturn_urlresponse, even though they are present in the sandbox.
Thereturn_urlis intended only to redirect customers back to your site after payment. It should not be used to retrieve complete subscription details.
- Configure your webhook URL in the Cashfree Dashboard.
- Enable the relevant events, such as
SUBSCRIPTION_AUTH_STATUSandSUBSCRIPTION_PAYMENT_SUCCESS.