question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

confirmSetupIntent not working as expected

See original GitHub issue

Describe the bug

Currently when I try to call confirmSetupIntent I get the following error:

{
  "stripeErrorCode": null,
  "declineCode": null,
  "localizedMessage": "Card details not complete",
  "message": "Card details not complete",
  "type": null,
  "code": "Failed"
}

Card details are always complete

To Reproduce Steps to reproduce the behavior:

This is my current code for the component

    <StripeProvider publishableKey="my test key">
      <CardField
        postalCodeEnabled={true}
        placeholder={{
          number: '4242 4242 4242 4242',
          expiration: '10/24',
          cvc: '123',
          postalCode: 'C.P.',
        }}
        cardStyle={{
          backgroundColor: '#FFFFFF',
          textColor: '#000000',
          borderWidth: 1,
          borderColor: COLOR.gray_100,
        }}
        style={{
          width: '100%',
          height: 50,
          marginVertical: SIZES.MD,
          borderRadius: SIZES.MD,
          ...STYLE_SHADOW,
        }}
        onCardChange={inputCard => {
          setCardDetails(inputCard);
        }}
        onFocus={focusedField => {
          setInputField(
            focusedField ? INPUT_FIELD[focusedField.toString()] : '',
          );
        }}
      />
      <Text>{inputField}</Text>
      <Button
        disabled={!cardDetails?.complete}
        onPress={submit}
        style={{
          marginTop: SIZES.MD,
          borderRadius: SIZES.MD,
          ...STYLE_SHADOW,
        }}>
        Guardar
      </Button>
    </StripeProvider>

And this is the submit function

  const submit = async () => {
    setLoading(true);
    try {
      await createOrUpdateClient();
      await updateProfile({
        variables: {
          input: {
            card: {
              last_digits: cardDetails?.last4,
              expiry_date: `${cardDetails?.expiryMonth}/${cardDetails?.expiryYear}`,
            },
          },
        },
      });
      const setupIntentResponse = await createSetupIntent();
      const billingDetails: PaymentMethods.BillingDetails = {
        email,
      };
      const { setupIntent, error } = await confirmSetupIntent(
        setupIntentResponse.data?.stripeSetUpIntent?.client_secret as string,
        {
          type: 'Card',
          billingDetails,
        },
      );
      console.log('LOG: error ', JSON.stringify(error, null, 2));
      console.log('LOG: setupIntent ', JSON.stringify(setupIntent, null, 2));
      if (error) {
        throw error;
      }
      Navigation.pop(componentId);
    } catch (error) {}
    setLoading(false);
  };

client_secret is always defined, so no issue there.

Expected behavior

The card is saved for future payments.

I debugged the issue directly on android studio and xcode, so I found that the native card manager is always null when it gets to the confirmSetupIntent native method on both platforms. I’m attaching the evidence from xcode.

Screenshots

Captura de Pantalla 2021-06-24 a la(s) 20 55 41

Desktop (please complete the following information):

  • OS: MacOS big sur (M1)

Smartphone (please complete the following information):

  • Device: I used the iOS simulator, the android emulator, an iPhone 11 and a moto g5 plus
  • OS: iOS 14, android 11

Additional context

Please, don’t close this issue until you can help, this is becoming a huge block for our company.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:4
  • Comments:28 (3 by maintainers)

github_iconTop GitHub Comments

5reactions
idcuestacommented, Jul 5, 2021

Background

We are in the process of migrating from tipsi-stripe to official react native library now due to Google Play Store not allowing anymore the version of stripe used by tipsi.

When migrating code, we have followed these steps:

  • When creating a new payment method (user adds a new card), we open a modal screen to capture payment method. We have replaced tipsi payment form with our own screen, and we are using CardField component. This screen calls stripe.createToken and returns the tokenId in a callback function.
  • From our checkout screen (totally different from the modal we use to capture a new card), and after user has assigned some payment method card, either by adding a new card (we work here with token), or by selecting from saved cards retrieved from our API (we work with paymentMethodId in this case), we make a call to confirmSetupIntent, passing as parameters either the token or paymentMethodId (by the time we make this call there is no UI related to stripe on screen).

Note: ConfirmSetupIntent.Param spec doesn’t consider any card parameter except for type.

Issues found

After calling confirmSetupintent, we are getting these errors:

  • On iOS, we get error Card details not complete when passing paymentMethodId instead of token.
  • On Android, app is crashing in both scenarios.

iOS investigation

When inspecting what happens under the hood when calling confirmSetupIntent on iOS, we can see that StripeSdk.swift#confirmSetupIntent is not handling paymentMethodId parameter, so because by the time this is called there is no cardFieldView and no token param is passed, error PaymentMethodError.cardPaymentMissingParams is resolved.

Android investigation

When inspecting what happens under the hood when calling confirmSetupIntent on Android, we can see that StripeSdkModule#confirmSetupIntent is not handling token or paymentMethodId parameters, so because by the time this is called there is no instance, and this causes cardParams to be null, app is throwing an exception when trying to create card params, and trying to use card!!

Conclusion

When using tipsi-stripe, they are under the hood calling stripe API V1 manually, and they handle passing paymentMethodId to POST v1/setup_intents/:id/confirm, but when replacing it with this library, paymentMethodId is ignored and not passed correctly. On top of that, Android is not handling correctly passing a token parameter.

2reactions
fdelacruzsotocommented, Jul 8, 2021

@thorsten-stripe @arekkubaczkowski any chance you are looking into this issue? It seems a lot of people is facing the same problem, and I already give you guys steps to reproduce the error.

My company is close to launching our apps and we heavily depend on this, so this is becoming a major blocking for us.

We can get into a call and I can give you details if that helps.

We really need this to get fixed 😢

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using confirmSetupIntent on stripe-react-native - Stack Overflow
I guess I'm not sure how Stripe expects the card details to be passed in. Has anyone else experienced the same issue? Any...
Read more >
confirmSetupIntent - Stripe Developer Resources
Suspend function to confirm a SetupIntent object. See Confirm a SetupIntent. POST /v1/setup_intents/:id/confirm. Return.
Read more >
confirmSetupIntent - Stripe JS Reference
Use stripe.confirmSetupIntent(clientSecret, data) to confirm the SetupIntent when you are not gathering payment information from an Element . Call this ...
Read more >
Stripe React Native Migration Function by Function - Tipsi ...
In tipsi-stripe to set up recurring payments or to create one-time payments with a final amount determined later, there is a confirmSetupIntent ......
Read more >
CreatePaymentIntent in stripe - Rust - Docs.rs
Amount intended to be collected by this PaymentIntent. ... This parameter is intended for simpler integrations that do not handle customer actions, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found