stripe / stripe-react-native

React Native library for Stripe.
https://stripe.dev/stripe-react-native
MIT License
1.23k stars 257 forks source link

Question : How is 3DS implemented ? Verification Code input not showing for every card [confirmSetupIntent] #733

Open AlixH opened 2 years ago

AlixH commented 2 years ago

Describe the bug

When I add my VISA card from Bank1, I receive a notification from my Bank app to authenticate. Then back to my app, my card is added When I add a VISA from Bank2, the 3DS page show a input to type the code I received by SMS, then when I enter the code, my card is added Problem : When I add a Mastercard from Bank3, the 3DS page shows no input (no Bank app notification, no SMS, no nothing)

How is decided to show a code input on the 3DS page ? Are there Bank-specfific inplementations, or card brand-specific implementations ? How is decided to use the bank app over SMS code to authenticate ?

Stripe react native

stripe-react-native: 0.1.4

Code

Link to my code (exact line) : https://github.com/sap-labs-france/ev-mobile/blob/c72851f17f84395d308c7e741359a9f31425d7f2/src/screens/payment-methods/stripe/StripePaymentMethodCreationForm.tsx#L64

Desktop (please complete the following information):

Smartphone (please complete the following information):

ClaudeROSSI commented 2 years ago

Actually, we face the problem with the ING bank. 3d secure authentication flow has been tested and works properly with other banks (such as BNP PARIBAS)

With the ING bank (and a master card) the 3d secure redirection displays a screen with two buttons (confirm and cancel) and where nothing can be entered (no input fields)

STEP#1 - enter card info

credit-card

STEP#2 - click on "confirm"

3dsecure-bank-ING

STEP#3 - Back to our app we receive the following error

debug-errorcode

The button "confirm" and the button "cancel" have the same behaviour! - error.code: "Canceled"

Note that we do not face the problem when doing it from our web app (Angular + typescript)

stianjensen commented 2 years ago

We have the same issue with some Norwegian banks. For security reasons, they don't support all of their verification flows outside of webpages they control themselves, so only web based verification is supported: https://github.com/stripe/stripe-ios/issues/1895

ClaudeROSSI commented 2 years ago

The situation becomes critical on our side. We are getting more and more feedback from end-users who confirm that the 3DS authentication does not work on their mobile phone.

The problem can be produced with the following banks:

The user interface to perform the authentication is not shown. With ING, only the first step is visible, showing a generic message and a button to "Continue" ... when pressing that button the next step is not shown and the payment flow returns to our app with an error.

When checking the event logs on the stripe side, we can see the error code: setup_intent_authentication_failure and the corresponding setup intent is marked as "incomplete"

Stripe account: acct_1IRCIVKhckfZCJHR Event: evt_1K6EapKhckfZCJHRrDW0X9oH

Typical Error: "last_setup_error": { "code": "setup_intent_authentication_failure", "doc_url": "https://stripe.com/docs/error-codes/setup-intent-authentication-failure", "message": "The latest attempt to set up the payment method has failed because authentication failed.", "payment_method": { "id": "pm_1K6EalKhckfZCJHRjlSTvMwI", "object": "payment_method", ...

Can you help? Thanks Claude

p.s.: The same operation (same bank, same credit card) works properly when using our web app. Unfortunately this is not an option for most of our customers.

scesbron commented 2 years ago

Same for us, we are getting more and more customers that cannot achieve their payments in the app but can do it in the web. On our side the code is pretty close between app and web

Here is a simplified version of our code, when the user clicks on the payment button we do

  const onPress = async () => {
    if (stripePaymentMethodId) {
      createDataInBackend(data, stripePaymentMethodId);
    } else {
      try {
        const { error, paymentMethodId } = await getStripePaymentMethod();
        if (error) {
          throw new Error(error.message);
        } else {
          createDataInBackend(data, paymentMethodId);
        }
      } catch (error) {
        paymentErrorModal();
      }
    }
  };

Then if the backend returns us a flag that indicates that we need a SCA check we do

  const scaCheck = async () => {
    try {
      const { error, paymentIntent } = await handleCardAction(paymentIntentClientSecret);
      if (paymentIntent?.status === PaymentIntents.Status.RequiresConfirmation) {
        createDataInBackend(data, paymentIntend.id);
      } else {
        // Whether there is an error or not, we should only accept payments with confirmation.
        throw new Error(error?.message ?? `Handle card action returns an incorrect status : ${paymentIntent?.status}`);
      }
    } catch (error) {
      paymentErrorModal();
    }
  };

One error we often get from ios users is "The PaymentIntent requires a PaymentMethod or Source to be attached before using STPPaymentHandler.".

ClaudeROSSI commented 2 years ago

Hello,

We keep facing issues with some banks when entering a new payment method. Customers are complaining that they can register their credit card only when using our web app. From our mobile app (based on react-native integration) does not work with some particular banks.

I tried myself with my own credit card (from ING) and we are stuck on the first step of the 3DS authentication process (from ING). A tap on "Continue" button simply navigates to the same screen with no error message. This behavior is different from the one that we had last year (which is described in my previous posts).

Moreover, the text of the authentication phase is not very professional. You may notice a wrong escaping of the line feed character (c.f.: screenshot below).

Can you communicate a list of banks that do not yet fully implement the 3DS authentication? Thanks for your help, Claude

IMG_20220107_104205_370 (1)

ClaudeROSSI commented 2 years ago

Hello,

Our application has just been tested with stripe-react-native 0.2.3 and the problem persists with (at least) the ING bank. So far we only tested the Android version. The symptom is the same than the one described 4 days ago. The end-user gets stuck on the first step of the 3DS authentication process (same screenshot). THe only difference is that the escaping of the line feeds (\n\n) is now properly done.

Can you please advise? Best regards, Claude

podotki commented 2 years ago

Hello,

Same issue here with ING bank too on Android during the 3DS.

Thanks for your precious help :)

davidme-stripe commented 2 years ago

We're working on a solution for this. If you're experiencing this issue and would like to opt into our testing program, please email 3ds2-mobile-fallback@stripe.com with your account ID. Thanks!

ClaudeROSSI commented 2 years ago

Hello,

FYI: We did some additional tests on Android (with stripe-react-native 0.2.3 ) and can confirm that we do NOT face any issues with the following banks:

Best regards, Claude

ClaudeROSSI commented 2 years ago

We're working on a solution for this. If you're experiencing this issue and would like to opt into our testing program, please email 3ds2-mobile-fallback@stripe.com with your account ID. Thanks!

Being part of the testing program, I've just tried again with my own ING Master Card and the authentication flow now works properly (on Android). Thanks a lot for the correction.

Let us know when this fix will be released to all customers.

Best regards, Claude

podotki commented 2 years ago

Great news ! Thank you all guys :)

nerder commented 2 years ago

Hey folks, we are facing a similar issue we are just trying to opt in into the program.

nerder commented 2 years ago

Is by any chance anyone working on a stable fix for this?

aaroajg commented 1 year ago

Hello! Any update on the above fix @davidme-stripe @charliecruzan-stripe? We also have some customers based in UK using Mastercard who are unable to update their payment methods, so a fix for this issue would be very helpful 🙏