UPI (Unified Payments Interface) is one of India’s most popular digital payment systems, enabling instant, secure, and real-time payments directly from customers’ bank accounts. Managed by the National Payments Corporation of India (NPCI), UPI has revolutionized digital transactions in India with features like 24/7 availability, multi-bank support, and seamless transaction processing. Integrating UPI with EBANX allows international merchants to accept payments from Indian customers using one of the most trusted payment methods in the region.
Requirements
- API credentials - Ensure you have your EBANX integration key. If not, complete the Merchant Signup Form.
- Familiarity with EBANX Direct - This setup follows the same general structure as other payment methods, with a few unique parameters.
Workflow options
UPI offers two distinct payment flows to accommodate different user interactions:
- UPI QR Code - This flow generates a QR code that users scan with their UPI app. It redirects them to the app, where the payment details are pre-filled. Users then enter their UPI PIN to complete the transaction.
- UPI Intent - This flow is designed for mobile devices. Users tap to pay, pre-selecting their UPI app (or a generic option). The deep link redirects them directly to the chosen app, with pre-filled payment details, where they authenticate the transaction with their UPI PIN.
The main difference is in how each flow is initiated: upi-qrcode requires scanning a QR code, while upi-intent involves tapping and selecting the UPI app.
How it Works
- Customer initiates payment - At checkout, the customer selects UPI as their preferred payment option.
- Payment method selection - The customer can choose between scanning a QR code (upi-qrcode) or tapping to pay using a specific UPI app (upi-intent).
- Redirection to UPI app
- For upi-qrcode, the user scans the QR code, which redirects them to the UPI app with pre-filled payment details.
- For upi-intent, the user is directly redirected to their chosen UPI app with pre-filled payment details.
- UPI PIN authentication - In the UPI app, the customer enters their UPI PIN to authorize and complete the transaction.
- Payment confirmation - Once the transaction is successful, the customer receives a confirmation notification in their UPI app, and the merchant is updated with the transaction status.
- EBANX notification - EBANX sends a notification to the you, confirming the successful transaction, allowing you to fulfill your customer's order.
Instructions
Follow the steps below.
- Select your environment
Select the appropriate environment for your integration. Use the sandbox environment for testing, or the production environment for live transactions. Use the URL for your HTTP requests based on your selection.
https://sandbox.ebanx.com/ws/direct Define your parameters
Basic parameters
Parameter Requirement Description integration_keyRequired Your EBANX integration key payment_type_codeRequired Set to upi-qrcodefor QR Code orupi-intentfor Intent paymentscountryRequired Set to infor IndiaCustomer data
Parameter Requirement Description nameRequired Customer's full name
Note: Minimum 5 characters, alphabets onlyemailRequired Customer's email phone_numberRequired Customer's phone
Note: Minimum 8 digits, maximum 10 digits, numbers onlyaddressRequired Customer's address
Note: Minimum 3 charactersstreet_numberOptional Customer's street number cityRequired Customer's city
Note: Minimum 3 characters, alphabets onlystateRequired Customer's state
Note: Refer this for state list. Either use state code or state namezipcodeRequired Customer's zipcode or pincode
Note: Must be 6 digits, numbers onlyCharge parameters
Parameter Requirement Description merchant_payment_codeRequired Unique Payment Reference Number as defined by Merchant currency_codeRequired Set to INRamount_totalRequired Total amount to be charged - UPI QR Code
In the upi-qrcode flow, users scan a QR code, which redirects them to their UPI app to complete the transaction. Upon redirection, the UPI app loads the pre-filled payment details and prompts the user to enter their UPI PIN for authentication, finalizing the transaction.
Request
Use the following example to initiate a request.
curl -X POST \
--location 'https://sandbox.ebanx.com/ws/direct' \
--header 'Content-Type: application/json' \
--data '{
"integration_key": "your_ebanx_integration_key",
"payment": {
"name": "John Doe",
"email": "john.doe@example.com",
"phone_number": "7000000000",
"address": "MG Road",
"street_number": "101",
"city": "Bangalore",
"state": "KA",
"zipcode": "560001",
"country": "in",
"payment_type_code": "upi-qrcode",
"merchant_payment_code": "0x012B01-IN-U01",
"order_number": "1234567",
"currency_code": "INR",
"amount_total": "100.00"
}
}'Response
A successful request returns a response like the example below.
{
"payment": {
"hash": "<{hash_here}>",
"country": "in",
"merchant_payment_code": "0x012B01-IN-U01",
"order_number": "1234567",
"status": "PE",
"status_date": null,
"open_date": "2024-01-01 01:01:01",
"confirm_date": null,
"transfer_date": null,
"amount_br": "100.00",
"amount_ext": "100.00",
"amount_iof": "0.00",
"currency_rate": "1.0000",
"currency_ext": "INR",
"due_date": "2024-01-01 01:06:01",
"instalments": "1",
"payment_type_code": "upi-qrcode",
"pre_approved": false,
"capture_available": null,
"upi": {
"qr_code_value": "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAABlBMVEX///8AAABVwtN+AAAACXBIWXMAAA7EAAAOxAGVKw4bAAADn0lEQVRogdVZQZKkMAwzxSFHnsBP4GNdDVN8LP2TPIFjDhReSWFmZ097xOTUgLoKJ7IsG3Os/T2s44Yfda6d58F3G1Y7Rtw5LQKgmnX74l56XCa3Wf94DZsfo5lNMQCzf/Zl78tr9OIZgHM4EYONx5i8BgLYcIwrAMnTaTOCUgzBAB22mlFwo7H3Nmz7yx4FIGHeg/uBO+7W1Qms5uHYL0bdDLhSb0MUfalz+gDwRVaXf3PzVoDW4qQLAdY1ku9LsV/rbkBLvaW8mmrpxaEO0jTjxRMA6bNPiqb3vkDnPiL5Ohy4YaRTBABeGXd2g4AY2ZPxj8UP0BxHY+kMAajdDhqDMOvIrYYgQCx2/A8kh+zFAJDGKBEb5AD1gkXt41+MAo+lEBEAkINsb1OJsMSthlxg/8kHFOKnAFpcm6/GqieOdAhza2FOIQB46UmJtzZ1yPZNGfInDmCGIBysu0YvBrvIoFAvWOXOEIDrtVdrSstii6LWK/mM+/4IQEWQ1F4+1OZDjGl6vQnxFAKAl87DqvYBLjdD5QxRLIwCNA8DgMtlj0P/ANNLb956HJN6RAFYozGiqCZ70NGqgw8VYYUANNvCa6zUPAwt7qYH6XwGAFLMemEkDGwZnPmMPETqjSofMQCIgHbxBX1gYw5nTh/GgwHJC88iAuCjKF60iyy1iEJppyjYBEcApIzDR+dVaLzULc5ytIv4gNR7BOBSi5ctRZ07zwKcxuEwTNE+ACAPMDl7r3mCZ289DuKQvWQUAQCyiywPoEyRyoE/bZbEyptDAHDdwcT2RVWM9mBWJi5SZk4PAgDU46zoFqgPiYaGIsbVxPcZADncTgaSnTi8+cyax8nNKAGJAFBJcymvaZRAsfgpzUEAMjnN05IwtcPeL5rTyj+eIQCQqck4hutbx5vpaSFiastpFx8BQJBkiGuaRJJz+9W40ajXIICWXcfIcSIH4ojihMlhvagm9P0AWnGonIaJjGKuplJMO6HiEQLAyuscebHUZnp1BnX9A5cRAOwWnI3YNd9011a7LgtL8xMAWqh6/tuZD5zb0JmnMwSA743T2EoPUTM6c2smx/ix6fvjws0AfQGxa3ZsmtszCk6TTHYxBIBj+bdUq5fxhn88aXFaH5kfBFjAj4XDxNkmpGMnZ87nP18nAwD4sYlFgg+ruomBI5GfGentABKGI6+jfcadkj6Iy/T+ZfXNgCv1UNSQerSLFz3kaMe/+nAr4H/rD82DGsSsJwHxAAAAAElFTkSuQmCC",
"expiration_date": "2024-01-01 09:36:01"
}
},
"status": "SUCCESS"
}The Base64 encoded
qr_code_valuewill be used to render the QR Code. - UPI Intent
In the upi-intent flow, mobile users select their preferred UPI app or choose the ‘Other UPI app’ option at checkout before proceeding with payment. Upon clicking to pay, they are redirected to their chosen UPI app. The app then loads the pre-filled payment details and prompts the user to enter their UPI PIN for authentication, completing the transaction.
Request
Use the following example to initiate a request.
curl -X POST \
--location 'https://sandbox.ebanx.com/ws/direct' \
--header 'Content-Type: application/json' \
--data '{
"integration_key": "your_ebanx_integration_key",
"payment": {
"name": "John Doe",
"email": "john.doe@example.com",
"phone_number": "7000000000",
"address": "MG Road",
"street_number": "101",
"city": "Bangalore",
"state": "KA",
"zipcode": "560001",
"country": "in",
"payment_type_code": "upi-intent",
"merchant_payment_code": "0x012B01-IN-U02",
"order_number": "1234567",
"currency_code": "INR",
"amount_total": "100.00"
}
}'Response
A successful request returns a response like the example below.
{
"payment": {
"hash": "<{hash_here}>",
"country": "in",
"merchant_payment_code": "0x012B01-IN-U02",
"order_number": "1234567",
"status": "PE",
"status_date": null,
"open_date": "2024-01-01 01:01:01",
"confirm_date": null,
"transfer_date": null,
"amount_br": "100.00",
"amount_ext": "100.00",
"amount_iof": "0.00",
"currency_rate": "1.0000",
"currency_ext": "INR",
"due_date": "2024-01-01 01:06:01",
"instalments": "1",
"payment_type_code": "upi-intent",
"pre_approved": false,
"capture_available": null,
"upi": {
"app_links": [
"gpay://upi/pay?pa=pay.merch0000000@bankltd&pn=Merchant&am=1.00&tr=000000000000&mc=0000&mode=00&purpose=00",
"phonepe://pay?pa=pay.merch0000000@bankltd&pn=Merchant&am=1.00&tr=000000000000&mc=0000&mode=00&purpose=00",
"paytmmp://pay?pa=pay.merch0000000@bankltd&pn=Merchant&am=1.00&tr=000000000000&mc=0000&mode=00&purpose=00",
"upi://pay?pa=pay.merch0000000@bankltd&pn=Merchant&am=1.00&tr=000000000000&mc=0000&mode=00&purpose=00"
],
"expiration_date": "2024-01-01 09:36:01"
}
},
"status": "SUCCESS"
}App Links (Deep Links)
Deep links are URLs that direct users to a specific app or page within an app, enabling seamless navigation directly to the desired content. The deep link details for launching specific UPI apps are provided within the
app_linksobject.-
Generic UPI App Link - When creating a URL to initiate a payment with a generic UPI app (instead of a specific one like Google Pay), you need to modify the URL structure:
- Original URL for Google Pay -
"gpay://upi/pay?"or"tez://upi/pay?"– This prefix is specifically for Google Pay. - Modified URL for a Generic UPI App -
"upi:/pay?"– This is a standardized prefix that works with any UPI app.
- Original URL for Google Pay -
By changing the prefix from Google Pay to generic, you ensure compatibility with all UPI apps, allowing users to complete the payment using their preferred app, not just Google Pay. All other URL parameters related to the transaction remain the same.
Redirection behavior
The redirection behavior for the generic URL varies between Android and iOS devices. On Android, users will see a list of compatible apps installed on their device and can select their preferred app. On iOS, users are automatically redirected to a default app (Generic UPI App link is not recommended to be used on iOS).
-
- Monitor payment for status changeAt this stage, the payment will appear as pending (PE) in yourEBANX Dashboardchevron_right
After completing UPI PIN authentication, your customer will receive a confirmation notification on their UPI app, indicating that the payment was successful.
Notifications
-
EBANX will send a notification whenever a payment status changes.
-
Make sure your system is set up to receive notifications from EBANX for any changes in payment status.
Status
-
After receiving a notification that status has changed, retrieve the payment status.
-
When a payment is confirmed, the status will change from pending (PE) to confirmed (CO). If the customer does not complete the payment, the status will eventually change to cancelled (CA).
-
- Vertical Requirements
This section illustrates any additional requirement for the verticals mentioned below.
Physical Goods
For merchants dealing in physical goods, a 6 or 8 digit HSN Code (i.e. Harmonized System of Nomenclature, a global standard used to classify goods) must be passed against the parameter
hsn_codeunder the arrayitemsin thews/directrequest.Note- Please review the Indian Government’s Foreign Trade Policy and do not trade in any restricted goods
- For the latest information on HSN codes, please refer to the Indian GST Department’s website
Parameter
Parameter Requirement Description payment.items[].hsn_codeMandatory HSN code of each distinct item
Note: Must be 6 or 8 digit code only. 2 or 4 digit codes are not acceptedPoints to Consider
DOs DON'Ts Only send 6 or 8 digit HSN code Don’t send blank, 2 or 4 digit HSN code Send distinct HSN code for each category of good under the transaction Don’t send a single HSN code for different categories of goods Send one HSN code if the category of good is same and only quantity varies Don’t send HSN codes restricted for trade by the Indian Government Request
Check the following sample request.
# ****** Only for Physical Goods merchants ******
curl -X POST \
--location 'https://sandbox.ebanx.com/ws/direct' \
--header 'Content-Type: application/json' \
--data '{
"integration_key": "your_ebanx_integration_key",
"payment": {
"name": "John Doe",
"email": "john.doe@example.com",
"phone_number": "7000000000",
"address": "MG Road",
"city": "Bangalore",
"state": "KA",
"zipcode": "560001",
"country": "in",
"payment_type_code": "upi-qrcode",
"merchant_payment_code": "0x012B01-IN-U01",
"order_number": "1234567",
"currency_code": "INR",
"amount_total": "100.00",
"items": [
{
"hsn_code": "61091000"
},
{
"hsn_code": "84713000"
}
]
}
}'Response
No change to the response. It will remain as shown earlier.Other Verticals
For other supported category of merchants, no additional information is required.
- Congratulations!
You have succesfully integrated UPI.
For more information, refer to theDirect API reference guidechevron_right
Expected Error Codes
If your payment request is not hard-declined (BP-DRs) by our business rules, we will send it to the customer's bank. However, the bank may still reject the payment attempt.
Please refer to the Error Codes listed under Resources for more info on hard declines.
In this case, the payment will move to CA (canceled) status and the reason will be included in the transaction_status node of the payment query response. In that section, you’ll find both the description and the description_code that indicate the reason for the cancellation. See the example below:
"transaction_status": {
"code": "NOK",
"description": "Insufficient funds in the user's account",
"description_code": "INSUFFICIENT_FUNDS"
}
For cancelled payments, the field code will be always NOK(not ok). Below you can find the possible description_code and description values:
| Description Code | Description Message | Details |
|---|---|---|
INVALID_MPIN_OR_OTP | Authentication failed due to incorrect input by user | The user failed to validate the request correctly. |
TIMEOUT_REMITTER_BANK_UNAVAILABLE | External service not available, try again | The user's bank was unavailable and did not respond to our payment scheduling attempt. Please try later. |
USER_ACCOUNT_CLOSED | User account is closed or blocked | The user's bank account is either closed or has a debit freeze. Please request user to try with a different VPA/account. |
REMITTER_BANK_NOT_AVAILABLE | Bank doesn't support the payment method | Remitter bank is either not live or doesn't support the payment method. |
TECHNICAL_ERROR | Technical failures or gateway errors | The payment failed due to gateway-level errors. Please try later. |
DUPLICATE_TRANSACTION | Duplicate Mandate/transaction request | Expected when a request for the same mandate/transaction has been made twice. |
LIMIT_EXCEEDED | Limit restrictions in the user's account | This can be due to breach in number of attempts allowed as per the remitter's bank. |
DO_NOT_HONOUR | Payment rejected by bank due to internal checks | Bank has declined to process the transaction due to internal checks. |
INSUFFICIENT_FUNDS | Insufficient funds in the user's account | The user account has insufficient balance for the transaction at this moment. Please try later. |
INVALID_PARAM | Parameter is invalid | One of the parameters such as currency, etc. is invalid. Please recheck before retrying. |
INVALID_AMOUNT | Value sent in the amount field is incorrect | Expected when the amount field value is incorrect. Please revalidate the amount before retrying. |
INVALID_VPA | VPA is either invalid or inactive | The VPA used for this transaction is not active or present. Please ask user to try with a valid and active VPA. |
CANCELED_BY_PAYER | User has declined the transaction | This error is received when user proactively declines or rejects the payment. |
NO_ACTION_BY_PAYER | Authentication not completed by user | This error is received when user fails to complete authentication before request expiry. |
ATTEMPTS_EXCEEDED_MPIN_OR_OTP | Authentication failed due to incorrect input by user | The user failed to validate the request correctly within the allowed attempts. |
TIMEOUT_ACQUIRING_BANK_UNAVAILABLE | External service not available, try again | The bank was unavailable and did not respond to our payment scheduling attempt. Please try later. |
TIMEOUT | External service not available, try again | The payment failed due to gateway-level errors. Please try later. |
SUSPECTED_FRAUD_REMITTER_BANK | Fraudulent transaction as per bank system | Remitter bank has declined due to internal risk checks. |
CUSTOMER_NUMBER_OR_ACCOUNT_CHANGE | User account has undergone changes to primary values | If the user's bank account or number is changed, the payment will fail. Please request user to try with a different VPA/account. |
MAX_AMOUNT_EXCEEDED | Mandate amount as set by bank exceeded | This can be due to breach in per transaction limit or per day limits defined at remitter's bank. |
TIMEOUT_BENEFICIARY_BANK_UNAVAILABLE | External service not available, try again | The bank was unavailable and did not respond to our payment scheduling attempt. Please try later. |
PAYEE_BLOCKED_AT_REMITTER | Merchant blocked at Remitter Bank due to internal checks | Merchant has been blocked at remitter bank due to their internal fraud or risk checks. |
BIN_MISMATCH | BIN mismatch for UPI on CC transactions | There seems to be an issue with the linked card. Please request user to try with a different account/card. |
TIMEOUT_NPCI_UNAVAILABLE | External service not available, try again | Network was temporarily unavailable. Please try later. |
BP-DR-86 | Parameter is invalid | The parameter sent was not valid. You would receive this in sync response. |
BP-REF-15 | Invalid operation: X | You are trying an invalid operation. You would receive this in sync response. |
DEFAULT_ERROR | Unknown error | You will receive this when an unexpected error is received from the network. |
UPI Intent UX flow
This demo illustrates the end-to-end payment experience with UPI Intent (or UPI App) flow. The journey begins on the merchant's checkout page, where the customer selects UPI App. After submitting the request, the generic intent link (only applicable for Android devices) is invoked on merchant checkout which opens the Android tray of UPI Apps. User clicks on the desired UPI app which redirects the user to the application. The user reviews and approves the payment directly within the app, and once confirmed, both the customer and the merchant receive immediate payment confirmation.
- This method only works on mobile flows i.e. app or mweb. Intent flow doesn’t work on tab or desktop web flows
- Generic intent link only works on Android. For iOS, this functionality doesn’t exist due to OS limitations. This option should not be shown on iOS
- Use a reverse timer to highlight end of payment session to user (industry wide norm is 5 minutes). User is expected to complete payment authentication during this time
UPI QR Code UX flow
This demo illustrates the end-to-end payment experience with UPI QR code flow. The journey begins on the merchant's checkout page, where the customer selects UPI QR code. After submitting the request, the Qr code is shown on the checkout page for user to scan. User selects their desired UPI app and scans the QR code shown. The user reviews and approves the payment directly within the app, and once confirmed, both the customer and the merchant receive immediate payment confirmation.
- This method is most preferred on desktop flows but can still work on mobile flows through "Download QR" option
- There should be a “Download QR” option if the method is being shown on mobile flows
- Use a reverse timer (industry wide counter norm is 5 minutes) to highlight end of payment session to user. User is expected to complete payment authentications during this time
- It is recommended to add a step wise user guidance (as shown above) on the checkout page along with the reverse timer for better user experience, such as:
- Step 1: Open your UPI app
- Step 2: Scan the QR code shown above
- Step 3: Authorise the payment with UPI PIN
- Step 4: Do not refresh this page and wait for final status
Resources
Use the following resources when testing in your sandbox environment.
Sample Cards
Click here to view mock card data to validate your payment integration.
API Reference
Click here to access detailed API documentation to integrate efficiently.
Mock Customer Data
Click here to view mock customer data for testing and validating user flows.
Error Codes
Click here to review common error codes to troubleshoot and resolve issues quickly.
Still need help?
We hope this article was helpful. If you still have questions, you can explore the following options:
- Merchant support: Contact our support team at sales.engineering@ebanx.com for assistance.
- Not a partner yet? Please complete the Merchant Signup Form, and our commercial team will reach out to you.