UPI Intent is an app-to-app redirect flow. The merchant checkout launches the customer's UPI app with payment details prefilled via a deep link. No VPA entry is required. On desktop, the same deep link is rendered as a QR code for scanning. Set payment_method_flow to
redirect
.
UPI Intent is the recommended integration. It improves mobile conversion and enables QR checkout on desktop. NPCI guidelines effective February 2026 restrict manual VPA entry on mobile transactions, making Intent the compliance standard for mobile checkouts.
UPI Intent is the migration target for existing UPI Collect integrations, due to deprecation plans of the latter.
Principle of operation
Selection at checkout Customer selects UPI as the payment method.
Payment initiation Send a payment request to Solidgate with payment_method_flow
redirect
and future_usage.payment_type
one-time
. Do not pass future_usage.billing_period or future_usage.max_amount. Solidgate returns a UPI deeplink in payment_type_data.deep_link_value.
App launch / QR display On mobile, render buttons for specific UPI apps using deeplinks constructed from the deep_link_value. On desktop, render the deep_link_value as a QR code for the customer to scan with their phone.
Authorization The customer authorizes the payment in their UPI app by entering their UPI PIN.
Merchant notification You receive a
notification
Webhook confirming the payment status.
Selection at checkout Customer selects UPI as the payment method and initiates mandate authorization.
Mandate initiation Send a payment request to Solidgate with payment_method_flow
redirect
, future_usage.payment_type
recurring
or
unscheduled
, plus future_usage.max_amount. For
recurring
, also pass future_usage.billing_period. Solidgate returns a UPI deeplink in payment_type_data.deep_link_value.
App launch / QR display On mobile, render buttons for specific UPI apps using deeplinks constructed from the deep_link_value. On desktop, render the deep_link_value as a QR code for the customer to scan with their phone.
Mandate authorization The customer reviews the mandate terms, including maximum charge amount and billing frequency, and authorizes the setup by entering their UPI PIN. A token is issued for subsequent charges.
Merchant notification You receive a
notification
Webhook confirming the payment status.
Recurring payments
Recurring payments up to ₹15,000 per individual transaction are processed without customer intervention. For amounts above ₹15,000 per transaction, an additional authentication factor is required for each debit. These debits are not supported.
Customer receives a notification 24 hours before the scheduled charge.
If the customer declines the follow-up charge, a decline response is returned.
If the customer does not decline the charge, a success response is issued.
When creating the initial payment, specify the amount to be debited for future subscription charges. This amount appears in the customer’s UPI app when the mandate is created. The mandate authorizes follow-up payments.
For example, if the merchant has sold the customer a subscription plan for up to ₹3,000, the customer sees this amount at the time of mandate creation, along with a notice that payments may be up to ₹3,000.
Any payment below the amount specified in the initial request occurs without additional confirmation from the customer. However, the customer still receives notifications the day before the follow-up payment and can cancel the subscription at any time.
Billing periods
The future_usage.billing_period maps to the UPI Autopay mandate frequency. Only the combinations of billing_period.unit and billing_period.value below are accepted.
billing_period.unit
billing_period.value
Interval
day
1
Daily
day
7
Weekly
week
1
Weekly
month
1
Monthly
year
1
Yearly
These rules apply when the billing period is sent directly in future_usage.billing_period and when you use product_id, the product configuration must match the table.
The UPI Autopay mandate fixes how often the customer is charged. A product trial that differs from the billing period can cause the first charge after the trial to be declined. Use a product without a trial, or a trial equal to the billing period, for example 7 days for weekly billing.
UPI Intent checkout
The
init payment
API response contains payment_type_data.deep_link_value, a generic UPI URI. One-time payments use
upi://pay
. Recurring payments use
upi://mandate
.
Render the deep_link_value as a QR code. Display logos of supported UPI apps above the QR code. Show a countdown timer reflecting the 15 minute session window. Generate the QR code directly from the URI. Do not use a payment provider's QR generation API.
Render a button for each supported UPI app. Construct app specific deeplinks by replacing the generic prefix in deep_link_value with an app specific scheme.
Replace the generic
upi://pay
prefix with the scheme for the selected app.
UPI app
App specific scheme
Google Pay
tez://upi/pay
PhonePe
phonepe://pay
Paytm
paytmmp://pay
CRED
credpay://upi/pay
BHIM
bhim://upi/pay
Navi
navi://pay
Amazon Pay
amazonpay://upi/pay
Generic
upi://pay
Example deep links after replacing
upi://pay
in deep_link_value:
On iOS, the universal UPI app tray does not work due to OS level restrictions. Replace the generic prefix with the per-app scheme before opening the deep link. This requires explicit app level handling on the frontend.
Payment Form
Integrate UPI Intent via APM buttons. Payment Form detects the device and renders the Intent flow on mobile or a QR code on desktop. Set upiButtonParams.enabled to
true
to display the button when UPI is enabled for the merchant.
Do not use a payment provider QR generation API. Payment Form generates the QR directly from the Intent deep link returned in payment_type_data.deep_link_value.
Selection at checkout Customer selects UPI on the Payment Form.
App selection Payment Form displays up to 6 to 8 UPI apps. Top apps appear first: Google Pay, PhonePe, Paytm, BHIM. Additional apps are under Show all.
App launch Customer selects an app and is redirected to authenticate and confirm. On iOS, Payment Form replaces the generic prefix with the per-app scheme before opening the deep link.
Payment result Payment Form receives the result via webhook and transitions to the success or error screen.
Selection at checkout Customer selects UPI on the Payment Form.
QR display Payment Form generates a QR code from the Intent deep link and displays supported UPI app logos above it.
Scan and authorize Customer scans the QR with their UPI app, then authenticates and confirms in the app.
Payment result Payment Form receives the result via webhook and transitions to the success or error screen. If the session expires, the QR is marked expired and the customer is prompted to restart.
Supported UPI apps
Platform
Apps
Android
Google Pay, PhonePe, CRED, Paytm, BHIM, Amazon Pay, iMobile by ICICI, PayZapp, Mobikwik, Navi
iOS
Google Pay, PhonePe, CRED, Paytm, BHIM
Schemes for additional apps are added to the
Guide
Check the latest updates, feature releases, API changes, and product improvements within the Solidgate orchestration platform.
changelog
as they are confirmed.
Required paymentIntent fields
Pass these fields when initializing the Payment Form for UPI Intent.
With product_id, use a product without a trial or with a trial equal to the billing period.
payment_method_flow
redirect
future_usage.payment_type
one-time
for one-time. Do not pass future_usage.billing_period or future_usage.max_amount.
unscheduled
for subsequent charges without a fixed schedule, with future_usage.max_amount
Required
. Do not pass future_usage.billing_period.
recurring
for recurring, future_usage.max_amount, and future_usage.billing_period
Required
billing_address.country and billing_address.zip_code
The
Guide
Add alternative payment method buttons to your payment form with customizable styling, placement, and method-specific display conditions.
UPI Intent button configuration
contains the full paymentIntent payload and upiButtonParams object.
future_usage.max_amount sets the maximum single charge amount the customer preauthorizes during mandate creation. It is displayed to the customer in their UPI app. Provide the value in paise, the minor currency unit. Any charge above this amount is declined.
This field is
required
if no product_id or product_price_id is provided.
future_usage.billing_period sets the recurring billing interval for the UPI mandate.
This field is
required
when payment_type is
recurring
and no product_id or product_price_id is provided.
Mandate display at checkout
Merchants must display mandated terms clearly at checkout, including the maximum charge amount and billing frequency, so customers can review them before mandate creation.
Customers can revoke a mandate at any time in their UPI app by selecting Delete AutoPay. Solidgate does not cancel the associated subscription immediately. The next charge attempt fails with
Guide
Invalid card token.
5.02,
then the subscription is cancelled with cancel code
Guide
The customer revoked the billing token by contacting customer support or the bank.
8.11
Token revoked by customer. Merchants receive the failed payment
notification
Webhook and the subscription cancel webhook.
Handle UPI errors
When a UPI Intent payment fails, the decline returns one of the codes below.
Guide
Use the error code reference to identify decline reasons for card and alternative payments and decide on retry or resolution steps.
UPI Intent error codes
include the customer message and the next step for each code.
Guide
Create a new order and ask the customer to approve the payment in the UPI app within 15 minutes.
0.02
Order expired The customer did not complete authorization within the 15-minute session window.
Guide
Validate the phone number, the postal code in billing_address.zip for API requests or billing_address.zip_code for Payment Form, and the city.
2.01
Invalid data Invalid or incorrectly formatted request fields. Validate
amount
, which must be above 0,
customer_phone
, the postal code, which is 6 characters for India and is passed in
billing_address.zip
in API requests or
billing_address.zip_code
in Payment Form, and
billing_address.city
when provided.