drenther / upi_pay

Flutter plugin for UPI (Only in India)
MIT License
60 stars 73 forks source link

IOS Implementation #2

Closed viveknimkarde closed 3 years ago

viveknimkarde commented 4 years ago

Any Idea of how to implement this plugin for IOS?

drenther commented 4 years ago

I haven't used Swift/Objective-C before. Don't have much idea. I am open to a discussion and PRs if anyone can take that up.

pratikjain04 commented 4 years ago

@drenther Any updates on iOS front?

drenther commented 4 years ago

I personally don't work with iOS as of now. Would be happy to take a PR if anyone is willing to?

reeteshranjan commented 4 years ago

I can do iOS programming. So far did not find any documentation on an iOS mechanism similar to Android intents though.

drenther commented 4 years ago

https://razorpay.com/docs/payment-gateway/payment-methods/upi-intent/ios/

There is an iOS intent flow in RazorPay SDK. It doesn't look like there is a spec (even roughly so like in android) for it though. Even, they seem to be supporting only three apps as of now.

Also not sure if we can emulate something similar on Flutter or not.

reeteshranjan commented 4 years ago

Great. I found these key custom schemes from this URL:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>tez</string>
    <string>phonepe</string>
    <string>paytmmp</string>
</array>

Was struggling as could not find these details of the apps published anywhere e.g. comgooglemaps for Google Maps is documented by Google and was able to launch Google Maps using this custom scheme using url_launcher package's launch() call to comgooglemaps://. Was trying with upi:// as per the NPCI spec but no apps bothered to respond to it.

Will experiment and document.

reeteshranjan commented 4 years ago

All these custom schemes work and with code like this on iOS you can launch the corresponding apps. Will see if the UPI parameters work.

          final urlString = 'paytmmp://';
          final bool check = await canLaunch(urlString);
          try {
            await launch(urlString);
          } catch(error) {
            print(error.toString());
          }
drenther commented 4 years ago

Great findings, looks like we can support iOS to some extent. Any edge cases you can think of? @pepsighan @reeteshranjan

pepsighan commented 4 years ago

I think they should work fine for each individual app. The work will be to find custom schemes for each individual app for all to be supported. I don't have an iPhone but google pay's custom schemes are given here: https://internal-absorbed-celsius.glitch.me/. You may try if these work.

reeteshranjan commented 4 years ago

I found custom schemes implemented by several apps using the method described here: https://www.amerhukic.com/finding-the-custom-url-scheme-of-an-ios-app.

I looked at these apps I have evaluated on Android (37) plus few more: Airtel Pay, Amazon Pay, Axis Pay, Bandhan Bank, Baroda Pay, BHIM, BOI UPI, Cent UPI, Cointab, CORP UPI, CSB Pay, DCB UPI, Freecharge, Google Pay, ICICI Mobile, IDFC UPI, IndianBank UPI, IndusPay, KBL UPI, KVB Upay, LVB Upaay, MahaUPI, Mi Pay, Mobikwik, Oriental Pay, PayTM, Paywiz, Phone Pe, PSB, RBL UPI, SBI Pay, SyndUPI, Truecaller, UCO UPI, UltraCash, Vijaya UPI, Yes Pay

Found these apps to implement custom schemes on iOS (16): PayTM, PhonePe, Amazon, iMobile, MobiKwik, Freecharge, KVB Upay, UBI UPI, UCO UPI, Vijaya UPI, BharatPe, SyndUPI, LOTZA Pay, Airtel, BHIM, Cent UPI

These apps have upi as one of their custom schemes implemented: Google Pay, Mobikwik, PayTM, PhonePe, Freecharge, Lotza Pay, UBI UPI

These apps have only upi as their custom scheme: KVB Upay, SyndUPI, Vijaya UPI

These apps do not have upi scheme but some generic app name based schemes implemented: Amazon, iMobile, Airtel, BharatPe, BHIM, Cent UPI, UCO UPI

I experimented with few using url_launcher to see if I can get to a success payment and some kind of callback.

  1. What the URL is going to be?

At this point, at least I do not see a way to figure out what query string structure is actually expected and parsed by these apps, beyond this finding of custom schemes. Though one can guess that if UPI "listening" has been implemented by these apps, the parameters should be standard and as per the UPI specs. However; there is no clarity about the URL path e.g. is it phonepe://upi?, phonepe://pay?, phonepe://upi/pay? or something else. The link https://internal-absorbed-celsius.glitch.me/ shared earlier helped me with this. The logical patterns seem to be: upi://pay? for upi custom schemes, and <non-upi-scheme>://upi/pay? for other custom schemes. And the few apps I tried with non-upi schemes, it worked out that way. I've not tested theupi:// custom schemes yet.

  1. Does the pre-filled payment form open up?

It did. For Google Pay and Phone Pe.

  1. Does the payment go through?

Yes, it did go through with Google Pay.

  1. Did the callback URL work?

I put in a working URL to one of my servers as the callback URL. But it was not called by Google Pay once the payment went through.

The twist, which I discovered a bit later, is that I was testing on my iPhone 6. Most of the apps get installed but do not even proceed once they detect it's iPhone 6 (as per NPCI guidelines). I did not want to continue this research/debugging any further because I'm not sure if few apps did not respond properly due to this etc.

reeteshranjan commented 4 years ago

One of my ideas was to implement a custom scheme in my app and pass a callback URL using that custom scheme (once the callback is verified to work for regular https URLs); but the UPI spec says that the callback URL must have http/https scheme. Had the URL with custom scheme worked, we would have had an experience of the whole workflow getting executed inside one's mobile, similar to how it works in Android.

At this point, not exploring any further till I get an iPhone version that is free of NCPI non-support worries.

drenther commented 4 years ago

Hey @reeteshranjan that is some exceptional dive deep points. Thanks for all the effort and time you have put in. I will try and explore along the same lines in iPhone X and see if we can get anything up that will be decent enough to be packaged in a lib. But, the callback bit seems like a deal breaker so far to me.

@pepsighan it will be great if you could share your thoughts whenever you can.

reeteshranjan commented 4 years ago

Hey @reeteshranjan that is some exceptional dive deep points. Thanks for all the effort and time you have put in.

Thank you @drenther! Happy to help. I love contributing to open source. Do check out my github and my organizations based repositories. Hopefully, you can find something that is useful.

reeteshranjan commented 4 years ago

I have captured the results of testing on iPhone 7 here:

https://docs.google.com/spreadsheets/d/1y8m2zrrhM7yZnvYJYgTUtueCatP76j6_WSJYFE6JmvQ/edit?usp=sharing

This is ongoing work. I'm stopped for today as my bank accounts either exhausted daily transaction limits (owing to this testing 🙂) or some other issues.

Since many apps support upi custom scheme (and some support only that), to test each of them without any ambiguity for iOS, I offloaded all but the one I wanted to test, and then launching a URL of the form upi://pay?pa=... did launch the solo app.

reeteshranjan commented 4 years ago

Some apps demanded iOS 13.5+. All the tests have been done on iOS 14.

reeteshranjan commented 4 years ago

Have started a communication with Google Pay about the callback not working. Hopefully it will point an error in my integration method such as anything being wrong with value of the url parameter. I did try 2 versions: URL encoded and unencoded and both failed. Thinking whether they would filter out any non-www domains as some sort of additional security filtering, I did setup a www URL with a working URL call welcoming GET and POST calls. But no luck.

reeteshranjan commented 4 years ago

Summary of experiments so far

Apps researched

These apps were chosen as they supported custom schemes including/excluding upi: Airtel, Amazon, BHIM Cent UPI, BHIM JK Bank UPI, BHIM@SyndUPI, BHIM UCO UPI, Cointab, Freecharge, iMobile, Google Pay, Mobikwik, Paytm, Phonepe, Truecaller, WhatsApp

Custom Schemes

Behaviour around custom schemes other than upi

The point of looking at these was that an app can unambiguously invoke a payment app of its user's choice. However; invoking URLs made using these custom schemes does not lead to a complete payment process. No pre-filled payment form view is shown on invocation in most cases barring few exceptions.

Exceptions

Special Mentions

Behaviour around upi custom scheme

Ambiguity resolution

Apps that perform payment process

Few apps exhibited the following behaviour for upi custom scheme URLs:

The apps are: BHIM JK Bank UPI, Cointab, Freecharge, Google Pay, Paytm, PhonePe, WhatsApp

Apps that did not respond well

Notes on behaviour around callback URL

None of the apps invoked the callback URL specified in url parameter.

Paytm is the one app that showed that it's trying to at least parse the URL. And it has some structural requirement on the callback URL that's not met with but it's not clearly notified by Paytm, and it gives a generic error "ref-url invalid length" for different values of url parameter.

Hacky methods of using refUrl (from earlier version of UPI linking spec) and callbackUrl (from Paytm payment API documentation) along with url parameter were tried; but were futile.

Discovery implementation

Screenshot 2020-09-25 at 10 15 26 AM

An app needs to specify the URL schemes it wishes to invoke in its project's Info.plist as shown above.

Discovery can be implemented by then calling canOpenUrl, as documented here https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl for each of these to see if these apps are installed. A simple tutorial here: https://useyourloaf.com/blog/querying-url-schemes-with-canopenurl/.

Limitations

This method does not return package bundleId of apps discovered, so while it's easy to figure out if these apps are available: Freecharge, Google Pay, Mobikwik, Paytm, PhonePe, and WhatsApp; it's impossible to figure out if the ones that implement and listen for upi custom scheme only are installed: BHIM JK Bank UPI, Cointab.

Hence, discovery needs to properly notify the user around this.

reeteshranjan commented 4 years ago

In their latest release, Jio has added support. On iOS, they have implemented custom schemes myJio and prefs. Did try it out and payment form did not open up.

reeteshranjan commented 3 years ago

Please see and review latest commits in #17. I have implemented the iOS support which is about discovering (as many as possible, see comments above about upi and other unique custom schemes) and launching any of the apps for UPI transactions.

reeteshranjan commented 3 years ago

See https://github.com/reeteshranjan/upi_pay/blob/master/APPS.md for latest verification status of a number of apps across android and ios.

drenther commented 3 years ago

closing this since #17 merged and published on pub.dev as v0.3.0

ngaurav commented 3 years ago
  • Paytm: Performs successful payments including pre-filled forms for paytmmp://upi/pay? URLs

@reeteshranjan I was trying to use the url scheme "paytmmp://upi/pay?" but it is not working on android. What is the current status on iOS?

reeteshranjan commented 3 years ago
  • Paytm: Performs successful payments including pre-filled forms for paytmmp://upi/pay? URLs

@reeteshranjan I was trying to use the url scheme "paytmmp://upi/pay?" but it is not working on android. What is the current status on iOS?

Custom scheme based calls are for iOS only. On Android, intent calls are needed.

reeteshranjan commented 3 years ago
  • Paytm: Performs successful payments including pre-filled forms for paytmmp://upi/pay? URLs

@reeteshranjan I was trying to use the url scheme "paytmmp://upi/pay?" but it is not working on android. What is the current status on iOS?

Missed responding about iOS status. I tested the paytmmp custom scheme last when this quoted comment was made. Post that I don't know what is the status of this. Please test for yourself.

ngaurav commented 3 years ago
  • Paytm: Performs successful payments including pre-filled forms for paytmmp://upi/pay? URLs

@reeteshranjan I was trying to use the url scheme "paytmmp://upi/pay?" but it is not working on android. What is the current status on iOS?

Custom scheme based calls are for iOS only. On Android, intent calls are needed.

Actually I am building a web app using flutter. On android, the custom schemes are a hit and a miss. For example, gpay://upi/pay? is working my Pixel 4a, but it is not working on the android phones. But, upi://pay? is working flawlessly everywhere. Just want to share this information with you. Also, I wanted to say thanks for the prompt response :)

drenther commented 3 years ago

@ngaurav thank you for your interaction here. But this package / repo and the issues there-of are to track bug reports and enhancement requests. We do appreciate this kind of discussions though and to support that in a more appropriate way, I have opened the discussions feature on the repo. Feel free to create a "UPI on Web" thread and continue community driven exploration of the same there.

Thanks @reeteshranjan (as always :) ) for your quick and insightful responses and @ngaurav

reeteshranjan commented 3 years ago
  • Paytm: Performs successful payments including pre-filled forms for paytmmp://upi/pay? URLs

@reeteshranjan I was trying to use the url scheme "paytmmp://upi/pay?" but it is not working on android. What is the current status on iOS?

Custom scheme based calls are for iOS only. On Android, intent calls are needed.

Actually I am building a web app using flutter. On android, the custom schemes are a hit and a miss. For example, gpay://upi/pay? is working my Pixel 4a, but it is not working on the android phones. But, upi://pay? is working flawlessly everywhere. Just want to share this information with you. Also, I wanted to say thanks for the prompt response :)

@drenther just closing this here.

Yes, it's correct that upi://pay? works everywhere, as that's the expected behaviour of apps implementing the UPI linking spec. Other custom schemes, their support for UPI payment etc. is completely the choice of the app developer and that's why you don't see a standard behaviour. So if you are looking for code working across multiple apps, you need to use upi://pay?.

About my comment about custom schemes vs intents, which might have been misleading: what I meant was that 'custom scheme' is an iOS specific term, and though the eventual URI formed out of intent calls are the same, the mechanism and coding is very different.

reeteshranjan commented 2 years ago

Is https://github.com/drenther/upi_pay/issues/38 relevant and important for you?

If yes, could you please respond to my twitter thread with UPI and NPCI handles included in your response asking how these must be solved and how it helps you? https://twitter.com/reeteshr08/status/1488746633068089345

@viveknimkarde @ngaurav