#saiksyapo_best-practices
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/1281237619669340262
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Hello, I am migrating away from deprecated createToken/source api and need help to understand what's the best practice / new standard flow (for custom funnel)
Context
Here is what I tried for my flow:
- create customer
- create setupIntent
- confirm setupIntent on client side
- attach the payment method on the customer level
- create subscription
I faced a problem with 3D secure.
When using this card Always authenticate 4000002760003184 (https://docs.stripe.com/testing#authentication-and-setup)
Customer have two 3ds challenge, one when confirming the setupIntent, and a second one when starting the subscription. It wasn't the case with the token API.
I then found this post https://stackoverflow.com/questions/73219803/stripe-subscription-with-setupintent-the-3ds-is-asked-twice
Which recommend creating an incomplete subscription and then confirm the payment something like
- create customer
- create incomplete subscription
- confirm paymentIntent
But then I have no way to attach the payment method used at the customer level (invoice_settings.default_payment_method) as there is no such SubscriptionCreateParams.PaymentSettings.SaveDefaultPaymentMethod.ON_CUSTOMER (only on ON_SUBSCRIPTION)
Hello
So yeah you don't want to create a SetupIntent at all here
When you create the Subscription that will create an underlying SetupIntent (if you use a trial) or PaymentIntent (if the first Invoice is not $0)
You then use that SetupIntent or PaymentIntent to collect the PaymentMethod
When you create the Subscription you also want to pass payment_settings.save_default_payment_method: https://docs.stripe.com/api/subscriptions/create#create_subscription-payment_settings-save_default_payment_method
That will set the PaymentMethod as the default for future payments upon successful confirmation
It only save the paymentMethod at the subscription level, but I want it at the customer level
And I can't attach it myself after the confirmPayment call, because it's state that it was already used without being already attached to my customer ๐ฌ
That's not true
If you create a Subscription and use its underlying SetupIntent/PaymentIntent with a charge_automatically Subscription then the PaymentMethod will be attached to the Customer and you can update it to the invoice_settings.default_payment_method after confirmation.
Ok, interresting, maybe I was using it wrong, let me grab some code !
I'd recommend trying it again and providing me with a Subscription ID that you tested with
SubscriptionCreateParams.PaymentSettings paymentSettings =
SubscriptionCreateParams.PaymentSettings
.builder()
.addPaymentMethodType(PaymentMethodType.CARD)
.addPaymentMethodType(PaymentMethodType.SEPA_DEBIT)
.setSaveDefaultPaymentMethod(SaveDefaultPaymentMethod.ON_SUBSCRIPTION)
.build();
SubscriptionCreateParams params = SubscriptionCreateParams.builder()
.setCustomer(stripeCustomerId)
[...]
.addExpand("latest_invoice.payment_intent")
.setProrationBehavior(
backdateStartDateSeconds.isPresent() ? SubscriptionCreateParams.ProrationBehavior.CREATE_PRORATIONS
: SubscriptionCreateParams.ProrationBehavior.NONE
)
.setPaymentSettings(paymentSettings)
.setPaymentBehavior(SubscriptionCreateParams.PaymentBehavior.DEFAULT_INCOMPLETE)
.build();
I then forward stripeSubscription.getLatestInvoiceObject().getPaymentIntentObject().getClientSecret() to the client
Confirm it using
const { paymentIntent, error: stripeError } = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: cardElement
}
})
And then when I try to attach paymentIntent.payment_method.toString() it's here where it fails
I'll look the doc for what you means by charge_automatically
charge_automatically is the default for collection_method: https://docs.stripe.com/api/subscriptions/create#create_subscription-collection_method
Which you don't look to be setting so yeah you are using charge_automatically
Please test again and then provide me the Subscription ID if you see an error trying to set the collected PaymentMethod for the Customer as their default
Even better if you can just provide the request ID of the error itself
Will do thanks for your time
To be clear, you don't need to attach the PaymentMethod in a separate request
It is attached upon confirmation
So that is probably your issue
The test customer id is cus_QnGLjO8EwPcRPA
We can ee that the PaymentMethod is not set by default on their own
Correct
You have to do that in a separate request
Where you update the Customer
You update the invoice_settings.default_payment_method: https://docs.stripe.com/api/customers/update#update_customer-invoice_settings-default_payment_method
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
Yeah that's what I was trying to do, but maybe I was doing something off
I'd recommend trying again!
As I have a generic attachDefault that clear all current paymentMethod
And since I detach the one the subscription just created, I guess it's why I can't reattach it after the confirm
Will try to promote it as default without cleaning, but I'm sure it's the problem.
Oh yep that would be an issue
Another question, during a Upsell workflow then, (when the subscription is already active and I have a default payment method). How to recollect payment details (if the customer provide another card instead of billing their default)
Should I detach the default, and update the subscription in a similar manner (update, not create params), setting it back as incomplete
Or should I could I use setupIntent and off-session subscription update
Currently, I can just set the new token I have on the customer and update the subscription and it will bill the new card
If the Subscription is already active and the Customer wants to pay for an update with a separate card then you create a SetupIntent to collect the new card and then update the default and then update the Subscription.
And will I have the double 3DS secure check both during the setup intent process and the charge on the subscription update ?
It is possible that happens, but unlikely. You don't want to remove the default and then update the Subscription as if there is no PaymentMethod attached it won't go through your retries and could lead to the Subscription being canceled.