> ## Documentation Index
> Fetch the complete documentation index at: https://www.cashfree.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# UPI Intent in JS SDK

> Enable UPI Intent inside the Cashfree JS SDK web checkout embedded in Android, React Native, Flutter, and Cordova apps using feature flags and URL handlers.

Merchants integrating the Cashfree Web checkout using Cashfree JS SDK. But they are unable to see the UPI intent option on the checkout page as the Cashfree checkout page is opening on Webview.

This document provides guidance for merchants developing their applications on platforms such as `Android, React Native, Flutter, Cordova` who have integrated the Cashfree JS SDK.

<Note>If you are using Cashfree Mobile SDK, refer to [Mobile SDK](/tools-ai/sdk#mobile-sdks).</Note>

### Feature flag based solution <Badge color="orange">Client-side</Badge>

Our checkout page provides the capability to display default UPI apps, including `PhonePe, GPay, and Paytm`, along with an option to pay via any UPI app. This feature ensures that these UPI apps are visible on the checkout page, regardless of whether they are installed on the user's device.

When a user selects a UPI app, merchants are responsible for handling the redirection. Only a minimal code snippet is required on the merchant's side to handle the UPI app click and manage the subsequent redirection process.

<AccordionGroup>
  <Accordion title="Android">
    <CodeGroup>
      ```java Android theme={"dark"}
      // Override shouldOverrideUrlLoading method in your webview.
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String request) {
         if (request != null) {
               if((request.startsWith("upi://pay") 
                   || request.startsWith("tez://") 
                   || request.startsWith("gpay://")
                   || request.startsWith("paytmmp://")
                   || request.startsWith("phonepe://")
                   || request.startsWith("amazonpay://")
                   || request.startsWith("credpay://")
                   || request.startsWith("bhim://")
                   || request.startsWith("navipay://")
                   || request.startsWith("mobikwik://")
                   || request.startsWith("myairtel://")
                   || request.startsWith("popclubapp://")
                   || request.startsWith("super://")
                   || request.startsWith("kiwi://")
                   || request.startsWith("simplypayupi://")
                   || request.startsWith("whatsapp-consumer://")
                   || request.startsWith("postpe://")
                   || request.startsWith("tnupi://")
                )){
                      // Open UPI app from here
                      final Intent intent = new Intent();
                      intent.setAction(Intent.ACTION_VIEW);
                      intent.setData(Uri.parse(request));
                      PackageManager pm = getPackageManager();
                      final List<ResolveInfo> resInfo = pm.queryIntentActivities(intent, 0);
                      if (!resInfo.isEmpty()) {
                          startActivity(intent);
                      } else {
                         //handle no app scenario
                      }
                     return true;
                   }
         }
         return false;
      }
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="React-Native">
    <CodeGroup>
      ```js JS theme={"dark"}
      // Override onShouldStartLoadWithRequest method in your webview.
      onShouldStartLoadWithRequest={event => {
               const url  = event.url
               if ((url.startsWith("upi://pay")
               || url.startsWith("tez://") 
               || url.startsWith("gpay://")
               || url.startsWith("paytmmp://")
               || url.startsWith("phonepe://")
               || url.startsWith("amazonpay://")
               || url.startsWith("credpay://")
               || url.startsWith("bhim://")
               || url.startsWith("navipay://")
               || url.startsWith("mobikwik://")
               || url.startsWith("myairtel://")
               || url.startsWith("popclubapp://")
               || url.startsWith("super://")
               || url.startsWith("kiwi://")
               || url.startsWith("simplypayupi://")
               || url.startsWith("whatsapp-consumer://")
               || url.startsWith("postpe://")
               || url.startsWith("tnupi://")
               )) {
                Linking.canOpenURL(url).then(supported => {
                        if (supported) {
                              Linking.openURL(url);
                        }else{
                            console.log("Not able to open")
                        }
                      });
                      return false;
                }
              return true;
      }}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Flutter">
    <CodeGroup>
      ```js Dart theme={"dark"}
      // Override shouldOverrideUrlLoading method in your webview.
      shouldOverrideUrlLoading: (controller, navigationAction) async {
                var uri = navigationAction.request.url!;
                if (["upi",
                "tez",
                "gpay",
                "paytmmp",
                "phonepe",
                "amazonpay",
                "credpay",
                "bhim",
                "navipay",
                "mobikwik",
                "myairtel",
                "popclubapp",
                "super",
                "kiwi",
                "simplypayupi",
                "whatsapp-consumer",
                "postpe",
                "tnupi"].contains(uri.scheme)) {
                  print("Opening PSP app");
                  await launchUrl(uri);
                  return NavigationActionPolicy.CANCEL;
                }
                return NavigationActionPolicy.ALLOW;
      }
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

<Note>To enable this flag, please fill out the [Support Form](https://merchant.cashfree.com/merchants/landing?env=prod\&raise_issue=1). they will enable this flag.</Note>

### Code based solution <Badge color="orange">Client-side</Badge>

You have to write some custom logic in your mobile app while opening Cashfree checkout page. When you are loading Webview, Please register `JS bridge` with name `Android` and implement few of its method.

<AccordionGroup>
  <Accordion title="Android">
    [Sample code](https://github.com/kishan-cashfree/CFWebIntegrationSample/blob/245b0d655475ad5f5595437efc1e6eb503774f68/app/src/main/java/com/cashfree/webintegration/MainActivity.kt#L87)
  </Accordion>

  <Accordion title="React-Native">
    In this case, you have to write android native module
    [Native Module](https://github.com/kishan-cashfree/CFWebIntegrationRN/tree/master/android/app/src/main/java/com/cfwebintegrationrn)

    Use these native module in you JS/TS code
    [JS code](https://github.com/kishan-cashfree/CFWebIntegrationRN/tree/master/native)

    [Sample Usage](https://github.com/kishan-cashfree/CFWebIntegrationRN/blob/master/WebSitePaymentScreen.tsx)
  </Accordion>

  <Accordion title="Flutter">
    In this case, you have to write android native module
    [Native Module](https://github.com/kishan-cashfree/CFSamplewebviewFL/tree/master/android/app/src/main/kotlin/com/example/cfsamplewebviewfl)

    Use these native module in you Dart code
    [Dart Code](https://github.com/kishan-cashfree/CFSamplewebviewFL/blob/master/lib/ui/webview/customwebview.dart)

    [Sample Usage](https://github.com/kishan-cashfree/CFSamplewebviewFL/blob/master/lib/main.dart)
  </Accordion>

  <Accordion title="iOS">
    When loading WebView, register JS bridge with name `nativeProcess` and implement the required methods.

    [Sample code](https://github.com/cashfree/CFWebIntegrationSampleiOS)
  </Accordion>
</AccordionGroup>

<div class="hidden" data-table-of-contents="bottom">
  <p class="mt-4 font-medium flex items-center gap-2 related-docs-heading">
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="w-4 h-4">
      <path d="M3 4h7a2 2 0 0 1 2 2v13a2 2 0 0 0-2-2H3z" />

      <path d="M21 4h-7a2 2 0 0 0-2 2v13a2 2 0 0 1 2-2h7z" />
    </svg>

    <span>Related topics</span>
  </p>

  <ul>
    <li><a href="https://github.com/kishan-cashfree/CFWebIntegrationSample/blob/245b0d655475ad5f5595437efc1e6eb503774f68/app/src/main/java/com/cashfree/webintegration/MainActivity.kt#L87" target="_blank">Android Sample Code</a></li>
    <li><a href="https://github.com/kishan-cashfree/CFWebIntegrationRN/blob/master/WebSitePaymentScreen.tsx" target="_blank">React Native Sample</a></li>
    <li><a href="https://github.com/kishan-cashfree/CFSamplewebviewFL/blob/master/lib/main.dart" target="_blank">Flutter Sample</a></li>
    <li><a href="/docs/payments/online/mobile/android">Mobile SDK Docs</a></li>
  </ul>
</div>
