#rfcgreg

1 messages · Page 1 of 1 (latest)

delicate monolithBOT
jade rune
#

hi, I think this is an issue I've seen before. Are you using one of the 'deferred' integrations where you confirm on the backend?

#

if so you actually need to pass mandate_data, but it's somewhat buried in the docs

verbal estuary
#

we dont actually take payment at this stage, its "off session"

jade rune
#

if you share the exact request ID req_xx from an error or a a PaymentIntent ID I can have a look, but I think it's this(it's come up a few times recently and the docs are not great here)

verbal estuary
#

sure, let me get you one

#

I think this is it: req_aCDrUEIO44y0oN

jade rune
#

hmm I think that example is not a great one since I'm not sure you used a SetupIntent in that case, looks more like you manually created a PaymentMethod and passed it directly when calling the Customer Create API

#

ah no, you did use one, you just integrate in an unusual way where you run the SetupIntent without a customer and then attach the PM to a customer later

verbal estuary
#

Yeah, so this "payment form" is only to collect payment details, it creates a setupintent first via php, then uses the js to create a payment method and confirm the intent, we then save all that to a new customer as the final step, otherwise if someone abandones we end up with a blank customer

jade rune
#

makes sense

verbal estuary
#

sometimes this may also be sent via email or whatever to ask someone to provide their card if they have an invoice or what not

#

Anyway so we need to pass mandate data into the setupintent when it's confirmed in order for that to be saved to the link payment method?

jade rune
#

ah but no, it can't be that, because you confirm on the frontend actually

#

so why isn't stripe.js collecting/passing the mandate for you... I don't know

verbal estuary
#

yep, that was the confusion because the mandate data is the 3DS etc? your bank asking you to confirm. this is normally done when we click the submit button as the js checks the card etc

#

I am wondering if clicking the box to use link is somehow not triggering the 3ds stuff?

jade rune
#

3D Secure isn't really related here I don't think

verbal estuary
#

oh my bad. I might need to re-read

jade rune
verbal estuary
#

eh, not me personally. Possibly the stripe account holder (boss)

#

I'm the developer account attached to it

#

Should I perhaps be requesting access to this new feature?

Try out our latest update

We’re making a slight improvement to the integration below to automatically handle mandate data and future proof your integration. To request early access, please click here.

jade rune
#

hmm, maybe!

#

sorry, there's a lot of things happening with Link and some rough edges, I'm not up to speed with all of them which is why I'd feel better answering in a support ticket where we have more time to dig in

verbal estuary
#

Fair enough, makes sense. We've unfortuantely not had much luck with link. I've been asked to disable it for now due to the issues we're having

jade rune
#

oh hmm

verbal estuary
#

This was a quick attempt to try see if I could get it fixed before I look at that

jade rune
#

what I've seen before is that if you disable Link on your account, effectively that 'cancels' the mandates for existing customers, because you don't want to be able to charge them using Link anymore

It can also happen if the end-customer is disabling Link in their settings

#

so if you disabled Link on your account around the time of that event, that could be why

verbal estuary
#

It should still be enabled at the moment

#

the req I sent you was the boss man testing his card last night

jade rune
#

yeah sorry I misread the event

#

ok sorry, it's super busy on Discord at the moment and myself and half the team are in a meeting so we don't have a lot of bandwidth to dig in. I'd suggest writing into https://support.stripe.com/?contact=true with exact code, request IDs, clean reproductions, and we can dig into

verbal estuary
#

yeah sure that's not a problem. I use a user defined settings file so I think I'm just going to add in a condition and a switch to disable or enable link for the tiem being. That way I can keep my code intact for the ticket

jade rune
#

I do think there is some confusion here in your testing , because for pm_1NuY2CBZh6y8njAy2jYQ6jHv, the PM from req_aCDrUEIO44y0oN , I really don't see any SetupIntent ever used with it , looks like it was just attached to the Customer directly after creating the PaymentMethod (which we never recommend as it doen't handle 3DS or mandates)

verbal estuary
#

I wonder if it's related to the use of link. without using it, I'm pretty sure they're used

#

do you have access to our test data? I have a live test form using the same code

#

you'd be welcome to take a look

#

as an example this is what we would normally see for a successful non link submission.

#

I can go ahead and launch a ticket though

wise tendon
#

Hi there 👋

verbal estuary
#

hello

wise tendon
#

Was reading through the thread, and I do think passing mandate_data will help avoid that error. Sorry, was trying to find a doc that I swore had a snippet showing that in it, but I'm having trouble finding it.

verbal estuary
#

No worries

wise tendon
#

Oh, wait, maybe I'm looking at the wrong Payment Intent, this one seems to have been created from the dashboard.

verbal estuary
#

yeah so we don't have a typical setup

#

this particular integration only ever takes the payment details and saves them to a new customer for later uses (off session) all payments for these would generally be initiated via the dashboard

#

the company does use other things like pabbly to take direct payments on site. But this particular integration is an inhouse solution we have

wise tendon
#

Gotcha, I'm going to try to find the Setup Intent for the Payment Method being discussed above.

#

Hm, no luck though, all I'm seeing is the request to create the Payment Method from the frontend, I'm not seeing any Setup Intent that was created to set up that Payment Method.

verbal estuary
wise tendon
#

Checking

#

That's a request to create a Customer.

#

Is there a guide that you're following to build this flow?

verbal estuary
#

This was more updating an exsting integration I made a while back

#

it's been created and updated according to stripe docs at each time

#

last major work I would say was the migration from stripe card element to the payment element,

wise tendon
#

Gotcha. So the concern here seems to be that Setup Intents aren't being used. The Setup Intent is the object that is responsible for constructing the mandates for future use, which aligns with the error you're getting when trying to process a payment.

#

It's a good starting place for flows like this.

#

Right now it seems like your flow uses Stripe Elements' createPaymentMethod function to create a Payment Method, and then attach that to a newly created Customer.

Instead, you'll want to:

  1. Create a Customer (if one doesn't already exist)
  2. Create a Setup Intent for that customer (unless you want to use a deferred intents flow, we can discuss that if so)
  3. Process the Setup Intent using Stripe.js
verbal estuary
#

The setup intent should be used and confirmed. Not sure why it wasn't showing though

#

I'm going to try share a condensed version of the js as that may explain better

wise tendon
#

Also, I'm seeing these objects are from live mode, are you able to reproduce this behavior in test mode as well?

verbal estuary
#

in test mode everything worked, even using confirmCardSetup

#

sorry that's still kinda long

#

thats the js anyway.

the intent is also created on page load :

<?php

// Create a Stripe SetupIntent instance
$intent = $stripe->setupIntents->create(
[
'usage' => 'off_session',
'automatic_payment_methods' => [
'enabled' => true,
'allow_redirects' => 'never',
],
]
);

// Set the client secret key into a variable
$clientSecretID = $intent->client_secret;

wise tendon
verbal estuary
#

it had been working but not with link. It now uses confirmSetup as shown above

#

link aside this integration does actually work as expected / intended

wise tendon
#

It looks like you create a Payment Method from the Elements instance, and then don't use that in the Setup Intent. Taking a closer look, I wonder if your flow is creating multiple Payment Methods.

verbal estuary
#

Here's some info from a successful submission not using link:

app-api-version
2023-08-16
account-api-version
2023-08-16
stripe-php-ver
12.4.0
payment_method
pm_1NuboyBZh6y8njAy2xQ7RZ7I
setup_intent
seti_1NubnkBZh6y8njAyChEETlUb
card_name
test
emailaddress
test@test.com
cardaddress
test,GB,test,test,te11st,
customerID
cus_Oi1s9v9ft5hl5a

#

thats in test mode right now if it helps

#

That's the data and ID's that's processed and printed at the end (thank you page of my test form)

wise tendon
#

Yup, you're creating multiple Payment Methods.

pm_1NuboyBZh6y8njAy2xQ7RZ7I is being created by your call to createPaymentMethod. Payment Methods created that way aren't set up for future usage.

Then you create and process seti_1NubnkBZh6y8njAyChEETlUb, which creates another PM, but that isn't tied to a Customer since the Setup Intent wasn't provided a Customer ID via the customer parameter.

#

There is a bit of redundancy with the current flow, do you have a use-case that requires you have access to a Payment Method object before you process a Setup Intent for it?

verbal estuary
#

I see... hmmm maybe its been an oversight

#

I don't think there's a specific reason for that no.

#

Sorry trying to wrap my head around this

wise tendon
verbal estuary
#

yeah thanks. I'll need to look again at my flow I guess. I do indeed see the two PM ID's in the logs now.

#

would the double Payment method be down to the switch from confirmCardSetup to ConfirmSetup?

wise tendon
#

Not alone.

#

I suspect your flow before created a Payment Method then passed that to the confirmCardSetup call which can accept already created PMs. It looks like now createPaymentMethod is still in place which creates the first Payment Method. Then confirmSetup is called which creates the second, since the line to pass the existing PM ID is commented out because that function doesn't accept existing payment methods.

verbal estuary
#

yeah ok I think thats exactly what it is

#

I did previously pass the payment method to card setup function

wise tendon
#

Gotcha. In that case, I would recommend making some adjustments to what you have currently. With the main changes being:

  • Remove the call to createPaymentMethod (the Setup Intent will create the PM for you)
  • Create the Customer before the Setup Intent, and pass the Customer ID to the customer field when creating the intent.
verbal estuary
#

So I currently create my customer via PHP after the JS returns a success and what not, I guess you would suggest I create the customer in the js instead?

wise tendon
#

I'd still do it from server-side code, probably in the same flow that currently creates a Setup Intent and returns its client secret to the frontend.

verbal estuary
#

oh ok, that's the reason I ended up doing the customer at the end. Currently the page loading is the trigger for the setup intent. if I created a customer at this stage any time the page is viewed a new blank customer would be created

wise tendon
#

Since you're using the deferred intents flow, you don't need an intent to render the Payment Element. So you can delay the customer creation as well as the intent creation parts of your process, those pieces can be triggered from the submit event listener.

verbal estuary
#

oh ok that would work

#

I was under the impression that it was best to have the intent first but I guess that was for the older methods

#

a lot has changed with stripe over the last couple years, can be hard to keep track of current best practices

wise tendon
#

Agreed, quite a bit has changed. That approach was the best option when that was the only way the Payment Element could be implemented. We got a lot of feedback that the approach created a lot of unused items that cluttered accounts and dashboard views though, so the deferred flow was built which allows a lot of those objects to be created later in the process when a payment is more likely to occur.

verbal estuary
#

yeah that's making sense, this integration was started all the way back then and has undergone the various changes. I am going to take notes from our conversation and get a plan of action to streamline the flow

#

thank you for the help, hopefully ill get it all working now