#nerder

1 messages ยท Page 1 of 1 (latest)

plucky frigateBOT
vestal belfry
#

hi! did you finalize the invoice? that's what creates the PI

neat apex
#

hey no, i was under the impression that was not needed

#

from a previous conversation

#
    await this.stripe.invoiceItems.create(
      {
        customer: customerId,
        price: priceId,
      },
      {
        stripeAccount: stripeAccountId,
      },
    );

    const invoice = await this.stripe.invoices.create(
      {
        customer: customerId,
        application_fee_amount: fee.amount,
        expand: ['payment_intent'],
      },
      {
        stripeAccount: stripeAccountId,
      },
    );

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

this is my current implementation

vestal belfry
#

yeah that's wrong since you have to finalize the invoice after creating it.

neat apex
#

i create the invoiceItems

#

ok great

#

let me try real quick

#

btw I have another small question related to fees since we are here

#

why application_fee_percent is not exposed here?

#

as in the subscription creation API?

vestal belfry
#

it just isn't, you have to use application_fee_amount instead

neat apex
#

yeah ๐Ÿ˜ฆ

vestal belfry
#

there's no good reason for it beyond a lack of prioritisation/design focus. For one time payments, we I suppose expect you to know the amount of the payment upfront and pass an appropriate amount. Made more sense years ago when stuff like automatic tax calculation and things didn't dynamically change the amount

neat apex
#

i can't imagine a technical reason why not to, but for sure there is something I don't know here

#

That's a great explaination @vestal belfry

#

at the moment since i'm supporting both recurring and one-off prices i calculate the fee my self

#

as a percentage when is for creating a sub, and as an amount when is for creating a one-off product to buy

#

i imagine that there are some strange things with prorate and all that things which is why subscription only expose application_fee_percent

#

would be very convinient tho to have application_fee_percent in the invoice API, and calculate that on your side ๐Ÿ˜‰ as a feedback for the future OFC

vestal belfry
#

yep I agree and that's been feedback for many years unfortunately

neat apex
#

Btw coming back from the original issue, i've tried to finalize

#

but still i don't receive the payment_intent

#
    await this.stripe.invoiceItems.create(
      {
        customer: customerId,
        price: priceId,
      },
      {
        stripeAccount: stripeAccountId,
      },
    );

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

    invoice = await this.stripe.invoices.finalizeInvoice(invoice.id, {
      stripeAccount: stripeAccountId,
    });

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

i'm doing this now

vestal belfry
#

the cast won't work because you didn't expand it on that call, so payment_intent is just an ID pi_xxx

neat apex
#

I should expand it in finalizeInvoice?

vestal belfry
#

you can do

      stripeAccount: stripeAccountId,
    });

I believe

#

this should all be in the docs but it's not unfortunately, the docs for one off invoices are quite bad

neat apex
#

umm nope actually, or at least TS complains about it

#

it says that finalizeInvoice only accept a string as ID

vestal belfry
#

well invoice = await stripe.invoices.finalizeInvoice(invoice.id, {expand:["payment_intent"]}); works at least, that's what I use in my own app

#

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

#

it's probably htat for Connect

neat apex
#

ok let me try that one

#

ok nice, that one yes

#

didn't know there was an actual params option in finalizeInvoice

#

but as you said it, the doc might be old

vestal belfry
#

in general all functions in the SDK work that way where it's stripe.foo.action(params, requestOptions)

#

some of them that require an ID though will be like stripe.foo.action(id, params, requestOptions)

neat apex
#

clear

#

still no luck, but might be something else

#

know the code looks good

#
    await this.stripe.invoiceItems.create(
      {
        customer: customerId,
        price: priceId,
      },
      {
        stripeAccount: stripeAccountId,
      },
    );

    let invoice = await this.stripe.invoices.create(
      {
        customer: customerId,
        application_fee_amount: fee.amount,
      },
      {
        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;
#

seems to be related with the invoiceItems now

#

becuse is creating the invoice properly, and finalize it

#

but is an invoice for 0$

#

so of course no payment_intent only setup_intent

vestal belfry
neat apex
#

yes yes, i knew that. But this wasn't the intended behaviour here is just something wrong with invoiceItems not setting the price properly

#

now i try to change the order and pass the invoice ID explicitly

#

like this:

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

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

But i don't want to waste your time anymore

#

i think i can go from here

#

thank you som much ๐Ÿ™‚

vestal belfry
#

yeah on the latest API versions you should create the invoice first, and then the items

#

or on older versions, use pending_invoice_item_behavior: "exclude" so you can opt into that behaviour, creating the items first and then the invoice is a pain and unreliable

neat apex
#

actually i prefer the other way, to be explicit on to which invoice i'm adding it instead of rely on that automagic default of "the next draft invoice"

vestal belfry
#

that's what I mean yes

neat apex
#

it worked btw ๐Ÿ˜‰

vestal belfry
#

great

neat apex
#

thank you so much for your help and for the insights

#

great chat