--- title: "API only" url: "https://docs.adyen.com/payment-methods/upi/api-only" source_url: "https://docs.adyen.com/payment-methods/upi/api-only.md" canonical: "https://docs.adyen.com/payment-methods/upi/api-only" last_modified: "2022-06-13T12:28:00+02:00" language: "en" --- # API only [View source](/payment-methods/upi/api-only.md) Accept UPI payments in India using our APIs, and build your own payment form to have full control over your checkout journey. ## Requirements | Requirement | Description | | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | **Integration type** | Make sure that you have built an [API-only integration](/online-payments/build-your-integration/advanced-flow?platform=Web\&integration=API%20only). | | **Setup steps** | Before you begin, [add in your test Customer Area](/payment-methods/add-payment-methods). | ### Tab: UPI Intent When a shopper pays using UPI Intent, you need to redirect them to the UPI app on their mobile device. We recommend that you implement UPI Intent for mobile users only. Use screen size to determine whether the shopper is accessing your site on mobile, desktop, or tablet. ## Make a payment Make a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request with: * `paymentMethod.type`: **upi\_intent** * `paymentMethod.appId`: The Id of the Third Party Application that is used to make the UPI payment. Possible values: * **gpay**: Google Pay * **phonepe**: PhonePe * **bhim**: BHIM (Bharat Interface for Money) * **paytm**: Paytm * **amazonpay**: Amazon Pay * **cred**: Cred * **wapay**: WhatsApp Pay * **jupiter**: Jupiter * **navi**: navi * **supermoney**: Super.money * **mobikwik**: MobiKwik * **freecharge**: Freecharge * `amount.currency`: INR * `amount.value`: The value of the payment, in minor units. **/payments request** ```json curl https://checkout-test.adyen.com/v72/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "amount": { "currency": "INR", "value": 15100 }, "countryCode": "IN", "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "reference": "YOUR_ORDER_NUMBER", "paymentMethod": { "type": "upi_intent", "appId": "gpay" }, "returnUrl": "https://your-company.example.com/checkout?shopperOrder=12xy.." }' ``` **/payments response** ```json { "resultCode": "Pending", "action": { "paymentData": "Ab02b4c0!BQABAg...", "paymentMethodType": "upi_intent", "url": "gpay://upi/pay?pa=upidirect@hdfcbank&pn=PayeeHDFC&tn=UPI&am=4.30&cu=INR&mc=6012&tr=BNLXDR7VHXFKTM92&qrMedium=06&mode=04", "type": "await" } } ``` ## Redirect the shopper The [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response contains: * `resultCode`: **Pending**. This means that the final status of the payment is not available yet. Inform the shopper that you have received their order, and are waiting for the shopper to complete the payment on the UPI app. * `action.url`: Use this to redirect the shopper to the UPI app on their mobile device. App redirects work differently on Android and iOS. On Android, shoppers are given a choice of compatible apps to open the redirect link. iOS makes a default choice of which app to use. To complete the payment, redirect the shopper to the `action.url` returned in the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response. **When using the HTTP GET method:**\ For security reasons, when displaying the redirect in the app, we recommend that you use [SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller) for iOS or [Chrome Custom Tabs](https://developer.chrome.com/multidevice/android/customtabs) for Android, instead of WebView objects. Also refer to the [security best practices](https://developer.android.com/topic/security/best-practices#webview) for WebView. ## Show the waiting screen 1. Show a waiting screen to the shopper. We recommend adding a countdown timer of 5 minutes to remind shoppers to complete the payment on their UPI app. 2. Check your [webhook notifications](/development-resources/webhooks) to see the payment result. We send you an AUTHORISATION notification after the shopper completes the payment in their UPI app. 3. Once you receive the notification webhook, redirect them to your website, and present the payment result. ## Present the payment result Wait for a notification webhook to know the outcome of the payment. The notification webhooks you can receive for UPI Intent are: | eventCode | success field | Description | Action to take | | ----------------- | ------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------- | | **AUTHORISATION** | **false** | The transaction failed. | Cancel the order and inform the shopper that the payment failed. | | **AUTHORISATION** | **true** | The shopper successfully completed the payment. | Inform the shopper that the payment has been successful and proceed with the order. | ## Test and Go Live Depending on your account setup, you may have access to the UPI simulator which you can use to test your UPI integration. Contact your Account Manager or our [Support Team](https://ca-test.adyen.com/ca/ca/contactUs/support.shtml?form=other) if you have questions about the simulator. You can also use your personal account on a UPI app to test your integration by making live payments with a low value. ### Tab: UPI QR When a shopper pays with UPI QR, you present a QR code which they can scan using the UPI app on their mobile device. We recommend that you use screen size to determine whether the shopper is accessing your site on mobile, desktop, or tablet and present the QR Code for shoppers on desktop or tablet. ## Make a payment Make a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request with: * `paymentMethod.type`: **upi\_qr** * `amount.currency`: INR * `amount.value`: The value of the payment, in minor units. **/payments request** ```json curl https://checkout-test.adyen.com/v68/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "amount": { "currency": "INR", "value": 3600 }, "countryCode": "IN", "reference": "YOUR_ORDER_NUMBER", "paymentMethod": { "type": "upi_qr" }, "browserInfo": { "acceptHeader": "*/*", "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" }, "returnUrl": "https://test.adyen.com/", "merchantAccount": "ADYEN_MERCHANT_ACCOUNT" }' ``` The [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response contains: * `action.qrCodeData`: Use this to render the QR code on your checkout page. **/payments response** ```json { "resultCode": "Pending", "action": { "paymentMethodType": "upi_qr", "qrCodeData": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADIA….", "type": "qrCode" }, "details": [ { "key": "payload", "type": "text" } ], "redirect": { "data": { "qrCodeData": "iVBORw0KGgoAAAANS…." }, } } ``` ## Present the QR code Follow these steps to render the QR code on your checkout page: 1. Use the `qrCodeData` from the `action` object to render the QR code on your checkout page. We recommend showing a countdown timer of 5 minutes to remind shoppers to complete the payment on their UPI app. 2. After the shopper scans the QR code and completes the payment, we send a [webhook](/development-resources/webhooks) informing you of the payment result. 3. [Present the payment result to your shopper](#present). ## Present the payment result Wait for a webhook to know the outcome of the payment. The webhooks you can receive for UPI QR are: | eventCode | success field | Description | Action to take | | ----------------- | ------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------- | | **AUTHORISATION** | **false** | The transaction failed. | Cancel the order and inform the shopper that the payment failed. | | **AUTHORISATION** | **true** | The shopper successfully completed the payment. | Inform the shopper that the payment has been successful and proceed with the order. | For UPI QR payments, you can receive the following `resultCode` values: | resultCode | Description | Action to take | | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Error** | There was an error when the payment was being processed. For more information, check the [`refusalReason` ](/development-resources/refusal-reasons)field. | Inform the shopper that there was an error processing their payment. | | **Pending** | The payment order was successfully received. | Inform the shopper that you have received their order, and are waiting for the payment to clear. You will receive the final result of the payment in an [AUTHORISATION webhook](/development-resources/webhooks/webhook-types). | | **Refused** | The payment was refused. For more information, check the [`refusalReason` ](/development-resources/refusal-reasons)field. | Ask the shopper to try the payment again using a different payment method. | ## Test and Go Live Depending on your account setup, you may have access to the UPI simulator which you can use to test your UPI integration. Contact your Account Manager or our [Support Team](https://ca-test.adyen.com/ca/ca/contactUs/support.shtml?form=other) if you have questions about the simulator. You can also use your personal account on a UPI app to test your integration by making live payments with a low value. ### Tab: UPI Collect * In November 2025, the National Payments Corporation of India (NPCI) has informed ecosystem partners of its plan to **deprecate UPI Collect**, shifting its focus toward UPI Intent and UPI QR as the primary UPI payment methods going forward. This decision has been driven by lower authorization rates and a higher likelihood of fraudulent transactions associated with UPI Collect. * Therefore, we will no longer offer UPI Collect for *new* merchant integrations, and *we have updated our drop-in and components ([V6.30.0](https://github.com/Adyen/adyen-web/releases/tag/v6.30.0))* to reflect this change. * **If you use UPI Collect via a custom Checkout API and UI**: We strongly recommend that you begin offering **UPI Intent** and/or **UPI QR** (if not already enabled) and start your migration as soon as possible. * Adyen is keeping merchants informed about this initiative with specific system messages. When a shopper pays with UPI Collect, they enter their virtual payment address and complete the payment using the UPI app on their mobile device. ## Validate UPI ID To avoid payment failure caused by an incorrect, invalid or inactive UPI ID (also known as Virtual Payment Address or VPA), send a [/validateShopperId](https://docs.adyen.com/api-explorer/Checkout/latest/post/validateShopperId) request to ensure that the UPI ID is: * in the correct format * valid and active in the UPI system By performing this validation check before creating a payment, you: * prevent errors at the input stage * reduce failed [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) calls caused by invalid, inactive, or incorrectly entered UPI IDs * provide faster, clearer feedback to shoppers without waiting for payment authorization failures UPI ID validation: * is optional and intended to improve the shopper's user experience * does not guarantee that a subsequent debit will succeed * confirms that the UPI ID is currently recognized and is active in the UPI system * is available only on our latest acquiring connection (Adyen Direct) and not on legacy connections (Billdesk / PayU) You can contact your implementation manager or [Support Team](https://ca-test.adyen.com/ca/ca/contactUs/support.shtml?form=other) to validate the suitability of using UPI ID validation. **Example /validateShopperId request for UPI validation** ```json curl https://checkout-test.adyen.com/checkout/v71/post/validateShopperId \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "shopperIP":"127.0.0.11", "shopperReference": "YOUR_SHOPPER_REFERENCE", "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "shopperEmail": "shopper@email.com", "paymentMethod": { "type": "upi_collect", "virtualPaymentAddress": "correct@okhdfcbank" } }' ``` The response includes `result` and `reason`: **Example /validateShopperId response** ```json { "result": "valid", "reason": "VPA is valid" } ``` Below is a list of possible responses, and how to proceed: | Result | Reason | Merchant action | | ----------- | -------------------------------------- | ------------------------------------------------------------------ | | **valid** | VPA is valid. | Proceed to `/payments`. | | **unknown** | Status unknown due to technical error. | Proceed to `/payments`. | | **invalid** | VPA is invalid. | Block `/payments`. Ask shopper to check UPI ID. | | **invalid** | VPA is incomplete. | Block `/payments`. Prompt shopper to complete UPI ID. | | **invalid** | VPA format is incorrect. | Block `/payments`. Show format hint (for example, **name\@bank**). | Do not block your [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request if the UPI ID validation request fails due to technical issues, for example for HTTP 4xx or 5xx [/validateShopperId responses](https://docs.adyen.com/api-explorer/Checkout/latest/post/validateShopperId#responses-400). Handle these cases gracefully and proceed with the payment request. Only block the payment flow when the validation result explicitly returns **INVALID**. ## Make a payment In your [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request, specify: * `paymentMethod.type`: **upi\_collect** * `paymentMethod.virtualPaymentAddress`: The UPI VPA that the shopper entered. * `amount.currency`: INR * `amount.value`: The value of the payment, in minor units. **/payments request** ```json curl https://checkout-test.adyen.com/v68/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "amount": { "currency": "INR", "value": 12000 }, "countryCode": "IN", "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "reference": "YOUR_ORDER_NUMBER", "paymentMethod": { "type": "upi_collect", "virtualPaymentAddress": "9999999999@upi" }, "returnUrl": "https://your-company.example.com/checkout?shopperOrder=12xy..", }' ``` The [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response contains: * `action.type`: **await**, this means you need to wait for the [webhook](/development-resources/webhooks) to know the payment outcome. **/payments response** ```json { "resultCode": "Pending", "action": { "paymentMethodType": "upi_collect", "type": "await" }, } ``` ## Show the waiting screen 1. Show a waiting screen to the shopper. We recommend adding a countdown timer of 5 minutes to remind shoppers to complete the payment on their UPI app. 2. Check your [webhooks](/development-resources/webhooks) to see the payment result. We send you an [AUTHORISATION webhook](/development-resources/webhooks/webhook-types) after the shopper completes the payment in their UPI app. 3. Once you receive the webhook, redirect the shopper to your website, and present the payment result. ## Present the payment result Wait for a webhook to know the outcome of the payment. The webhooks you can receive for UPI Collect are: | eventCode | success field | Description | Action to take | | ----------------- | ------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------- | | **AUTHORISATION** | **false** | The transaction failed. | Cancel the order and inform the shopper that the payment failed. | | **AUTHORISATION** | **true** | The shopper successfully completed the payment. | Inform the shopper that the payment has been successful and proceed with the order. | Use the `resultCode` that you received in the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response to inform your shopper of the payment status. The `resultCode` values you can receive for payments made through UPI Collect are: | resultCode | Description | Action to take | | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Error** | There was an error when the payment was being processed. For more information, check the [`refusalReason` ](/development-resources/refusal-reasons)field. | Inform the shopper that there was an error processing their payment. | | **Pending** | The payment order was successfully received. | Inform the shopper that you have received their order, and are waiting for the payment to clear. You will receive the final result of the payment in an [AUTHORISATION webhook](/development-resources/webhooks/webhook-types). | | **Refused** | The payment was refused. For more information, check the [`refusalReason` ](/development-resources/refusal-reasons)field. | Ask the shopper to try the payment again using a different payment method. | ## Test and Go Live Use these credentials to test UPI Collect: | Parameter | Value | | --------- | -------------- | | VPA | testvpa\@icici | Depending on your account setup, you may have access to the UPI simulator which you can use to test your UPI integration. Contact your Account Manager or our [Support Team](https://ca-test.adyen.com/ca/ca/contactUs/support.shtml?form=other) if you have questions about the simulator. You can also use your personal account on a UPI app to test your integration by making live payments with a low value.