#rudi - card_error_authentication_required

1 messages ยท Page 1 of 1 (latest)

cunning zodiac
#

Good question. Checking in to the ID now

#

It does sound like it will require 3DS here but I am unsure what you should do to react to that at the moment. Looking in to it..

cyan fern
#

@real jetty I think that means the card you've used needs to be authenticated but one of your parameters on your payment intents is configured as you can't do like so.

Check if off_session is false in your Payment Intent.

cunning zodiac
#

Thanks for the assist. That sounds right. I think here, it is more a case that you should try to attack the Payment Method to a customer before making a payment with it

real jetty
#

weird, I use that code for 3ds too

#

I have confirmation_method: 'manual',
confirm: true,

cunning zodiac
real jetty
#

setup_future_usage: 'off_session'

cunning zodiac
#

Can you tell me a bit more about the flow of your iOS app here? Do you always colect the card info and immediately try to pay?

real jetty
#

sometimes, in this case it is interactive, so if the response contains the requires_action:true parameter, the second part of the flow starts.

#

I am creating the customer and then attaching the intent with Stripe::PaymentIntent.create

#

then Stripe::PaymentMethod.attach(intent.payment_method, { customer: stripe_customer_id }, connect_opts)

#

if intent.status == 'requires_action' we pass the management of 3ds authorization to Stripe JS (otherwise the status will be 'succeeded').

#

it is the documented workflow and it usually works ...

weary iris
#

You can attach the payment method as part of the Payment Intent flow.

#

rather than handling it a separate process

real jetty
#

I don't understand, so it shoudld have never work my workflow ... If the card needs authentication, why the payment intent does not returns requires_action?

weary iris
#

The payment method did require authentication. From the payment method I saw it did return a requires_action status. However in your flow the Payment Method got stuck waiting for 3DS authentication.

real jetty
#

I'll try in test mode with a card that requires authentication

weary iris
#

Good idea ๐Ÿ‘

real jetty
#

I tried and it works.

weary iris
#

๐ŸŽ‰

real jetty
#

I mean it works with the test card, and I think it works in production too with other cards (it's been like that since 3DS started ... )

#

so the flow implemented is legit.

weary iris
#

What is the "it" here?

real jetty
#

the workflow. The web form that submits the card to stripe and returns to us the payment_method_id.

#

we create the intent, in this case I see that intent.status == 'requires_action' so we redirect to stripe (the stripe popup for fake 3d secure auth opens)

#

Using the real card on the same exact code the authentication_required error is raised

weary iris
#

Yes, that is the recommended flow

real jetty
#

it exactly raises a Stripe::CardError as soon as I try to attach the intent Stripe::PaymentIntent.create(opts, connect_opts) # attach for later reuse
if intent.payment_method
pm = Stripe::PaymentMethod.attach(intent.payment_method, { customer: stripe_customer_id }, connect_opts)

#

With the test card "4000 0027 6000 3184" it does not happen.

weary iris
#

This card does not result in a 3DS authentication flow?

real jetty
#

which one? the real one? No, it raises the Stripe::CardError

weary iris
#

The test card

tulip trout
#

Hello! Taking over and catching up now...

real jetty
#

the test one result in a 3DS authentication flow

#

Hello

tulip trout
#

So you've got an integration where the test card ending in 3184 prompts for 3D Secure as expected and everything works correctly, but it does not work in live mode with a real card?

real jetty
#

exactly.

#

it raises a Stripe error with message card_authentication_required, when we attach the intent to the pm:

#

Stripe::PaymentMethod.attach(intent.payment_method, { customer: stripe_customer_id },

#

The integration has been working for years ... I don't know how many 3ds transactions we had, but I guess this it's not the first one.

#

the cardholder says that her card worked before.

#

btw this transaction is just 10 eur

tulip trout
#

What's the Payment Intent ID for that specific transaction?

real jetty
#

I don't know but I have the req id: req_BN3AbbHoXVvdyB

tulip trout
#

That request created a Payment Intent and used that Payment Method, but the Payment Intent has a status of requires_action, which means an action is required to complete the payment. In this case the action required is authentication via 3D Secure, but you never did anything to complete that action, so the Payment Method is stuck in an authentication_required state and, thus, cannot be attached to a Customer, hence the error you're seeing.

#

Does that make sense? ๐Ÿ™‚

real jetty
#

I do not get why the same code with a test card behave one way, with this card behave another way. How can we test the integration if the behaviour on test card is different?

#

I mean the flow has always been like that. If the same flows works for some card and not for other cards I am confused. Is there a 100% correct flow?

tulip trout
#

I'm not sure I 100% understand your question. You have an outstanding Payment Intent that has not yet succeeded, but you're trying to attach the Payment Method to the Customer anyway. That's not recommended and can lead to issues like this one.

#

Why are you not waiting for the Payment Intent with setup_future_usage to succeed before attaching the Payment Method to the Customer?

real jetty
#

I don't understand, the payment intent does not know about the card until I attach the pm.

tulip trout
#

Look at the times those requests were made.

#

The request to create the Payment Intent was made two seconds before the failed attach request.

real jetty
#

Yes, that's the flow I have been using for years.

#

Which is the correct flow? It is unclear and the fact that my supposedly wrong workflow works most of the time does not help ๐Ÿ™‚

#

(I cannot see the requests because I have not access to the dashboard of that account, it is a connected account, but if you look to the master account you'll see that we have been doing hundreds of transactions ... )

tulip trout
real jetty
#

If i recall well (i wrote the integration in 2019!) the separate attach step is to save the card on our system

#

pm = Stripe::PaymentMethod.attach(intent.payment_method, { customer: stripe_customer_id }, connect_opts)

#

pm.id is the stripe card id, pm.card.last4 and so on are card details.

#

And if the intent does not requires action, we are done (payment done and card saved and reusable)

tulip trout
#

the separate attach step is to save the card on our system

Not sure what you mean here? Can you provide more details?

real jetty
#

intent = Stripe::PaymentIntent.create(...)

#

x = Stripe::PaymentMethod.attach(intent.payment_method, { customer: stripe_customer_id }, connect_opts)

#

x.id is the id of the card on Stripe, x.card.* are card attributes (funding, last4, expiration date, ... )

tulip trout
#

Right, but that doesn't answer my question. Let me ask it another way: you're currently creating Payment Intents with setup_future_usage set, and you're specifying both a Customer and a Payment Method. Doing that alone will attach the Payment Method to the Customer when the Payment Intent succeeds. Then, in addition to that, you are also directly attaching the Payment Method to the Customer for some reason, which seems like an extra step that should not be happening. Can you explain why you're performing this extra step?

real jetty
#

because I guess it's the only way I found at that time to have the card identifier and the card other attributes

cunning zodiac
#

It should be attached and have the same info when you attach it via confirming the PaymentIntent since you hace setup_future_usage.

real jetty
#

the confirm step is not alway done. When 3dsecure is not asked there is no confirm step.

cunning zodiac
#

Also is the user currently on the app when you are making the call to create your payment intent?

real jetty
#

yes I check the requires_Action status AFTER the attach, and it usually works. With the test cards it always works.

cunning zodiac
#

When you do this in test mode, the flow requires_action goes through properly? It should be the same behavior in test mode

real jetty
#

yes it works (see the screenshot above). But it works in porduction too, usually. It's the first time that I've been told of this problem.

#

I will try without that attach step. Using the 4242 cards (no 3dsecure) I see that the data is already present into the payment intent.

cunning zodiac
#

Thanks for the clarification. I think that this might be because the 3184 card doesnt' require an aithorization when being attached to the customer. Real cards usually don't require it but sometimes do. Either way, confirming the payment with those params should be able to attach the card as you want

#

Sounds good.

real jetty
#

"payment_method":"pm_1KjpnvL2DI6wht39sQAxX1IS","payment_method_details":{"card":{"brand":"visa", ...

#

So what is the purpose of the attach api?

cunning zodiac
#

That would be if you are just creating the payment method without a payment and want to attach to the customer.