#seth_react-native-paymentsheet-applepay
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/1344701533849256048
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Hello there
Hmm yeah so using ConfirmationMethod manual is the legacy server-side confirmation flow.
The current server-side flow is documented at https://docs.stripe.com/payments/mobile/finalize-payments-on-the-server?platform=react-native&type=payment
I think to accompish what you are looking for you would use the "Setup a PaymentMethod" flow: https://docs.stripe.com/payments/mobile/finalize-payments-on-the-server?platform=react-native&type=setup
In which case you would collect the PaymentMethod and be able to control confirmation with the sheet closed.
Where is there documentation stating that ConfirmatonMethod being set to manual is legacy? I have had this conversation before too, and this property is offered in the most updated version of paymnet intent creation on my server code.
Everything else you are suggesting is exactly what I am currently doing, and the flow works with every payment method except for when I use apple pay.
Yeah ConfirmationMethod is still supported but you'll notice that none of our documentation suggests using it anymore. The intention is to be able to create the PaymentMethod on the client and then you control confirming from your server, instead of the intent-first approach which involved setting ConfirmationMethod "manual" before we supported the ability to create the PaymentMethod from the client.
Hmm that said yeah okay after looking a moment more I do see what you mean...
The custom flow should still close the sheet
Regardless of the ManualConfirmation part...
Can you show me your full client-side code snippet just so I'm on the same page?
Yes one moment
const fetchPaymentSheetParams = async (user: IPrivateUser) => {
return await makeRequestWithAuth('POST', ${path}/..., user.token, false)
.then((response: any) => {
return {
id: response.associated_objects[0].id,
secret: response.secret
};
})
.catch((error: Error) => {
if (error.message.includes('401') || error.message.includes('403')) {
dispatch(logoutUser(error));
}
throw new Error(error.message);
});
};
const confirmHandler = async (paymentMethod: any, shouldSavePaymentMethod: any, intentCreationCallback: any) => {
if (user && selectedRide && currentSegment) {
await bookRide(user, selectedRide, currentSegment, paymentMethod.id)
.then((response) => {
//NOTE: calling intentCreationCallback causes failure because intent that is returned is set to manual
//intentCreationCallback({clientSecret: response.clientSecret});
setLoading(false);
setShowBookingSuccessDialog(true);
})
.catch(error => {
setLoading(false);
// intentCreationCallback({error: {
// code: 500,
// message: error,
// localizedMessage: error.message
// }});
})
};
};
const openPaymentSheet = async () => {
if (user && currentSegment) {
setLoadingPaymentsheet(true);
await fetchPaymentSheetParams(user)
.then((response: any) => {
return initPaymentSheet({
merchantDisplayName: "...",
customerId: response.id,
customerEphemeralKeySecret: response.secret,
intentConfiguration: {
//@ts-ignore
mode: {
amount: currentSegment.total,
currencyCode: 'USD',
},
confirmHandler: confirmHandler,
},
returnURL: '...',
// NOTE: Apple Pay currently disabled
// applePay: {
// merchantCountryCode: 'US',
// },
customFlow: true,
});
})
.then(() => {
setLoadingPaymentsheet(false);
return presentPaymentSheet();
})
.then((response) => {
setPaymentInformation(response.paymentOption);
})
.catch((error) => {
setLoadingPaymentsheet(false);
// log error
});
};
};
I can post the full React component into a file if you prefer. Let me know.
In case you need this instead.
Thanks. I actually found the internal ticket where this was reported. Looks like it has not been resolved yet but is believed to be a bug. I think the next step is that I'll bump that ticket to try and get it moved along faster. The other thing that would help here is if you submit an issue to the Github repo: https://github.com/stripe/stripe-react-native
This would help encourage the team to priortiize the fix here and also potentially get any further information from you if that is necessary.
Okay, I can go ahead and post an issue on GitHub
Here is the post: https://github.com/stripe/stripe-react-native/issues/1841
Can you think of additional information I might need to add? I really want to ensure this gets resolved.
Hi ๐
I'm stepping in as my colleague needs to go soon
Hello, thanks
I'm reviewing your GH issue now
Cool, appreciate it. I'll reiterate that an internal ticket has been created, but your colleague suggested I create a GH issue to increase visibility.
Yes I am aware of that ticket.
And my colleague is correct, the detail (especially the code sample) in the GH issue is likely to help with reproduction of the issue and ultimately a resolution.
Great, thank you.
Can you explain to me a little more about how the SetupIntent works? It essentially is an extra step compared to manual payment? So for example:
- Client will reach out to serve to generate setup intent with payment method (credit card, apple pay, etc). What is weird in the documentation is it doesn't seem to require you to set an amount in the intentConfiguration. Doesn't the Apple Pay modal require an amount?
- SetupIntent will then exist (indefinitely? Does it expire?).
- When you are ready to generate an confirm the PaymentIntent, the server will handle ALL of this and the user does not have to do anything. The PaymentIntent is created and confirmed. Once this happens, does the SetupIntent expire?
Sure.
Setup Intents represent your intent to save a payment method for future use. They are used to create a Payment Method and (optionally) attach it to a Customer while optimizing it for off-session usage. Setup Intents do not expire but they cannot be re-used once they reach a terminal state.
Since the intent of a Setup Intent is to save the Payment Method without charging it, we do not have an amount to display.
This will attempt to confirm the Payment Intent immediately using the saved Payment Method
Okay, I think that adds a step that isn't necessary for our business. We just need a PaymentIntent, so hopefully this can get resolved. I appreciate your help
You can also save a Payment Method for later use during the first Payment Intent (If you need to save PMs at all). We have a guide for that approach here
Yup, we do that process already too. Just have the issue with a payment intent set to manual (and not coming back as confirmed to the client) is causing error.
Manual what? Manual confirmation? Manual Capture?
manual confirmation
Outline above with what your colleague and I discussed earlier
Okay yeah and that's because you are trying to finalize the PI on the server, right?
Yup. Not sure if we have a choice to do it any other way. Our users book reservations, but they have to be confirmed (later) by a different user offering the reservation before we charge the original user who booked.
Yeah, that makes sense. You wouldn't want to have the charge the customer and then refund them every time the reservation wasn't available
Correct
Well I appreciate the help. Hopefully we can get this working. We aren't fully blocked, credit cards work, it just seems to be Apple Pay that wigs out
Oh! One thing I did notice that you might want to update in the GH Issue. The version numbers for both the iOS and RN SDK.
I know you have "latest" but it really helps avoid confusion if we can have the exact number
Cool I can update that!
Awesome. It removes just a little bit of friction for our SDK maintainers and allows them to get to testing things faster.