stripe / stripe-node

Node.js library for the Stripe API.
https://stripe.com
MIT License
3.9k stars 756 forks source link

NodeJs - InvoiceItemsUpdateParams - Missing "invoice" param as an option #2105

Closed Skippy565 closed 5 months ago

Skippy565 commented 5 months ago

Describe the bug

Documentation here (https://docs.stripe.com/api/invoiceitems) states that "You can add an invoice item to to an invoice by creating or updating it with an invoice parameter". The SDK currently has the parameter on the create parameters, and it works. The update SDK does not have 'invoice' on the InvoiceItemUpdateParams and overloading it to send anyway produces response : "Received unknown parameter: invoice. Did you mean invoiceitem?"

To Reproduce

  1. Create an invoiceitem not attached to an invoice
  2. Create an invoice and leave it open (don't finalize)
  3. Update invoiceItem from step 1 to include invoice id from step 2 as per documentation states and create call works
  4. Error

Expected behavior

As per documentation, the pending invoice item should be attached to the invoice (by id) that was passed along

Code snippets

//This doesn't work and it should if valid item id and valid invoice id
stripe.invoiceItems.update(item.id, { invoice: stripeInvoice.id })

OS

macOS

Node version

Node v16.14.2

Library version

stripe-node v8.218.0

API version

2022-08-1

Additional context

I recognize we are on an older version, but it also doesn't exist on the latest version

remi-stripe commented 5 months ago

@Skippy565 You can't set the invoice on Update InvoiceItem API. It's not a valid parameter here. I think that first sentence is incorrect and I'll get our docs fixed but the types are correct, invoice can only be set on creation

remi-stripe commented 5 months ago

I also don't see the sentence you quoted anywhere in our API Reference but if you have more details on where you see it exactly I can get it fixed!

Skippy565 commented 5 months ago

The sentence itself is part of the InvoiceItem description. Text is this "An invoice item is added to an invoice by creating or updating it with an invoice field" (screenshot attached too)

Screenshot 2024-06-10 at 8 30 05 PM

While I understand it isn't currently part of the stripe API, slightly different question of 'Why not?' I found it perfectly reasonable to be able to attach a pending (not on an invoice) invoice item to an invoice item by updating - This also somewhat reflects the UI's button to 'Invoice Now' which I assumed was just an invoice create followed by invoice item updates. MAYBE one restriction of not being able to set a different invoice id on an invoice item that already has one. Definitely not be able to change it if the invoice is billed/beyond or the invoice item in question is on an already billed/beyond state.

Asking the inverse question - Does that mean we should only create invoice items not attached to an invoice if we expect it to be part of the subscription cycled invoice?

remi-stripe commented 5 months ago

Thanks for the docs screenshot., totally missed it when I looked around earlier. I'll get that fixed.

reflects the UI's button to 'Invoice Now' which I assumed was just an invoice create followed by invoice item Not really! What happens in that case is that the Invoice is created with the pending_invoice_items_behavior parameter set to include in that case.

For many years until the API version 2022-08-01 the default behaviour on Invoice creation was to pull any pending InvoiceItems on it. Additionally, you could not create an Invoice without a pending InvoiceItem first, it would fail so developers always had to

  1. Create an InvoiceItem
  2. Create an Invoice (which pulls it in)
  3. Create extra InvoiceItems with invoice: 'in_123'

While I understand it isn't currently part of the stripe API, slightly different question of 'Why not?' The main reason is that it's confusing to have a parameter on update that can only be set once from null to in_1234. And we don't want to support "moving" an InvoiceItem from Invoice A to Invoice B. So it's simpler to just not allow updating it at all. With the current/new default behaviour since 2022, you now create an Invoice and then explicitly attach each new InvoiceItem to it on creation.

Does that mean we should only create invoice items not attached to an invoice if we expect it to be part of the subscription cycled invoice? I would say yes, unless you are on an old API version or want to use pending_invoice_items_behavior: 'include' but we discourage it now.