#tonyp-rn-dupe-pi

1 messages · Page 1 of 1 (latest)

quasi fog
#

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

kind wadi
#

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

quasi fog
#

So there's not actually a 2nd Payment Intent/payment?

#

Can you share a specific Payment Intent ID where this has been problematic?

kind wadi
#

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

quasi fog
#

Taking a look

kind wadi
#

thanks

quasi fog
#

Hmm, those PIs are created 5 minutes apart

#

Can you share the code from your completePurchase endpoint

kind wadi
#

`
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

quasi fog
#

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

kind wadi
#

yes it's what I think is happening too

#

so I was wondering what is the expected ux ?

quasi fog
kind wadi
#

so the client should poll my api waiting for PI status update before showing a success or an error page ?

quasi fog
#

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

kind wadi
quasi fog
#

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
    }
kind wadi
#

this is what I'm not getting, the else if (paymentIntent) condition ensures that the PI will have a succeeded status if not already ?

quasi fog
#

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

kind wadi
#

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

quasi fog
#

You shouldn't need to call your API endpoint at that point in the confirmPayment Promise chain

kind wadi
#

yes once I've updated my api to handle PI webhooks events

#

alright thanks for your time !