Skip to main content

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.

  1. 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
  2. Define your parameters

    Basic parameters

    ParameterRequirementDescription
    integration_keyRequiredYour EBANX integration key
    payment_type_codeRequiredSet to upi-qrcode for QR Code or upi-intent for Intent payments
    countryRequiredSet to in for India

    Customer data

    ParameterRequirementDescription
    nameRequiredCustomer's full name
    Note: Minimum 5 characters, alphabets only
    emailRequiredCustomer's email
    phone_numberRequiredCustomer's phone
    Note: Minimum 8 digits, maximum 10 digits, numbers only
    addressRequiredCustomer's address
    Note: Minimum 3 characters
    street_numberOptionalCustomer's street number
    cityRequiredCustomer's city
    Note: Minimum 3 characters, alphabets only
    stateRequiredCustomer's state
    Note: Refer this for state list. Either use state code or state name
    zipcodeRequiredCustomer's zipcode or pincode
    Note: Must be 6 digits, numbers only

    Charge parameters

    ParameterRequirementDescription
    merchant_payment_codeRequiredUnique Payment Reference Number as defined by Merchant
    currency_codeRequiredSet to INR
    amount_totalRequiredTotal amount to be charged
  3. 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_value will be used to render the QR Code.

  4. 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_links object.

    • 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.

    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).

  5. Monitor payment for status change

    At this stage, the payment will appear as pending (PE) in your
    EBANX 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

    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).

  6. 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_code under the array items in the ws/direct request.

    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

    ParameterRequirementDescription
    payment.items[].hsn_codeMandatoryHSN code of each distinct item
    Note: Must be 6 or 8 digit code only. 2 or 4 digit codes are not accepted

    Points to Consider

    DOsDON'Ts
    Only send 6 or 8 digit HSN codeDon’t send blank, 2 or 4 digit HSN code
    Send distinct HSN code for each category of good under the transactionDon’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 variesDon’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.

  7. Congratulations!

    You have succesfully integrated UPI.

    For more information, refer to the
    Direct 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.

Note

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 CodeDescription MessageDetails
INVALID_MPIN_OR_OTPAuthentication failed due to incorrect input by userThe user failed to validate the request correctly.
TIMEOUT_REMITTER_BANK_UNAVAILABLEExternal service not available, try againThe user's bank was unavailable and did not respond to our payment scheduling attempt. Please try later.
USER_ACCOUNT_CLOSEDUser account is closed or blockedThe 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_AVAILABLEBank doesn't support the payment methodRemitter bank is either not live or doesn't support the payment method.
TECHNICAL_ERRORTechnical failures or gateway errorsThe payment failed due to gateway-level errors. Please try later.
DUPLICATE_TRANSACTIONDuplicate Mandate/transaction requestExpected when a request for the same mandate/transaction has been made twice.
LIMIT_EXCEEDEDLimit restrictions in the user's accountThis can be due to breach in number of attempts allowed as per the remitter's bank.
DO_NOT_HONOURPayment rejected by bank due to internal checksBank has declined to process the transaction due to internal checks.
INSUFFICIENT_FUNDSInsufficient funds in the user's accountThe user account has insufficient balance for the transaction at this moment. Please try later.
INVALID_PARAMParameter is invalidOne of the parameters such as currency, etc. is invalid. Please recheck before retrying.
INVALID_AMOUNTValue sent in the amount field is incorrectExpected when the amount field value is incorrect. Please revalidate the amount before retrying.
INVALID_VPAVPA is either invalid or inactiveThe VPA used for this transaction is not active or present. Please ask user to try with a valid and active VPA.
CANCELED_BY_PAYERUser has declined the transactionThis error is received when user proactively declines or rejects the payment.
NO_ACTION_BY_PAYERAuthentication not completed by userThis error is received when user fails to complete authentication before request expiry.
ATTEMPTS_EXCEEDED_MPIN_OR_OTPAuthentication failed due to incorrect input by userThe user failed to validate the request correctly within the allowed attempts.
TIMEOUT_ACQUIRING_BANK_UNAVAILABLEExternal service not available, try againThe bank was unavailable and did not respond to our payment scheduling attempt. Please try later.
TIMEOUTExternal service not available, try againThe payment failed due to gateway-level errors. Please try later.
SUSPECTED_FRAUD_REMITTER_BANKFraudulent transaction as per bank systemRemitter bank has declined due to internal risk checks.
CUSTOMER_NUMBER_OR_ACCOUNT_CHANGEUser account has undergone changes to primary valuesIf 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_EXCEEDEDMandate amount as set by bank exceededThis can be due to breach in per transaction limit or per day limits defined at remitter's bank.
TIMEOUT_BENEFICIARY_BANK_UNAVAILABLEExternal service not available, try againThe bank was unavailable and did not respond to our payment scheduling attempt. Please try later.
PAYEE_BLOCKED_AT_REMITTERMerchant blocked at Remitter Bank due to internal checksMerchant has been blocked at remitter bank due to their internal fraud or risk checks.
BIN_MISMATCHBIN mismatch for UPI on CC transactionsThere seems to be an issue with the linked card. Please request user to try with a different account/card.
TIMEOUT_NPCI_UNAVAILABLEExternal service not available, try againNetwork was temporarily unavailable. Please try later.
BP-DR-86Parameter is invalidThe parameter sent was not valid. You would receive this in sync response.
BP-REF-15Invalid operation: XYou are trying an invalid operation. You would receive this in sync response.
DEFAULT_ERRORUnknown errorYou 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.

Guidelines
  • 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.

Guidelines
  • 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.

Still need help?

Help Image

We hope this article was helpful. If you still have questions, you can explore the following options: