#ben_api

1 messages · Page 1 of 1 (latest)

twilit pelicanBOT
#

👋 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/1335890687975227463

📝 Have more to share? Add more details, code, screenshots, videos, etc. below.

mint matrix
#
            $invoice = InvoiceFinalize::handle($schedule->subscription->latest_invoice, $connect_account->stripe_account_id);
            $requires_action = $this->checkPaymentIntentAction($invoice, $connect_account->stripe_account_id);
            if ($requires_action) {
                return $requires_action;
            }
            throw new \Exception('No start date provided for staged product');
            $invoice = InvoicePay::handle($invoice->id, $connect_account->stripe_account_id);```

For context
#

(the throw is intentional whilst I am testing)

upbeat rivet
#

Is it about how to handle 3ds for recurring payments?

mint matrix
#

Yes. Our flow works when 3DS is not involved, however I wonder if it needs to change.

We collect the payment method and send the ID to our backend. We attach the PM to the customer and make it default. Then depending on the product we create a sub either directly or via schedule and charge.

But for 3DS obviously we need to address the verification / auth required.

Our 3ds flow is working for standard recurring products where we simply create the subscription against the customer. This is fine as the invoice moves immediately to a requires_action status and we can prompt for 3DS auth in the front end.

However for the subscrotions created via a schedule this is not happening. Those are not by default billed immediately in stripe, so we were previously advised to use finalise invoice then call pay on the invoice. However this results in an error when testing with the 3DS card awlays authenticate (4000002760003184) as the invouice appears to be in a requires_confirmation status not requires_action.

#

So my question is really what re we supposed to do?

upbeat rivet
#

What's the invoice ID?

mint matrix
#

2 moments

#

in_1QoBC5S5b7oU7ZDXcFxFbslU

#

If i pass back the action of requires_confirmation with the secret to the frontend, will that trigger the same 3ds flow as requires_action?

twilit pelicanBOT
reef mesa
#

hi! I'm taking over this thread.

mint matrix
#

Hi Soma

reef mesa
#

have you tried confirming that Invoice on the frontent? my guess is this would trigger the 3DS flow

mint matrix
#

So passing the client secret from the payment intent with status requires_cofnirmation back to the frontend, as we do when it is requires_action?

reef mesa
#

yes, that's what I recommend testing this is test mode to see what happens

mint matrix
#

ok let me see, give me 10 - 15 mins

#

OK so this works when the schedule is created to start now. But nothing is triggered when it is a future date.

When we allow a customer to sell their product to start on a future date, we create the subscription first, then we apply a schedule where the firsrt phase a trial that takes them up to the chosen start date (this was recommended by stripe to us).

In this instance, when we use the 3DS always authenticate card the auth flow doesn't appear to be triggered, presumely because it is a trial?

So what would happen in X days when the trial ends and a charge is made?

reef mesa
#

OK so this works when the schedule is created to start now. But nothing is triggered when it is a future date.
can you share a specific object ID so I can have a look?

mint matrix
#

yes. moments

#

acct_1QUXxpS5b7oU7ZDX (connect account)
cus_RUNyfeTpc20bUt
sub_1QoLdjS5b7oU7ZDXHVgJTcC9 (currently on trial)

I cant seem to find the id of the upcoming invoice

reef mesa
#

sorry for the delay, having a look

#

I'm a bit confused. if it's a free trial, then there's no PaymentIntent. so are you using the pending_setup_intent?

mint matrix
#

Unsure, we don't intentionally create any payment intents. We create the sub, apply the schedule which creates teh first phase as. trial and then offsets the remainig phases accordingly. That is all we currently do.

If no 3ds, come trial end the customer is billed to their default payment method

#

So what woud we need to do differently?

#

our stripe elements in the frontend are in mode: 'setup'

reef mesa
#

our stripe elements in the frontend are in mode: 'setup'
got it, so you have a SetupIntent in this case. can you share its ID?

mint matrix
#

Where would i find this?

reef mesa
#

can you re-explain your payment flow in more details? after you create the Susbcription with a free trial, what happens exactly?

mint matrix
#

OK. So we pass in the chosen product from the customer checkout session, as well as the payment method id collected in the front end.

First we attached the PM to the customer.

Then because the product is staged (uses a schedule) and is due to start on a future date, we first create the subscription via subscriptions->create.

Then we wrap this in a schedule, where the first pahse is a trial up until the proposed start date. Subsequent phases are as per the product design (so perhaps £500 for 8 weeks, then £300 pm for example).

Usually we would then reteurn the completed checkout info to the end user confirming. their setup. In X days wehn the trial ends (the trial is hidden from the purchaser) the card is charged and the suvscription officially starts

twilit pelicanBOT
empty isle
#

👋 taking over for my colleague. Let me catch up.

mint matrix
#

sure

empty isle
#

whenever you create create a subscription, whether it's in trial or there's an invoice created upon subscription creation, the Subscription object will always have an Intent you could use to save the payment method for the recurring payment

#

you shouldn't use SetupIntents that you create yourself to save the payment method

mint matrix
#

well i am not, that was Soma asking me.

#

But when we check the invoice in this case, there is no action required even though a 3ds test card is used

empty isle
mint matrix
#

I am not. As above, we send the payment id from the payments element to the back end. Our front end is in mode setup. We take that payment method id and attach the PM to the customer, set as default

Then in this particular instance, we create a subscription using subscriptions->create.

We then wrap it in a scedule where the first pahse is a trial up until the poposed start date of the product.

Then we return the invoice

#

but we need to acount for 3ds auth which is currently not working in this instance

empty isle
#

I am not. As above, we send the payment id from the payments element to the back end. Our front end is in mode setup. We take that payment method id and attach the PM to the customer, set as default
that's what I'm saying... and this is wrong

mint matrix
#

what bit is wrong? can you be more specific? As thisworks for all other flows we have

#

(also our configuration is what was recommened to us by stripe...)

empty isle
#

when creating a subscription you shouldn't create a PaymentMethod and attach it to the customer

mint matrix
#

OK, what should we be doing? as we have been doing this for almost 2 years for thousands of customers ?

empty isle
#

if the customer has a default Payment Method they can use it, but if you're creating a new one, you should use the subscription's pending_setup_intent or the latest_invoice.payment_intent to get the client_secret and use it in your frontend app to collect the payment details

mint matrix
#

OK, so that isn't that different from what we're doing. We use a custom checkout that collects their billing details payment details using hte address and payment elements. The onyl difference is we take the paymeth method, attach it and make it default and the ncreate the sub.

I dont particuarly want to rewrite all our paymnte flows (that work) for this once instance, but you are saying in this instance to get this to work we should essentially reverse it?

empty isle
#

it's the same flow on the frontend

#

you just need to change where you get the client-secret from

mint matrix
#

I dont know if im being thick but i still fail to see how this addresses the 3ds issue?

#

Given the invoice created has no action

empty isle
#

because this would authenticate the intent while the customer is on session

#

which reduces the risk of having 3DS on an off_session invoice

mint matrix
#

OK so walk me through this. We load the checkout, and have already created the subscription at this poiunt?

We pass the checkout the client secret from the sub and use that? What are we doing with this secret?

Sorry this is compeltely foreign as this is not at all how we do it

#

and a bit of a surprise after all this time and our configuration beeing done by the accelerate team

empty isle
#

OK so walk me through this. We load the checkout, and have already created the subscription at this poiunt?
not necessary

#

this is an example

mint matrix
#

this more 99% what we are doing

#

this is*

empty isle
#

are you using the pending_setup_intent and the latest_invoice.payment_intent to get the client_secret?

mint matrix
#

we are using the latter but its null only in this instance with this product type and future start date

#

i will re run this now to look for pedning setup intent

#

please give me 15-20 mins

empty isle
#

sure take your time

mint matrix
#

i think ewhat i am getting caught up on here, is we are currently checking whether there is an action required by looking at the payment intent status. But are you saying e should actually awlways be returning the client secret up from the intent (whether from the sub itself or latest invoice) and just letting hte frnotend handle it rehardless?

empty isle
#

yep

mint matrix
#

yeah the problem is latest_invoice.payment_intent is null

empty isle
#

but what about the pending_setup_intent

mint matrix
#

il check that now

empty isle
#

on the subscription object?

mint matrix
#

yes im just checking that one now

#

Should the secret look like this seti_1QoNH8S5b7oU7ZDXZyzQaKCr_secret_RhmqbkkU64fZ9JikHsW6C8hhF5mzkPg ?

empty isle
#

yes

mint matrix
#

ok, let me keep testing then as this failed, but i need to make some other changes

empty isle
#

sure

twilit pelicanBOT
mint matrix
#

OK so that is triggering 3ds now, however this creates some new problems.

Because the subscription is already created with trial applied, it is technically active at this point as no payment is initially required. If the user fails 3ds, or cancels, the checkout sessioj nis still in progress... but there is now a live subscription in existance.

For this reason this flow feel like a disaster waiting to happen.

What do you advise?

lean forum
#

Hey! Taking over for my colleague.

If the user fails 3ds, or cancels, the checkout sessioj nis still in progress... but there is now a live subscription in existance.
The Checkout Session expires after 24h (max) so your integration need to make sure that the customer has a valid PaymentMethod by the end of the trial period

#

For example you can keep asking the customer to provide a new PaymentMethod periodically during the trial period

#

or to block the creation of the Subscription untill the custom provided a valid PaymentMethod

mint matrix
#

we use a custom check out as previously mentioned

#

the issue with the flow tarzan proposed is that once we gather the PM and send it to the backend, if we then return the client secret to deal with 3DS and the user cancels 3ds, we are left with an open checkoujt session but a LIVE subscripiton as teh subscription was alrfeady crearted and put into a trial state.

How do we deal with cleaing up that mess?

#

This is why this feels wrong to me

lean forum
#

How do we deal with cleaing up that mess?
This is not a mess realyl, because the Checkout will expire at some point (even if it's custom) . What part exaclty you are referring to as a "mess"? having an active Checkout Session, having a Subscription without a valid payment method or what exactly ?

mint matrix
#

sorry, that is quite the assumption. How do you know hte checkout will expire if its custom? As i am God in that situation and have total control over it lol.

The mess is having a live subscrioption in trial without a valid payment method.

#

(its doesnt expire)

#

the reason we have a rtial in this isntance is because this is how both the discord support and the accelerate team told us to set this partcualr product up. This product type is a product that uses schedules to iterate over various prices. And in this instance the subscription is set to start on a future date

lean forum
mint matrix
#

as this is not actually support by stripe we were given 2 otptions, and the recomend option was to use a trial to feign the period between subscribing and starting

#

I assume payment intent but i was told above not to do that

lean forum
mint matrix
#

Forgive me challenging this, but you are the 5th person in this thead now and i keep getting slightly different answers

#

I need ot make sure we get the right answer as this thing is in production and is causing us hige headaces since we put this live with stripe

lean forum
lean forum
#

There are multiple options, it depends on your use case and what are you expecting.

#

Do you want to have a Subscription without a valid PaymentMethod (regardless of the reason behind)?

mint matrix
#

Not creating until we have a valid payment method is the preference as it prevents subscritions being created that are likely to become incomplete or this instancem live when they sholudnt.

We would never have a sub without a valid payment method.

We need a flow that allows for 3DS to be dealt with ahead of creation (if possible). Curently we are doing this off the latest invoice which is post creation and less than ideal

#

So ideally we capture the PM, validate it and do 3DS if needed, then attach it, create the sub and charge

lean forum
#

In this case, you should use SetupIntent to collect a payment method

#

Once you have a valid PaymentMethod, then you create a Subscription with that payment method as a default one.

mint matrix
#

OK, now is that something we trigger in the front end or back end? As currently our front end has the payment element setup in mode: 'setup'

lean forum
#

It requires both frontend and backend.

mint matrix
#

OK, so we create teh setup intent in the backend and provide it to the front end to use when submitting the payment element right?

I note this references a return url. Is this required and when is it actually used?

lean forum
#

OK, so we create teh setup intent in the backend and provide it to the front end to use when submitting the payment element right?
Correct

#

I note this references a return url. Is this required and when is it actually used?
It's used for redirect based PaymentMethods

mint matrix
#

OK can we not allow redirect based payment methods? And is there a list of them somewhere?

Also, is there any issue exposing the client secret to the frontend?

lean forum
#

Also, is there any issue exposing the client secret to the frontend?
it's safe to share the client_secret, it's built to be used in frontend.

mint matrix
#

Ok, and I have to get the client secret and set this in the options? I note that when i try to do this, i cannot use the mode param. Is this correct? This is the only way to do ti?

I am confirming as I am having to literally unwind our entire process for this

lean forum
#

Ok, and I have to get the client secret and set this in the options? I note that when i try to do this, i cannot use the mode param. Is this correct? This is the only way to do ti?
You need to omit the mode option.

twilit pelicanBOT
mint matrix
#

Can you point me a test card that will cause redirection so i can test this behaviour?

lean forum
#

But card payments aren't a redirection based payment methods

mint matrix
#

ok noted, so we couold lock this down to card only?

lean forum
mint matrix
#

1ok thanks

lean forum
mint matrix
#

ok, and is there a way to prevent the same card being added as a duplicate?

empty portal
mint matrix
#

Ok but this could only be done in the backend once we have called stripe.confirmSetup ? So at this point we could have duplicates?

empty portal
mint matrix
#

ok thanks, that mifght be one for later

#

Ok so the above (several above) process adds the PM to the customer, but it is not set as default. I presume the most appropriate course of action would be to the pm id from the setupIntent when confirmSetup returns, and pass this to the backend to use to fine and set that PM as defautl?

empty portal
#

Yes if you want it to be customer's default you'll need to manaully update that field

mint matrix
#

OK and another one, i am getting the setupintent / clietn secret on checkout load. At what point is that considered consumed? E.g. if 3ds fails, or the user cancels 3ds, is the setupintent cinsumed or can they retry without me requesting another?

empty portal
#

The only terminal state would be succeeded or canceled. It'll only ever transition to canceled if you manually cancel it

#

Otherwise the intents can be re-confirmed up to a limited number of times

mint matrix
#

and what do you mean by manually cancelled?

#

also, now that we are using setupintent and concirming the PM before we craeate and subscriptions, can an invoice ever havea status of requires_action or simmilar that reauires some other form of 3ds auth? Or can i now remove that logic?

empty portal
empty portal
mint matrix
#

Ok but that would only trigger if we wer using bank payments? or this could techcnially occur on a card payment?

empty portal
#

It can happen on card payments yes

mint matrix
#

the rabbit hole gets deeper.

Is there a test card to simulate this?

empty portal
#

Sure, a card that always needs 3DS/auth: 4000002760003184

mint matrix
#

ok thats what ive bee using to test, and that seems to get triggered when i call stripe.confirmSetup

#

So this is before I create the sub and might collection any payments. What I was asking was could there be any chance of an invoice having the status of requires_action or requires_confirmation AFTER we have already called stripe.confirmSetup and gone through that 3ds flow

empty portal
empty portal
mint matrix
#

Yeah i know that particular card will, but will this ever happen in real life?

#

as ive never come across a situation where a subscription requires me to reauth ti every month

#

I simply mean with in the checkout flow, is it possible a user to be prompted twice

empty portal
#

Potentially yes, hence why we have cards to simulate these scenarios

mint matrix
#

OK i think short term, what i ahve is goign t owork, long term we are going to have to compeltely re do this

empty portal
#

Not sure why overall you save the card and then create a sub

mint matrix
#

the answer to that is above in this thread

empty portal
#

As the sub creation will generate the required intent (payment/setup) for you anyway

empty portal
mint matrix
#

We have an insaenly complex product setup

#

you can rthank my CPO

empty portal
#

Let me know if I can help with anything else

mint matrix
#

possibly as this isnt working now with standard rcurring products

#

thnk im ready to find hrte nearest bridge

#

so it seems when a subscription is created normally with subscriptions->create, for whatever reason the invoice is ust sat pending and the subscription incomplete

#

but no error

#

sub_1QoOxxS5b7oU7ZDXpJPtJspw this is the sub id

#

evt_1QoOy0S5b7oU7ZDXLmOz6ho5 it says custoemr attemepd to subscribe

#

ok so tis failing because it is saing the invoice requires confirmaiotn by the user?

#

is this becasue im using the always auth card?

empty portal
#

This is exactly the behaviour I described – we attempted to pay the invoice with the saved card on the customer (3184) but 3DS was requested (as expected) so you need to handle that by calling confirmPayment with the intent

mint matrix
#

im getting a bit lost here, why would i 3ds twice?

#

ive never seen this in reality

empty portal
mint matrix
#

well ive jsut tried 4000002500003155 and it still happened

empty portal
empty portal
mint matrix
#

this is what i am not following. So you are telling me it is perfectly normaly for an end user to have to 3ds twice in the same checko ut session?

#

if so, please show me this in reality as i never once in my life had that happen to me

empty portal
#

I wouldn't say normal, but I'd say that your integration should account for it yes

mint matrix
#

right now i cannot process a pyment testing 3ds that doesnt fail

#

so im going to say something is wrong here

#

and we are misunderstanding each other

#

I want a card, that allows me to test 3ds with the new configuation we have setup that required me to rewrite most of this over the last 3 days, that will trigger 3ds ONCE as i am confirmSetup and then process the payment for the subscription that is subdsequentlt crearted

#

i cant stres enough this is a proeuction issue

empty portal
#

Don't believe there is one I'm afraid

empty portal
mint matrix
#

we are talking about two different things her

#

since ive made this most recent change you suggested, i now cannot process any payments in our checkout

#

so i am strugglign to simulate a 3ds scenario and no that this works

#

and know&*

#

know*

empty portal
#

I didn't suggest a change to your code? I recommended a card to use that would trigger a scenario you asked if was possible

mint matrix
#

youre the 6th person in this thead

empty portal
#

If you get a failure on a subscription creatrion, then just call confirmPayment on the intent generated by the subscription/invoice and it'll handle 3DS again

mint matrix
#

but that will prompt the user to 3ds again?

empty portal
mint matrix
#

so youre' telling me this will happen in production?

mint matrix
#

its like you just hward what i said out loud

#

dude im a super black and white person

#

yes and nos

#

i cant process informaiton anh other way

empty portal
mint matrix
#

i dont want niche scenarios

#

i want the answer to a very specific question

empty portal
#

OK, hit me with the very specific question

mint matrix
#

right now, it is looking like whilst testing 3ds in sandbox with trest cards is going to trigger 3ds TWICE in the same checkout session within seconds of each other.

WIth the setup we now have which is:

Create a setup intent when checkout loads
Use that intent when the user checks out to stripe.confirmSetup (which adds the card and provides it back to me in the frontend)
Pass the pm to the backend to make it default
create a subscripotin, whether normally, with a schedule or a scheudle + trial for future date start

in production will the user end up getting hit with 3ds twice within short succession because of the above under nomral circumstances?

I am asking this becuase it is happening in test 100% of the time now

empty portal
#

right now, it is looking like whilst testing 3ds in sandbox with trest cards is going to trigger 3ds TWICE in the same checkout session within seconds of each other.
As we've explained this is a result of your unorthodox integration which we don't recommend (e.g. save/setup a card via a SI and then charge it immediately in same 'checkout'). The native subscription integration handles the intent generation for you, but I understand business needs make this a requirement

2x 3DS is probably really uncommon, but if your integration is setup correctly then it's a non-issue albeit potentially annoying for customers

I didn't really into your business needs that make this flow a requirement, but if it's specifically about collecting PM details before the subscription is created then consider a deferred flow which enables that and will reduce potential 3DS instances to one

#

I am asking this becuase it is happening in test 100% of the time now
That ultimately is because of the test cards we have available. There isn't one that'll work in your integration and only trigger 3DS once

At the end of the day, 3DS/auth is up to bank/issue discretion. We apply for SCA exemptions where possible when using saved cards, but in some scenarios they may still request 3DS. It's annoying and we do our best to reduce the likelihood of that

mint matrix
#

This is all because we need to allow our users to sell products (which are ultimately subscriptions) that start on a future date. Those products sometimes need to have stages to them, so we use schedules. Stripe do not support a future start date in this scenario. As a result, the accelerate team (and support here on discord) both told us we would need to use trials to simulate this situation until such time this feature becomes available as standard.

Previously we did not collect the payment method like this.

But when dealing with 3ds because of having to use a trial and relying on the intent from the sub and/or invoice, by the time we get this, the subscription technically is live as it is ina trial state.

Wehn we returned the action to the frontend to ask the user to 3ds verify in this situation, if they were cancel for some reason, or it fails, we are left iwth an active subvscription. So we asked for a solution for this

#

i dont really give 2 sh1ts when we actually do the 3ds things in the flow, i jsut asked for a flow that would make our lives as easy as possible as they are already sinanely difficult with all this schedule product crap. I am trying to find hte path of least resistance

#

so it now sounds liek i nneed to revert all of this

lean forum
#

Wehn we returned the action to the frontend to ask the user to 3ds verify in this situation, if they were cancel for some reason, or it fails, we are left iwth an active subvscription. So we asked for a solution for this
There is no magic solution here, simply you need to monitor the Susbcription and see if it has a valid payment methods or not.

#

For example, you can listen to the event customer.subscription.trial_will_end and check if the Subscription/customer have a valid payment or not, if not you simply disbale the Susbcription

mint matrix
#

i am currently reverting everytging to test this

lean forum
mint matrix
#

im still trying to deal with 3ds cacnellation and subs left active that shouldnt be

#

yeah this isnt going to work either

#

there has to be a solution this, i honestly cant beleive this to be impsosible

twilit pelicanBOT
lean forum
#

yeah this isnt going to work either
What is not working exactly ?

#

What are you expecting exactly ?

mint matrix
#

what ever direction i go in wit hthis, one element of our flow breaks

#

so im trying to work out which on is most likely to be resolvable without having to actually change what we offer. I canot do that easily as this thing is live in rpoduction with people using it

#

is there something i can listen for when a user either cancels or fails 3ds? I need a way to clean up in that scenario to get rid of these subscriptions that were created

lean forum
#

is there something i can listen for when a user either cancels or fails 3ds?
Not exactly this but you receive a webhook endpoint invoice.payment_action_required saying that an invoice/payment is requiring an action (3DS)

#

So in your integration, you can implement a job that monitors the related invoice and decide when to cancel or not the Susbcription.

#

I canot do that easily as this thing is live in rpoduction with people using it
I'm sorry I'm not seeing this a probleme as when you migrate to a new flow only new Subscription will be impacted, so it should be transparant

#

Unless you have other constraints

mint matrix
#

Im refefrring to our product offering

mint matrix
#

not quite, as that coud be fired when we dont want to clear up

lean forum
#

You need to implement some code and filter when you want to clear and when not.

twilit pelicanBOT