Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recent Version Releases Incompatible with Expo #357

Closed
qjimmy opened this issue Jun 18, 2021 · 3 comments
Closed

Recent Version Releases Incompatible with Expo #357

qjimmy opened this issue Jun 18, 2021 · 3 comments

Comments

@qjimmy
Copy link

qjimmy commented Jun 18, 2021

Context

Not sure to put this as feature request or bug, sorry in advance if I mislabeled it.

This happened while I was using version 0.1.4 with Expo SDK 41. This is happens due to the fact that anything higher than version 0.1.1 with expo is incompatible. More details as follows.

Bug Description

I’m trying to save a card payment method using Stripe’s React Native SDK. (To set up future payments.) Here's what I followed: https://stripe.com/docs/payments/save-and-reuse?platform=react-native

Here’s the flow I got:

  • Create a setup intent on the server with the customer id in the param:
   stripe.setupIntents.create({
      customer: stripeCustomerId,
    });
  • On the mobile client, using Stripe’s React Native SDK, use the client secret to confirm the setup intent
import { CardField, useStripe } from '@stripe/stripe-react-native';
// ...
function Screen() {
   const { confirmSetupIntent } = useStripe();
   const foo = async () => {
      const clientSecret = // sample: seti_1J3lHgGhawG1pGgAodD4TgSF_secret_Jh9aaPwXpgtfxdLjZRKdpBsEvlZzTxB
      const result = await confirmSetupIntent(clientSecret, {
        type: 'Card',
        billingDetails,
      });
    console.log(result) // { setupIntent: undefined }
   }
   return <View>
      <CardField {...props} />
      <Button onPress={foo}>
   </View>
}

Now here’s the issue I am facing. This flow allows me to successfully save the payment method on the customer in stripe (I see it in the stripe dashboard). However, the confirmSetupIntent(...) returns { setupIntent: undefined } . As per the docs, the returned value should be { error?: undefined; setupIntent: SetupIntent } on success. While the returned value should be { error: StripeError; setupIntent?: undefined } on error only. Here is the reference to the docs: https://stripe.dev/stripe-react-native/api-reference/modules.html#confirmsetupintentresult

Here is a screenshot of the logs. I logged the client_secret first, then the result of the confirmSetupIntent(...).

Screen Shot 2021-06-18 at 1 49 07 PM

Once the logs were printed, the payment method was successfully attached to the customer on the Stripe dashboard, even though the SDK returns { setupIntent: undefined }.

To Reproduce

  1. To reproduce this, setup an Expo app (version 41) with the latest stripe-react-native SDK
  2. Try the flow mentioned above.
  3. Now try installing the stripe-react-native SDK version 0.1.1
  4. Reproduce the flow detailed above.
  5. The behaviour is as expected.

Expected behavior

On confirm setup intent, the returned setupIntent should be

// Sample
{
  "setupIntent": Object {
    "clientSecret": "seti_1J3nhQGhawG1pGgA18t03arI_secret_JhC5mbYtZ4wHT3JhCnzaYsdydzBHuMm",
    "created": 1624045796000,
    "description": null,
    "id": "seti_1J3nhQGhawG1pGgA18t03arI",
    "lastSetupError": null,
    "livemode": false,
    "paymentMethodId": "pm_1J3nhRGhawG1pGgAWJl79P3z",
    "paymentMethodTypes": Array [
      "Card",
    ],
    "status": "Succeeded",
    "usage": "OffSession",
  },
}

Cause

Upon further inspection, I learned that it was because of version incompatibility with expo. Tested with version 0.1.1 and it worked. However, it would be preferable to have recent releases compatible with Expo. For instance, this issue #222 was fixed in version 0.1.3, but since I would have to use version 0.1.1, this would mean that the mentioned issue would not be fixed in my application.

Screen Shot 2021-06-18 at 3 52 08 PM

Smartphone

  • Device: iPhone 11
  • OS: iOS 14
  • Expo: SDK 41
@shanutthankachan

This comment has been minimized.

@qjimmy
Copy link
Author

qjimmy commented Jun 19, 2021

Alright here's the workaround.

You can use the @stripe/stripe-react-native SDK with Expo but only on version 0.1.1 as of now. You can install it with expo install @stripe/stripe-react-native or yarn add @stripe/[email protected].

Functionality will works, such as confirmSetupIntent, etc. But as mentioned, the <CardField /> element will display the keypad on focus. On blur, the element does not dismiss the keypad. This is fixed in version 0.1.3, but since Expo is only compatible with version 0.1.1, here's the workaround

Workaround

You can add a hidden <TextInput /> component and add the display: none; css attribute. Use the useRef hook and use JS to imperatively focus that hidden input and then immediately blur that same hidden input. This switches the keyboard to a dismissable one, then on blur, will dismiss the keyboard.

function MyComponent() {
   const hiddenInput = useRef<TextInput>(null);

   const dismissKeyboard = () => {
    if (hidden.current) {
      hiddenInput.current.focus(); // focusing on this hidden input will switch the keyboard to a dismissable one
      hiddenInput.current.blur(); // blur will dismiss the keyboard
     }
   };

   return (
     <>
      <CardField />
      <TextInput ref={hiddenInput} style={{ display: 'none' }}/>
     </>
   )
}

You can then use the dismissKeyboard() to dismiss the CardField's keyboard. You can place it in a button's onPress or use some Screen wizardry to close the keyboard.

@thorsten-stripe
Copy link
Contributor

We will need to wait for SDK 42 for these newer versions to become compatible with Expo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants