NetBanking Integration
This section explains how to integrate NetBanking payments for cross-border transactions using the Server-to-Server (S2S) flow.
Post the required parameters to PayU for plain card payment
Check and handle the response received from PayU
Verify the payment status and ensure transaction completion
Update the invoice ID associated with the transaction
Upload invoice documents related to the completed transaction
Step 1: Post Parameters to PayU
Post the payment parameters to PayU's _payment API endpoint to initiate a plain card transaction.
Reference: For more information, refer to One-Time Payment for Cards - CB.
Environment
| Environment | URL |
|---|---|
| Test | https://test.payu.in/_payment |
| Production | https://secure.payu.in/_payment |
HTTP Method: POST
Content Type: application/x-www-form-urlencoded
Request Parameters
| Parameter | Description | Example |
|---|---|---|
keymandatory | StringMerchant key provided by PayU during onboarding. | JPM7Fg |
txnidmandatory | StringThe transaction ID is a reference number for a specific order generated by the merchant. Must be unique. | payuTestTxn12345 |
amountmandatory | StringThe payment amount for the transaction. | 100.00 |
productinfomandatory | StringA brief description of the product. Character Limit: 100 | iPhone |
firstnamemandatory | StringThe first name of the customer. Character Limit: 60 | Ashish |
emailmandatory | StringThe email address of the customer. Character Limit: 50 | [email protected] |
phonemandatory | StringThe phone number of the customer. | 9876543210 |
surlmandatory | StringThe Success URL - page PayU will redirect to if the transaction is successful. | https://example.com/success |
furlmandatory | StringThe Failure URL - page PayU will redirect to if the transaction fails. | https://example.com/failure |
pgmandatory | StringThis parameter defined the payment gateway. For NetBanking, pg=NB. | NB |
bankcodemandatory | String. The merchant must post this parameter with the corresponding payment option's bank code value in it. For the list of bank codes that can be used with the bankcode parameter, refer to Net Banking Codes. Reference: For the test Net Banking credentials, refer to Test Cards, UPI ID and Wallets. | TESTPGNB |
txn_s2s_flowmandatory | IntegerParameter to enable S2S flow. Set to 4 for S2S4 flow. | 4 |
s2s_client_ipmandatory | StringClient IP captured by merchant in S2S flow. Required for fraud detection. | 10.200.12.12 |
s2s_device_infomandatory | StringUser Agent captured by merchant in S2S flow. | Mozilla/5.0 (Windows NT 10.0; Win64; x64) PayU-API-Test/1.0 |
udf1conditional | StringUser-defined field 1. For PACB: Buyer's PAN number. | AELPR****E |
udf2optional | StringUser-defined field 2. Character Limit: 255 | - |
udf3 optional but recommended for higher approval rate | String Date of Birth (DOB) of buyer in DD-MM-YYYY | 02-02-1980 |
udf4 mandatory for payment aggregators | String End merchant legal entity name. For UPI, this field should not be passed. Character limit: 255. | XYZ Pvt. Ltd. |
udf5mandatory | String Contains invoice ID for the transaction. Invoice ID / number should be the ID present on the invoice issued to the customer. Character limit: 255. | INV123456 |
buyer_type_businessoptional in case of B2B transaction for cross-border payments | Binary To be sent as "1" in case the buyer is a business. In case of individual buyers, it can be skipped. Default is "0".Note: This will be included in hash if posted (covered in next section). | 1 |
udf_params optional | String JSONUDF7 value to capture "Import or Export Code" of the buyer UDF8 value to capture Airway Bill Number / Consignment Number (in case of goods imports) Note: This must be included in hash if posted (check below this table). | {"udf7":"0100000029", "udf8":"99953729071"} |
hashmandatory | String Crucial security parameter using SHA512 hash encryption. Formula incorporates key, txnid, amount, productinfo, firstname, email, udf fields, si_details, and merchant salt. | <Generated Hash> |
Hash Generation
Parameters in the below sequence needs to be checked before generating the hash, if these params are being posted, it needs to be added in the hash calculation:
|additional_charges|miles|base_payuid|base_merchantid|paisa_mecode|subvention_amount|subvention_eligibility|merchant_data|payoutdetails|loan_id|twid_customer_hash|splitrequest|percentage_additional_charges|force_pa|udf_params|buyer_type_business|tcs_amount
- Case1 example: Simple Hashing, if the merchant is not sending the api_version in the payment request, then it will be treated as hash sequence version 1.
key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5||||||si_details|salt
- Case2 example: if the merchant is passing the additional_charges in the payment request then they have to append the additional_charges value in the raw hash sequence as below.
key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5||||||si_details|salt|additional_charges
- Case3 example: If the merchant wants to pass additional_charges, buyer_type_business in the payment request, then hash formula for payment request will be:
key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5||||||si_details|salt|additional_charges|buyer_type_business
- Case4 example: if the merchant wants to pass the api_version = 7 and buyer_type_business, udf_params in the payment request.
key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5||||||si_details|salt|udf_params|buyer_type_businesskey|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5|udf6|udf7|udf8|udf9|udf10|salt|additional_charges|buyer_type_business- Case4 example: if the merchant wants to pass the api_version = 7 and buyer_type_business, udf_params in the payment request.
key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5|udf6|udf7|udf8|udf9|udf10|si_details|salt|udf_params|buyer_type_businessSample Request
curl --location --request POST 'https://test.payu.in/_payment' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'key=JPM7Fg' \
--data-urlencode 'txnid=payuTestTransaction12345' \
--data-urlencode 'amount=100.00' \
--data-urlencode 'firstname=Ashish' \
--data-urlencode '[email protected]' \
--data-urlencode 'phone=9988776655' \
--data-urlencode 'productinfo=Product Info' \
--data-urlencode 'surl=https://test.payu.in/admin/test_response' \
--data-urlencode 'furl=https://test.payu.in/admin/test_response' \
--data-urlencode 'pg=NB' \
--data-urlencode 'bankcode=TESTPGNB' \
--data-urlencode 'txn_s2s_flow=4' \
--data-urlencode 's2s_client_ip=10.200.12.12' \
--data-urlencode 's2s_device_info=Mozilla/5.0 (Windows NT 10.0; Win64; x64) PayU-API-Test/1.0' \
--data-urlencode 'udf1=AELPR1234E' \
--data-urlencode 'udf3=02-02-1980' \
--data-urlencode 'udf4=XYZ Pvt. Ltd.' \
--data-urlencode 'udf5=INV123456' \
--data-urlencode 'buyer_type_business=1' \
--data-urlencode 'udf_params={"udf7":"0100000029","udf8":"99953729071"}' \
--data-urlencode 'hash=YOUR_CALCULATED_HASH'Step 2: Handle the Initiate Response from PayU
After posting the payment request, PayU returns a response containing transaction status and next steps for 3DS authentication.
Response Parameters
| Parameter | Description | Example |
|---|---|---|
| metaData | ObjectJSON object containing transaction metadata. | - |
| metaData.referenceId | StringPayU reference ID to be sent back in subsequent calls. | 5a3e7cb9884e003dce1f28f965478a9a12fb9244fc15be91b0b3de48763a12e7 |
| metaData.txnId | StringMerchant's transaction ID. | payuTestTransaction12345 |
| metaData.txnStatus | StringTransaction status (e.g., "Enrolled"). | Enrolled |
| metaData.unmappedStatus | StringStatus for flow control: pending, captured, or failed. | pending |
| result.otpPostUrl | StringURL to post OTP for verification. | https://test.payu.in/ResponseHandler.php |
| result.acsTemplate | StringBase64 encoded HTML form for bank ACS redirect. | PGh0bWw+PGJvZHk+... |
| binData.pureS2SSupported | BooleanWhether native S2S OTP flow is supported. | true |
| binData.issuingBank | StringCard issuing bank. | AXIS |
| binData.category | StringCard category ( creditcard or debitcard). | creditcard |
| binData.cardType | StringCard network ( VISA, MAST, RUPAY). | MAST |
| binData.isDomestic | BooleanWhether the card is domestic. | true |
Sample Response
{
"metaData": {
"message": null,
"referenceId": "e1bc7be8c52b8f269124e723b2d201800a629895299f5628fe168a9c8dc40f5e",
"statusCode": null,
"txnId": "my_order_89122",
"txnStatus": "pending",
"unmappedStatus": "pending"
},
"result": {
"acsTemplate": "PGh0bWw+PGJvZHk+PGZvcm0gbmFtZT0icGF5bWVudF9wb3N0IiBpZD0icGF5bWVudF9wb3N0IiBhY3Rpb249Imh0dHBzOi8vcGdzaW0wMS5wYXl1LmluL2luaXRpYXRlIiBtZXRob2Q9InBvc3QiPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9Im1lcmNoYW50TmFtZSIgdmFsdWU9IlBBWVUiPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9Im1lcmNoYW50Q29kZSIgdmFsdWU9IlNsRXNjdUpBOTgiPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9Im1lck5hbWUiIHZhbHVlPSJTdWRoYW5zaHUiPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9InR4bkFtb3VudCIgdmFsdWU9IjEuMDAiPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9InR4bkRhdGUiIHZhbHVlPSIyMDI2LTAzLTA1Ij48aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJ0eG5DdXJyZW5jeSIgdmFsdWU9IklOUiI+PGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iY3VzdE5hbWUiIHZhbHVlPSIiPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImN1c3RFbWFpbCIgdmFsdWU9IiI+PGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iY3VzdE1vYmlsZSIgdmFsdWU9IjkzNjgyNTIyNDgiPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9InR4blJlZklkIiB2YWx1ZT0ibXlfb3JkZXJfODkxMjIiPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImxpdmVtb2RlIiB2YWx1ZT0iZmFsc2UiPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9InNvdXJjZSIgdmFsdWU9IiI+PGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iUlUiIHZhbHVlPSJodHRwczovL3Rlc3QucGF5dS5pbi9lMWJjN2JlOGM1MmI4ZjI2OTEyNGU3MjNiMmQyMDE4MGUxM2Y0ZjQ2YTk5OTQyMDdkYmZhOWQxMjYzYTBhZjA0L1Rlc3RQZ19yZXNwb25zZS5waHAiPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9Im1vZGUiIHZhbHVlPSJUa0k9Ij48aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJ0eG5EZXNjcmlwdGlvbiIgdmFsdWU9IlRlc3QgTmV0IEJhbmtpbmcgUGF5bWVudCI+PGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iaWJpYm9fY29kZSIgdmFsdWU9IkFYSUIiPjwvZm9ybT48c2NyaXB0IHR5cGU9J3RleHQvamF2YXNjcmlwdCc+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cub25sb2FkPWZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZm9ybXNbJ3BheW1lbnRfcG9zdCddLnN1Ym1pdCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICA8L3NjcmlwdD48L2JvZHk+PC9odG1sPg==",
"otpPostUrl": "https://test.payu.in/ResponseHandler.php"
}
}Handling the Response
In S2S4, rely on the metaData.unmappedStatus field from the response JSON. Perform the following actions based on its value:
- If metaData.unmappedStatus = 'pending':
- Check the value of the binData.pureS2SSupported parameter:
- If binData.pureS2SSupported = true:
- Invoke the OTP page and present it to the customer, Use Submit OTP API to Collect & Submit OTP from your Page.
- If the customer opts to redirect to the bank ACS for entering the OTP, provide a "Redirect to Bank Page" link. Upon selection, load the value of the result.acsTemplate parameter as the Bank Form by decoding it using base64 encoding formula.
- If binData.pureS2SSupported = false:
- Redirect the customer using the result.acsTemplate parameter, which contains a Base64-encoded HTML form.
- Check the value of the binData.pureS2SSupported parameter:
- The metaData.referenceId value from the response JSON will be used as the input for the referenceId parameter in both the submitOtp and resentOtp APIs.
- If metaData.unmappedStatus = 'failure', refer to the metaData.statusCode and metaData.msg fields for details on the failure reasons.
Based on the unmappedStatus value, take the following actions:
| Status | Action |
|---|---|
pending | Proceed with 3DS authentication using the acsTemplate or OTP flow |
captured | Transaction successful, no further action needed |
failed | Transaction failed, display error to customer |
Redirect the customer using the result.acsTemplate(base64encoded) to their bank's page for authentication. The final response will be posted to surl/furl and the configured Webhook.
Reference: PayU recommends you to use PayU Hash Verification Tool to verify the reverse hashing. For more information, refer to Using PayU Hash Verification Tool
Step 3: Verify the payment
After the payment is complete, verify the transaction status using PayU's verification APIs.
Verification Methods
Use one of the following methods to verify the payment:
- Webhook/Callback: PayU sends a POST request to your
surlorfurlwith transaction details - Verify Payment API: Call the
verify_paymentAPI with the transaction ID
Verify Payment API
curl --location --request POST 'https://info.payu.in/merchant/postservice.php?form=2' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'key=JPM7Fg' \
--data-urlencode 'command=verify_payment' \
--data-urlencode 'var1=payuTestTransaction12345' \
--data-urlencode 'hash=YOUR_CALCULATED_HASH'Use the webhooks to verify the payment. The following is the sample webhook payload in response. For more information, refer to Webhook Events and Sample Payloads.
Sample Webhook Response
mihpayid=27553369917
&mode=SBQR
&status=success
&key=rZ1fX4
&txnid=T2603041446091822117753
&amount=40.00
&addedon=2026-03-04+14%3A46%3A14
&productinfo=Static+QR
&firstname=
&lastname=
&address1=
&address2=
&city=Gurgaon
&state=
&country=
&zipcode=122001
&email=
&phone=##########
&udf1=
&udf2=
&udf3=
&udf4=SoftQR
&udf5=BFL0000006601446
&udf6=
&udf7=
&udf8=
&udf9=
&udf10=
&card_token=
&card_no=
&field0=STQ9IUFeqlafg78815827
&field1=PRIYA+SHANKAR+PUSNAKE
&field2=995486
&field3=_mobilenum_%40axl
&field4=bajajpay.6879729.d2m9cckd%40indus
&field5=AXLd36cfcd317f243b5b3a2d62bc71caf78
&field6=00000038683323284%7C_mobilenum_%7CSBIN0011418
&field7=APPROVED+OR+COMPLETED+SUCCESSFULLY%7C00
&field8=Payment+from+PhonePe
&field9=Transaction+is+Successful.+Bank+Sent%3ATransaction+success
&payment_source=payu
&cardToken=
&authenticaticationMethod=
&PG_TYPE=SBQR-PG
&error=E000
&error_Message=No+Error
&net_amount_debit=40
&discount=0.00
&offer_key=
&offer_availed=
&unmappedstatus=captured
&hash=aefe0213c4299c7ee2039d5430f7bee63711ee627e1b47d2605d0384abbbf828f3641dae3cb126c8b2f761084cbb0bebad27bb325696cc44ce3061157d7cd9ff
&bank_ref_no=793887773815
&bank_ref_num=793887773815
&bankcode=UPISBQR
&surl=
&curl=
&furl=
&psp_nStep 4: Update Invoice ID [Conditional]
If the Invoice ID value was unavailable when posting the transaction at Step 1, it can be updated using the UDF Update API by posting it in the UDF5 parameter.
Environment
| Test Environment | <https://test.payu.in/merchant/postservice.php?form=2> |
| Production Environment | <https://info.payu.in/merchant/postservice.php?form=2> |
Sample request other then UPI AutoPay
curl --location --globoff 'https://test.payu.in/merchant/postservice.php?form=2' \
--form 'key="PRiQvJ"' \
--form 'command="udf_update"' \
--form 'var1="my_order_642"' \
--form 'var2="AAAPZ1234C"' \
--form 'var4="22/08/1972"' \
--form 'var5="SellerName"' \
--form 'var6="INV000000005"' \
--form 'hash="{{hash}}"'Sample request for UPI AutoPay
curl --location 'https://test.payu.in/merchant/postservice.php?form=2' \
--form 'key="PRiQvJ"' \
--form 'command="udf_update"' \
--form 'var1="my_order_642"' \
--form 'var2="AAAPZ1234C||22-08-1972"' \
--form 'var4="INV_121312||SellerName"' \
--form 'hash="{{hash}}"'Sample response
Success Scenario
- If successfully updated for cards or Net Banking
{
"status": "UDF values updated",
"transaction_id": "my_order_64240",
"udf1": "AAAPZ1234C",
"udf2": "",
"udf3": "22/08/1972",
"udf4": "SellerName",
"udf5": "INV000000005"
}- If successfully updated for UPI autopay:
{
"status": "UDF values updated",
"transaction_id": "my_order_64240",
"udf1": "AAAPZ1234C||22-08-1972",
"udf2": "",
"udf3": "INV_121312||SellerName"
}Failure Scenarios
- If the transaction ID is empty
(
[status] => 0
[msg] => Parameter missing
) - If the transaction ID is invalid
(
[status] => 0
[msg] => Invalid TXN ID
) - If Hash is invalid:
{
"status": 0,
"msg": "Invalid Hash."
}- If the merchant is not enabled for UDF updates:
{
"status": "0",
"msg": "Update not allowed on provided Field"
}- If no data found in the transaction ID:
{
"status": "0",
"msg": "No Data Found for txnid: 3424"
}- If the merchant is inactive:
{
"msg": "Merchant is not authorized to use PayU API",
"status": 0
}Step 5: Upload the Invoices [Optional]
The invoices / Airway Bill can be uploaded using the Invoice Upload API API. AWB details are mandatory for Goods transactions. Invoice copies can be uploaded optionally.
Environment
| Test Environment | <https://test.payu.in/merchant/postservice.php?form=2> |
| Production Environment | <https://info.payu.in/merchant/postservice.php?form=2> |
Sample request
curl --location -g --request POST '{{baseUrl}}/merchant/postservice?form=2' \
--form 'key="{{merchantKey}}"' \
--form 'command="opgsp_upload_invoice_awb"' \
--form 'var1="403993715525825059"' \ - PayuId
--form 'var2="TestInv0001234568"' \ - invoice Id
--form 'var3="Invoice"' \ - type of upload - Invoice/AWB
--form 'file=@"/path/to/file"' \ - file
--form 'hash="{{hash}}"' Sample response
Success Scenario
- When a file is uploaded successfully:
{
"responseCode":"00",
"responseMsg":"File Uploaded Successfully"
}Failure Scenarios
- When there is an error in uploading the file:
{
"responseCode": "103",
"responseMsg": "Failed to Upload"
} - When the file format is not supported:
{
"responseCode": "105",
"responseMsg": "Not an PACB merchant, contact KAM"
} - When the payuid is invalid:
{
"responseCode":"107",
"responseMsg":"The PayuID in request is invalid"
}- When a mandatory field is missing:
{
"responseCode":"109",
"responseMsg":"All fields are mandatory, please check!"
} Response Code and Description
Error Handling
If any error message is displayed with an error code, refer to Error Codes to understand the reason. For error codes during various transaction stages, refer to Transaction Stages - Error References.
Updated about 2 hours ago
