Invoicing Workflow

    Understand Stripe Billing’s invoicing workflow

    Invoices move through a series of statuses from creation to getting paid. Stripe calls this process our automatic collection workflow.

    You can configure whether an invoice should go through automatic collection by toggling the auto_advance property on the invoice. When automatic collection is turned off, you or your integration will be responsible for transitioning the invoice between statuses.

    Overview

    Invoices can take on the following statuses:

    Status Description Possible Actions
    draft Starting status for all invoices; at this point, the invoice can still be edited. Finalize it to open, or delete it.
    open The invoice has been finalized, and is now awaiting payment from the customer. It can no longer be edited. Send, void, mark uncollectible, or pay the invoice.
    paid This invoice was paid.
    void This invoice was a mistake, and should be canceled.
    uncollectible It’s unlikely that this invoice will be paid, and it should be treated as bad debt in reports. Void or pay the invoice.

    These statuses allow for invoices to be drafted and revised before finalizing them, sending them to customers, and attempting payment.

    Voiding invoices

    To cancel, delete, or effectively undo an invoice that has already been finalized, you can void it. Voiding is similar to deleting an invoice, but maintains a record of when it was created, finalized, then voided. Invoices with a void status are not payable. Voiding an invoice effectively zeros its amounts in any reports, ensuring an accounting papertrail.

    Uncollectible invoices

    Sometimes customers cannot pay your invoice—for example, perhaps they declare bankruptcy and cannot pay their debts. Uncollectible invoices can be treated as “bad debt” in your accounting.

    Finally, the paid status is simply used for invoices that are paid. Invoices are automatically marked as paid when payments are processed through Stripe, though you can manually mark invoices as paid to reflect out of band payments.

    Workflow transitions

    In this section we’ll cover the transitions that invoices can make between statuses.

    Invoice status transition endpoints and webhooks

    The following table outlines the status transitions and their endpoints—along with the webhooks emitted by the endpoint, and the resulting status for each.

    Status API Endpoint Emitted Webhook End Status
    draft DELETE /v1/invoices/:id invoice.deleted (Deleted)
    draft POST /v1/:id/finalize invoice.finalized open
    open POST /v1/:id/pay invoice.payment_succeeded paid
    open POST /v1/:id/pay invoice.payment_failed open
    open POST /v1/:id/send invoice.sent open
    open POST /v1/:id/void invoice.voided void
    open POST /v1/:id/mark_uncollectible invoice.marked_uncollectible uncollectible
    uncollectible POST /v1/:id/pay invoice.payment_succeeded paid
    uncollectible POST /v1/:id/pay invoice.payment_failed uncollectible
    uncollectible POST /v1/:id/void invoice.voided void

    Finalizing draft invoices

    Invoices are initially created with status=draft, and is the only state in which an invoice can be edited.

    Once an invoice is ready to be paid, it should be finalized. Doing so will set status=open on the invoice.

    Finalize invoices programmatically

    You can promptly finalize a one-off or subscription invoice via the API:

    curl https://api.stripe.com/v1/invoices/:id/finalize \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -X POST
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    invoice = Stripe::Invoice.finalize_invoice('in_18jwqyLlRB0eXbMtrUQ97YBw')
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    invoice = stripe.Invoice.finalize_invoice('in_18jwqyLlRB0eXbMtrUQ97YBw')
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    $invoice = \Stripe\Invoice::retrieve('in_18jwqyLlRB0eXbMtrUQ97YBw');
    $invoice->finalizeInvoice();
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";
    
    Invoice invoice = Invoice.retrieve("in_18jwqyLlRB0eXbMtrUQ97YBw");
    invoice.finalizeInvoice();
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    stripe.invoices.finalizeInvoice('in_18jwqyLlRB0eXbMtrUQ97YBw', function(err, invoice) {
      // asynchronously called
    });
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    
    params := &stripe.InvoiceFinalizeParams{}
    i, err := invoice.FinalizeInvoice("in_18jwqyLlRB0eXbMtrUQ97YBw", params)
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    StripeConfiguration.SetApiKey("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    var options = new InvoiceFinalizeOptions{};
    var service = new InvoiceService();
    var invoice = service.FinalizeInvoice("in_18jwqyLlRB0eXbMtrUQ97YBw", options);
    

    If you have configured webhook endpoints, you will receive a invoice.finalized event when an invoice is finalized.

    Upon finalization

    Finalizing an invoice does the following things:

    • It allows the invoice to be paid
    • It ensures that an invoice number is present
    • It makes certain properties immutable on the invoice
    • It creates an incomplete payment intent for the invoice
    • It generates a unique URL where someone can pay the invoice, as well as a link to download a PDF of the invoice.

    Restrictions on finalized invoices

    After an invoice is finalized, certain fields pertaining to the amount and customer being invoiced cannot be changed. This is to satisfy the common tax-compliance requirement that finalized invoices be retained-—as they were finalized—-for a legally required minimum time period.

    If updates to the invoice amount are required after finalization, this can be achieved through credit notes. Credit notes allow you to modify the invoice amount by specifying an adjustment in money owed by the customer. Credit notes can be issued for any invoice in an open or paid status.

    Upon finalization, the following customer fields are copied to the invoice and made immutable:

    If you want to change a customer related property on an invoice, void the current invoice, ensure the customer information is updated correctly, and issue a new invoice.

    Limits on editing finalized invoices

    As outlined above, finalized invoices are only adjustable by issuing credit notes, which provide an accounting paper trail of changes to the invoice amount. In some jurisdictions, editing fields that modify an invoice’s total amount due could render the invoice invalid. These are typically fields associated with your account, customer, line items, or taxes.

    Emails after finalization

    By default, Stripe automatically sends invoices when billing=send_invoice is set.

    Stripe does not email invoices in the following cases:

    You can manually cause invoices to be sent by using the dashboard or using the send invoice method.

    Deleting draft invoices

    You can delete a draft invoice at any time.

    curl https://api.stripe.com/v1/invoices/:id \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -X DELETE
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    Stripe::Invoice.delete('in_18jwqyLlRB0eXbMtrUQ97YBw')
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    stripe.Invoice.delete('in_18jwqyLlRB0eXbMtrUQ97YBw')
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    $invoice = \Stripe\Invoice::retrieve('in_18jwqyLlRB0eXbMtrUQ97YBw');
    $invoice->delete();
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";
    
    Invoice invoice = Invoice.retrieve("in_18jwqyLlRB0eXbMtrUQ97YBw");
    invoice.delete();
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    stripe.invoices.del('in_18jwqyLlRB0eXbMtrUQ97YBw');
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    
    params := &stripe.InvoiceParams{}
    i, err := invoice.Del("in_18jwqyLlRB0eXbMtrUQ97YBw", params)
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    StripeConfiguration.SetApiKey("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    var service = new InvoiceService();
    var invoice = service.Delete("in_18jwqyLlRB0eXbMtrUQ97YBw");
    

    If you have configured webhook endpoints, you will receive a invoice.deleted event when the invoice is deleted.

    Marking as uncollectible

    Accounts Receivable departments sometimes have customers who cannot pay their outstanding bills. For example, assume that you supply $1,000 worth of services to your customer, but the customer informs you that they have since declared bankruptcy, and (even after liquidating assets) will not be able to pay the outstanding invoice balance.

    With this information, you decide to write off the invoice as unlikely to be paid. You could then update the invoice’s status to be uncollectible. This allows you to track the amount owed for reporting purposes, as part of your bad-debt accounting process.

    You can mark an invoice as uncollectible either through the Dashboard (from the invoice’s detail page), or with an API integration, as shown in the following example:

    curl https://api.stripe.com/v1/invoices/:id/mark_uncollectible \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -X POST
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    invoice = Stripe::Invoice.mark_uncollectible('in_18jwqyLlRB0eXbMtrUQ97YBw')
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    invoice = stripe.Invoice.mark_uncollectible('in_18jwqyLlRB0eXbMtrUQ97YBw')
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    $invoice = \Stripe\Invoice::retrieve('in_18jwqyLlRB0eXbMtrUQ97YBw');
    $invoice->markUncollectible();
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";
    
    Invoice invoice = Invoice.retrieve("in_18jwqyLlRB0eXbMtrUQ97YBw");
    invoice.markUncollectible();
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    stripe.invoices.markUncollectible('in_18jwqyLlRB0eXbMtrUQ97YBw', function(err, invoice) {
      // asynchronously called
    });
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    
    params := &stripe.InvoiceMarkUncollectibleParams{}
    i, err := invoice.MarkUncollectible("in_18jwqyLlRB0eXbMtrUQ97YBw", params)
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    StripeConfiguration.SetApiKey("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    var options = new InvoiceMarkUncollectibleOptions{};
    var service = new InvoiceService();
    var invoice = service.MarkUncollectible("in_18jwqyLlRB0eXbMtrUQ97YBw", options);
    

    If you have configured webhook endpoints, you will receive a invoice.marked_uncollectible event when an invoice moves into the uncollectible status.

    Voiding invoices

    Voiding an invoice is conceptually similar to deleting it. However, voiding an invoice maintains a paper trail, allowing the invoice to be looked up by number. When voided, invoices are treated as zero-value for reporting purposes. The Hosted Invoice Page will still be accessible, and display a message indicating the invoice has been voided. Void invoices are not payable.

    You can void invoices only when they are in either the open or the uncollectible status. You can do so either through the Dashboard (from the invoice’s detail page), or with an API integration, as shown in the following example:

    curl https://api.stripe.com/v1/invoices/:id/void \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -X POST
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    invoice = Stripe::Invoice.void_invoice('in_18jwqyLlRB0eXbMtrUQ97YBw')
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    invoice = stripe.Invoice.void_invoice('in_18jwqyLlRB0eXbMtrUQ97YBw')
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    $invoice = \Stripe\Invoice::retrieve('in_18jwqyLlRB0eXbMtrUQ97YBw');
    $invoice->voidInvoice();
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";
    
    Invoice invoice = Invoice.retrieve("in_18jwqyLlRB0eXbMtrUQ97YBw");
    invoice.voidInvoice();
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    stripe.invoices.voidInvoice('in_18jwqyLlRB0eXbMtrUQ97YBw', function(err, invoice) {
      // asynchronously called
    });
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    
    params := &stripe.InvoiceVoidParams{}
    i, err := invoice.VoidInvoice("in_18jwqyLlRB0eXbMtrUQ97YBw", params)
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    StripeConfiguration.SetApiKey("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    var options = new InvoiceVoidOptions{};
    var service = new InvoiceService();
    var invoice = service.VoidInvoice("in_18jwqyLlRB0eXbMtrUQ97YBw", options);
    

    If you have configured webhook endpoints, you will receive a invoice.voided event when an invoice moves into the void status.

    When payment occurs through Stripe for an invoice, the invoice is moved into the paid status. This status is terminal, which means that paid invoices can never take on another status. For invoices paid through Stripe, you can find the payment receipt on the invoice’s Charge.

    To attempt a payment through the Dashboard, open the invoice’s detail page and click the Charge customer button.

    If an invoice was paid out of band (outside Stripe), you can manually mark the invoice as paid in the Dashboard. From the invoice’s detail page, use the context menu to select Change invoice status. In the resulting modal, select the Paid option.

    If you are using the API, the following example shows how to transition an invoice into a paid state using the Pay an invoice API endpoint.

    If you have configured webhook endpoints, you will receive a invoice.payment_failed or invoice.payment_succeeded event, depending on the outcome of the payment attempt.

    curl https://api.stripe.com/v1/invoices/:id/pay \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -X POST
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    invoice = Stripe::Invoice.pay('in_18jwqyLlRB0eXbMtrUQ97YBw')
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    invoice = stripe.Invoice.pay('in_18jwqyLlRB0eXbMtrUQ97YBw')
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    $invoice = \Stripe\Invoice::retrieve('in_18jwqyLlRB0eXbMtrUQ97YBw');
    $invoice->pay();
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";
    
    Invoice invoice = Invoice.retrieve("in_18jwqyLlRB0eXbMtrUQ97YBw");
    invoice.pay();
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    stripe.invoices.pay('in_18jwqyLlRB0eXbMtrUQ97YBw', function(err, invoice) {
      // asynchronously called
    });
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    
    params := &stripe.InvoicePayParams{}
    i, err := invoice.Pay("in_18jwqyLlRB0eXbMtrUQ97YBw", params)
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    StripeConfiguration.SetApiKey("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    var options = new InvoicePayOptions{};
    var service = new InvoiceService();
    var invoice = service.Pay("in_18jwqyLlRB0eXbMtrUQ97YBw", options);
    

    Asynchronous payments

    Some payment methods require customer interaction to complete the payment – for example, a European card or bank transfer which may require Strong Customer Authentication (SCA).

    Use the Invoice’s payment_intent to choose how to handle the payment attempt’s response, which may be either success or requires_action.

    When the PaymentIntent’s status is requires_action you should have your user complete a 3D Secure authentication flow to complete the payment.

    Instead of building this yourself, you can rely on Stripe Billing to handle it for you. Enable reminder emails in the Stripe Dashboard so that Stripe can automatically send emails to your Customers whenever requires_action occurs. These emails include a link to the Hosted Invoice Page, where a customer can perform all the actions required to pay the invoice. Learn more about these emails and how to customize them on the automatic collection page.

    Enabling/disabling automatic advancement and collection

    By default, Stripe automatically advances invoices generated by subscriptions toward collection. This behavior includes:

    • Automatically finalizing invoices.
    • Automatically attempting to collect payments.
    • Emailing invoices and receipts.
    • Emailing 3D Secure reminders for incomplete payments.
    • Using Smart Retries to automatically retry payment collection.

    One-off invoices created via the dashboard will automatically be advanced once leaving the draft state, unless explicitly disabled. One-off invoices created via the API will not automatically be advanced unless auto_advance is explicitly set to true.

    Pausing automatic collection

    There are cases where you might want to stop Stripe from automatically advancing your invoices toward collection. For example:

    • You want to use your own business logic to manage an invoice’s lifecycle.
    • You want to decide, on a per-invoice basis, whether and when to send invoice emails.

    In these cases, you can use the auto_advance property to disable or enable (pause or unpause) the automatic collection behavior.

    Updating the auto_advance property

    You can toggle the auto_advance property on draft and open invoices. Automatic collection will never occur on invoices in uncollectible, void, or paid statuses, so for invoices in these statuses, auto_advance will always be set to false.

    curl https://api.stripe.com/v1/invoices/:id \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -X PUT \
      -d auto_advance=false
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    Stripe::Invoice.update(
      'in_18jwqyLlRB0eXbMtrUQ97YBw',
      {
        auto_advance: false,
      }
    )
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    stripe.Invoice.modify(
      'in_18jwqyLlRB0eXbMtrUQ97YBw,
      auto_advance=False
    )
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    \Stripe\Invoice::update(
      'in_18jwqyLlRB0eXbMtrUQ97YBw',
      [
        'auto_advance' => false,
      ]
    );
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";
    
    Invoice invoice = Invoice.retrieve("in_18jwqyLlRB0eXbMtrUQ97YBw");
    Map<String, Object> updateParams = new HashMap<String, Object>();
    updateParams.put("auto_advance", false);
    invoice.update(updateParams);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    stripe.invoices.update(
      'in_18jwqyLlRB0eXbMtrUQ97YBw',
      {
        auto_advance: false,
      },
      function(err, invoice) {
        // asynchronously called
      }
    )
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    
    params := &stripe.InvoiceParams{
      AutoAdvance: stripe.Bool(false),
    }
    i, err := invoice.Update("in_18jwqyLlRB0eXbMtrUQ97YBw", params)
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    StripeConfiguration.SetApiKey("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    var options = new InvoiceUpdateOptions {
      AutoAdvance = false,
    };
    var service = new InvoiceService();
    var invoice = service.Update("in_18jwqyLlRB0eXbMtrUQ97YBw", options);
    

    Effects of toggling auto_advance

    When auto_advance is set to false (disabling automatic collection), most of Stripe Billing’s automatic features are disabled—leaving collection up to you.

    The following table outlines some key changes in automatic collection’s behavior, depending on whether auto_advance is set to true or false:

    Feature auto_advance=true auto_advance=false
    Finalize drafts to open ✅ after approximately 1-hour
    Emailing invoices ✅ ⚙️
    Attempting payments
    Retries (email and charge) ✅ ⚙️
    Invoice reminder emails ✅ ⚙️
    3D Secure reminder emails ✅ ⚙️
    Email receipts ✅ ⚙️ *email settings ✅ ⚙️ *email settings

    Legend

    • ✅ = Can be enabled (depending on the settings ⚙️)
    • ⚙️ = Configurable in settings
    • ⛔ = Not enabled—the invoice is not automatically transitioned

    Questions?

    We're always happy to help with code or other questions you might have. Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    Was this page helpful? Yes No

    Send

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.

    On this page