#tonyp-rn-dupe-pi
1 messages · Page 1 of 1 (latest)
Hey there! Can you elaborate on the '2 payment intents are proceeded' part? What does 'proceeded' mean?
Are you creating multiple Payment Intents? A single PI cannot be confirmed (charged) multiple times
A single payment intent is created when the user clicks on the "pay" button in the checkout flow, thus the ux problem as the user is clicking a second time when my confirmPayment endpoint returns an error because the first retrieved payment intent status is not succeeded
So there's not actually a 2nd Payment Intent/payment?
Can you share a specific Payment Intent ID where this has been problematic?
There is, here is an example with two successive PI for the same customer :
pi_3KppIfHMOWEObXZm15pTeNOs
pi_3KppNnHMOWEObXZm1xgM1iyp
my confirmPurchase endpoint is sending back an error for the first PI as its status is not succeeded when retrieved
so the user restart the checkout process and a 2nd PI is created
this is not happening for every customer, but from time to time
this is not a situation I'm able to reproduce with the test cards
Taking a look
thanks
Hmm, those PIs are created 5 minutes apart
Can you share the code from your completePurchase endpoint
`
const userId = ctx.user.id
const paymentIntent = await stripe.getPaymentIntent(paymentIntentId)
const { metadata, status } = paymentIntent
if (metadata.userId !== userId || metadata.offerPaymentIntentId !== offerPaymentIntentId) return new Error('payment-intent-does-not-match')
if (status !== 'succeeded') return new Error('payment-failed')
`
oups sorry for the formatting
there is business logic following this
What is the purpose of that endpoint? Can you share the code where you call it
Generally you should rely on events/webhooks for any post-payment fulfilment/actions
My assumption here is that it's some kind of race condition, where your logic is running before the PI status is updated to reflect the payment success
here you go : https://codeshare.io/eVYgP9
yes it's what I think is happening too
so I was wondering what is the expected ux ?
Generally you should rely on events/webhooks for any post-payment fulfilment/actions, rather than calling an API inside of the confirmPayment Promise chain
so the client should poll my api waiting for PI status update before showing a success or an error page ?
No, you'd just transition the UI in the confirmPayment Promise chain: https://stripe.com/docs/payments/accept-a-payment?platform=react-native&ui=custom#react-native-submit-payment
It's highlighted there, in the if/else block
Your post-payment/fulfilment actions you should handle via webhooks
There's no guarantee your customers even hang around on your site following payment, which is why handling fulfilment async is our recommendation
I understand, but it means that I cannot display to the user her/his purchase ? as I'm not sure of the PI status. As an example, isn't Deliveroo waiting for payment success before displaying the screen showing order progress to the user ?
Sure, you can do that. But I'm not sure why you need to call an API to lookup the status of the PI
confirmPayment resolves to the Payment Intent object on success:
const {paymentIntent, error} = await confirmPayment(clientSecret, {
type: 'Card',
billingDetails,
});
if (error) {
console.log('Payment confirmation error', error);
} else if (paymentIntent) {
// Show your success UI here
}
this is what I'm not getting, the else if (paymentIntent) condition ensures that the PI will have a succeeded status if not already ?
Well, it depends. What payment methods are you offering? If only cards, then at that point status: 'succeeded' is guaranteed. Only with some async payment methods would status be something like processing
But you can check that right here in the client. Just look at paymentIntent.status
yes only cards
so somehow at few occurencies, when my api endpoint is called the retrieved PI status isn't already updated
I'll update my api to handle PI webhook events then
You shouldn't need to call your API endpoint at that point in the confirmPayment Promise chain