stripe / stripe-react-native

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

[iOS] 3DS webview not closing after completion #1667

Open danwoodbury opened 1 month ago

danwoodbury commented 1 month ago

I know this has been asked 100 times but all of the solutions offered do not work for us or are already implemented.

From debugging I can see that after completing 3DS it does not look like the webview is firing the deeplink listeners, if i run xcrun simctl openurl booted 'myapp://stripe-redirect from the command line it opens the app and works as expected and the result of handleURLCallback is false as you would expect but when going through the payment process using the sheet, these listeners never get triggered therefore handleURLCallback is never actually run.

I am hoping if there is something obvious I have missed, is there any more I can do to debug this issue to figure out what might be going wrong? Is there a way I can forcefully close the webview from the code? The payment completes fine in the background, I just need the webview to close.

This is a shortened version of the implementation:

Provider

<StripeProvider
      publishableKey={Constants.expoConfig?.extra?.stripeApiKey}
      urlScheme={Linking.createURL('')}
      threeDSecureParams={{
        timeout: 5
      }}
    >
      {children}
</StripeProvider>

Deeplink Listener

import { addEventListener, getInitialURL } from 'expo-linking';

const onChange = useCallback(
    async (event: { url: string }) => {
      await handleURLCallback(event.url);
    },
    [handleURLCallback],
  );

  useEffect(() => {
    getInitialURL().then(async (url) => {
      if (url) {
        await handleURLCallback(url);
      }

      setLinkingUrl(url);
    });

    const subscription = addEventListener('url', onChange);

    return () => subscription.remove();
  }, [handleURLCallback, onChange]);

initPaymentSheet

 const { error } = await initPaymentSheet({
        merchantDisplayName,
        customerId,
        customerEphemeralKeySecret: ephemeralKey,
        returnURL: Linking.createURL('stripe-redirect'),
        appearance: {},
        intentConfiguration: {
          mode: {
            amount: amountInMinors,
            currencyCode: 'gbp',
          },
          confirmHandler,
        },
      });

Thanks in advance!

seanzhang-stripe commented 1 month ago

Hi @danwoodbury I'm not sure if your code is the correct way to handle deeplink. Can you use the example code from the integration guide instead?