In previous versions of the Stripe API, Invoices did not have statuses. Instead, there was a series of booleans, like
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
draftstatus indicates that an invoice is mutable.
openstatus indicates that the invoice has been finalized, is no longer mutable, and is ready for payment.
paidstatus indicates that the invoice has been paid in full.
voidstatus indicates that the invoice is no longer valid.
uncollectiblestatus 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, please see the invoicing workflow guide.
Sample invoice timelines
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.createdwebhook, notifying you of the recently-created invoice. Looking at the API, you see that the invoice has
- Nov 26: After reviewing the invoice, an accountant finalizes the invoice via the Stripe Dashboard. While the invoice is being finalized, its status is updated to
finalized_atfield is set. Stripe sends an
invoice.finalizedwebhook, notifying you that the invoice was finalized.
- Nov 26: Seconds later, Stripe sends the invoice via email, and begins retries. To help your CRM system keep track of when invoices are sent, Stripe sends an
invoice.sentwebhook 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_failedwebhook 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.paidwebhook notifying you of this success, saves the card, and sets the invoice to
status='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
- Nov 30: Three days before the trial ends, Stripe sends a
customer.subscription.trial_will_endwebhook. 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 an
invoice.createdwebhook, notifying you of the recently-created invoice.
- Dec 03: Approximately one hour later, the invoice is automatically finalized. This entails updating the
finalized_at, and sending an
- Dec 03: Soon after, Stripe attempts to charge the customer’s card on file. The customer’s payment succeeds. Stripe sends the
invoice.paidwebhook to notify you of this success, and sets the invoice to
New API methods
- Send an invoice: Stripe automatically sends and re-sends invoices via email. This endpoint, available via 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 via 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.
The following sections list functional changes in the
Invoice object, and in invoice-related webhooks.
Stripe has added several fields to the
Invoice object to help users better understand its status and behavior.
finalized_at field indicates the time at which the invoice was finalized. This is available for requests made on all API versions.
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=trueboolean is removed. Check for the equivalent
- For requests made with the 2018-11-08 version and later, the
forgiven=trueboolean is removed. Check for the equivalent
auto_advance field indicates whether automatic collection is active. For the
'open' statuses, the
auto_advance field can be updated. Otherwise,
auto_advance will always be
auto_advance=false, Stripe will not:
- Automatically issue draft invoices
- Automatically send the first (or reminder) emails for
- Automatically attempt the first (or retry) payments for
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
auto_advance field is always
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
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.
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 a
draftinvoice is deleted, either through the API or in the Dashboard.
invoice.payment_failed: Sent when an attempt to pay an invoice succeeds or fails.