Sign in
An image of the Stripe logo
Create account
Sign in
Home
Payments
Business operations
Financial services
Developer tools
Security
All products
Home
Payments
Business operations
Home
Payments
Business operations
Financial services
Developer tools
Support
Overview
Overview
How subscriptions work
How to model subscriptions
Get started
Quickstart
Design an integration
Build a subscriptions integration
Integrate the customer portal
Migrate subscriptions to Stripe
Billing resources
Coupons
Customers
Subscriptions
Subscription invoices
Manage subscriptions
Change subscriptions
Usage-based billing
Use trial periods
Set payment methods
Subscriptions with multiple products
Set subscription quantities
Subscription webhooks
Schedule subscriptions
Tax
Integrate with Salesforce
Manage recurring revenue
Revenue recognition
Revenue recovery
Subscription metrics
Testing
Test your integration
Test clocks
Metered billing with Elements
Fixed-price billing with Elements
Per-seat billing with Elements
Migrate to Prices
Strong Customer Authentication (SCA)
Invoices API updates
Improved tax support
Testing
No-code options
Billing
·
HomePaymentsSubscriptions

Invoices API updates

Stripe has recently improved the clarity and expressiveness of the statuses that an invoice can have.

Backward compatibility

All changes outlined in this document are backward-compatible. This means that you are not required to update your integration.

However, if you choose to take advantage of the new functionality available, this reference guide helps you understand what has changed.

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 has status='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 the finalized_at field is set. Stripe sends an invoice.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 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 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 an invoice.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', setting finalized_at, and sending an invoice.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 to status='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 equivalent status='paid' instead.
  • For requests made with the 2018-11-08 version and later, the forgiven=true boolean is removed. Check for the equivalent status='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 a draft invoice is deleted, either through the API or in the Dashboard.
  • invoice.paid or invoice.payment_failed: Sent when an attempt to pay an invoice succeeds or fails.
Was this page helpful?
Questions? Contact us.
View developer tutorials on YouTube.
Check out our product changelog.
Powered by Markdoc
You can unsubscribe at any time. Read our privacy policy.
On this page
Sample invoice timelines
New API methods
Upgrade checklist
Stripe Shell
Test mode
▗▄ ▄▟█ █▀▀ ▗▟████▙▖ ██████ ███▗▟█ ███ ███▗▟██▙▖ ▗▟█████▙▖ ███▖ ▀▀ ███ ███▀▀▀ ███ ███▀ ███ ███ ███ ▝▜████▙▖ ███ ███ ███ ███ ███ █████████ ▄▄ ▝███ ███ ▄ ███ ███ ███▄ ███ ███ ▄▄ ▝▜████▛▘ ▝▜███▛ ███ ███ ███▝▜██▛▘ ▝▜█████▛▘ ███ ▀▘
Welcome to the Stripe Shell! Stripe Shell is a browser-based shell with the Stripe CLI pre-installed. Login to Stripe docs and press Control + Backtick on your keyboard to start managing your Stripe resources in test mode. - View supported commands: - Find webhook events: - Listen for webhook events: - Call Stripe APIs: stripe [api resource] [operation] (e.g. )
The Stripe Shell is best experienced on desktop.
$