#sylar_api

1 messages ยท Page 1 of 1 (latest)

jade kayakBOT
#

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

tawny leafBOT
tidal stream
exotic kayak
#

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

tidal stream
#

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.

exotic kayak
#

this one: seti_1QWfqULT0n97qDN270KLVkYj ?

tidal stream
#

No, I'm looking for the subsequent payment that you said still required 3DS after you confirmed that Setup Intent.

exotic kayak
#
      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

exotic kayak
#

Here is the payment id:
pi_3QWetKLT0n97qDN20Aq4avCz

tidal stream
#

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.

exotic kayak
#

Ok. Gimme just a sec, I will attach a new card and pay for test subscription -> then ill provide the info. 2 mins

tidal stream
#

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

exotic kayak
#

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

tidal stream
#

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.

exotic kayak
#

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();
    }
  }
tidal stream
#

Is your plan always to immediately create a Subscription using the newly created Payment Method?

exotic kayak
#

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

tidal stream
tidal stream
exotic kayak
exotic kayak
#

I'd gladly set 10/10 for your help if I could ๐Ÿ˜„

tidal stream
exotic kayak
#

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?

tidal stream
#

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.

exotic kayak
#

Cool.
Thank u very very much.

Best support I ever seen.
Bye ๐Ÿ™‚

tidal stream
#

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.

exotic kayak
#

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

tidal stream
#

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.

exotic kayak
#

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