flutter_stripe_payment icon indicating copy to clipboard operation
flutter_stripe_payment copied to clipboard

Platform Exception

Open vikas-shrma opened this issue 4 years ago • 15 comments

HI. I Followed all steps and after when i call PaymentIntents StripePayment.confirmPaymentIntent( PaymentIntent(clientSecret: key, paymentMethodId: paymentMethod.id, ),).then((paymentIntent) { print( "Payment intent id ${paymentIntent.paymentIntentId}"); setState(() {_paymentIntent = paymentIntent;}); Then Secure Payment Page opend. after click on Complete Authentication i am getting PlatformException(failed, failed, null) did i am missing any Permission or anything else?

vikas-shrma avatar Nov 08 '19 04:11 vikas-shrma

All process done with Stripe Test Account and Real Device Android 9.0

vikas-shrma avatar Nov 08 '19 04:11 vikas-shrma

Do you have a minimal project for me to reproduce?

jonasbark avatar Nov 13 '19 05:11 jonasbark

@jonasbark I can confirm the PlatformException. We run on 1.0.5

We used the method to gather PaymentMethod from user. We tried to call directly StripePayment.paymentRequestWithCardForm(CardFormPaymentRequest()).then((method) { debugPrint(method); }); with no address or prefilled data with no success.

And even by prefilling all data in form for address, we get a Platform Exception when doing a simple:

StripePayment.paymentRequestWithCardForm(CardFormPaymentRequest.fromJson({
        "requiredBillingAddressFields": "full",
        "prefilledInformation": {
          "billingAddress": {
            "city": "San Francisco",
            "country": "US",
            "line1": "123 fake street",
            "line2": "app 102",
            "name": "Obi Wan Kenobi",
            "postalCode": "90129",
            "state": "CA"
          }
        }
      })).then((paymentMethod) {
  debugPrint(paymentMethod);
});

=> PlatformException(IllegalArgumentException, null, null)

Detail:

[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(IllegalArgumentException, null, null)
E/flutter ( 9934): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:569:7)
E/flutter ( 9934): #1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:316:33)
E/flutter ( 9934): <asynchronous suspension>
E/flutter ( 9934): #2      StripePayment.paymentRequestWithCardForm (package:stripe_payment/src/stripe_payment.dart:94:34)

To repro: just paste my code in main it will trigger the error

blackholegalaxy avatar Dec 02 '19 19:12 blackholegalaxy

Any updates on this? I have a similar issue but with authenticateSetupIntent

var result; try { result = await StripePayment.authenticateSetupIntent(clientSecret: secretKey); } catch (e) { print(e); }

That code generates the error: PlatformException(api, FAILED, null) on ios PlatformException(unexpected, Unexpected state, null) on android

The secretKey comes from my api call to my backend which works and returns a valid secretKey. The setup intent has an attached paymentMethod as well.

Not sure what I'm doing wrong or how to fix this, appreciate any input.

Isakdl avatar Dec 11 '19 21:12 Isakdl

I implemented this in a clean flutter project only adding this plugin and firebase functions (to call my backend), and I still get the same error:

PlatformException(unexpected, Unexpected state, null)

This is currently a huge blocker for me, and I'm not really sure where to begin debugging this error.

Isakdl avatar Dec 13 '19 20:12 Isakdl

I have done some more digging around, and looked through the native code. I have tried creating a setupIntent with and without attaching a payment method.

When a create a payment method with the function:

 await StripePayment.paymentRequestWithCardForm(CardFormPaymentRequest());

and attached that one on my backend to the setupIntent and then return the secrect key I get the error I did before, ie: PlatformException(unexpected, Unexpected state, null)

in the native java code it ends up with the status: RequiresCapture or RequiresConfirmation.

If I do not attach a payment method I instead end up with the error: PlatformException(authenticationFailed, The user failed authentication., null)

in the native java code it stops at RequiresAction or RequiresPaymentMethod.

The function never launches any other GUI or webview to handle the authentication flow, it just simply throws the error.

@jonasbark do you have any input on this?

///StripeModule.java in gettipsi/stripe
private void attachSetupResultActivityListener(final Promise promise) {
    ActivityEventListener ael = new BaseActivityEventListener() {
      @Override
      public void onActivityResult(Activity a, int requestCode, int resultCode, Intent data) {
        final ActivityEventListener ael = this;

        mStripe.onSetupResult(requestCode, data, new ApiResultCallback<SetupIntentResult>() {
          @Override
          public void onSuccess(@NonNull SetupIntentResult result) {
            removeActivityEventListener(ael);

            try {
              switch (result.getIntent().getStatus()) {
                case Canceled:
                  // The Setup Intent was canceled, so reject the promise with a predefined code.
                  promise.reject(CANCELLED, "The SetupIntent was canceled by the user.");
                  break;
                case RequiresAction:
                case RequiresPaymentMethod:
                  /**********
                  **Fails here if the setup intent does not have a payment method attached
                  ***********/
                  promise.reject(AUTHENTICATION_FAILED, "The user failed authentication.");
                  break;
                case Succeeded:
                  promise.resolve(convertSetupIntentResultToWritableMap(result));
                  break;
                case RequiresCapture:
                case RequiresConfirmation:
                  /**********
                  **Is one of these cases if I have a payment method attached to the setupIntent
                  ***********/
                default:
                  promise.reject(UNEXPECTED, "Unexpected state");
              }
            } catch (Exception e) {
              promise.reject(UNEXPECTED, "Unexpected error");
            }
          }

          @Override
          public void onError(@NonNull Exception e) {
            removeActivityEventListener(ael);
            e.printStackTrace();
            promise.reject(toErrorCode(e), e.getMessage());
          }
        });
      }

      @Override
      public void onActivityResult(int requestCode, int resultCode, Intent data) {
        onActivityResult(null, requestCode, resultCode, data);
      }
    };
    addActivityEventListener(ael);
  }

Isakdl avatar Dec 15 '19 22:12 Isakdl

As I just ported the code you might be able to find more help on https://github.com/tipsi/tipsi-stripe

jonasbark avatar Dec 16 '19 10:12 jonasbark

Hello, I was getting the same error, just had to add the following in my initState() and problem solved.

StripePayment.setOptions(StripeOptions(publishableKey: STRIPE_PUBLISHABLE_KEY));

Serveix avatar Apr 02 '20 00:04 Serveix

I received the same error with this code:

await StripePayment.authenticatePaymentIntent( clientSecret: clientSecret, );

I set the publishable key before but still run into this Exception:

PlatformException(failed, failed, null)

herrytco avatar Apr 20 '20 11:04 herrytco

Solved this issue by adding the androidPayMode properties in the StripeOptions.

StripePayment.setOptions(
    StripeOptions(
      publishableKey: publishableKey,
      androidPayMode: 'test', // if you are testing
    ),
  );

drys262 avatar Jun 12 '20 16:06 drys262

Solved this issue by adding the androidPayMode properties in the StripeOptions.

StripePayment.setOptions(
    StripeOptions(
      publishableKey: publishableKey,
      androidPayMode: 'test', // if you are testing
    ),
  );

Thanks bruh, that did the trick!

travisjayday avatar Jun 28 '20 18:06 travisjayday

i did androidPayMode, in init state but still having issue

umairali4433 avatar Aug 19 '20 10:08 umairali4433

any update on this issue?

ahmadrana24 avatar Sep 13 '20 16:09 ahmadrana24

I solved this issue by declaring the init method in the payment_services.dart file:

static init() {
    StripePayment.setOptions(

    StripeOptions(

        publishableKey: 'your_publish_code',

        merchantId: 'Test',

       androidPayMode: 'test',

  ),

);

and then calling it in the initState consuming file which in my case was signup.dart file:

@override
void initState() {

    StripeServices.init();
    super.initState();
}

ahmadrana24 avatar Sep 13 '20 21:09 ahmadrana24

put

StripePayment.setOptions(StripeOptions( publishableKey:'YOUR_TOKEN', merchantId: "Test", androidPayMode: 'test'));

in initState method

e.g:

@override void initState() { super.initState();

StripePayment.setOptions(StripeOptions( publishableKey:'YOUR_TOKEN', merchantId: "Test", androidPayMode: 'test'));

}

saifaly7995 avatar Dec 10 '20 11:12 saifaly7995