Invoices API updates
In previous versions of the Stripe API, Invoices didn’t have statuses. Instead, there was a series of booleans, like closed
, paid
, and forgiven
.
We’ve introduced statuses on invoices to better correlate Stripe invoices with finance workflows. Now, all Invoice objects have a status
property. The status
field can have the values draft
, open
, paid
, void
, and uncollectible
.
- The
draft
status indicates that an invoice is mutable. - The
open
status indicates that the invoice has been finalized, is no longer mutable, and is ready for payment. - The
paid
status indicates that the invoice has been paid in full. - The
void
status indicates that the invoice is no longer valid. - The
uncollectible
status indicates that the invoice is very unlikely to be paid, and could be considered a bad debt.
For more details on these statuses, and the transitions between them, see the invoicing guide.
Sample invoice timelines
This section presents sample timelines for both one-off and subscription invoices, showing the statuses that both types of invoices can proceed through.
One-off invoice example
Here is an example timeline that a one-off invoice could go through. This sequence of events presents no changes from the pre-existing invoicing timeline, except that Stripe now exposes a status
field to more clearly represent an invoice’s status.
- Nov 16: Through the API, you might create an invoice that represents shipping 12 widgets to a customer. Stripe sends an
invoice.created
webhook, notifying you of the recently-created invoice. Looking at the API, you see that the invoice hasstatus='draft'
. - Nov 26: After reviewing the invoice, an accountant finalizes the invoice using the Stripe Dashboard. While the invoice is being finalized, its status is updated to
status='open'
and thefinalized_at
field is set. Stripe sends aninvoice.finalized
webhook, notifying you that the invoice was finalized. - Nov 26: Seconds later, Stripe emails the invoice, and begins retries. To help your CRM system keep track of when invoices are sent, Stripe sends an
invoice.sent
webhook each time it’s sent. - Dec 01: Your customer clicks the link in the email and pays the invoice using a Hosted Invoice Payment page. Unfortunately, they pay with an expired credit card. Their payment fails, and Stripe sends the
invoice.payment_failed
webhook notifying you of this failure. - Dec 03: With an updated credit card, the customer tries again. This time, the payment succeeds! Stripe sends the
invoice.paid
webhook notifying you of this success, saves the card, and sets the invoice tostatus='paid'
. If configured, Stripe also immediately emails your customer a receipt showing that the invoice was paid.
Subscription invoice example
Here is an example timeline for an invoice generated by a subscription.
- Nov 13: Through the dashboard, you create a recurring subscription for a customer, configured for charging automatically. The subscription has a 20 day trial, so the first invoice will be in 20 days (Dec 03). Stripe sends a
customer.subscription.created
webhook.
- Nov 30: Three days before the trial ends, Stripe sends a
customer.subscription.trial_will_end
webhook. Three days before charging the credit card would be a good time to send a trial reminder email.
- Dec 03: At the end of the trial, a
status='draft'
invoice is created. Stripe sends aninvoice.created
webhook, notifying you of the recently-created invoice. - Dec 03: Approximately one hour later, the invoice is automatically finalized. This entails updating the
status
as'open'
, settingfinalized_at
, and sending aninvoice.finalized
webhook. - Dec 03: Soon after, Stripe attempts to charge the customer’s card on file. The customer’s payment succeeds. Stripe sends the
invoice.paid
webhook to notify you of this success, and sets the invoice tostatus='paid'
.
New API methods
Stripe has released a suite of new APIs for managing the status of an invoice. The new options, detailed in the upgrade checklist below, are:
- Send an invoice: Stripe automatically sends and re-sends invoices through email. This endpoint, available in the Stripe API, allows you to send the invoice to your customer whenever you want.
- Finalize an invoice: In the example above, the accountant finalized the invoice using the Stripe Dashboard. This functionality is also available in the Stripe API.
- Void an invoice: Once an invoice has been finalized, it can’t be deleted. Voiding is used to indicate that the invoice was issued in error. You could consider voiding an invoice with an error in your company’s name, and then creating an entirely new invoice to replace it.
- Delete a draft invoice: This action is applicable only to draft invoices. Deleted invoices aren’t visible through your Dashboard or the API. They cannot be un-deleted.
- Mark an invoice uncollectible: Your accounting department might want to maintain a register of “doubtful debts” - that is, a list of invoices that are deemed to be uncollectible. You can use this API to tag applicable invoices.
Upgrade checklist
The following sections list functional changes in the Invoice
object, and in invoice-related webhooks.
Invoice
object
Stripe has added several fields to the Invoice
object to help users better understand its status and behavior.
finalized_at
The new finalized_at
field indicates the time at which the invoice was finalized. This is available for requests made on all API versions.
status
The new status
field is available for requests made on all API versions. This replaces many booleans on the invoice, such as:
- For requests made with the 2018-11-08 version and later, the
paid=true
boolean is removed. Check for the equivalentstatus='paid'
instead. - For requests made with the 2018-11-08 version and later, the
forgiven=true
boolean is removed. Check for the equivalentstatus='uncollectible'
instead.
auto_advance
The new auto_advance
field indicates whether automatic collection is active. For the 'draft'
and 'open'
statuses, the auto_advance
field can be updated. Otherwise, auto_advance
will always be false
.
When auto_advance=false
, Stripe will not:
- Automatically issue draft invoices
- Automatically send the first (or reminder) emails for
collection_method='send_invoice'
invoices - Automatically attempt the first (or retry) payments for
collection_method='charge_automatically'
invoices
Even with auto_advance=false
, Stripe automatically reconciles inbound credit transfers. If a transfer references an invoice, the credit transfer is reconciled to that invoice. If an invoice isn’t provided, Stripe searches for unpaid invoices and tries to pay them.
For invoices with the statuses 'uncollectible'
, 'void'
, and 'paid'
, the auto_advance
field is always false
.
On versions prior to 2018-11-08, the closed
field is still present, and equal to the inverse of auto_advance
. For example, auto_advance=true
is equivalent to closed=false
(and vice versa). Invoices created using prior API versions will continue to default to closed=false
.
Webhooks
With this update, we’ve introduced three new webhooks:
invoice.finalized
: Sent when an invoice is finalized.invoice.voided
: Sent when an invoice is voided.invoice.marked_uncollectible
: Sent when an invoice is marked uncollectible.
The existing invoice.created
webhook is sent upon creating an invoice. If your webhook handler needs to differentiate between one-off invoices and invoices generated by a subscription, check for the existence of the invoice.subscription
property in the webhook body.
These pre-existing webhooks are unchanged:
invoice.sent
: Sent when an invoice is emailed to a user, either automatically, through the API, or in the Dashboard.invoice.deleted
: Sent when adraft
invoice is deleted, either through the API or in the Dashboard.invoice.paid
orinvoice.payment_failed
: Sent when an attempt to pay an invoice succeeds or fails.