Applying Taxes to Subscriptions

    Learn how to set taxes on subscriptions so that Stripe can calculate invoice tax amounts for you.

    To collect taxes on a subscription, either set tax rates on the subscription, or set the tax rates on invoices as the subscription cycles.

    Recommended: Setting tax rates on a subscription

    You can apply taxes at the subscription level and the subscription item level and set up to five tax rates on each subscription item.

    When invoices are generated for subscriptions, tax rates are copied from the subscription to the invoice. In the example below, the first subscription item has two tax rates: 3% and 5%, which overrides the 1% from the subscription level tax rate. The second item doesn’t have any tax rates set directly on it, so the 1% from the subscription level tax rate is automatically applied.

    Subscription item 1 3% and 5% ➡️ Invoice item 1 3% and 5%
    Subscription item 2 (no tax set) ➡️ Invoice item 2 (no tax set)
    Subscription 1% ➡️ Invoice 1%

    You can set tax rates when you create or update subscription items by passing the tax rate IDs. The example below updates an existing subscription item with two tax rates:

    curl https://api.stripe.com/v1/subscription_items/si_FbyjdxUlCCOAtv \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d "tax_rates[0]=txr_1F6kmAAJVYItwOKqV9IWehUH" \
      -d "tax_rates[1]=txr_2J8lmBBGHJYyuUJqF6QJtkNM"
    
    # 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::SubscriptionItem.update(
      'si_FbyjdxUlCCOAtv',
      {
        tax_rates: [
          'txr_1F6kmAAJVYItwOKqV9IWehUH',
          'txr_2J8lmBBGHJYyuUJqF6QJtkNM',
        ],
      }
    )
    
    # 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.SubscriptionItem.modify(
      'si_FbyjdxUlCCOAtv',
      tax_rates=[
        'txr_1F6kmAAJVYItwOKqV9IWehUH',
        'txr_2J8lmBBGHJYyuUJqF6QJtkNM',
      ]
    )
    
    // 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\SubscriptionItem::update(
      'si_FbyjdxUlCCOAtv',
      [
        'tax_rates' => [
          'txr_1F6kmAAJVYItwOKqV9IWehUH',
          'txr_2J8lmBBGHJYyuUJqF6QJtkNM',
        ],
      ]
    );
    
    // 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";
    
    SubscriptionItem subscriptionitem = SubscriptionItem.retrieve("si_FbyjdxUlCCOAtv");
    Map<String, Object> updateParams = new HashMap<String, Object>();
    List<String> taxRates = Arrays.asList(
      "txr_1F6kmAAJVYItwOKqV9IWehUH",
      "txr_2J8lmBBGHJYyuUJqF6QJtkNM"
    );
    updateParams.put("tax_rates", taxRates);
    subscriptionitem.update(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
    const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    stripe.subscriptionItems.update(
      'si_FbyjdxUlCCOAtv',
      {
        tax_rates: [
          'txr_1F6kmAAJVYItwOKqV9IWehUH',
          'txr_2J8lmBBGHJYyuUJqF6QJtkNM',
        ],
      },
      function(err, invoiceItem) {
        // 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.SubscriptionItemParams{
      TaxRates: stripe.StringSlice([]string{
        "txr_1F6kmAAJVYItwOKqV9IWehUH",
        "txr_2J8lmBBGHJYyuUJqF6QJtkNM",
      }),
    }
    ii, err := subscriptionitem.Update("si_FbyjdxUlCCOAtv", 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.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";
    
    var options = new SubscriptionItemUpdateOptions
      TaxRates = new List<string> {
        "txr_1F6kmAAJVYItwOKqV9IWehUH",
        "txr_2J8lmBBGHJYyuUJqF6QJtkNM",
      },
    };
    var service = new SubscriptionItemService();
    var subscriptionItem = service.Update("ii_CWYsi_FbyjdxUlCCOAtvWo9Ham19N4a", options);
    

    You can set subscription level tax rates when you create or update subscriptions. Set the tax rates you want to apply by passing the default tax rate IDs. The example below updates an existing subscription with two tax rates:

    curl https://api.stripe.com/v1/subscriptions/sub_BVxXIrxAAYb7Fb \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d "default_tax_rates[0]=txr_1EO66sClCIKljWvs98IiVfHW" \
      -d "default_tax_rates[1]=txr_1EEOvcClCIKljWvsqYb9U0MB"
    
    # 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::Subscription.update(
      'sub_BVxXIrxAAYb7Fb',
      {
        default_tax_rates: [
          'txr_1EO66sClCIKljWvs98IiVfHW',
          'txr_1EEOvcClCIKljWvsqYb9U0MB',
        ],
      }
    )
    
    # 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.Subscription.modify(
      'sub_BVxXIrxAAYb7Fb',
      default_tax_rates=[
        'txr_1EO66sClCIKljWvs98IiVfHW',
        'txr_1EEOvcClCIKljWvsqYb9U0MB',
      ]
    )
    
    // 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\Subscription::update(
      'sub_BVxXIrxAAYb7Fb',
      [
        'default_tax_rates' => [
          'txr_1EO66sClCIKljWvs98IiVfHW',
          'txr_1EEOvcClCIKljWvsqYb9U0MB',
        ],
      ]
    );
    
    // 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";
    
    Subscription subscription = Subscription.retrieve("sub_BVxXIrxAAYb7Fb");
    Map<String, Object> updateParams = new HashMap<String, Object>();
    List<String> defaultTaxRates = Arrays.asList(
      "txr_1EO66sClCIKljWvs98IiVfHW",
      "txr_1EEOvcClCIKljWvsqYb9U0MB"
    );
    updateParams.put("default_tax_rates", defaultTaxRates);
    subscription.update(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
    const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    stripe.subscriptions.update(
      'sub_BVxXIrxAAYb7Fb',
      {
        default_tax_rates: [
          'txr_1EO66sClCIKljWvs98IiVfHW',
          'txr_1EEOvcClCIKljWvsqYb9U0MB',
        ],
      },
      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.SubscriptionParams{
      DefaultTaxRates: stripe.StringSlice([]string{
        "txr_1EO66sClCIKljWvs98IiVfHW",
        "txr_1EEOvcClCIKljWvsqYb9U0MB",
      }),
    }
    i, err := subscription.Update("sub_BVxXIrxAAYb7Fb", 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.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";
    
    var options = new SubscriptionUpdateOptions
      DefaultTaxRates = new List<string> {
        "txr_1EO66sClCIKljWvs98IiVfHW",
        "txr_1EEOvcClCIKljWvsqYb9U0MB",
      },
    };
    var service = new SubscriptionService();
    var subscription = service.Update("sub_BVxXIrxAAYb7Fb", options);
    

    Dynamically configuring tax rates on each subscription cycle

    If you add extra invoice items, or sell in enough jurisdictions that tax rates change frequently, dynamically calculate and assign tax rates to the subscription’s invoice as it’s created.

    When a subscription renews and creates an invoice, Stripe sends the invoice.created webhook event. Stripe waits approximately one hour before finalizing the invoice and attempting payment or sending an email. During that delay, the invoice is a draft and is editable. Follow the process to assign tax rates to that invoice.

    Next steps

    Now that you understand how to charge taxes on subscriptions, you may want to check out:

    Was this page helpful?

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

    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.

    On this page