#ionu_api

1 messages ยท Page 1 of 1 (latest)

halcyon wagonBOT
#

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

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

hollow raptor
#

The 3184 card requires authentication on all transactions as mentioned here

mighty dock
#

yes, the popup for sca comes in, I hit complete, than with the pm, I try to do the payment intent. So it is confirmed

#

4000003800000446 for example needs confirmation at first payment. And it works

hollow raptor
#

Oh I see, so you expect the PaymentIntent goes to requires_action, but it's declined straighaway instead?

mighty dock
#

well my process is like this : I create from js a confirmSetup, than the popup for sca comes in, I hit complete, and it goes to a backend request, with the pm_ and I do \Stripe\PaymentIntent::create() with payment_method added.
for the other 2 cards, having off_session = true just does the transaction, and all is ok. For the 3184 card it throws that authentication_required not even requires_action (the sca should have been confirmed for that pm anyway)

hollow raptor
#

For the last point, the SCA is an engine but the card issuer still hold the last decision of whether or not to request or to decline the transaction. 3184 simulates such a case (which means it could happen in Live mode)

mighty dock
hollow raptor
#

Hi, can you upload some other video format. And btw I know what you are asking, looking around...

mighty dock
#

thanks ๐Ÿ™‚ I am converting it

halcyon wagonBOT
mighty dock
tepid topaz
#

It seems like you confirm and authenticate the card successfully, but still get the error?

mighty dock
#

yes, I pass the pm to the backend, and from there I try to do the PaymentIntent. There I get that error

tepid topaz
#

My initial guess, in your code, you save the error message somewhere, in this case authentication_required, and when the authentication is completed, instead of clearing the error, you show it to the user. I don't see any other ways how this could happen otherwise

mighty dock
#

I am popping the error as I get the result. The error is not saved. It is a try catch statement on \Stripe\PaymentIntent::create()
and this call is done after the user hit confirm. and comes with the success message. Isn't that when the authentication is complete ?

#

for example in the case of 4000003800000446 card, it follows the same process, and the payment is created ok

tepid topaz
#

A successful authentication request to Stripe will not give you this error message, so it comes from an earlier step.

mighty dock
#

or 4000008260003178 gives insufficient funds

tepid topaz
#

Could you please share your code?

mighty dock
#

sure

#

give me a minute

mighty dock
#

sorry for the formatting, but I could not send a direct message

tepid topaz
#

Why are you creating a PaymentIntent but using confirmSetup()?

#

Wait, are you creating a PaymentMethod with SetupIntent and then charging it with a PaymentIntent?

mighty dock
#

yes

tepid topaz
#

What are you trying to achieve? Do you want to save the Payment Method for future usage?

mighty dock
#

yes.
we have right now the process with our own fields and we want to implement google pay. We have normal transactions and "recurring" payments that we process based on our calendar with the saved profiles. Because of that we need the future usage.
That the final amount is calculated in the backend, that is why the payment intent is done there.
in the old code we had 'setup_future_usage' = 'off_session', but I removed it

#

the old approach was :
this.stripe.createToken(this.cardNumber, this.setBillingData(stripeBillingFields)).then((result) => {
if (result.error) {
this.tokenizationResult.success = false;
this.tokenizationResult.message = result.error.message.replace(/(*)+/g, '***');
} else {
const {token} = result;
this.tokenizationResult.success = true;
this.tokenizationResult.token = token.id;

            this.createTokenField(token.id);
            this.updateSystemFields(this.adaptTokenizationResponse(token.card));

        }
tepid topaz
#

I see why 3184 card fails then:
You set it up correctly with SetupIntent and complete 3DS, but since it's "Always authenticate", when you attempt to charge it with PaymentIntent 3DS is required again and it fails.

mighty dock
#

yes ๐Ÿ™‚

#

in the old approach we had a different page for sca, and we handled it separately. There it works

#

I thought that if the method was authenticated, it was enough

tepid topaz
tepid topaz
mighty dock
#

we are showing it from javascript, but we still need to calculate it in the backend to prevent frauds

#

could we use some intermediate page for it ? like the old approach just for this

#

something like if we get that error, to try to authenticate again

tepid topaz
#

If you create a PaymentIntent before collecting payment details, it can only be confirmed for the specified amount, no more no less. You should just calculate the amount, create the PaymentIntent on the backend (with setup_future_usage if needed) and send the client_secret to the frontend to confirm. It's the standard approach.

halcyon wagonBOT
mighty dock
#

I know there is an issue when too much time time passes between the initial click and the confirm payment intent (going to backend, calculate amount and doing the actual confirmation of the payment intent). Stripe considers it an automatic action instead of an user trigger

tepid topaz
#

You create a PaymentIntent when the customer enters the checkout page. After that they have 24h to confirm the PaymentIntent on the frontend. There's no need to confirm it on the backend.

mighty dock
#

we need to create the payment method to store it for future charges. Also I need the payment confirmation on the spot, to know if it is a valid transaction

#

oh, they confirm it in the front, and than we have the details after the confirmation

tepid topaz
#

I am just trying to clarify that your use case is very common, and you can use the most standard, most reliable solution for this. No need for complex integrations with multiple steps.

mighty dock
#

yes, setup intents was recommended by someone from stripe support, but at first glance the above is what we need. Thank you very much for your help. I will start working with the above and hopefully I will not come back for help ๐Ÿ™‚

lost heron
#

Hey, taking over here. Let me know if there's any follow-up Qs I can answer!

mighty dock
#

we cannot create a paymentIntent on page load, because we do not know the final amount. Without the paymentIntent we cannot generate the payment element. How do we display the payment element without the amount already calculated ?

#

also we have this "Failed to execute 'postMessage' on 'Window': Delegation is not allowed without transient user activation" if we use the backend calculation for the amount and than confirm it in the front end. That is why we went for confirmSetup

#

So the main idea is that we do not have any info on the page load, and the amount is dynamic. We need to show the card details form before knowing the amount. ConfirmSetup does that for us, but we have the issue with that one card 4000002760003184 that throws the error.

lost heron
halcyon wagonBOT
mighty dock
#

this is what we are doing with await stripe.confirmSetup. However, when using this specific card 4000002760003184 (This card requires authentication on all transactions, regardless of how the card is set up.) after clicking confirm for the 3d secure popup, the paymentIntent fails with
"outcome": {
"network_status": "declined_by_network",
"reason": "authentication_required",
"risk_level": "normal",
"risk_score": 37,
"seller_message": "The bank returned the decline code authentication_required.",
"type": "issuer_declined"
},
using 4000003800000446, or 4000008260003178 (for sca) or normal non-sca cards, work as expected

bleak trout
#

can you post the SetupIntent seti_xxx from that video?

mighty dock
#

here is an example of the req req_ciYrpBpDDK5QOv, req_icOqjPEwMOvaoS, req_q3FWvjmiKV9EMk

#

let me get the seti

bleak trout
#

hmm this seems normal? you did the SetupIntent which succeeded, fine, and then you immediately tried to do a PaymentIntent on the saved card, which is expected to fail on that card.

mighty dock
#

seti_1Pxlr4G5NORjrd4mCa5mAuG3

bleak trout
#

it's the 4000002500003155 card, and only the 4000002500003155 card, that can be charged off_session and simulates getting an exemption from 3D Secure

#

in general also you should never do SetupIntent->immediate PaymentIntent, that's a bad flow as it can lead to double-authentication flows. You can create a PaymentIntent with setup_future_usage as mentioned earlier to charge + save the card

mighty dock
#

my issue is that with the old appropach, we did a separate page for sca, and that did not fail. it went through. There it was a status requires_action and after the sca was confirmed, it went through.

bleak trout
#

yes , because the behaviour is different when you confirm with off_session:true

mighty dock
#

my problem with the PaymentIntent is that we do not have the final amount when displaying the page. So because of "If you create a PaymentIntent before collecting payment details, it can only be confirmed for the specified amount, no more no less. You should just calculate the amount, create the PaymentIntent on the backend (with setup_future_usage if needed) and send the client_secret to the frontend to confirm" we cannot change it

bleak trout
#

when you confirm with off_session:true and the payment requires 3D Secure, it just declines(because you tell us the customer is not there so they can't do an action), so then you can contact the customer and re-confirm on-session(which does present 3DS and goes to requires_action)

mighty dock
#

so we could return them to a page and try to do a off_session:false with the old approach

bleak trout
# mighty dock my problem with the PaymentIntent is that we do not have the final amount when d...

yeah unfortuantely there's not great soution. I do suggest trying to optimise for the fewest number charges as possible so it's generally better to do one PaymentIntent than two, or a SetupIntent + a later PaytmentIntent.
options include

  • use your SetupIntent + off_session PaymentIntent flow(if the payment amount really takes O(hours) to know and confirm)
  • SetupIntent, contact the customer later when you know an amount and charge on-session PaymentIntent then
  • PaymentIntent for some large-ish/estimated amount, with capture_method:manual, and then capture the amount you need(and if you need more, do an off-session PaymentIntent)
mighty dock
#

and this "SetupIntent, contact the customer later when you know an amount and charge on-session PaymentIntent then" is not falling into "never do SetupIntent->immediate PaymentIntent, that's a bad flow as it can lead to double-authentication flows" issue ?

bleak trout
#

not really since you'd be doing it O(hours) apart in a clearly different flow

mighty dock
#

well, the idea is that if I do the payment later, than I do not have the resolution on the spot, right ?

bleak trout
#

what I'm talking about is where you enter your card, you get a popup saying "Authenticate your non-payment authorisation to save the card with <merchant>" and you do that in your bank app, then two seconds later you get another popup "Authenticate your payment of $156 with <merchant>" and have to do that in your bank app too. That's a real flow/bug/issue I've had live merchants report to me and it's because they do SI->PI

bleak trout
mighty dock
#

the amount is calculated based on the user interaction, but the page is already loaded with the payment form

bleak trout
#

then can't you just use the Deferred Intent flow where you don't have to create the PaymentIntent until after the user already entered their card details and pressed Pay?

#

seems like what you need(you're probably thinking you need the Intent-first flow where you create the Intent on page load, but over the last year we made the Deferred flow more supported)
https://docs.stripe.com/payments/accept-a-payment-deferred
there's a frontend amount you can control by updating Elements as the cart changes too

mighty dock
#

hmm, looks like it. I can add a payment in the elements options, and update it with elements.update({amount: newAmount}); THan in the backend I can still verify if any amount manipulations happened. I guess I can do here the confirmation of the payment in the backend as well with the "confirm" = true, and it would mimic the flow we have now

bleak trout
mighty dock
#

ok, thanks. I will look into that. Also customerSessionClientSecret can be updated with elements.update(); ? The reason I am asking is that after the user adds the details, mainly the email, we want to identify if he already has a customer id on that email, and use it to add the payment profile. Not creating a new customer each time

bleak trout
#

yes it can be updated

mighty dock
#

ok, thank you. I will try this approach. I really appreciate the help