#dannyhadders_code
1 messages ยท Page 1 of 1 (latest)
๐ 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/1367514230521331813
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
npx expo --version 0.22.26
"@stripe/stripe-react-native": "^0.45.0",
Gotcha and can you share your full relevant code snippet here?
const initializePaymentSheet = async () => {
const paymentRequest: CreatePaymentRequest = {
amount: Math.floor(selectedQuote?.quotePrice?.totalPrice! * 100),
journeyReferenceNumber: journeyReference,
};
const createPaymentResponse = await mutateAsync(paymentRequest);
const paymentResponse = createPaymentResponse as PaymentResponse;
const driver = data!.drivers!.find((driver) => driver);
const address: Address = {
postalCode: driver?.address?.postcode!,
country: "GB",
};
const billingDetails: BillingDetails = {
name: driver!.firstName! + " " + driver!.lastName!,
email: data?.email!,
phone: data?.mobileNumber!,
address: address,
};
const returnUrl = Linking.createURL("/dashboard/policy-summary");
const { error } = await initPaymentSheet({
paymentIntentClientSecret: paymentResponse.secret!,
customFlow: true,
merchantDisplayName: "Covertime.",
style: "automatic",
returnURL: returnUrl,
defaultBillingDetails: billingDetails,
});
if (!error) {
setPaymentSheetReady(true);
} else {
console.error("Payment sheet init error:", error);
}
};
const openPaymentSheet = async () => {
if (!paymentSheetReady) {
return;
}
const presentOptions: PresentOptions = {
// TODO set the timeout to be x seconds until the hour
timeout: 30000,
};
const { error, paymentOption } = await presentPaymentSheet(presentOptions); // Let user pick a payment method
if (error) {
switch (error.code) {
case "Canceled":
console.log("Payment sheet was canceled by the user.");
break;
case "Failed":
console.log("Payment sheet failed:", error.message);
break;
case "Timeout":
console.log("Payment sheet timed out:", error.message);
break;
default:
console.log(`Payment method selection failed: ${error.code}`, error.message);
}
} else {
console.log("Payment method selected:", paymentOption);
setHasSelectedPaymentOption(true);
setSelectedPaymentOption(paymentOption?.label!);
router.push("/dashboard/policy-summary");
}
};
Error throws at presentPaymentSheet - with FlowController must be successfully initialized using configureWithPaymentIntent(), configureWithSetupIntent() or configureWithIntentConfiguration() before calling presentPaymentOptions()
no idea where FlowController etc is coming from though
Flow Controller is a reference to the underlying Android SDK
Which is where the error is coming from
That said... nothing jumping out immediately for why it doesn't like this.
Have you logged out the client secret to ensure that is set?
I have tried copying the example from the docs itself - same error
You tried using the intentConfiguration instead of passing the client secret?
Like:
const { error, paymentOption } = await initPaymentSheet({
merchantDisplayName: "Example, Inc.",
customFlow: true,
intentConfiguration: {
mode: {
amount: 1099,
currencyCode: 'USD',
},
confirmHandler: handleConfirmation
}
});
also tried a few versions of the "@stripe/stripe-react-native" package as I saw online other people had an issue
Yes I have actually - had difficulties working out what "handleConfirmation" should be - not explained in the documenation
Also I saw somewhere that you dont need to do intentConfiguration if you supply initPaymentSheet with a paymentIntent from our API
Yeah that should be the case.
I'm looking more, give me a min
What happens if you only pass in:
paymentIntentClientSecret: paymentIntent,
customFlow: true,
merchantDisplayName: 'Example Inc.',
Ah wait
It might be that an Ephemeral Key is required when using a Custom Flow
I'd try doing:
const { error, paymentOption } = await initPaymentSheet({
customerId: customer,
customerEphemeralKeySecret: ephemeralKey,
paymentIntentClientSecret: paymentIntent,
customFlow: true,
merchantDisplayName: 'Example Inc.',
});
Where you pass a Customer and Ephemeral Key
Let me add it and give it a test ๐
no luck unfortunately- tried various values for both customerEphemeralKeySecret and customerId but same error
Can you log out the values and provide them to me along with your updated code?
also - I see this warning if that helps at all :
No task registered for key StripeKeepJsAwakeTask
const { error } = await initPaymentSheet({
customerId: "123",
customerEphemeralKeySecret: customerAccountId!,
paymentIntentClientSecret: paymentResponse.secret!, // Example value of this would be 1bb4d454-7049-4e50-ade0-73774c557d71
customFlow: true,
merchantDisplayName: "Covertime.",
style: "automatic",
returnURL: returnUrl,
defaultBillingDetails: billingDetails,
});
Logger outputs:
(NOBRIDGE) LOG Payment sheet failed: FlowController must be successfully initialized using configureWithPaymentIntent(), configureWithSetupIntent() or configureWithIntentConfiguration() before calling presentPaymentOptions().
(NOBRIDGE) WARN No task registered for key StripeKeepJsAwakeTask
Okay well first you need to use real values in test mode here. Second, your PaymentIntent Client Secret should be in the format pi_xxx_secret_xxxxxx.
So that could be the original issue here
Can you create an actual paymentintent in test mode and log out the client secret on your client.
Sorry - that comment was meant for the customerEphemeralKeySecret
paymentResponse.secret - pi_3RJzA0P3GP3QiIPp1ODXg4sJ_secret_20mx2pNgAQ2t3t0NX5ICYUYv3
Okay and can you do the same for Customer and Ephemeral Key Secret.
Those should be from actual test mode objects, not just place holders.