#nerder

1 messages ยท Page 1 of 1 (latest)

slim jackalBOT
vocal oasis
#

๐Ÿ‘‹ happy to help

zealous socket
#

Hello

#

so it seems to me that is not possible to setup a default payment method when the payment intent confirmed is coming from an invoice

#

i'll try to explain the code so that you can try to reproduce it

vocal oasis
#

are we talking about a one-off invoices or a subscription's invoice?

zealous socket
#

one-off invoices yes

#

with subscriptions everything work as expected

vocal oasis
#

what are you setting up as a default_payment_method to?

zealous socket
#

this is how i'm creating the invoice and finalize it

    let invoice = await this.stripe.invoices.create(
      {
        customer: customerId,
        application_fee_amount: fee.amount,
      },
      {
        stripeAccount: stripeAccountId,
      },
    );

    await this.stripe.invoiceItems.create(
      {
        invoice: invoice.id,
        customer: customerId,
        price: dropIn.code,
      },
      {
        stripeAccount: stripeAccountId,
      },
    );

    invoice = await this.stripe.invoices.finalizeInvoice(
      invoice.id,
      { expand: ['payment_intent'] },
      {
        stripeAccount: stripeAccountId,
      },
    );

    const clientSecret = (invoice.payment_intent as Stripe.PaymentIntent).client_secret;
vocal oasis
#

do you mean you want the PM to become the Customer's invoice_settings.default_payment_method?

zealous socket
#

so the payment intent is created here

#

the PI that comes our from finalizeInvoice has setup_future_usage set as null

#

than in my frontend, using the client_secret i go ahead and confirm that PI

#
    await _stripe.confirmPayment(
      clientSecret,
      PaymentMethodParams.card(
        paymentMethodData: PaymentMethodData(
          billingDetails: BillingDetails(
            email: customerEmail,
            name: customerName,
          ),
        ),
        options: PaymentMethodOptions(
          setupFutureUsage: PaymentIntentsFutureUsage.OffSession,
        ),
      ),
    );

NOTE: i'm using flutter_stripe to confirm the PI

#

now what I expected to happen (as for subscriptions) is that the payment method used to confirm this payment intent is attached to the customer and saved as default

#

as it happens automagically for subscriptions

vocal oasis
#

it actually doesn't really happen automatically for subscriptions either

#

what you need to do is listen to the invoice.paid event, and update the Customer to add the invoice_settings.default_payment_method property

zealous socket
#

ok, here comes the issue

vocal oasis
zealous socket
#

i was doing something similar last night

#

but listening to payment_intent.succeeded

#

and when trying to attach the payment method to a customer i get an error

vocal oasis
#

it is already attached to the Customer

#

you just need to update the invoice_settings.default_payment_method

zealous socket
#

nope is not, if I try to updete the customer it asks me to attach it first

#

and if I try to attach it I can't

#

this is the limitation/bug here

#

This PaymentMethod was previously used without being attached to a Customer or was detached from a Customer, and may not be used again.

vocal oasis
#

ok, let's try this

#

before sending the client_secret to the front-end

zealous socket
#

I like this!

#

good idea

#

let me try this one

#

very weird, doesn't find that PI but in the dashboard exists: No such payment_intent: 'pi_3M7drELAVB3C1lDI1V2mwTvT'

#

oh shit my bad sorry

#

forgot the connected account ID

#

sorry

vocal oasis
#

no worries

zealous socket
#

YES

#

you are the best!

#

it actually works

vocal oasis
#

and after that you'd have to listen invoice.paid

zealous socket
#

took me like 2 days to make it work

vocal oasis
#

It's always better to use invoice.paid than payment_intent.succeeded for invoices

zealous socket
#

yes yes, i'm using that infact

vocal oasis
#

since it will get you the Invoice instead of the PaymentIntent object in the webhook request body

zealous socket
#

i'll get that and set it up as default

#

now that the payment method is attached

#

sweet

#

actually I can even do that in payment_method.attached

vocal oasis
zealous socket
#

my understanding now is that using setup_future_usage: 'off_session' the payment method is attached to the customer but is not the default right?

#

so what i should do now is to listen for a webhook event either payment_intent.succeeded, invoice.paid or payment_method.attached to set it as a default on the customer

zealous socket
#

but anyway no worries, now I can do it by myself. I know how to handle it from here to fit in my usecase

vocal oasis
#

no the other ones ๐Ÿ˜›

zealous socket
#

I trust you on this one

#

eheh

vocal oasis
#

as you should have ๐Ÿ˜†

zealous socket
#

have a good rest of the day

#

by the way as a little feedback

vocal oasis
#

you too ๐Ÿ™‚ let me know if you need any more help

vocal oasis
zealous socket
#

the API for one-off invoices is a bit weird

vocal oasis
zealous socket
#

there are couple of strange things imo

vocal oasis
#

hit me up

zealous socket
#

all of them are on finalizeInvoice

#

for instance

    invoice = await this.stripe.invoices.finalizeInvoice(
      invoice.id,
      { expand: ['payment_intent'] },
      {
        stripeAccount: stripeAccountId,
      },
    );
#

initially I didn't know that you can add expand to it, because the doc let you think that finalize doesn't accept params

#

but only the ID

#

infact i was wronlgy expading the payment intent in the invoice.create method

#

then this little workaround of updating the PI i think it should be a parameters on finalizeInvoice, like "what do you want to do with the payment method when the invoice is paid"?

#

instead of default it to null and let me update it afterward as we did here

#

like if finalizeInvoice is creating the PI for me (on top of other things), than it should let me create it as a i like it

#

instead of forcing me to update it manually later, which feels like a workaround

vocal oasis
zealous socket
#

ok i see what you mean actually

#

i retreive it back from the update directly

#

btw maybe i'm doing it wrong or misunderstanding the API

#

anyway was a great learning

#

thank you so much for your help again

vocal oasis
#

sorry I haven't read all of your messages, I will comment one by one

zealous socket
#

take your time

vocal oasis
#

but just thought that this would make your integration faster

#

since we don't have to expand the PI which would take extra time

zealous socket
#

is good advice actually yes

vocal oasis
#

ok so the rest falls under the same statement as my previous one ๐Ÿ™‚