#sylar_api
1 messages ยท Page 1 of 1 (latest)
๐ 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/1318235172692557876
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Hi there ๐ what test card are you using for this testing?
Are you using our "authenticate unless set up" card?
4000 0025 0000 3155
https://docs.stripe.com/testing#authentication-and-setup
Yes, im using this one:
4000002500003155
{
"id": "seti_1QWfqULT0n97qDN270KLVkYj",
"object": "setup_intent",
"automatic_payment_methods": null,
"cancellation_reason": null,
"client_secret": "seti_1QWfqULT0n97qDN270KLVkYj_secret_RPUqGPhHk3SUnSHLvHrj7WAiS7Y1eII",
"created": 1734361470,
"description": null,
"last_setup_error": null,
"livemode": false,
"next_action": null,
"payment_method": "pm_1QWfqaLT0n97qDN2dVNcLtwO",
"payment_method_configuration_details": null,
"payment_method_types": [
"card"
],
"status": "succeeded",
"usage": "off_session"
}
here is setup result
Okay, can you share the ID of the Payment Intent then?
My suspicion is that you're setting setup_future_usage on it, which triggers setting the card up again, but I'd like to take a closer look.
this one: seti_1QWfqULT0n97qDN270KLVkYj ?
No, I'm looking for the subsequent payment that you said still required 3DS after you confirmed that Setup Intent.
const intent = await this.stripe.setupIntents.create({
customer: user.paymentSystemId,
payment_method_types: ['card'],
automatic_payment_methods: { enabled: true },
// off_session: true,
// confirm: true,
});
this is my setup intent code
Ah ok, let me see
Here is the payment id:
pi_3QWetKLT0n97qDN20Aq4avCz
The Subscription you created doesn't seem to use the Payment Method from the Setup Intent you shared.
The ID of the Payment Method being used in that latest screenshot doesn't match the ID of the Payment Method in the body of the Setup Intent you shared.
Ok. Gimme just a sec, I will attach a new card and pay for test subscription -> then ill provide the info. 2 mins
You aren't specifying an ID of a particular Payment Method to use when creating the Subscription, so we use the Customer's invoice_settings.default_payment_method, which it doesn't look like you're updating after processing the Setup Intent.
If you want to use the new Payment Method for the Subscription you're creating, you should provide that ID in the default_payment_method field when creating the Sub:
https://docs.stripe.com/api/subscriptions/create#create_subscription-default_payment_method
If you want to change the default for the Customer, you should update the Customer object and replace invoice_settings.default_payment_method with the new ID:
https://docs.stripe.com/api/customers/update#update_customer-invoice_settings-default_payment_method
I do that actually)
async setDefaultPaymentMethod(user: Express.User, paymentMethod: string) {
const customer = await this.userModel.findByPk(user.id);
return await this.stripe.customers.update(customer.paymentSystemId, {
invoice_settings: { default_payment_method: paymentMethod },
});
}
Ok., I detached and attached the card again.
transaction:
pi_3QWgFRLT0n97qDN20tupUIwO
I see that payment_method id is the same as in the card setup payment id
Hm, this may be expected, since the first Invoice for a Subscription sets setup_future_usage on the underlying intent, or at least it is here. Let me double check this with my teammates.
Ill paste some code of my flow here
Backend setup intent creation :
async createSetupIntent(user: User) {
try {
const intent = await this.stripe.setupIntents.create({
customer: user.paymentSystemId,
payment_method_types: ['card'],
});
return intent;
} catch (e) {
return new BadRequestException();
}
}
Frontend collecting card info and confirmation:
const sResult = await stripe?.confirmCardSetup(intent?.client_secret || '', {
payment_method: {
card: cardElement,
},
});
Backend subscription creation:
async payFromPreInvoice(
user: Express.User,
preInvoiceId: string,
paymentMethod: string,
) {
try {
const previewInvoice = await this.stripe.invoices.retrieve(preInvoiceId);
const customer =
typeof previewInvoice.customer === 'string'
? previewInvoice.customer
: previewInvoice.customer.id;
const subscription = await this.stripe.subscriptions.create({
customer,
items: previewInvoice.lines.data.map((item) => ({
price: item.price.id,
})),
payment_settings: {
payment_method_types: ['card'],
},
default_payment_method: paymentMethod,
expand: ['latest_invoice.payment_intent'],
});
return subscription;
} catch (e) {
console.error(e);
return new BadRequestException();
}
}
Is your plan always to immediately create a Subscription using the newly created Payment Method?
The business requires to be able to attach users card for future payments:
a) Subscriptions
b) One-time payments
But in terms of the subscriptions - no, there could be many cards for each customer, so the customer can choose what card he uses for the payment
Do you see the same behavior if you set off_session to true when creating the Subscription?
https://docs.stripe.com/api/subscriptions/create#create_subscription-off_session
I'm not sure this aligns with your code, since you set the default PM at the Customer object level, so that change will apply to all Subscriptions belonging to the Customer that don't have their own default PM specified at the Subscription object level.
Whoa. Lets go)
Seems like I missed smth in the docs. Now it process the payment just fine!
Thank u so much
What if potential user has a default method, but he can pick (just before he pays) what card to use? I mean can I specify that inside default_payment_method or I should use another property (object field) ?
I'd gladly set 10/10 for your help if I could ๐
Yup, you'd set the default_payment_method when creating the Subscription:
https://docs.stripe.com/api/subscriptions/create#create_subscription-default_payment_method
That will cause the Subscription to always use the Payment Method you specified in that field, rather than the one set at the Customer object level.
Ok, the very last question before I go away ๐
What if a customer has a runnin subscription and admin / customer deletes the payment method used in that subscription?
I think the Subscription's recurring payments will begin failing, but I'd recommend testing and confirming. You can use our Test Clocks to test that out relatively quickly:
https://docs.stripe.com/billing/testing/test-clocks
If the Customer object also has a default PM set via invoice_settings.default_payment_method, then we might fall back onto that one.
Cool.
Thank u very very much.
Best support I ever seen.
Bye ๐
One quick follow-up, I was still chatting with my teammates to understand why you were seeing that test card trigger 3DS.
It's because that testcard always requires authentication for on-session payments, which is why adding off_session to true avoided the behavior:
This card requires authentication for off-session payments unless you set it up for future payments. After you set it up, off-session payments no longer require authentication. However, on-session payments with this card always require authentication.
So I wouldn't recommend setting off_session to true all the time, only if your customer isn't actually on your site when you create the Subscription object for them.
The thing is: Im not using session creation.
I authenticate users using internal database, on the client side Im using custom stripe elements (card element) to setup the card.
I dont use checkouts
It's not about Checkout Sessions. "on session" payments indicate to us that your Customer is on your site, and available to complete additional authentication. "off session" payments indicate your customer isn't on your site/app, and isn't around to complete additional requirements, so we'll throw errors rather than asking for customer input.
Oh wow. So the issue is basically related to the specific cards only, ok.
Ill make future tests so I will know if off_session can cause an issue with different cards.
thanks