#gabriel_api

1 messages ยท Page 1 of 1 (latest)

rare willowBOT
#

๐Ÿ‘‹ Welcome to your new thread!

โฑ๏ธ We automatically close idle threads, which makes them read-only. Make sure you stick around to chat in realtime!

๐Ÿ”— This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1212491501519642735

๐Ÿ“ Have more to share? You can add more detail below, including code, screenshots, videos, etc.

โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question. Thank you for your patience!

ancient kernelBOT
mint smelt
#

Hello

#

You are using your own button here with the Payment Request Button integration?

robust idol
#

Hi, thanks for the quick reply. I am not using Stripe's components, only the API calls, here is how is implemented:

` const handleWalletCheckout = (payload: HandleWalletCheckoutPayload) => {
const paymentRequest = stripe!.paymentRequest({
country: 'US',
currency: 'usd',
total: {
label: 'Total',
amount: Math.round(quote.pricing_breakdown.total * 100),
},
});

paymentRequest
  .canMakePayment()
  .then((result) => {
    if (result) {
      paymentRequest.show();
      paymentRequest.on('paymentmethod', (paymentMethodConfirmedEvent) =>
        onWalletPaymentMethodConfirmed(
          paymentMethodConfirmedEvent,
          payload,
        ),
      );
    }
  })
  .catch(() => {
    console.error('Error checking available payment methods');
    // add metrics
  });

};`

mint smelt
#

Yep so that is Payment Request Button and using your own Button like you stated.

#

But you aren't able to reproduce this reliably?

#

Do you have a screenshot or a video of it happening?

#

Anywhere we can visit to try and reproduce?

#

Lastly, are you firing any sort of alert or anything in this path?

robust idol
mint smelt
#

Okay so that has a specific warning there that you are changing the prop for your Elements Provider.

#

Which you can't do without re-rendering

mint smelt
#

Can you show me that code and what you are doing?

#

Mostly it looks like something from your code is interfering with the modal showing. Like an alert or a toast -- if you have some sort of overlay already running then the Google Pay modal won't function.

#

But I'd recommend starting with inspecting the Stripe Provider prop change warning

#

As that shouldn't be happening.

robust idol
# mint smelt Can you show me that code and what you are doing?

For sure:

Here is how my NextJS/React application uses the Elements Providers, so the Stripe promise is added to the react-stripe-js, so I can use the hooks from useStripe:

`import { Elements } from '@stripe/react-stripe-js';
import { loadStripe } from '@stripe/stripe-js';

const App = ({
Component,
pageProps,
}: AppProps<{ data?: { [key: string]: any } }>) => {
//Unrelated logic omitted

const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_KEY || '');

return <QueryClientProvider client={queryClient}>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<ThemeProvider theme={themes.kyte}>
<ThemeBootstrap theme="kyte">
<GoogleOAuthProvider
clientId={
process.env.NEXT_PUBLIC_GOOGLE_LOGIN_APP_ID || ''
}
>
<SegmentProvider>
<NotificationProvider>
<Elements stripe={stripePromise}>
{showNavigation && (
<Nav searchConfig={searchConfig} />
)}
<Content disableHeightConstrains={!showNavigation}>
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<Component
data={pageProps?.data}
{...pageProps}
/>
</Content>
<Footer />
<SessionsDialog />
<div id="kyte-portal" />
</Elements>
</NotificationProvider>
</SegmentProvider>
</GoogleOAuthProvider>
</ThemeBootstrap>
</ThemeProvider>
</PersistGate>
</Provider>
</QueryClientProvider>

});`

We have this normal React button:

<Button onPress={onCheckout} loading={isBookingLoading}> {content.checkout_confirmation.cta} </Button>

`

#

The onCheckout calls that logic that I posted before:

` const handleWalletCheckout = (payload: HandleWalletCheckoutPayload) => {
const paymentRequest = stripe!.paymentRequest({
country: 'US',
currency: 'usd',
total: {
label: 'Total',
amount: Math.round(quote.pricing_breakdown.total * 100),
},
});

paymentRequest
  .canMakePayment()
  .then((result) => {
    if (result) {
      paymentRequest.show();
      paymentRequest.on('paymentmethod', (paymentMethodConfirmedEvent) =>
        onWalletPaymentMethodConfirmed(
          paymentMethodConfirmedEvent,
          payload,
        ),
      );
    }
  })
  .catch(() => {
    console.error('Error checking available payment methods');
    // add metrics
  });

};`

#

The onWalletPaymentMethodConfirmed calls our BE to create a Setup Intent and return the client secret to confirm the Payment Method:

` const handlePaymentConfirmation = (
authenticatedBookingPayload: AuthenticatedBookingPayload,
walletEvent?: any,
) => {
const createSetupPayload: SetupIntentCreationPayload = {
card_token: authenticatedBookingPayload.stripeToken!,
quote_token: quote.token,
user_uuid: me?.uuid,
};
setIsPaymentSetupLoading(true);
confirmCardSetup(createSetupPayload)
.then(() => {
walletEvent?.complete('success');

    makeBooking(authenticatedBookingPayload);
  })
  .catch((error) => {
    walletEvent?.complete('fail');

    showError(error);
  })
  .finally(() => {
    setIsPaymentSetupLoading(false);
  });

};`

The confirmCardSetup is an abstraction of the logic that I mentioned above:

`const confirmCardSetup = (createSetupPayload: SetupIntentCreationPayload) => {
return new Promise<SetupIntentCreationResponse>((resolve, reject) => {
createSetupIntent(createSetupPayload, {
onSuccess: async (result: SetupIntentCreationResponse) => {
try {
const { error } = await stripe!.confirmCardSetup(
result.client_secret,
undefined,
{ handleActions: false },
);

        if (error) {
          reject(error);
        } else {
          resolve(result);
        }
      } catch (error) {
        reject(error);
      }
    },
    onError: (error) => {
      reject(error);
    },
  });
});

};`

robust idol
#

I just fixed the warning "Unsupported prop change on Elements: You cannot change the stripe prop after setting it", by moving the const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_KEY || ''); outside of the App component

mint smelt
#

Yeah I was wondering if your App component was re-rendering which was causing that

#

I assume that didn't fix things here though?

#

As I don't actually think that would be the root cause of not seeing the modal.

robust idol
mint smelt
#

Yep so if there is any overlay already present then the payment modal can't render.

#

There is a chance you are just hiding these overlays instead of actually removing them?

#

I'd check on that.

#

But it does seem to me like when you bring up that overlay for the insurance stuff then you aren't properly removing it before the payment modal attempts to show.

robust idol
#

It seems like it, I will investigate it better, thanks a lot for your help! ๐Ÿ™‚