#jpeck_api

1 messages ยท Page 1 of 1 (latest)

slate wadiBOT
#

๐Ÿ‘‹ 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/1433562478637219901

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

rotund ember
#

Hi there! Do you have an example PaymentIntent that I can look at?

slow fulcrum
#

Sure! Do you just need the id?

rotund ember
#

Yes, please

slow fulcrum
#

pi_3SO39fCG1MymwEQN1lzQuOL4

rotund ember
#

yeah, those events are identical except the contents of next_action: which mostly differ because of unique strings

#

ok so my question is, when you create the on-session paymentintent, why do you pass confirm: true?

slow fulcrum
#

I believe it's to get the 3DS required response and client secret.

rotund ember
#

are you using the Payment Element?

#

the PaymentIntent's client_secret property isn't contingent on confirm: true

slow fulcrum
#

We're not using Payment Elements in this case.

#

Okay, maybe we just need to see if we can skip confirm in this particular case on the first go-round. I'll have to dig some.

rotund ember
#

But further, I think you should be able to nix the second PaymentIntent altogether

#

So you try to charge the card and authentication is required - you should be able to just keep that PaymentIntent and pass its client secret to the PaymentElement and call stripe.confirmPayment and stripe.js will handle the authentication flow

slow fulcrum
#

Yeah - right now we cancel that first payment intent with the failed charge, but I'm not totally clear why. I'll ask my team and see if we can change that flow without breaking other stuff :). I've got to head out for the day but thank you so much for the responses!

rotund ember
#

No problem!

royal lance
#

@rotund ember From the documentation:

Confirm that your customer intends to pay with current or provided payment method. Upon confirmation, the PaymentIntent will attempt to initiate a payment.

If the selected payment method requires additional authentication steps, the PaymentIntent will transition to the requires_action status and suggest additional actions via next_action

If my understanding is correct, that means it won't transition to requires_action (and therefore the use_stripe_sdk state) unless we pass confirm: true or otherwise confirm serverside

#

Is the alternative to create the PaymentIntent with confirm: false and then let the SDK do the rest of the work?

#

If it's the latter, we've avoided that approach as we perform some persistence and business logic server-side and do not want to pull that into client JS

rotund ember
#

Our recommended approach would be this:

I think you're doing something like this - stripe.paymentIntents.create({options: {
amount: 1099,
currency: "usd",
off_session: true,
confirm: true,
customer: 'cus_123',
payment_method: 'pm_123'
})

If 3DS is required, you'll get a 402 decline, but that decline will also contain a PaymentIntent with a client secret. If you know that you have to bring your customer on-session to authenticate, you can pass that client secret to the frontend and use it to authenticate with the Payment Element & Stripe.js

#

My comments about not passing confirm true were in the context of a situation where you have just tried to charge a particular card and been declined for 3DS. Now your confidence that 3DS is going to be required on another attempt is very high, so you just create the PaymentIntent (confirm: false isn't neccessary to pass because it is the default) and then pass the client secret to the frontend and call stripe.confirmPayment with it.

royal lance
#

Yeah, that's what we do for the off-session case

#

For on-session payments, we use:

  off_session: true,
  confirm: true,

to poke it again in case it allows frictionless payment

rotund ember
#

off_session: true tells Stripe to tell the issuer that the cardholder isn't present in the flow and not present to authenticate, so we return a 402 /decline instead of a 200 if 3DS is required but Stripe thinks the cardholder might be present

#

But overall, I think the best thing to do here would be to make your integration more efficient by just reusing the first PaymentIntent.

#

the message I'm trying to get across is that if you hit a 3DS required decline, you can still confirm that PaymentIntent client-side

#

If its helpful I can give you exact instructions on how to test this and the right test card

slate wadiBOT
royal lance
#

I think we've been using the right test card and flow, but would be curious to see what you have in mind

For arguments sake, let's say that the user is on-session for the first ever attempt. It means that we don't already have a PaymentIntent to re-use. Wouldn't we have to use confirm: true in that case and still end up with a double confirmation?

coral pollen
#

Hi there,
I took over for my colleague who had to step away. If the customer is on_session you can confirm:true directly

#

are you using Payment Element? Or how do you collect the payment method/card information?

royal lance
#

@coral pollen The original issue we're trying to solve is differentiating between the payment_intent.requires_action webhook fired by the initial, server-side PaymentIntent creation that results when 3DS is required and the second payment_intent.requires_action webhook event that fires when we call confirmPayment from the Stripe JS SDK when the Customer resolves 3DS

#

We have to call confirmPayment in the front-end to invoke the 3DS modal, right?

coral pollen
royal lance
#

Ah ha, got it, so there's no way around the two payment_intent.requires_action events, right?

If not, is there any way to grab information about the payment_attempt attached to each event?

The two events are identical except for the the payment_attempt id attached

coral pollen
#

You mean the payment attempt ID in the next_action object? We currenlty don't have a public API for Payment Attempts

slate wadiBOT
royal lance
#

@coral pollen @sonic thicket Yeah, that seemed like the only usable difference

Total shot in the dark, but is there any way to pass data through one of the confirmation points and not the other? Or a way to differentiate between a payment_attempt created from the Ruby SDK and the JS SDK?

sonic thicket
#

Apologies for the wait! Am catching up on this

#

am i getting it right?

royal lance
#

@sonic thicket Kind of ๐Ÿ˜…

More, how to tell that evt_3SO39fCG1MymwEQN1JRhswtB was resulted from #1 and that evt_3SO39fCG1MymwEQN1sRoh00M resulted from #2

sonic thicket
#

Apologies, missed your message!