#matthys_unexpected

1 messages Β· Page 1 of 1 (latest)

celest roostBOT
#

πŸ‘‹ Welcome to your new thread!

⏲️ 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.

⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

πŸ”— 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/1300787488507433012

πŸ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

mortal canyon
#

The code I am using is

  const initializePayment = async () => {
    try {
      setIsLoading(true);

      const paymentData = await createPaymentIntent(parsedService.id);
      console.log("πŸš€ ~ initializePayment ~ parsedService.id:", parsedService.id)

      if (!paymentData || !paymentData.clientSecret) {
        throw new Error('Payment intent creation failed or missing client secret.');
      }

      const initResult = await initPaymentSheet({
        paymentIntentClientSecret: paymentData.clientSecret,
        merchantDisplayName: coachName || 'Votre Coach',
        returnURL: 'ekklo://stripe-redirect',
        style: 'automatic',
        merchantCountryCode: 'FR',
        googlePay: false,
        applePay: false,
        appearance: {
          colors: {
            primary: '#84cc16',
            background: '#ffffff',
            componentBackground: '#f3f4f6',
            componentBorder: '#e5e7eb',
            componentDivider: '#e5e7eb',
            primaryText: '#1f2937',
            secondaryText: '#6b7280',
            componentText: '#1f2937',
            placeholderText: '#9ca3af',
          },
        },
        defaultBillingDetails: {
          name: coachName,
        },
        allowsDelayedPaymentMethods: true,
        billingDetailsCollectionConfiguration: {
          name: 'required',
          phone: 'required',
          email: 'required',
          address: 'full',
        },
      });

      if (initResult.error) {
        throw new Error(initResult.error.message);
      }

      const presentResult = await presentPaymentSheet();
      if (presentResult.error) {
        throw new Error(presentResult.error.message);
      }

      Alert.alert('Success', 'Payment was successful!');
      router.back();
    } catch (error) {
     //some error log
    } finally {
      setIsLoading(false);
    }
  };
opaque pewter
#

Hi, let me help you with this.

#

Could you please share the PaymentIntent ID pi_xxx?

mortal canyon
#

Hi !
sure

#

pi_3QFDh02cOk0fiuD21a8a6Xsz

opaque pewter
#

Are you sure this error happens when you call initPaymentSheet()? Maybe it's because you call presentPaymentSheet() immediately after it?

#

Generally you should aim to initialize Payment Sheet as soon as the page loads, and then present it when the customer clicks on some button, e.g. "Pay"/"Confirm"

mortal canyon
#

Ok thank you ! I will try and give you an update

celest roostBOT
mortal canyon
#
LOG  Starting payment intent creation process...
LOG  Received payment intent response: {"account_id": "acct_XXXXX", "amount": 100, "client_secret": "pi_3QFE2h2cOk0fiuD2XXXXXX", "currency": "eur", "is_recurring": false, "payment_intent_id": "pi_3QFE2h2cOk0fiuD2XXXXX", "public_key": "pk_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"}
LOG  Waiting for a brief delay to ensure payment intent is accessible...
LOG  Payment Intent ID: pi_3QFE2h2cOk0fiuD2XXXXX
LOG  Client Secret: pi_3QFE2h2cOk0fiuD2XXXXXX
LOG  Public Key: pk_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
LOG  Received payment intent response: {"amount": 100, "clientSecret": "pi_3QFE2h2cOk0fiuD2XXXXXX", "currency": "eur", "interval": undefined, "isRecurring": false, "paymentIntentId": "pi_3QFE2h2cOk0fiuD2XXXXX", "publicKey": "pk_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "subscriptionId": undefined}
LOG  Payment sheet initialized successfully.
LOG  Presenting payment sheet...
ERROR  Payment Error: [Error: Resource payment_intent inexistant: 'pi_3QFE2h2cOk0fiuD2XXXXX']

Ok so it it during the presentPaymentSheet

as you can see it appear and disappear

tight grove
#

Can you move presentPaymentSheet call outside of your initializePayment function?

#

Also, how do you invoke initializePayment?

#

You should call initPaymentSheet sheet on page load, like in an effect, and then presentPaymentSheet should be called on a button click

#

Right now it seems like it happens all on your button handler?

mortal canyon
#

I just tried and I still have the same problem 😦

LOG  Starting payment intent creation process...
LOG  Received payment intent response: {
  "account_id": "acct_XXXXX", 
  "amount": 100, 
  "client_secret": "pi_XXXXX_secret_XXXXX", 
  "currency": "eur", 
  "is_recurring": false, 
  "payment_intent_id": "pi_XXXXX", 
  "public_key": "pk_test_XXXXX"
}
LOG  Waiting for a brief delay to ensure payment intent is accessible...
LOG  Payment Intent ID: pi_XXXXX
LOG  Client Secret: pi_XXXXX_secret_XXXXX
LOG  Public Key: pk_test_XXXXX
LOG  Received payment intent response: {
  "amount": 100, 
  "clientSecret": "pi_XXXXX_secret_XXXXX", 
  "currency": "eur", 
  "interval": undefined, 
  "isRecurring": false, 
  "paymentIntentId": "pi_XXXXX", 
  "publicKey": "pk_test_XXXXX", 
  "subscriptionId": undefined
}
LOG  Payment sheet initialized successfully.
LOG  Presenting payment sheet...
ERROR  Payment Error: [Error: Ressource payment_intent inexistante : 'pi_XXXXX']

this are my logs

the error is stille the same

tight grove
#

Please share the code you're using now

mortal canyon
tight grove
#

Can you share the code you use to initialise <StripeProvider />

#

Looks like you're doing direct charges so you need to make sure you initialise the provider with the correct params

#

The error you're seeing is because it cannot find the intent (likely as it's on a different account)

mortal canyon
#
import { useEffect, useRef, useState } from "react";
import { DefaultTheme, PaperProvider } from "react-native-paper";
import { StripeProvider } from "@stripe/stripe-react-native";
import { useFonts } from "expo-font";
import * as Notifications from 'expo-notifications';
import { router, SplashScreen, Stack } from "expo-router";
import { StatusBar } from "expo-status-bar";

import { SessionProvider } from "../src/context/ctx";
import { DateProvider } from "../src/context/DateContext";



Notifications.setNotificationHandler({
    handleNotification: async () => ({
        shouldShowAlert: true,
        shouldPlaySound: false,
        shouldSetBadge: false,
    }),
});

const theme = {
    ...DefaultTheme,
    colors: {
        ...DefaultTheme.colors,
        primary: '#CAFF58',
        onPrimary: '#333',
        surfaceDisabled: '#333',
        onSurfaceDisabled: '#616161',
    },
};

const RootLayout = () => {
    const notificationListener = useRef<Notifications.Subscription>();
    const responseListener = useRef<Notifications.Subscription>();

  

    return (
        <StripeProvider publishableKey="pk_test_XXX" urlScheme="ekklo">
            <SessionProvider>
                <DateProvider>
                    <PaperProvider theme={theme}>
                        <StatusBar style="light" />
                        <Stack screenOptions={{ headerShown: false }}>
                            <Stack.Screen name="index" options={{ headerShown: false }} />
                        </Stack>
                    </PaperProvider>
                </DateProvider>
            </SessionProvider>
        </StripeProvider>
    );
}

export default RootLayout;

tight grove
#

Yeah you're missing the stripeAccountId param which needs to be the acct_xxx ID for the account you're creating the intent on

#

(acct_1QEu752cOk0fiuD2)

mortal canyon
#

ok thank you for your helpπŸ™
I don't know how I missed this