flutter_stripe_payment icon indicating copy to clipboard operation
flutter_stripe_payment copied to clipboard

web support

Open ayushin opened this issue 4 years ago • 33 comments

Hi guys!

I wonder what would be our options to add flutter web support?

ayushin avatar Apr 08 '20 16:04 ayushin

Looks like it would be possible to do this the same way https://github.com/Lyokone/flutterlocation is implemented for both mobile and web.

We could create flutter_stripe_payment_platform for platform abstraction and flutter_stripe_payment_web to use https://stripe.com/docs/js/

Any interest in this?

ayushin avatar Apr 11 '20 07:04 ayushin

@ayushin Would love this! Do you know if there are any workarounds or packages that enable integrating Stripe on Flutter for Web?

peterjeffrey avatar Apr 28 '20 16:04 peterjeffrey

It seems there's a dart wrapper for stripe https://pub.dev/packages/stripe and also there's a fully native https://pub.dev/packages/stripe_sdk

Unfortunately I don't have much time to work on this now, but I would love to help where I can.

ayushin avatar Apr 29 '20 07:04 ayushin

good news!

  1. Managed to generate functional js-interop library with https://github.com/dart-lang/js_facade_gen

  2. Got a few methods working

Will post prototype library soon.

If anybody else is working on this - let me know

ayushin avatar May 01 '20 19:05 ayushin

So I've made a https://github.com/jonasbark/flutter_stripe_payment/pull/147 initially for native pay but there are quite a few open questions:

  • native pay supports both Apple and Android so canMakeNativePay requires country, currency and returns null if not supported or object with applePay = true for apple pay

  • paymentRequestWithNativePay takes double, but stripe sdk expects int in smallest currency, for now hacked as total * 100 but that's not right

  • initially i wanted to implement this as flutter_stripe_payment_web but because of the above this doesn't work without modifying the original plugin

  • we should be using PlatformInterface to avoid platform specific methods i.e. Platform.isIOS etc inside of the plugins

  • quite unfortunately the original plugin models do not coincide with stripe models generated from typescript (i.e Token, BankAccount)

  • completePayment should be able to take 'success', 'failure', 'cancel'

All in all some higher level refactoring would be needed to have all 3 platforms integrated seamlessly in one interface (I don't really see the need for separate ApplePayOptions and AndroidPayOptions - stripe doesn't have them).

I'm very short on time, so if anybody wants to help - I would be super happy.

ayushin avatar May 02 '20 09:05 ayushin

any progress on this issue? Really looking forward to using this sdk for web payment. thanks!

gorillatapstudio avatar May 28 '20 01:05 gorillatapstudio

Well the PR above works for us so far, but it requires a bit of adaptation as per above.

ayushin avatar May 28 '20 06:05 ayushin

Thanks for working on that! Looking forward to a new release!

gorillatapstudio avatar May 31 '20 16:05 gorillatapstudio

Please elaborate... "Well the PR above works for us so far, but it requires a bit of adaptation as per above."

I tried to find the PR, and seems gone. Is it correct to assume this has been pushed to master? If so, can we conclude stripe_payment supports flutterweb? If so, would be great to make that visible in pub.dev.

eliudio avatar Jun 25 '20 17:06 eliudio

There's this breaking change:

native pay supports both Apple and Android so canMakeNativePay requires country, currency and returns null if not supported or object with applePay = true for apple pay

and the proper implementation requires refactoring the plugin... if a day had 72 hours.... :-)

ayushin avatar Jun 25 '20 18:06 ayushin

@ayushin are you still moving this forward in the near future? Thanks!

gorillatapstudio avatar Aug 14 '20 03:08 gorillatapstudio

@gorillatapstudio we use this in production:

  stripe_payment:
    git:
      url: https://github.com/apexlabs-ai/flutter_stripe_payment
      ref: web

The only plan we have is to split it into separate flutter_stripe_payment_web but on hold due to lack of resources atm.

ayushin avatar Aug 14 '20 05:08 ayushin

The stripe_payment plugin for web doesn't implement the method 'createTokenWithCard' does createTokenWith card supported in the web branch?i have added

stripe_payment:
    git:
      url: https://github.com/apexlabs-ai/flutter_stripe_payment
      ref: web

naikdp7 avatar Aug 14 '20 10:08 naikdp7

that could be - i'll try to have a look at it when i have time, however it can be we are not using that functionality at all

ayushin avatar Aug 14 '20 10:08 ayushin

i have check the code.there is no case for createTokenWithCard.

naikdp7 avatar Aug 14 '20 10:08 naikdp7

@ayushin I am using the apexlabs-ai branch and have two issues to report. Not sure if it only happened to me or everyone.

(1) when i tried to call

StripePayment.paymentRequestWithCardForm(CardFormPaymentRequest());

it showed an error of

The stripe_payment plugin for web doesn't implement the method 'paymentRequestWithCardForm'

(2) when the payment intent succeed (confirmed in stripe), paymentIntentResult.status is null (although I do receive "succeeded" when running on ios or android native app).

Everything else is working great! Thanks!

gorillatapstudio avatar Oct 22 '20 02:10 gorillatapstudio

  1. See the above:

native pay supports both Apple and Android so canMakeNativePay requires country, currency and returns null if not supported or object with applePay = true for apple pay

  1. Did not get to implement this yet, should be very easy, but in our case we pass credit card details from own flutter form

ayushin avatar Oct 23 '20 15:10 ayushin

Thanks @ayushin ! so for web stripe payment, would you further clarify what I should do to make sure the paymentIntentResult.status can return either "succeeded" or "failed" but not null? All my code for web and native payment are the same at the moment.

gorillatapstudio avatar Oct 23 '20 16:10 gorillatapstudio

Well, there's no separate method for "not supported", so that's why you get null to indicate that. We'd need a different interface all together if we don't want null there (like an enum)

ayushin avatar Oct 23 '20 17:10 ayushin

However, my payment was charged successfully at stripe. Does it mean the status variable in callback was not supported for web? In the meantime, is there anyway I can do to know if the payment was successful or not. Thanks!

gorillatapstudio avatar Oct 23 '20 18:10 gorillatapstudio

@ayushin I am using the apexlabs-ai branch and have two issues to report. Not sure if it only happened to me or everyone.

(1) when i tried to call

StripePayment.paymentRequestWithCardForm(CardFormPaymentRequest());

it showed an error of

The stripe_payment plugin for web doesn't implement the method 'paymentRequestWithCardForm'

(2) when the payment intent succeed (confirmed in stripe), paymentIntentResult.status is null (although I do receive "succeeded" when running on ios or android native app).

Everything else is working great! Thanks!

@gorillatapstudio I fail to see what is working, if it is working at all. None of the methods in the example works for web, namely

createSourceWithParams
paymentRequestWithCardForm
createTokenWithCard
createPaymentMethod
paymentRequestWithNativePay

Any one of them returns error of either not configured or is available on web. Did you test on web? What did you do to make anything work?

yaizudamashii avatar Oct 27 '20 18:10 yaizudamashii

@yaizudamashii we do payments via backend so we did not have need for those methods... sorry for half-ready solution

paymentRequestWithNativePay should work though! it works for us on web

ayushin avatar Oct 27 '20 18:10 ayushin

@ayushin Thank you for the clarification. paymentRequestWithNativePay working would be great, other methods aren't that necessary.

When I try paymentRequestWithNativePay in stripe_payment.dart:77 final token = await _channel.invokeMethod("paymentRequestWithNativePay", options); I get an error

"Error: PlatformException(unavailable, Native pay is not configured or available, null, null)
    at Object.throw_ [as throw] (http://localhost:5000/dart_sdk.js:4339:11)
    at StandardMethodCodec.decodeEnvelope (http://localhost:5000/packages/flutter/src/services/system_channels.dart.lib.js:784:19)
    at MethodChannel._invokeMethod (http://localhost:5000/packages/flutter/src/services/system_channels.dart.lib.js:946:32)
    at _invokeMethod.next (<anonymous>)
    at http://localhost:5000/dart_sdk.js:37679:33
    at _RootZone.runUnary (http://localhost:5000/dart_sdk.js:37533:58)
    at _FutureListener.thenAwait.handleValue (http://localhost:5000/dart_sdk.js:32507:29)
    at handleValueCallback (http://localhost:5000/dart_sdk.js:33054:49)
    at Function._propagateToListeners (http://localhost:5000/dart_sdk.js:33092:17)
    at _Future.new.[_completeWithValue] (http://localhost:5000/dart_sdk.js:32935:23)
    at async._AsyncCallbackEntry.new.callback (http://localhost:5000/dart_sdk.js:32957:35)
    at Object._microtaskLoop (http://localhost:5000/dart_sdk.js:37794:13)
    at _startMicrotaskLoop (http://localhost:5000/dart_sdk.js:37800:13)
    at http://localhost:5000/dart_sdk.js:33309:9"

My flutter version is

Flutter 1.23.0-18.1.pre • channel beta • https://github.com/flutter/flutter.git
Framework • revision 198df796aa (12 days ago) • 2020-10-15 12:04:33 -0700
Engine • revision 1d12d82d9c
Tools • Dart 2.11.0 (build 2.11.0-213.1.beta)

and I am using Chrome Version 86.0.4240.111 (Official Build) (x86_64)

Would you happen to know if anything that could make this method work?

yaizudamashii avatar Oct 27 '20 18:10 yaizudamashii

I see that canMakeNativePayPayments is returning null, so somehow the browser does not allow payment. Maybe there is some problem with authentication?

yaizudamashii avatar Oct 27 '20 18:10 yaizudamashii

@ayushin I read the code a bit more, is this web extension designed to be used in a browser in iOS devices? Do I understand correctly that canMakeNativePayPayments is true if there is Apple Pay available?

yaizudamashii avatar Oct 27 '20 19:10 yaizudamashii

@yaizudamashii use the http call to your backend server for createPaymentIntent. However the StripePayment.confirmPaymentIntent is partially implemented for web I guess since it succeed in stripe dashboard but didn’t return status code.

gorillatapstudio avatar Oct 27 '20 19:10 gorillatapstudio

Yes, null means it it not supported, make sure you try it with https

ayushin avatar Oct 27 '20 22:10 ayushin

Ok I read the Stripe documentation, no wonder I was getting null back, even when trying with ngrok for https

paymentRequest.canMakePayment only returns true on Safari 10.1+ (desktop and mobile), Chrome 61+ (desktop and mobile), and Microsoft Edge 16.16299+ when the customer has a card already saved with Apple Pay, Microsoft Pay, or their browser. https://stripe.com/docs/js/payment_request/can_make_payment

yaizudamashii avatar Oct 31 '20 00:10 yaizudamashii

Thank you @ayushin Finally I was able to receive the payment token using chrome with credit card saved, with https, localhost forwarded via ngrok. The example is still not perfect, as the window did not disappear after receiving the token and prevented me from clicking on "Complete Native Payment" button before timeout. I might look into how to dismiss that window.

yaizudamashii avatar Oct 31 '20 00:10 yaizudamashii

you need to call completeNativePayment method (or similar - long time since i saw the code) for apple pay

ayushin avatar Oct 31 '20 16:10 ayushin