curl --request POST \
--url https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment \
--header 'Content-Type: application/json' \
--header 'x-client-id: <api-key>' \
--header 'x-client-secret: <api-key>' \
--data '
{
"bill_fetch_ref_id": "REF20240501ABC123",
"transaction_ref_id": "TXN20240501XYZ789"
}
'import requests
url = "https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment"
payload = {
"bill_fetch_ref_id": "REF20240501ABC123",
"transaction_ref_id": "TXN20240501XYZ789"
}
headers = {
"x-client-id": "<api-key>",
"x-client-secret": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-client-id': '<api-key>',
'x-client-secret': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
bill_fetch_ref_id: 'REF20240501ABC123',
transaction_ref_id: 'TXN20240501XYZ789'
})
};
fetch('https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'bill_fetch_ref_id' => 'REF20240501ABC123',
'transaction_ref_id' => 'TXN20240501XYZ789'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-client-id: <api-key>",
"x-client-secret: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment"
payload := strings.NewReader("{\n \"bill_fetch_ref_id\": \"REF20240501ABC123\",\n \"transaction_ref_id\": \"TXN20240501XYZ789\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-client-id", "<api-key>")
req.Header.Add("x-client-secret", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment")
.header("x-client-id", "<api-key>")
.header("x-client-secret", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"bill_fetch_ref_id\": \"REF20240501ABC123\",\n \"transaction_ref_id\": \"TXN20240501XYZ789\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-client-id"] = '<api-key>'
request["x-client-secret"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"bill_fetch_ref_id\": \"REF20240501ABC123\",\n \"transaction_ref_id\": \"TXN20240501XYZ789\"\n}"
response = http.request(request)
puts response.read_body{
"status": "OK",
"message": "Payment is still being processed",
"data": {
"bill_payment_response": {
"head": {
"bill_fetch_ref_id": "7a2ab40099e046d9b146357453062440743"
},
"reason": {
"approval_ref_num": "",
"response_code": "PENDING",
"response_reason": "Processing",
"compliance_resp_cd": "",
"compliance_reason": ""
},
"txn": {
"transaction_ref_id": "CH016244D27AOJ4XDQXF"
},
"bill_details": null,
"biller_response": null,
"additional_info": null
}
}
}Bill Payment Response
Use this API to poll for the result of a previously submitted bill payment request.
Call this using both bill_fetch_ref_id and transaction_ref_id from the Bill Payment Request API. The bill_fetch_ref_id is not required for the direct pay flow.
If synchronous responses are enabled for your account and the Bill Payment Request API returned HTTP 200, the final payment status is already available in data.result and you do not need to poll. Poll only when the request returned HTTP 202.
Polling strategy
Polling strategy
Poll at increasing intervals until message is no longer "Payment is still being processed":
| Attempt | Wait before this poll |
|---|---|
| 1 | 5 seconds |
| 2 | 15 seconds |
| 3 | 30 seconds |
| 4 | 1 minute |
| 5+ | 3 minutes |
Stop polling when message is "Payment successful" or "Payment failed". If the payment remains in a processing state beyond your retry limit, treat it as a timeout and raise a support ticket.
Response outcomes
Response outcomes
The outcome is conveyed by the top-level message and can be confirmed from data.bill_payment_response.reason.response_code:
Payment is still being processed(response_codePENDING): payment is still in progress. Continue polling.Payment successful(response_code000): payment completed successfully.Payment failed: payment failed. Readreason.compliance_reasonfor the cause.
Version differences
Version differences
x-api-version: 2025-01-01(default): on success, the response returnsbiller_response(single object) with the confirmed bill details.x-api-version: 2026-10-01: on success, the response returnsbiller_responses(array) for LIST type billers (biller_response_type: LISTin Fetch Billers Info). A LIST biller can confirm multiple bills in a single payment response. Useselection_typefrom Fetch Billers Info to understand how many bills were selected by the customer.
curl --request POST \
--url https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment \
--header 'Content-Type: application/json' \
--header 'x-client-id: <api-key>' \
--header 'x-client-secret: <api-key>' \
--data '
{
"bill_fetch_ref_id": "REF20240501ABC123",
"transaction_ref_id": "TXN20240501XYZ789"
}
'import requests
url = "https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment"
payload = {
"bill_fetch_ref_id": "REF20240501ABC123",
"transaction_ref_id": "TXN20240501XYZ789"
}
headers = {
"x-client-id": "<api-key>",
"x-client-secret": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-client-id': '<api-key>',
'x-client-secret': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
bill_fetch_ref_id: 'REF20240501ABC123',
transaction_ref_id: 'TXN20240501XYZ789'
})
};
fetch('https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'bill_fetch_ref_id' => 'REF20240501ABC123',
'transaction_ref_id' => 'TXN20240501XYZ789'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-client-id: <api-key>",
"x-client-secret: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment"
payload := strings.NewReader("{\n \"bill_fetch_ref_id\": \"REF20240501ABC123\",\n \"transaction_ref_id\": \"TXN20240501XYZ789\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-client-id", "<api-key>")
req.Header.Add("x-client-secret", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment")
.header("x-client-id", "<api-key>")
.header("x-client-secret", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"bill_fetch_ref_id\": \"REF20240501ABC123\",\n \"transaction_ref_id\": \"TXN20240501XYZ789\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.cashfree.com/bbps/cou/v1/billers/response/bill-payment")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-client-id"] = '<api-key>'
request["x-client-secret"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"bill_fetch_ref_id\": \"REF20240501ABC123\",\n \"transaction_ref_id\": \"TXN20240501XYZ789\"\n}"
response = http.request(request)
puts response.read_body{
"status": "OK",
"message": "Payment is still being processed",
"data": {
"bill_payment_response": {
"head": {
"bill_fetch_ref_id": "7a2ab40099e046d9b146357453062440743"
},
"reason": {
"approval_ref_num": "",
"response_code": "PENDING",
"response_reason": "Processing",
"compliance_resp_cd": "",
"compliance_reason": ""
},
"txn": {
"transaction_ref_id": "CH016244D27AOJ4XDQXF"
},
"bill_details": null,
"biller_response": null,
"additional_info": null
}
}
}Authorizations
Your unique client identifier issued by Cashfree. You can find this in your Merchant Dashboard.
Your unique client secret issued by Cashfree. Keep this confidential and never expose it in client-side code. You can find this in your Merchant Dashboard.
Headers
API version to be used. Format is YYYY-MM-DD. Supported versions are 2025-01-01 (default) and 2026-10-01. If not specified, 2025-01-01 is used. The version determines the response structure for bill fetch and payment status ā 2025-01-01 returns biller_response (single object), while 2026-10-01 returns biller_responses (array).
2025-01-01, 2026-10-01 Body
Request parameters to poll a bill payment request.
The transaction_ref_id received in the Bill Payment Request API response (data.transaction_ref_id). Used to identify this specific payment transaction.
"TXN20240501XYZ789"
The bill_fetch_ref_id received in the Bill Payment Request API response (data.bill_fetch_ref_id). Used to identify the original bill fetch. Not required for the direct pay flow, which has no prior bill fetch.
"REF20240501ABC123"
Response
Success response for polling a bill payment request.
Always "OK" for all poll responses, regardless of the payment outcome.
"OK"
Payment state, and the field to poll on. One of "Payment successful", "Payment failed", or "Payment is still being processed".
"Payment successful"
Response payload containing the payment status and full transaction details.
Show child attributes
Show child attributes
Was this page helpful?