Creating an Enrollment using Intent/QR
UPI Autopay works by establishing an authorization, achieved through an enrollment process, between a merchant and a customer, and referencing it in every recurring payment.
By following this integration guide, you will understand how you can create enrollments and accept UPI Autopay recurring payments in your checkout, by using EBANX Direct API. To complete a payment with UPI Autopay, you will need to create an enrollment for your customer, and then recurring payments can be raised on the same enrollment going forward.
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. See EBANX Direct for more info.
Instructions
To complete a UPI Autopay enrollment using Intent or QR Code, please 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 - Create Enrollment and First Charge
To start the recurring payment process, use the
/ws/directendpoint to create the mandate and process the first charge. This step involves collecting essential customer details, first charge payment details, and subscription parameters to establish the recurring billing agreement.Users will be required to complete a 2FA in order to accept this enrollment on their app. Once the process is complete, the customer will be enrolled for the recurring payment cycle.
NoteThis is a single API request which includes mandate creation as well as first charge. Once the user authenticates the request through the app link or by scanning the QR code, mandate creation and first charge shall be processed automatically at EBANX's end.
To trigger this process, call the endpoint
/ws/directwith the following parameters:Basic parameters
Parameter Requirement Description integration_keyRequired Your integration key payment.payment_type_codeRequired Can be either upi-intent-autopayorupi-qrcode-autopayoperationRequired Must be requestEnrollment data
Parameter Requirement Description payment.enrollment.merchant_enrollment_codeRequired Unique identifier associated with the enrollment. payment.enrollment.back_urls.successRequired Callback URL for a successful response. payment.enrollment.back_urls.failureRequired Callback URL for a failure response. payment.enrollment.subscription.subscription_nameRequired A descriptor of the service being provided, which will be displayed in the customer's app. No special characters allowed. Maximum characters allowed - 50. (Currently, only Gpay displays this information) payment.enrollment.subscription.expiration_dateRequired Defines when the enrollment is no longer valid, and no further payments will be charged. payment.enrollment.subscription.frequencyRequired The billing cycle of the enrollment. Available frequencies are: weekly, monthly, yearly, and ondemand. payment.enrollment.subscription.recurrence_valueOptional (only required if frequencyis set to weekly, monthly, or yearly)If weekly, 1 to 7. If monthly or yearly, 1 to 31. Note: If recurrence value is set as "5" for frequency "monthly", then the recurring charge has to be initiated on the 5th of every month. payment.enrollment.subscription.recurrence_ruleOptional (only required if frequencyis set to weekly, monthly, or yearly)Currently only supports on.payment.enrollment.subscription.min_amountRequired Minimum amount (per payment) during the validity of the subscription plan (in INR currency). payment.enrollment.subscription.max_amountRequired Maximum amount (per payment) during the validity of the subscription plan (in INR currency). Payment data
Parameter Requirement Description payment.nameRequired Customer's full name. Minimum 5 characters, alphabets only. payment.emailRequired Customer's email. payment.phone_numberRequired Customer's phone. Minimum 8 digits, maximum 10 digits, numbers only. payment.countryRequired Set to infor India.payment.merchant_payment_codeRequired Unique code for the payment. payment.currency_codeRequired Set to INR.payment.amount_totalRequired Payment amount. payment.addressRequired Customer's address. Minimum 3 characters. payment.street_numberOptional Customer's street number. payment.cityRequired Customer's city. Minimum 3 characters, alphabets only. payment.stateRequired Customer's state. Either use state code or state name. Refer to the state list for reference. payment.zipcodeRequired Customer's zipcode or pincode. Must be 6 digits, numbers only. Note- When setting the max and min amounts, any charge made outside the set value will be declined and shall require a new enrollment set-up with new values in the fields
min_amountandmax_amount. - The following parameters will be displayed in the user's UPI app with the subscription authentication request:
expiration_date,frequency,min_amount,max_amount. - The predefined values for
frequencyset the rules for payment execution, but they don't automate the required actions.- Pre-debit notifications and payment requests must be managed manually.
- Payments outside these rules will be declined.
- Avoid using the last day of the frequency period as the recurrence value.
- If the time window is missed, the subscription status remains unchanged, and payments can proceed in the next window. Merchants can send a one-time request charge to cover such cases.
- For more flexibility, consider using "ondemand" as
frequency.
- When setting the max and min amounts, any charge made outside the set value will be declined and shall require a new enrollment set-up with new values in the fields
- QR Code Flow
In the
upi-qrcode-autopayflow, 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": "{<integration_key>}",
"operation": "request",
"payment": {
"name": "John Doe",
"email": "john.doe@example.com",
"address": "AV MIRACATU",
"street_number": "2993",
"city": "Bengaluru",
"state": "Karnataka",
"zipcode": "560087",
"country": "in",
"phone_number": "9999999999",
"payment_type_code": "upi-qrcode-autopay",
"amount_total": 200,
"currency_code": "INR",
"merchant_payment_code": "{<unique_payment_code>}",
"enrollment": {
"merchant_enrollment_code": "{<unique_enrollment_code>}",
"back_urls": {
"success": "{<merchant_success_url_here>}",
"failure": "{<merchant_failure_url_here>}"
},
"subscription": {
"subscription_name": "{<subscription_name>}",
"expiration_date": "2035-12-31",
"min_amount": "1",
"max_amount": "500",
"frequency": "ondemand"
}
}
}
}'Response
A successful request returns a response like the example below.
{
"status": "SUCCESS",
"payment": {
"hash": "{<hash_here>}",
"country": "in",
"merchant_payment_code": "{<unique_payment_code>}",
"order_number": null,
"status": "PE",
"status_date": null,
"open_date": "2026-03-22 15:14:39",
"confirm_date": null,
"transfer_date": null,
"amount_br": "200.00",
"amount_ext": "200.00",
"amount_iof": "0.00",
"currency_rate": "1.0000",
"currency_ext": "INR",
"due_date": "2026-03-22 15:19:39",
"instalments": "1",
"payment_type_code": "upi-qrcode-autopay",
"pre_approved": false,
"capture_available": null,
"customer": {
"document": "",
"email": "john.doe@example.com",
"name": "John Doe",
"birth_date": null
},
"single_transaction": {
"amount_local": "0.00",
"amount_crossborder": "200.00"
},
"upi": {
"expiration_date": "2026-03-22 15:24:39",
"qr_code_value": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAA..."
},
"currency_ext_base": "INR"
}
}The
qr_code_valuefield contains a base64-encoded PNG image (data:image/png;base64,...). Render this value directly in an<img>tag on your checkout page for the customer to scan. - Intent (App) Flow
In the
upi-intent-autopayflow, 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": "{<integration_key>}",
"operation": "request",
"payment": {
"name": "John Doe",
"email": "john.doe@example.com",
"address": "AV MIRACATU",
"street_number": "2993",
"city": "Bengaluru",
"state": "Karnataka",
"zipcode": "753009",
"country": "in",
"phone_number": "9999999999",
"payment_type_code": "upi-intent-autopay",
"amount_total": 200,
"currency_code": "INR",
"merchant_payment_code": "{<unique_payment_code>}",
"enrollment": {
"merchant_enrollment_code": "{<unique_enrollment_code>}",
"back_urls": {
"success": "{<merchant_success_url_here>}",
"failure": "{<merchant_failure_url_here>}"
},
"subscription": {
"subscription_name": "{<subscription_name>}",
"expiration_date": "2035-12-31",
"min_amount": "1",
"max_amount": "500",
"frequency": "ondemand"
}
}
}
}'Response
A successful request returns a response like the example below.
{
"status": "SUCCESS",
"payment": {
"hash": "{<hash_here>}",
"country": "in",
"merchant_payment_code": "{<unique_payment_code>}",
"order_number": null,
"status": "PE",
"status_date": null,
"open_date": "2026-03-22 15:14:39",
"confirm_date": null,
"transfer_date": null,
"amount_br": "200.00",
"amount_ext": "200.00",
"amount_iof": "0.00",
"currency_rate": "1.0000",
"currency_ext": "INR",
"due_date": "2026-03-22 15:19:39",
"instalments": "1",
"payment_type_code": "upi-intent-autopay",
"pre_approved": false,
"capture_available": null,
"customer": {
"document": "",
"email": "john.doe@example.com",
"name": "John Doe",
"birth_date": null
},
"single_transaction": {
"amount_local": "0.00",
"amount_crossborder": "200.00"
},
"upi": {
"expiration_date": "2026-03-22 20:49:39",
"app_links": [
"gpay://upi/mandate?pa=pay.merch0000000@bankltd&pn=Merchant&mn=Create+Mandate&validitystart=22032026&validityend=31122035&am=1.00&am=200.00&amrule=MAX&recur=ASPRESENTED&tr=000000000000&cu=INR&mc=5817&mc=0000&mode=00&purpose=00&txnType=CREATE&rev=Y&block=N",
"phonepe://mandate?pa=pay.merch0000000@bankltd&pn=Merchant&mn=Create+Mandate&validitystart=22032026&validityend=31122035&am=1.00&am=200.00&amrule=MAX&recur=ASPRESENTED&tr=000000000000&cu=INR&mc=5817&mc=0000&mode=00&purpose=00&txnType=CREATE&rev=Y&block=N",
"paytmmp://mandate?pa=pay.merch0000000@bankltd&pn=Merchant&mn=Create+Mandate&validitystart=22032026&validityend=31122035&am=1.00&am=200.00&amrule=MAX&recur=ASPRESENTED&tr=000000000000&cu=INR&mc=5817&mc=0000&mode=00&purpose=00&txnType=CREATE&rev=Y&block=N",
"upi://mandate?pa=pay.merch0000000@bankltd&pn=Merchant&mn=Create+Mandate&validitystart=22032026&validityend=31122035&am=1.00&am=200.00&amrule=MAX&recur=ASPRESENTED&tr=000000000000&cu=INR&mc=5817&mc=0000&mode=00&purpose=00&txnType=CREATE&rev=Y&block=N"
]
},
"currency_ext_base": "INR"
}
}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.- Google Pay App Link - Starts with
gpay://upi/mandate?.. - PhonePe App Link - Starts with
phonepe://mandate?.. - Paytm App Link - Starts with
paytmmp://mandate?.. - Generic UPI App Link - Starts with
upi://mandate?...
NoteThe generic app link (
upi://mandate?...) can only be used on Android. iOS does not support generic UPI links correctly. - Google Pay App Link - Starts with
- Confirming the Enrollment
As soon as the enrollment is confirmed by the customer in their banking app, the enrollment status is modified from
pendingtoaccepted, and a Status Update Notification is sent to the URL defined in your merchant configuration. Check the notification example below:operation=enrollment_status_change¬ification_type=update&merchant_enrollment_code=99911110104To ensure efficient and compliant interactions, EBANX allows merchants to confirm a user's enrollment status before sending multiple notifications or processing transactions.
So, before requesting any payments, using the ID provided in
merchant_enrollment_code, call the/ws/userenrollments/queryendpoint to get the latest status of the enrollment.Check the example:
curl -X POST \
--location 'https://sandbox.ebanx.com/ws/userenrollments/query' \
--header 'Content-Type: application/json' \
--data '{
"integration_key": "{<integration_key>}",
"payment_type_code": "{<payment_type_code>}",
"enrollment": {
"country": "in",
"merchant_enrollment_code": "{<unique_enrollment_code>}"
}
}'A successful request will return a JSON response like the one below, with a status of
acceptedfor the enrollment approved by the customer. Other possible enrollment statuses includenot accepted,paused,pending,expired,not_found, andrevoked, depending on the actions taken by the merchant or customer.{
"status": "SUCCESS",
"payment_type": "{<payment_type_code>}",
"enrollment": {
"status": "accepted"
}
}If your enrollment has the status accepted, you can start requesting the recurring payments following the instructions on the Recurring Payment Request page.
- Monitor payment for status changes
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).
-
- Congratulations!
You have successfully integrated UPI Autopay Enrollment using Intent/QR.
For more information, refer to theDirect API reference guidechevron_right
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 the 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. The user clicks on the desired UPI app, which redirects them to the application. The user reviews and approves the mandate directly within the app, and once confirmed, both the customer and the merchant receive immediate mandate confirmation.
- This method only works on mobile flows (app or mobile-web). Intent flow does not work on laptop, tablet, or desktop web flows.
- The 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 the end of the session to the user (industry-wide norm is 5 minutes). The user is expected to complete authentication during this time.
UPI QR Code UX Flow
This demo illustrates the end-to-end payment experience with the UPI QR code flow. The journey begins on the merchant's checkout page, where the customer selects the UPI QR code. After submitting the request, the QR code is shown on the checkout page for the user to scan. The user selects their desired UPI app and scans the QR code shown. The user reviews and approves the mandate directly within the app, and once confirmed, both the customer and the merchant receive immediate mandate confirmation.
- This method is most preferred on desktop flows, but can still work on mobile flows through a "Download QR" option.
- There should be a "Download QR" option if the method is being shown on mobile flows.
- Using a reverse timer (industry-wide norm is 5 minutes) to highlight the end of the session to the user is a good practice. The user is expected to complete the authentication during this time.
- It is recommended to add step-wise user guidance 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 mandate with UPI PIN
- Step 4: Do not refresh this page and wait for the final status
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 integration@ebanx.com for assistance.
- Not a partner yet? Please complete the Merchant Signup Form, and our commercial team will reach out to you.