#pain-help

1 messages · Page 1 of 1 (latest)

grim sundial
#

hi there! how can i help?

brittle ermine
#

Could I get an explanation on the authentication_required response, is that a response if 3D secure is required?

#

what does the response mean initially because I only see one way to handle it

grim sundial
brittle ermine
#

Oh I see so the authentication_required is more of the customer requiring to reach out to their bank or state it was them making the payment and are told to retry?

#

It's not related to the 3DS from what I'm reading

grim sundial
#

In most cases, yes. Because Stripe would typically automatically request for 3DS for transactions that require it.

For the 3DS that you're reading about, the status of the PaymentIntent would be requires_action - https://stripe.com/docs/payments/intents

brittle ermine
#

I see, let me try something really quickly

#

Sorry, seems like I can't find it; but what is the test card number that always requires 3D secure?

grim sundial
brittle ermine
#

I see, so how am I meant to handle this?

#

e.g I save the card, they provide 3D secure and then if they wish to charge the card (stripe handles this when adding the card and gives the prompt)

#

they will have to use provide the 3D secure again, no?

#

it returned payment_intent.status: 'requires_payment_method'

grim sundial
#

what's the PaymentIntent id?

brittle ermine
#

pi_3LCxkIITzJ0aXxz712smWZRG

grim sundial
#

i'm guessing you clicked on the fail authentication button?

brittle ermine
#

No, my flow goes as follows: Customer can add their card for future usage, once they add their card they can continue the payment with it (or select it) and pay with it

#

I simply added the card, 3D secure popped up and I did not fail it. It saved the card and then I tried to charge the card

#

When I charge the card I just pass the payment method id

#

In this case I would be just selecting it

#

They would go on to confirm the payment and when I attempt to charge the card it just returns the above.

grim sundial
#

ah okay, so the problem is that you're trying to charge a card that always requires authentication off_session. Since the customer is off_session, they will never be able to perform authentication so the card is declined with authentication_required

brittle ermine
#

I see, so what must I do?

grim sundial
#

are you really charging the customer off_session?

#

cause based on the screenshot, it looks like the flow is on_session

brittle ermine
#

The document said to set up it like that, my flow allows the user to add a card if they haven't already and use it straight away, or come back later and select the card to use?

#
const paymentIntent = await stripe.paymentIntents.create({
    amount: event.package.price * 100,
    currency: 'usd',
    customer: event.customerId,
    payment_method: event.paymentMethod,
    off_session: true,
    confirm: true,
    metadata: {
        txnId: transaction.id
    }
});

This is how I have it set up currently.

grim sundial
#

don't pass in off_session=true if it's not really an off session payment

brittle ermine
#

That's what* I thought initially, I will try it now.

#

Alright it's returning the status: 'requires_action' now

#

Could you point me in the right direction to handle this now please?

grim sundial
#

sorry not that one, how are you collecting payment methods currently?

#

are you using the Payment Element?

brittle ermine
#

I handle all of that before the charge

#

I am

grim sundial
#

yes, but i'd like to know how you're doing it

brittle ermine
#

Like the entire flow?

grim sundial
#

alright, that's the Payment Element

brittle ermine
#

Oh alright.

brittle ermine
# brittle ermine I am

Sorry this was meant to "I am using the payment element", should've probably clarified.

grim sundial
brittle ermine
#

so instead of doing confirmSetup I use confirmPayment?

grim sundial
#

it depends

brittle ermine
#

Wait I think I misunderstood, just a moment

#

Oh, yeah that wouldn't work for me I believe?

#

I can see that the returned data has a next_action in the object

next_action: {
    type: 'use_stripe_sdk',
    use_stripe_sdk: {
      type: 'three_d_secure_redirect',
      stripe_js: 'https://hooks.stripe.com/redirect/authenticate/src_1LCyAsITzJ0aXxz7Y2GroFw5?client_secret=src_client_secret_uT5cLzX4kB6SNxJpGxB99Ayi&source_redirect_slug=test_YWNjdF8xRnBSQnpJVHpKMGFYeHo3LF9MdW5tTG9UZ3FsYlhWNzJPcHUxc05uR29wNWhsekxV0100ZuQ3BFoo',
      source: 'src_1LCyAsITzJ0aXxz7Y2GroFw5'
    }
  },
grim sundial
#

if the user currently has no PaymentMethod, you can use confirmSetup to create and attach the card

#

hmmm

#

onesec, let me think about this for a bit

brittle ermine
#

So my flow depends on the user having to attach a card, they don't pay directly but attach a card and have it for future usage

#

So when they add a card and they continue to the next step, it will simply use the stripe.paymentIntents.create and pass confirm :true parameter (once payment submitted)

#

I guess it's possible to add an option to save card instead, instead of saving it always like I am currently? I would capture the payment intent and confirm it once they've confirmed the payment on the form; not really too sure.

grim sundial
#

i get why you need to do it this way based on your current flow, but you're going to have to make additional requests. Gimme a while to think of whether there's a workaround.

brittle ermine
#

Okay, I sort of demand 3D secure on every payment as well

#

so it's required for me

#

I'm trying to think if it would benefit to do it the way stated above, but I'd end back at the same spot again

#

If they saved a card and tried to use it, then 3DS is required I can send them to that link in stripe_js to authorize it but that's quite iffy already since then I'd need to listen to callbacks and such

plush compass
brittle ermine
#

Currently I'm just using stripe elements to save card information then proceed with a payment

#
const { error } = await stripe.confirmSetup({
    elements: stripeElements,
    redirect: "if_required",
    confirmParams: {
        return_url: `${host}/dashboard/profile`,
    }
});
#

Afterwards, I return the payment methods to the client, they choose their card accordingly and send it back to the server

#

Where I handle the payment

#
const paymentIntent = await stripe.paymentIntents.create({
    amount: event.package.price * 100,
    currency: 'usd',
    customer: event.customerId,
    payment_method: event.paymentMethod,
    // off_session: true,
    confirm: true,
    metadata: {
        txnId: transaction.id
    }
});
#

Should I be adding the setup_future_usage to this paymentintent?

plush compass
#

No you don't need. you have already collected the payment_method with SetupIntent.

brittle ermine
#

Right, so my current issue is that 3DS is handled on the client by Stripe when adding the card

#

but afterwards the user makes the payment and the payment fails with the status: 'requires_action'

brittle ermine
plush compass
#

OK. this is a normal use case that your application should handle. Your app should notify your customer to go back to your application to continue with the 3DS flow.

brittle ermine
#

If it was handled this way, wouldn't I need to listen to the webhook for further information?

#

Because currently the flow is asynchronous, that would mean I would have to handle the rest of the flow by listening to the webhook instead of waiting for a reply using the Stripe package/module

plush compass
brittle ermine
#

but this would mean that I am required to await the customer to finalize the 3D secure if it's off_session (the customer not being there when I charge the card automatically) and listen to the webhook for the request when the paymentIntent has been finalized?

plush compass
#

Do you confirm paymentIntent from the client or server?

brittle ermine
#

I do that on the server

#

I just pass the confirm parameter as true when I create the intent

plush compass
#

OK, is there a reason why you don't do it from client-side? Based on the screenshot that you shared, you customer is still on your webpage when the payment happens.

brittle ermine
#

I don't see the benefits of handling it on the client, because I will be charging the card later if they automatically topup their balance (on the site) and would still run into the same problem, no?

plush compass
#

Actually the sample code also confirm the paymentIntent on client side.

#

// Pass the failed PaymentIntent to your client from your server
stripe.confirmCardPayment(intent.client_secret, {
payment_method: intent.last_payment_error.payment_method.id
}).then(function(result) {
if (result.error) {
// Show error to your customer
console.log(result.error.message);
} else {
if (result.paymentIntent.status === 'succeeded') {
// The payment is complete!
}
}
});

brittle ermine
#

My website has a balance (credit), they're able to top that up by adding a card and then charging that card upon payment confirmation. But I'd also like to automatically charge the card in order to topup their balance if it falls below 0.

brittle ermine
#

I can see that the result passes back this parameter client_secret: 'pi_3LCyK1ITzJ0aXxz71YP52uY5_secret_1y8fTQfmCOftzqN4cySvTXzzM',

plush compass
brittle ermine
#

Well my current flow is > They add a card > they can use that card to charge it

#

I should probably swap it to > Payment Element (bool to save card) > then charge

#

Seems like the automatic_payment_methods is a better approach too

plush compass
brittle ermine
#

^ During checkout

plush compass
#

Yes you are right. In this flow you just need to use PaymentIntent and there's no need to call SetupIntent in your integration.

brittle ermine
#

Okay so that solves one aspect of the question, if I want to charge the card whilst they are not on the site (off_session)

brittle ermine
plush compass
#

Yes and don't forget to set off_session to true

brittle ermine
#

When I did that, it just declined the payment if it was 3DS

plush compass
#

However, keep in mind that issuer might still think the transaction requires 3DS and thus the paymentIntent status may becomes requires_action.

brittle ermine
plush compass
#

In this case, you still need to handle the 3DS in client-side and call stripe.confirmPayment to start the 3DS flow.

#

Can you send me the PaymentIntent ID?

brittle ermine
#

I believe it was pi_3LCxkIITzJ0aXxz712smWZRG

#

(this occurred earlier not now)

plush compass
#

which test card did you use?

brittle ermine
#

4000 0027 6000 3184

plush compass
#

This card requires authentication on all transactions, regardless of how the card is set up. and that's why you are getting this response

#

In this case, you need to bring your customer to your website and call stripe.confirmPayment with the clientSecret of this paymentIntent

brittle ermine
#

I see,

#

Is there a way to request 3DS whilst the user is on site but don't request it otherwise?

#

I can see there is a rule is_off_session for radar

#

Okay I believe I have a firm understanding on what I should be doing now, I will integrate the save-during-payment flow to give the user a choice on whether the card should be saved or not and afterwards just charge the cards that are saved. If it requries 3DS I will ask the user to come back and complete it using the paymentIntent.client_secret?

plush compass
#

There's no way to turn off 3DS from Stripe's end. It's really up to the issuer to decide whether to trigger 3DS for a particular transaction.

brittle ermine
#

Sorry I clarified above but probably wasn't clear, I force a 3DS on every charge.

plush compass
#

OK, so you want to enforce 3DS if the card support it?

brittle ermine
#

Yeah, I have these rules set up already

plush compass
#

Great

brittle ermine
#

I just looked at the rules more and I will be able to avoid this by checking the is_off_session setting in the rules

#

So that way I wont be enforcing a 3DS on off_session charges

#

I really appreciate the patience and assistance you guys have been able to provide, thanks to that I understand what I should be doing now.

plush compass
#

No problem, we are always here to help!