API Test Keys

Create a Bill Payment

POST
/v1/bill_payments/payments

Click to copy

Use this endpoint to confirm a bill payment on the BBPS network after you have collected payment from the customer via the

. Razorpay acts as both the Payment Aggregator (PA) and the Customer Operating Unit (COU). You, the Agent Institution, orchestrate two steps: collect money via the PG, then call this API to confirm the bill settlement.

This is an asynchronous API. The response immediately returns a processing status with a bill payment id. Poll the

API or listen to webhooks until the status reaches a terminal state (success or failed).

Prerequisite

Call this API only after the Razorpay PG payment is captured. The payments[].id field must be a valid Razorpay payment id with a captured status. Calling this API before the PG payment is captured will result in a failed bill settlement.

Idempotency

Pass a unique X-Bill-Payments-Idempotency header (4–36 characters, alphanumeric with hyphens, underscores or spaces) to safely retry requests without creating duplicate payments. A UUID v4 is recommended. The request body on retries must match the original request, else it is rejected as a BAD_REQUEST_ERROR.

Normal Pay vs Direct Pay

  • Normal Pay - used when a bill is retrieved first via . Pass bill_request_id.
  • Direct Pay - used when the biller's bill_request_required flag is optional or not_supported and you skip the bill retrieval step. Pass biller_id (or gateway_biller_id), biller_data.account_holder and device instead.

Is this page helpful?

Normal Pay

1
curl -u [YOUR_KEY_ID]:[YOUR_KEY_SECRET] \
2
-X POST https://api.razorpay.com/v1/bill_payments/payments \
3
-H "Content-Type: application/json" \
4
-H "X-Bill-Payments-Idempotency: 53cda91c-8f81-4e77-bbb9-7388f4ac6bf4" \
5
-d '{
6
"bill_request_id": "billreq_ERNEungCtXpZqM",
7
"bill_pay_amount": 1015,
8
"currency": "INR",
9
"fees": {
10
"app_convenience_fee": 10,
11
"biller_convenience_fee": 5
12
},
13
"payments": [
14
{
15
"id": "pay_MbJ5AvwNpAkfLB",
16
"amount": 600,
17
"currency": "INR",
18
"provider": "razorpay",
19
"method": "card",
20
"card": {
21
"type": "credit",
22
"last4": "0153",
23
"auth_code": "Card"
24
}
25
},
26
{
27
"id": "pay_MbJ5AvwNpAkfLA",
28
"amount": 430,
29
"currency": "INR",
30
"provider": "razorpay",
31
"method": "upi",
32
"upi": {
33
"vpa": "gaurav.kumar@okhdfc.com"
34
}
35
}
36
],
37
"bills": [
38
{
39
"bill_number": "820356722187",
40
"amount": 1015,
41
"currency": "INR"
42
}
43
]
44
}'

Success

Failure

1
{
2
"id": "bill_pay_xxxx",
3
"entity": "bill_payment.payment",
4
"status": "processing",
5
"customer": {
6
"id": "rzp_cust_123",
7
"name": "Gaurav Kumar",
8
"mobile": "919000090000",
9
"email": "gaurav.kumar@example.com"
10
},
11
"biller_id": "biller_001",
12
"gateway_biller_id": "TPOW00000MUM01",
13
"gateway_transaction_id": "bbps_txn_id",
14
"gateway": "bbps",
15
"created_at": 1609459200
16
}
Request Parameters
bill_request_id
string

Bill request id returned by

. Mandatory for Normal Pay. When omitted, the request is treated as Direct Pay and device and biller_data.account_holder become mandatory. For example, billreq_ERNEungCtXpZqM.

biller_id
string

Razorpay's internal biller id. Required for Direct Pay if gateway_biller_id is not provided.

gateway_biller_id
string

NPCI's biller id. Required for Direct Pay if biller_id is not provided. For example, TPOW00000MUM01.

bill_pay_amount

*

integer

Actual bill amount for which the bill payment is raised, in paise. Excludes fees. Must satisfy the biller's payment_config.amount_exactness rule (Exact, Exact and above, Exact and below or Any). This value can be less or more than an individual bill amount. For example, 1015 represents ₹10.15.

currency

*

string

Currency in which the bill payment is initiated. Defaults to INR.

fees

*

object

Fee breakdown. Pass 0 for components that do not apply.

fees.app_convenience_fee

*

integer

Merchant/app convenience fee charged to the customer, in paise. Not part of NPCI standard. Platform-specific. Pass 0 if not applicable.

fees.biller_convenience_fee

*

integer

Customer Convenience Fee charged by the biller, in paise. Maps to the biller's fee_config.fee_types[].fee_code=CCF1 returned by the Fetch Billers API and to NPCI's custConvFee. Pass 0 if the biller charges no CCF.

payments

*

array

Payment details collected via the Razorpay PG. Use multiple objects for split payments across methods.

payments[].id

*

string

Razorpay payment id received from the Razorpay PA post Payment Create. Required as per NPCI guidelines. For example, pay_MbJ5AvwNpAkfLB.

payments[].provider

*

string

Payment provider. Hardcode to razorpay when the payment is processed via the Razorpay gateway.

payments[].amount

*

integer

Amount paid via the selected method, in paise.

payments[].currency

*

string

ISO 4217 currency code. Only INR is supported currently.

payments[].method

*

string

Payment method. Maps to NPCI paymentMode. Supported values: card, upi, netbanking, wallet.

payments[].card
object

Required when method is card.

payments[].card.type

*

string

Card type. Values: credit, debit, prepaid.

payments[].card.last4

*

string

Last 4 digits of the card.

payments[].card.auth_code

*

string

Hardcode to Card as per NPCI guidelines.

payments[].upi
object

Required when method is upi.

payments[].upi.vpa

*

string

Customer's actual UPI VPA if available; otherwise pass the Razorpay payment id.

payments[].netbanking
object

Required when method is netbanking.

payments[].netbanking.account_number

*

string

Customer's account number if available; otherwise hardcode to PG.

payments[].netbanking.ifsc_code

*

string

IFSC code if available; otherwise pass the Razorpay payment id.

payments[].wallet
object

Required when method is wallet.

payments[].wallet.name

*

string

Name of the actual wallet used. For example, amazon_pay, payzapp.

bills

*

array

Bills being paid. Minimum 1 bill required for Normal Pay. Pass an empty array [] for Direct Pay (no bill was retrieved).

bills[].bill_number
string

bills[].bill_number received in the Fetch Bill Request response. Required when a bill was retrieved.

bills[].amount

*

integer

Bill amount in paise. Must match the bill amount returned by the Fetch Bill Request API or satisfy the biller's payment_config.amount_exactness rules.

bills[].currency

*

string

Currency code. Hardcode to INR.

customer
object

Customer information passed as dynamic key-value pairs. Free-form metadata for your own tracking and reconciliation. Razorpay echoes these back on responses and webhooks without validation.

customer.id
string

Dynamic key-value pair holding your customer reference. Not validated by Razorpay.

customer.name
string

Dynamic key-value pair holding the customer name. Not validated by Razorpay.

customer.mobile

*

string

Customer's mobile number with country code. For example, 919000090000.

customer.email
string

Dynamic key-value pair holding the customer email. Not validated by Razorpay.

biller_data
object

Bill account holder details. Mandatory if bill_request_id is not provided.

biller_data.account_holder
object

Dynamic key-value pairs that identify the customer's account at the biller. The keys and values are dictated by the biller's account_holder_config returned by the

API. Razorpay does not control the keys nor the values - pass them exactly as defined by the biller.

device
object

Info about the device initiating the bill payment. Mandatory if bill_request_id is not provided.

device.initiating_channel

*

enum

Channel from which the bill payment is initiated, based on NPCI terminology. Values:

  • INT - Web
  • MOB - Mobile App
  • MOBB - Mobile Banking App
  • INTB - Internet Banking
  • AGT - Agent
  • BNKBRNCH - Bank Branch
  • BSC - Business Correspondent

device.mobile
string

End agent's mobile number (10 digits) for offline channels. Required for BNKBRNCH, AGT, BSC channels.

device.geocode
string

Latitude, Longitude. Required for INT, MOB, BNKBRNCH, AGT, BSC channels. For example, 12.9667,77.5667.

device.ip
string

IPv4 or IPv6 address. Required for INT, INTB, MOB, MOBB channels.

device.mac
string

MAC address. Required for INT, INTB channels. For example, 00-0D-60-07-2A-F0.

device.os
string

Operating system. Required for MOB, MOBB channels. For example, android, iOS.

device.app
string

Application name. Required for MOB, MOBB channels. For example, amazon_pay.

Response Parameters
id
string

Razorpay's unique bill payment transaction id. Use this for internal tracking, refund reference, reconciliation and to poll for the final status. For example, bill_pay_xxxx.

entity
string

Entity type. Always bill_payment.payment.

status
string

Initial payment status. processing on the create response. Poll

for the final state. Possible final values: success (NPCI responseCode=000), pending (NPCI responseCode=091) or failed (any other NPCI responseCode).

customer
object

Customer who made the payment. Echoed from the request.

biller_id
string

Razorpay biller entity id. Use for internal biller identification, reporting and analytics.

gateway_biller_id
string

NPCI biller id.

gateway_transaction_id
string

BBPS/NPCI transaction reference number. Fixed length of 12 or 20 characters. Maps to NPCI txnReferenceId. Store for NPCI reconciliation, settlement tracking and dispute resolution.

gateway
string

Bill payment gateway used. Defaults to bbps.

created_at
integer

UNIX timestamp when the bill payment was created at Razorpay.

Errors

The ref_id is required.

Error Status: 400

ref_id is required.

Solution

The bill_request_id is invalid or expired.

Error Status: 400

Invalid or expired ref_id.

Solution

The bill_pay_amount does not match the fetched amount.

Error Status: 400

Payment amount does not match fetch/validate amount.

Solution

The customer parameters do not match the bill request.

Error Status: 400

Customer parameters do not match fetch/validate request.

Solution

The payment method is not supported for this biller.

Error Status: 400

Payment method not supported for this biller.

Solution

The payment amount exceeds the maximum limit.

Error Status: 400

Payment amount exceeds maximum limit of {max_amount} for {payment_mode}.

Solution

Required payment instrument details are missing.

Error Status: 400

Required payment instrument details missing for {payment_mode}.

Solution

Payment authorisation not found from PA.

Error Status: 400

Payment authorisation not found from PA.

Solution

The X-Bill-Payments-Idempotency header is missing or invalid.

Error Status: 400

The idempotency key must be 4-36 characters and contain only alphanumeric characters, hyphens, underscores or spaces.

Solution

Bill payment failed at biller.

Error Status: 502

The biller rejected the bill payment.

Solution

Duplicate payment at biller.

Error Status: 502

Bill payment failed at biller because of a duplicate payment.

Solution

Payment request timed out at NPCI.

Error Status: 502

NPCI did not respond within the timeout window.

Solution

Biller temporarily unavailable for payments.

Error Status: 502

The biller is temporarily unavailable for payments.

Solution

The API <key/secret> provided is invalid.

Error Status: 401

The API credentials passed in the request differ from the ones generated on the Dashboard.

Solution

Create a Bill Payment

POST
/v1/bill_payments/payments

Click to copy

Use this endpoint to confirm a bill payment on the BBPS network after you have collected payment from the customer via the

. Razorpay acts as both the Payment Aggregator (PA) and the Customer Operating Unit (COU). You, the Agent Institution, orchestrate two steps: collect money via the PG, then call this API to confirm the bill settlement.

This is an asynchronous API. The response immediately returns a processing status with a bill payment id. Poll the

API or listen to webhooks until the status reaches a terminal state (success or failed).

Prerequisite

Call this API only after the Razorpay PG payment is captured. The payments[].id field must be a valid Razorpay payment id with a captured status. Calling this API before the PG payment is captured will result in a failed bill settlement.

Idempotency

Pass a unique X-Bill-Payments-Idempotency header (4–36 characters, alphanumeric with hyphens, underscores or spaces) to safely retry requests without creating duplicate payments. A UUID v4 is recommended. The request body on retries must match the original request, else it is rejected as a BAD_REQUEST_ERROR.

Normal Pay vs Direct Pay

  • Normal Pay - used when a bill is retrieved first via . Pass bill_request_id.
  • Direct Pay - used when the biller's bill_request_required flag is optional or not_supported and you skip the bill retrieval step. Pass biller_id (or gateway_biller_id), biller_data.account_holder and device instead.

Is this page helpful?

Request Parameters
bill_request_id
string

Bill request id returned by

. Mandatory for Normal Pay. When omitted, the request is treated as Direct Pay and device and biller_data.account_holder become mandatory. For example, billreq_ERNEungCtXpZqM.

biller_id
string

Razorpay's internal biller id. Required for Direct Pay if gateway_biller_id is not provided.

gateway_biller_id
string

NPCI's biller id. Required for Direct Pay if biller_id is not provided. For example, TPOW00000MUM01.

bill_pay_amount

*

integer

Actual bill amount for which the bill payment is raised, in paise. Excludes fees. Must satisfy the biller's payment_config.amount_exactness rule (Exact, Exact and above, Exact and below or Any). This value can be less or more than an individual bill amount. For example, 1015 represents ₹10.15.

currency

*

string

Currency in which the bill payment is initiated. Defaults to INR.

fees

*

object

Fee breakdown. Pass 0 for components that do not apply.

fees.app_convenience_fee

*

integer

Merchant/app convenience fee charged to the customer, in paise. Not part of NPCI standard. Platform-specific. Pass 0 if not applicable.

fees.biller_convenience_fee

*

integer

Customer Convenience Fee charged by the biller, in paise. Maps to the biller's fee_config.fee_types[].fee_code=CCF1 returned by the Fetch Billers API and to NPCI's custConvFee. Pass 0 if the biller charges no CCF.

payments

*

array

Payment details collected via the Razorpay PG. Use multiple objects for split payments across methods.

payments[].id

*

string

Razorpay payment id received from the Razorpay PA post Payment Create. Required as per NPCI guidelines. For example, pay_MbJ5AvwNpAkfLB.

payments[].provider

*

string

Payment provider. Hardcode to razorpay when the payment is processed via the Razorpay gateway.

payments[].amount

*

integer

Amount paid via the selected method, in paise.

payments[].currency

*

string

ISO 4217 currency code. Only INR is supported currently.

payments[].method

*

string

Payment method. Maps to NPCI paymentMode. Supported values: card, upi, netbanking, wallet.

payments[].card
object

Required when method is card.

payments[].card.type

*

string

Card type. Values: credit, debit, prepaid.

payments[].card.last4

*

string

Last 4 digits of the card.

payments[].card.auth_code

*

string

Hardcode to Card as per NPCI guidelines.

payments[].upi
object

Required when method is upi.

payments[].upi.vpa

*

string

Customer's actual UPI VPA if available; otherwise pass the Razorpay payment id.

payments[].netbanking
object

Required when method is netbanking.

payments[].netbanking.account_number

*

string

Customer's account number if available; otherwise hardcode to PG.

payments[].netbanking.ifsc_code

*

string

IFSC code if available; otherwise pass the Razorpay payment id.

payments[].wallet
object

Required when method is wallet.

payments[].wallet.name

*

string

Name of the actual wallet used. For example, amazon_pay, payzapp.

bills

*

array

Bills being paid. Minimum 1 bill required for Normal Pay. Pass an empty array [] for Direct Pay (no bill was retrieved).

bills[].bill_number
string

bills[].bill_number received in the Fetch Bill Request response. Required when a bill was retrieved.

bills[].amount

*

integer

Bill amount in paise. Must match the bill amount returned by the Fetch Bill Request API or satisfy the biller's payment_config.amount_exactness rules.

bills[].currency

*

string

Currency code. Hardcode to INR.

customer
object

Customer information passed as dynamic key-value pairs. Free-form metadata for your own tracking and reconciliation. Razorpay echoes these back on responses and webhooks without validation.

customer.id
string

Dynamic key-value pair holding your customer reference. Not validated by Razorpay.

customer.name
string

Dynamic key-value pair holding the customer name. Not validated by Razorpay.

customer.mobile

*

string

Customer's mobile number with country code. For example, 919000090000.

customer.email
string

Dynamic key-value pair holding the customer email. Not validated by Razorpay.

biller_data
object

Bill account holder details. Mandatory if bill_request_id is not provided.

biller_data.account_holder
object

Dynamic key-value pairs that identify the customer's account at the biller. The keys and values are dictated by the biller's account_holder_config returned by the

API. Razorpay does not control the keys nor the values - pass them exactly as defined by the biller.

device
object

Info about the device initiating the bill payment. Mandatory if bill_request_id is not provided.

device.initiating_channel

*

enum

Channel from which the bill payment is initiated, based on NPCI terminology. Values:

  • INT - Web
  • MOB - Mobile App
  • MOBB - Mobile Banking App
  • INTB - Internet Banking
  • AGT - Agent
  • BNKBRNCH - Bank Branch
  • BSC - Business Correspondent

device.mobile
string

End agent's mobile number (10 digits) for offline channels. Required for BNKBRNCH, AGT, BSC channels.

device.geocode
string

Latitude, Longitude. Required for INT, MOB, BNKBRNCH, AGT, BSC channels. For example, 12.9667,77.5667.

device.ip
string

IPv4 or IPv6 address. Required for INT, INTB, MOB, MOBB channels.

device.mac
string

MAC address. Required for INT, INTB channels. For example, 00-0D-60-07-2A-F0.

device.os
string

Operating system. Required for MOB, MOBB channels. For example, android, iOS.

device.app
string

Application name. Required for MOB, MOBB channels. For example, amazon_pay.

Response Parameters
id
string

Razorpay's unique bill payment transaction id. Use this for internal tracking, refund reference, reconciliation and to poll for the final status. For example, bill_pay_xxxx.

entity
string

Entity type. Always bill_payment.payment.

status
string

Initial payment status. processing on the create response. Poll

for the final state. Possible final values: success (NPCI responseCode=000), pending (NPCI responseCode=091) or failed (any other NPCI responseCode).

customer
object

Customer who made the payment. Echoed from the request.

biller_id
string

Razorpay biller entity id. Use for internal biller identification, reporting and analytics.

gateway_biller_id
string

NPCI biller id.

gateway_transaction_id
string

BBPS/NPCI transaction reference number. Fixed length of 12 or 20 characters. Maps to NPCI txnReferenceId. Store for NPCI reconciliation, settlement tracking and dispute resolution.

gateway
string

Bill payment gateway used. Defaults to bbps.

created_at
integer

UNIX timestamp when the bill payment was created at Razorpay.

Errors

The ref_id is required.

Error Status: 400

ref_id is required.

Solution

The bill_request_id is invalid or expired.

Error Status: 400

Invalid or expired ref_id.

Solution

The bill_pay_amount does not match the fetched amount.

Error Status: 400

Payment amount does not match fetch/validate amount.

Solution

The customer parameters do not match the bill request.

Error Status: 400

Customer parameters do not match fetch/validate request.

Solution

The payment method is not supported for this biller.

Error Status: 400

Payment method not supported for this biller.

Solution

The payment amount exceeds the maximum limit.

Error Status: 400

Payment amount exceeds maximum limit of {max_amount} for {payment_mode}.

Solution

Required payment instrument details are missing.

Error Status: 400

Required payment instrument details missing for {payment_mode}.

Solution

Payment authorisation not found from PA.

Error Status: 400

Payment authorisation not found from PA.

Solution

The X-Bill-Payments-Idempotency header is missing or invalid.

Error Status: 400

The idempotency key must be 4-36 characters and contain only alphanumeric characters, hyphens, underscores or spaces.

Solution

Bill payment failed at biller.

Error Status: 502

The biller rejected the bill payment.

Solution

Duplicate payment at biller.

Error Status: 502

Bill payment failed at biller because of a duplicate payment.

Solution

Payment request timed out at NPCI.

Error Status: 502

NPCI did not respond within the timeout window.

Solution

Biller temporarily unavailable for payments.

Error Status: 502

The biller is temporarily unavailable for payments.

Solution

The API <key/secret> provided is invalid.

Error Status: 401

The API credentials passed in the request differ from the ones generated on the Dashboard.

Solution

Normal Pay

1
curl -u [YOUR_KEY_ID]:[YOUR_KEY_SECRET] \
2
-X POST https://api.razorpay.com/v1/bill_payments/payments \
3
-H "Content-Type: application/json" \
4
-H "X-Bill-Payments-Idempotency: 53cda91c-8f81-4e77-bbb9-7388f4ac6bf4" \
5
-d '{
6
"bill_request_id": "billreq_ERNEungCtXpZqM",
7
"bill_pay_amount": 1015,
8
"currency": "INR",
9
"fees": {
10
"app_convenience_fee": 10,
11
"biller_convenience_fee": 5
12
},
13
"payments": [
14
{
15
"id": "pay_MbJ5AvwNpAkfLB",
16
"amount": 600,
17
"currency": "INR",
18
"provider": "razorpay",
19
"method": "card",
20
"card": {
21
"type": "credit",
22
"last4": "0153",
23
"auth_code": "Card"
24
}
25
},
26
{
27
"id": "pay_MbJ5AvwNpAkfLA",
28
"amount": 430,
29
"currency": "INR",
30
"provider": "razorpay",
31
"method": "upi",
32
"upi": {
33
"vpa": "gaurav.kumar@okhdfc.com"
34
}
35
}
36
],
37
"bills": [
38
{
39
"bill_number": "820356722187",
40
"amount": 1015,
41
"currency": "INR"
42
}
43
]
44
}'

Success

Failure

1
{
2
"id": "bill_pay_xxxx",
3
"entity": "bill_payment.payment",
4
"status": "processing",
5
"customer": {
6
"id": "rzp_cust_123",
7
"name": "Gaurav Kumar",
8
"mobile": "919000090000",
9
"email": "gaurav.kumar@example.com"
10
},
11
"biller_id": "biller_001",
12
"gateway_biller_id": "TPOW00000MUM01",
13
"gateway_transaction_id": "bbps_txn_id",
14
"gateway": "bbps",
15
"created_at": 1609459200
16
}