Buy Now Pay Later (BNPL) allows your customers to spread their purchases over manageable installments or pay later at the end of the billing cycle. You can collect payments from customers with BNPL using the Merchant Hosted (seamless) integration.
To initiate a BNPL transaction, provide "BNPL" for paymentMethod.name and the relevant provider code for paymentMethod.bankCode.
For the list of supported BNPL provider codes, refer to BNPL Codes.
Environment
| Test Environment | https://apitest.payu.in/v2/payments |
| Production Environment | https://api.payu.in/v2/payments |
Request header
| Parameter | Description |
|---|---|
| date | The current date and time. For example, format of the date is Wed, 28 Jun 2023 11:25:19 GMT. |
| authorization | The actual HMAC signature generated using the specified algorithm (sha512) and includes the hashed data. For more information, refer to authorization fields description. |
authorization fields description
| Field | Description |
|---|---|
| username | Represents the username or identifier for the client or merchant, for example smsplus. |
| algorithm | Use SHA512 algorithm for hashing and send this as header value. |
| headers | Specifies which headers have been used in generating the hash, for example date. |
| signature | The HMAC signature generated using the specified algorithm. For more information, refer to hashing algorithm. |
hashing algorithm
You must hash the request parameters using the following hash logic:
Hash logic: sha512(`<Body data>` + '|' + date + '|' + merchant_secret)
Where <Body data> contains the request body posted with the request.
Sample header code
var merchant_key = '<YOUR_TEST_KEY>';
var merchant_secret = 'YOUR_TEST_SALT';
// date
var date = new Date();
date = date.toUTCString();
// authorization
var authorization = getAuthHeader(date);
function getAuthHeader(date) {
var AUTH_TYPE = 'sha512';
var data = isEmpty(request['data']) ? "" : request['data'];
var hash_string = data + '|' + date + '|' + merchant_secret;
var hash = CryptoJS.SHA512(hash_string).toString(CryptoJS.enc.Hex);
return `hmac username="${merchant_key}", algorithm="${AUTH_TYPE}", headers="date", signature="${hash}"`;
}Request body
| Parameter | Description | Example |
|---|---|---|
| accountId | String The merchant key provided by PayU. | MERCHANT123 |
| txnId | String Unique transaction identifier generated by merchant. Character limit: 50. | TXN_BNPL_20261005 |
| currency | String Currency code. Must be "INR". | INR |
| paymentMethod | Object Details about BNPL method. For more information, refer to paymentMethod object. | {"name": "BNPL", "bankCode": "LAZYPAY"} |
| order | Object Details about the transaction order. For more information, refer to order object. | Refer to order section |
| additionalInfo | Object S2S flow configuration and BNPL options. For more information, refer to additionalInfo object. | Refer to additionalInfo section |
| callBackActions | Object Redirection callback URLs. For more information, refer to callBackActions object. | Refer to callBackActions section |
| billingDetails | Object Customer contact and billing address details. See billingDetails object. | Refer to billingDetails section |
paymentMethod object fields description
| Field | Description | Example |
|---|---|---|
name |
|
BNPL |
bankCode |
|
LAZYPAY |
order object fields description
| Parameter | Description | Example |
|---|---|---|
productInfomandatory | Product details. Type: String | Product details |
orderedItemoptional | Details about the items ordered. Type: Array of Objects | |
userDefinedFieldsoptional | Custom fields for additional information. Type: Object. Fields: udf1, udf2, udf3, udf4, udf5, udf6, udf7, udf8, udf9, udf10. | |
paymentChargeSpecificationmandatory | Includes amount and charges. Type: Object. For more information, refer to paymentChargeSpecification object fields description |
paymentChargeSpecification object fields description
| Parameter | Description | Example |
|---|---|---|
pricemandatory | The transaction amount. Type: Number | 1000 |
netAmountDebitoptional | Net amount to be debited. Type: Number | 1000 |
taxSpecificationoptional | Tax details of the product/order. Type: Object | |
convenienceFeeoptional | Fees format. Type: String | CC:12 |
offersoptional | Offers applied or available for the payment. Type: Object |
userDefinedFields object fields description
| Field | Description |
|---|---|
| udf1 | User defined field. |
| udf2 | User defined field. |
| udf3 | User defined field. |
| udf4 | User defined field. |
| udf5 | User defined field. |
| udf6 | User defined field. |
| udf7 | User defined field. |
| udf8 | User defined field. |
| udf9 | User defined field. |
| udf10 | User defined field. |
additionalInfo object fields description
| Field | Description | Example |
|---|---|---|
txnS2sFlow |
|
4 |
createOrder |
|
true |
enforcePaymethod |
|
BNPL |
callBackActions object fields description
| Parameter | Description | Example |
|---|---|---|
successActionmandatory |
URL to be called on payment success. | https://example.com/success |
failureActionmandatory |
URL to be called on payment failure. | https://example.com/failure |
cancelActionmandatory |
URL to be called if user cancels the payment. | https://example.com/cancel |
codActionoptional |
URL for Cash on Delivery (COD) action. | https://example.com/cod |
billingDetails object fields description
| Parameter | Description | Example |
|---|---|---|
firstNamemandatory |
First name of the billing contact. | Ashish |
lastNameoptional |
Last name of the billing contact. | Kumar |
address1mandatory |
Primary billing address. | 123 Main Street |
address2optional |
Secondary billing address. | Apt 4B |
phoneoptional |
Phone number of the billing contact. | 9123456789 |
emailmandatory |
Email address of the billing contact. | [email protected] |
cityoptional |
City of the billing address. | Bharatpur |
stateoptional |
State of the billing address. | Rajasthan |
countryoptional |
Country of the billing address. | India |
zipCodeoptional |
Postal/Zip code of the billing address. | 321028 |
Sample request
curl -X POST 'https://apitest.payu.in/v2/payments' \
-H 'date: Mon, 05 Oct 2026 10:00:00 GMT' \
-H 'authorization: hmac username="<YOUR_TEST_KEY>", algorithm="sha512", headers="date", signature="<SIGNATURE>"' \
-H 'content-type: application/json' \
-d '{
"accountId": "<YOUR_TEST_KEY>",
"txnId": "TXN_BNPL_20261005",
"currency": "INR",
"paymentMethod": {
"name": "BNPL",
"bankCode": "LAZYPAY"
},
"order": {
"productInfo": "Fashion Apparel",
"paymentChargeSpecification": {
"price": 5000.00
},
"userDefinedFields": {
"udf1": "cart_123",
"udf2": "app_checkout"
}
},
"additionalInfo": {
"txnS2sFlow": "4",
"createOrder": true
},
"callBackActions": {
"successAction": "<redacted URL>",
"failureAction": "<redacted URL>",
"cancelAction": "<redacted URL>"
},
"billingDetails": {
"firstName": "John",
"lastName": "Doe",
"phone": "9876543210",
"email": "[email protected]",
"address1": "123 Main Street",
"city": "Mumbai",
"state": "Maharashtra",
"country": "India",
"zipCode": "400001"
}
}'import requests
import json
url = "https://apitest.payu.in/v2/payments"
headers = {
"date": "Mon, 05 Oct 2026 10:00:00 GMT",
"authorization": 'hmac username="<YOUR_TEST_KEY>", algorithm="sha512", headers="date", signature="<SIGNATURE>"',
"content-type": "application/json"
}
payload = {
"accountId": "<YOUR_TEST_KEY>",
"txnId": "TXN_BNPL_20261005",
"currency": "INR",
"paymentMethod": {
"name": "BNPL",
"bankCode": "LAZYPAY"
},
"order": {
"productInfo": "Fashion Apparel",
"paymentChargeSpecification": {
"price": 5000.00
},
"userDefinedFields": {
"udf1": "cart_123"
}
},
"additionalInfo": {
"txnS2sFlow": "4",
"createOrder": True
},
"callBackActions": {
"successAction": "<redacted URL>",
"failureAction": "<redacted URL>",
"cancelAction": "<redacted URL>"
},
"billingDetails": {
"firstName": "John",
"lastName": "Doe",
"phone": "9876543210",
"email": "[email protected]",
"address1": "123 Main Street",
"city": "Mumbai",
"state": "Maharashtra",
"country": "India",
"zipCode": "400001"
}
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())<?php
$url = "https://apitest.payu.in/v2/payments";
$payload = json_encode([
"accountId" => "<YOUR_TEST_KEY>",
"txnId" => "TXN_BNPL_20261005",
"currency" => "INR",
"paymentMethod" => [
"name" => "BNPL",
"bankCode" => "LAZYPAY"
],
"order" => [
"productInfo" => "Fashion Apparel",
"paymentChargeSpecification" => [
"price" => 5000.00
]
],
"additionalInfo" => [
"txnS2sFlow" => "4",
"createOrder" => true
],
"callBackActions" => [
"successAction" => "<redacted URL>",
"failureAction" => "<redacted URL>",
"cancelAction" => "<redacted URL>"
],
"billingDetails" => [
"firstName" => "John",
"lastName" => "Doe",
"phone" => "9876543210",
"email" => "[email protected]",
"address1" => "123 Main Street",
"city" => "Mumbai",
"state" => "Maharashtra",
"country" => "India",
"zipCode" => "400001"
]
]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"date: Mon, 05 Oct 2026 10:00:00 GMT",
"authorization: hmac username=\"<YOUR_TEST_KEY>\", algorithm=\"sha512\", headers=\"date\", signature=\"<SIGNATURE>\"",
"content-type: application/json"
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class PayUBNPLRequest {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String payload = """
{
"accountId": "<YOUR_TEST_KEY>",
"txnId": "TXN_BNPL_20261005",
"currency": "INR",
"paymentMethod": {
"name": "BNPL",
"bankCode": "LAZYPAY"
},
"order": {
"productInfo": "Fashion Apparel",
"paymentChargeSpecification": {
"price": 5000.00
}
},
"additionalInfo": {
"txnS2sFlow": "4",
"createOrder": true
},
"callBackActions": {
"successAction": "<redacted URL>",
"failureAction": "<redacted URL>",
"cancelAction": "<redacted URL>"
},
"billingDetails": {
"firstName": "John",
"lastName": "Doe",
"phone": "9876543210",
"email": "[email protected]",
"address1": "123 Main Street",
"city": "Mumbai",
"state": "Maharashtra",
"country": "India",
"zipCode": "400001"
}
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://apitest.payu.in/v2/payments"))
.header("date", "Mon, 05 Oct 2026 10:00:00 GMT")
.header("authorization", "hmac username=\"<YOUR_TEST_KEY>\", algorithm=\"sha512\", headers=\"date\", signature=\"<SIGNATURE>\"")
.header("content-type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}const url = "https://apitest.payu.in/v2/payments";
const payload = {
accountId: "<YOUR_TEST_KEY>",
txnId: "TXN_BNPL_20261005",
currency: "INR",
paymentMethod: {
name: "BNPL",
bankCode: "LAZYPAY"
},
order: {
productInfo: "Fashion Apparel",
paymentChargeSpecification: {
price: 5000.00
}
},
additionalInfo: {
txnS2sFlow: "4",
createOrder: true
},
callBackActions: {
successAction: "<redacted URL>",
failureAction: "<redacted URL>",
cancelAction: "<redacted URL>"
},
billingDetails: {
firstName: "John",
lastName: "Doe",
phone: "9876543210",
email: "[email protected]",
address1: "123 Main Street",
city: "Mumbai",
state: "Maharashtra",
country: "India",
zipCode: "400001"
}
};
fetch(url, {
method: "POST",
headers: {
"date": "Mon, 05 Oct 2026 10:00:00 GMT",
"authorization": 'hmac username="<YOUR_TEST_KEY>", algorithm="sha512", headers="date", signature="<SIGNATURE>"',
"content-type": "application/json"
},
body: JSON.stringify(payload)
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error("Error:", err));Sample response
{
"status": "PENDING",
"result": {
"checkoutUrl": "<redacted URL>"
},
"txnId": "TXN_BNPL_20261005",
"paymentId": "1999110000001769",
"message": "Redirect customer to checkoutUrl to authenticate BNPL credit line"
}Response parameters
| Parameter | Description |
|---|---|
| message | This parameter contains the status message of the transaction. |
| status | This parameter returns the status of web service call. The status can be any of the following: `0` - If web service call failed. `1` - If web service call succeeded. |
| result | This parameter contains the payment status details in a JSON format including payment ID of the transaction. For more detailes, refer to the result JSON Object fields description table (next accordion) |
Reference:To check the transaction status, refer to Verify Payment API.
Error Codes
| Code | HTTP Status | Description | Resolution |
|---|---|---|---|
INVALID_AMOUNT | 400 | Amount exceeds BNPL credit limit | Verify customer credit line or use another method |
INVALID_CURRENCY | 400 | Unsupported currency | Set currency: "INR" |
AUTHENTICATION_FAILED | 401 | Invalid token or signature | Verify authorization credentials |
DUPLICATE_REFERENCE | 409 | txnId already used | Use unique transaction ID |
PAYMENT_DECLINED | 422 | BNPL provider declined credit | Customer should choose another payment option |
Next Steps
- Redirect to Provider Gateway:
- Redirect the customer to
result.paymentUrlto enter their OTP and complete approval on the chosen BNPL provider's screen.
- Redirect the customer to
- Handle Ineligibility & Credit Rejections:
- If the provider rejects credit authorization, gracefully direct the user back to your checkout to choose standard Cards, UPI, or Net Banking.
- Verify Payment & Fulfill Order:
- Validate the callback response hash and verify transaction status via the Verify Payment API.
