# Update existing subscriptions Learn how to update existing subscriptions to Stripe Tax. [Stripe Tax](https://docs.stripe.com/tax.md) allows you to calculate the tax to collect on your transactions. It computes the taxes and adds them to the payment automatically, based on the product and the customer location. When you integrate with Stripe Tax, you need to update existing subscriptions to make sure that tax is automatically calculated going forward. Stripe provides tooling to help you update your subscriptions. You can also manually update subscriptions where you want more control over certain options. ## Update existing subscriptions using automated tooling First, you need to activate Stripe Tax. To learn how, read the [setup guide](https://docs.stripe.com/tax/set-up.md). To use the tooling, follow these steps: 1. Go to the [Dashboard](https://dashboard.stripe.com/tax/migrations). 1. Review the subscriptions you need to update. 1. Review the recommended actions. 1. Make any necessary manual updates. Stripe removes manual [tax rates](https://docs.stripe.com/billing/taxes/tax-rates.md) from the subscriptions, which can take up to 5 business days. When the process is complete, we notify you by email. We don’t prorate the tax changes. The updates take effect at the start of the next billing cycle. You can use the tooling to update subscriptions that meet the following criteria: * Are active * Don’t automatically collect tax * Have sufficient [address information](https://docs.stripe.com/tax/customer-locations.md#address-hierarchy-other) to calculate tax You need to update the following types of subscriptions: - Subscriptions with schedules. To learn more, see [the Update Subscriptions with subscription schedules section](#existing-subscription-schedules). - Subscriptions that use the [charge types](https://docs.stripe.com/connect/charges.md#types) destination charges or separate charges and transfers. ## Update existing subscriptions manually * [Review customer locations](#customer-locations) and make any required updates. * [Update products and prices](#products_prices) with tax codes and tax behaviors. * [Update subscriptions](#subs) to automatically calculate taxes on future invoices. * [Confirm](#confirm) that you’ve updated the subscriptions correctly. ## Check customer locations To correctly calculate tax, we need to know the customer’s tax location status. You can check it in the Dashboard or in exported data, or get the information using the API. To check a customer’s tax location status through the Dashboard, go to the [Customers page](https://dashboard.stripe.com/customers), select the customer, and expand their details. The tax location status (`automatic_tax`) has four possible values: | Status | Description | Possible Action | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Valid (`supported`) | Automatic tax fully supported. | No further action required. | | Unrecognized location (`unrecognized_location`) | The address isn’t valid for determining a tax location. | Ask the customer for an updated address and set [customer.address](https://docs.stripe.com/api/customers/update.md#update_customer-address) to the new value. You can update the value through the API or Dashboard by editing the customer’s details. | | Not registered (`not_collecting`) | The address is recognized and resolved to a location that you haven’t set up a collection location for. | The action to take depends on your [tax obligations](https://docs.stripe.com/tax/monitoring.md). If you proceed, Stripe Tax doesn’t assess any taxes. If you want it to assess tax, [add an active registration](https://docs.stripe.com/tax/registering.md) for the jurisdiction the customer is based in. | | `failed` | An [error](https://docs.stripe.com/error-codes.md) occurred with Stripe’s servers. This is rare. | Try the request again or contact Stripe support for additional assistance. | In case the `status=unrecognized_location` you need to update the customer location with [an address that Stripe Tax can use](https://docs.stripe.com/tax/customer-locations.md). In the Dashboard, you can go into the [Customers page](https://dashboard.stripe.com/customers), select the customer, and change its billing or shipping address under Details. ### Check tax location status through exports To check the tax location status of your customers through Dashboard exports, go to the [Customers page](https://dashboard.stripe.com/customers), click **Export**, and select **All columns**. The CSV file includes a Boolean column named **Tax Location Recognized** that you can use to determine whether a customer has a [valid](https://docs.stripe.com/tax/customer-locations.md#supported-formats) address. To check a customer’s tax location status using the API, retrieve the [Customer object](https://docs.stripe.com/api/customers/object.md) and [expand](https://docs.stripe.com/api/expanding_objects.md) the response by adding `expand: ['tax']` to your request. You must use `expand` because the default response doesn’t include the [tax](https://docs.stripe.com/api/customers/object.md#customer_object-tax) field. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new CustomerGetOptions { Expand = new List { "tax" } }; var service = new CustomerService(); Customer customer = service.Get("<>", options); ``` ```go stripe.Key = "<>" params := &stripe.CustomerParams{}; params.AddExpand("tax") result, err := customer.Get("<>", params); ``` ```java Stripe.apiKey = "<>"; CustomerRetrieveParams params = CustomerRetrieveParams.builder().addExpand("tax").build(); Customer customer = Customer.retrieve("<>", params, null); ``` ```node const stripe = require('stripe')('<>'); const customer = await stripe.customers.retrieve( '<>', { expand: ['tax'], } ); ``` ```python import stripe stripe.api_key = "<>" customer = stripe.Customer.retrieve( "<>", expand=["tax"], ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $customer = $stripe->customers->retrieve('<>', ['expand' => ['tax']]); ``` ```ruby Stripe.api_key = '<>' customer = Stripe::Customer.retrieve({ expand: ['tax'], id: '<>', }) ``` The response includes expanded tax fields that indicate the computed tax location, and whether you can use automatic tax calculation with the given customer. ```json { "tax": { "automatic_tax": "supported", "ip_address": null, "location": {"country": "US", "state": "CA", "source": "billing_address"} }, "id": "cus_JvecILHjNPGKSI", "object": "customer", "address": null, "balance": 0, "created": 1627380831, "currency": null, "default_source": "src_0JHnP4507O8KAxCGgDurDgoS", "delinquent": false, "description": "1st Deposit", "discount": null, "email": "jenny.rosen@example.com", "invoice_prefix": "66CD4DB9", "invoice_settings": { "custom_fields": null, "default_payment_method": null, "footer": null }, "livemode": false, "metadata": { }, "name": "Jenny Rosen", "next_invoice_sequence": 1, "phone": null, "preferred_locales": [ ], "shipping": null, "tax_exempt": "none" } ``` The value of `automatic_tax` (**Tax location status** in the Dashboard) has four possible statuses: | Status | Description | Possible Action | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Valid (`supported`) | Automatic tax fully supported. | No further action required. | | Unrecognized location (`unrecognized_location`) | The address isn’t valid for determining a tax location. | Ask the customer for an updated address and set [customer.address](https://docs.stripe.com/api/customers/update.md#update_customer-address) to the new value. You can update the value through the API or Dashboard by editing the customer’s details. | | Not registered (`not_collecting`) | The address is recognized and resolved to a location that you haven’t set up a collection location for. | The action to take depends on your [tax obligations](https://docs.stripe.com/tax/monitoring.md). If you proceed, Stripe Tax doesn’t assess any taxes. If you want it to assess tax, [add an active registration](https://docs.stripe.com/tax/registering.md) for the jurisdiction the customer is based in. | | `failed` | An [error](https://docs.stripe.com/error-codes.md) occurred with Stripe’s servers. This is rare. | Try the request again or contact Stripe support for additional assistance. | In case the `status=unrecognized_location` you need to update the customer location with [an address that Stripe Tax can use to calculate tax](https://docs.stripe.com/tax/customer-locations.md). You can [update the customer](https://docs.stripe.com/api/customers/update.md#update_customer-address) through the API: ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new CustomerUpdateOptions { Address = new AddressOptions { Line1 = "27 Fredrick Ave", City = "Brothers", PostalCode = "97712", State = "OR", Country = "US", }, Expand = new List { "tax" }, }; var service = new CustomerService(); Customer customer = service.Update("<>", options); ``` ```go stripe.Key = "<>" params := &stripe.CustomerParams{ Address: &stripe.AddressParams{ Line1: stripe.String("27 Fredrick Ave"), City: stripe.String("Brothers"), PostalCode: stripe.String("97712"), State: stripe.String("OR"), Country: stripe.String("US"), }, }; params.AddExpand("tax") result, err := customer.Update("<>", params); ``` ```java Stripe.apiKey = "<>"; Customer resource = Customer.retrieve("<>"); CustomerUpdateParams params = CustomerUpdateParams.builder() .setAddress( CustomerUpdateParams.Address.builder() .setLine1("27 Fredrick Ave") .setCity("Brothers") .setPostalCode("97712") .setState("OR") .setCountry("US") .build() ) .addExpand("tax") .build(); Customer customer = resource.update(params); ``` ```node const stripe = require('stripe')('<>'); const customer = await stripe.customers.update( '<>', { address: { line1: '27 Fredrick Ave', city: 'Brothers', postal_code: '97712', state: 'OR', country: 'US', }, expand: ['tax'], } ); ``` ```python import stripe stripe.api_key = "<>" customer = stripe.Customer.modify( "<>", address={ "line1": "27 Fredrick Ave", "city": "Brothers", "postal_code": "97712", "state": "OR", "country": "US", }, expand=["tax"], ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $customer = $stripe->customers->update( '<>', [ 'address' => [ 'line1' => '27 Fredrick Ave', 'city' => 'Brothers', 'postal_code' => '97712', 'state' => 'OR', 'country' => 'US', ], 'expand' => ['tax'], ] ); ``` ```ruby Stripe.api_key = '<>' customer = Stripe::Customer.update( '<>', { address: { line1: '27 Fredrick Ave', city: 'Brothers', postal_code: '97712', state: 'OR', country: 'US', }, expand: ['tax'], }, ) ``` For more information on which customer address is valid, how they’re used, or how to handle errors, see [Collect customer addresses](https://docs.stripe.com/tax/customer-locations.md). ## Update products and prices Your products and prices use the default tax behavior you assigned when activating Stripe Tax. If you’d prefer to update active products and prices to calculate tax independently, set a tax_code and tax_behavior. See the full list of [available tax codes](https://docs.stripe.com/tax/tax-codes.md) and the [guide for setting up](https://docs.stripe.com/tax/products-prices-tax-codes-tax-behavior.md) tax codes and tax behavior for more information. For more information about [products and prices](https://docs.stripe.com/billing/taxes/collect-taxes.md#product-and-price-setup), including how to decide whether a price should be inclusive or exclusive, see the [Tax Setup FAQ](https://docs.stripe.com/tax/faq.md#set-up). ### Update products First, update any existing products with a `tax_code`. If you don’t explicitly define a `tax_code` on your product, Stripe Tax uses the preset product tax code from your settings. To update a Product with a `tax_code` in the Dashboard, go to the [Products page](https://dashboard.stripe.com/products?active=true), select a product to edit and, in the product information page, choose the tax code from the drop-down menu. Here’s how to update a product with a `tax_code` using the API: ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new ProductUpdateOptions { TaxCode = "<>" }; var service = new ProductService(); Product product = service.Update("<>", options); ``` ```go stripe.Key = "<>" params := &stripe.ProductParams{TaxCode: stripe.String("<>")}; result, err := product.Update("<>", params); ``` ```java Stripe.apiKey = "<>"; Product resource = Product.retrieve("<>"); ProductUpdateParams params = ProductUpdateParams.builder().setTaxCode("<>").build(); Product product = resource.update(params); ``` ```node const stripe = require('stripe')('<>'); const product = await stripe.products.update( '<>', { tax_code: '<>', } ); ``` ```python import stripe stripe.api_key = "<>" product = stripe.Product.modify( "<>", tax_code="<>", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $product = $stripe->products->update('<>', ['tax_code' => '<>']); ``` ```ruby Stripe.api_key = '<>' product = Stripe::Product.update('<>', {tax_code: '<>'}) ``` ### Update prices Next, update the tax behavior for your prices. You can’t change `tax_behavior` after it’s been set to one of `exclusive` or `inclusive`. If you want to change the tax behavior of a price, you need to create a new price with the desired behavior, and archive the old price. To update a price using the Dashboard: 1. Go to the [products page](https://dashboard.stripe.com/products). 1. Select the product with the price you want to update. 1. Select additional options in the price information section. 1. In the **Include tax in price** drop-down menu, select the behavior you want to associate with the price. Here’s how to update a price using the API: ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new PriceUpdateOptions { TaxBehavior = "exclusive" }; var service = new PriceService(); Price price = service.Update("<>", options); ``` ```go stripe.Key = "<>" params := &stripe.PriceParams{TaxBehavior: stripe.String(string(stripe.PriceTaxBehaviorExclusive))}; result, err := price.Update("<>", params); ``` ```java Stripe.apiKey = "<>"; Price resource = Price.retrieve("<>"); PriceUpdateParams params = PriceUpdateParams.builder().setTaxBehavior(PriceUpdateParams.TaxBehavior.EXCLUSIVE).build(); Price price = resource.update(params); ``` ```node const stripe = require('stripe')('<>'); const price = await stripe.prices.update( '<>', { tax_behavior: 'exclusive', } ); ``` ```python import stripe stripe.api_key = "<>" price = stripe.Price.modify( "<>", tax_behavior="exclusive", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $price = $stripe->prices->update('<>', ['tax_behavior' => 'exclusive']); ``` ```ruby Stripe.api_key = '<>' price = Stripe::Price.update('<>', {tax_behavior: 'exclusive'}) ``` ## Update subscriptions With your customers, products, and prices updated, you’re ready to update existing subscriptions. Get the list of subscriptions that need to be updated from the [subscriptions page in the Dashboard](https://dashboard.stripe.com/subscriptions). To display only subscriptions that don’t have automatic tax enabled, click **Filter**, check **Automatic tax**, and select **Disabled**. Alternatively, you can export all filtered subscriptions to view them as a CSV file. To do this, click **Export** and select **All** as the **Date range**. How you update the subscriptions depends on their state: - If your subscriptions [don’t have existing tax rates](#no-tax-rates), you only need to enable automatic tax. - If your subscriptions have [existing tax rates](#existing-tax-rates) (at either the subscription or line-item level), you need to clear out any existing tax rates and enable automatic tax. To avoid creating prorated items, you can schedule this update. - If your subscriptions have [subscriptions schedules](#existing-subscription-schedules), you need to remove instances of `automatic_tax[enabled]=false` in the subscription schedule plans. ### Update subscriptions with no existing tax rates To update subscriptions with no existing tax rates using the Dashboard, update the subscription and turn on the **Calculate tax automatically** option. To [update subscriptions](https://docs.stripe.com/api/subscriptions/update.md) that you haven’t configured [tax rates](https://docs.stripe.com/billing/taxes/tax-rates.md) for, set [automatic_tax.enabled](https://docs.stripe.com/api/subscriptions/update.md#update_subscription-automatic_tax) to `true`. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new SubscriptionUpdateOptions { AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true }, }; var service = new SubscriptionService(); Subscription subscription = service.Update("<>", options); ``` ```go stripe.Key = "<>" params := &stripe.SubscriptionParams{ AutomaticTax: &stripe.SubscriptionAutomaticTaxParams{Enabled: stripe.Bool(true)}, }; result, err := subscription.Update("<>", params); ``` ```java Stripe.apiKey = "<>"; Subscription resource = Subscription.retrieve("<>"); SubscriptionUpdateParams params = SubscriptionUpdateParams.builder() .setAutomaticTax(SubscriptionUpdateParams.AutomaticTax.builder().setEnabled(true).build()) .build(); Subscription subscription = resource.update(params); ``` ```node const stripe = require('stripe')('<>'); const subscription = await stripe.subscriptions.update( '<>', { automatic_tax: { enabled: true, }, } ); ``` ```python import stripe stripe.api_key = "<>" subscription = stripe.Subscription.modify( "<>", automatic_tax={"enabled": True}, ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $subscription = $stripe->subscriptions->update( '<>', ['automatic_tax' => ['enabled' => true]] ); ``` ```ruby Stripe.api_key = '<>' subscription = Stripe::Subscription.update('<>', {automatic_tax: {enabled: true}}) ``` Setting `automatic_tax.enabled=true` activates automatic tax calculations for all subsequent invoices created for that subscription. ### Update subscriptions with existing tax rates To update subscriptions with [tax rates](https://docs.stripe.com/billing/taxes/tax-rates.md) through the Dashboard, edit the subscription, then enable the **calculate tax automatically** option. The Dashboard removes any existing tax rates and automatically calculates tax going forward. If you haven’t updated your prices to set `tax_behavior`, the Dashboard prompts you to update any missing details before you can update the subscription. To update subscriptions with [tax rates](https://docs.stripe.com/billing/taxes/tax-rates.md) set at the [subscription level](https://docs.stripe.com/billing/taxes/collect-taxes.md?tax-calculation=tax-rates#static-configuration), you need to remove the tax rates before enabling `automatic_tax`. When you make the update: - Pass an empty string in the [default_tax_rates](https://docs.stripe.com/api/subscriptions/update.md#update_subscription-default_tax_rates) and [tax_rates](https://docs.stripe.com/api/subscriptions/object.md#subscription_object-items-data-tax_rates) fields for each subscription [item](https://docs.stripe.com/api/subscriptions/object.md#subscription_object-items). Doing this clears out tax rates set at both the subscription (`default_tax_rates`) and line-item (`tax_rates`) levels. - Set [automatic_tax.enabled](https://docs.stripe.com/api/subscriptions/update.md#update_subscription-automatic_tax) to `true`. ```ruby <> subscription = Stripe::Subscription.retrieve('{{SUBSCRIPTION_ID}}') Stripe::Subscription.update( subscription.id, { automatic_tax: { enabled: true }, # Removes existing tax_rates for each item in the subscription items: subscription.items.data.map {|item| {id: item.id, tax_rates: ''}}, default_tax_rates: '' } ) ``` ```python <> subscription = stripe.Subscription.retrieve('{{SUBSCRIPTION_ID}}') stripe.Subscription.modify( subscription.id, automatic_tax={"enabled": True}, # Removes existing tax_rates for each item in the subscription items=list(map(lambda item: {"id": item.id, "tax_rates": ""}, subscription['items']['data'])), default_tax_rates="" ) ``` ```php <> $subscription = $stripe->subscriptions->retrieve( '{{SUBSCRIPTION_ID}}', [] ); $passEmptyTaxRates = function($item) { return [ 'id' => $item->id, 'tax_rates' => '' ]; }; $stripe->subscriptions->update( $subscription->id, [ 'automatic_tax' => ['enabled' => true], // Removes existing tax_rates for each item in the subscription 'items' => array_map($passEmptyTaxRates, $subscription->items->data), 'default_tax_rates' => '' ], ); ``` ```javascript <> const subscription = await stripe.subscriptions.retrieve('{{SUBSCRIPTION_ID}}'); const updatedSubscription = await stripe.subscriptions.update( subscription.id, { automatic_tax: {enabled: true}, // Removes existing tax_rates for each item in the subscription items: subscription.items.data.map(item => ({id: item.id, tax_rates: ''})), default_tax_rates: '', }, ); ``` ```java <> Subscription subscription = Subscription.retrieve("{{SUBSCRIPTION_ID}}"); Map automaticTax = new HashMap<>(); automaticTax.put("enabled", true); // Building an array containing the subscription item ids // with tax_rates="" to remove tax_rates for each item. ArrayList> itemsWithEmptyTaxRates = new ArrayList<>(); for (SubscriptionItem item: subscription.getItems().getData()) { Map newItem = new HashMap<>(); newItem.put("id", item.getId()); newItem.put("tax_rates", ""); itemsWithEmptyTaxRates.add(newItem); } Map params = new HashMap<>(); params.put("automatic_tax", automaticTax); params.put("items", items); params.put("default_tax_rates", ""); Subscription updatedSubscription = subscription.update(params); ``` ```dotnet <> var service = new SubscriptionService(); var subscription = service.Get("sub_JzUpaTphIGpTOI"); var options = new SubscriptionUpdateOptions { AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true }, // Removes existing tax_rates for each item in the subscription Items = subscription.Items.Data.ConvertAll( item => new SubscriptionItemOptions{Id = item.Id, TaxRates = new List()} ), DefaultTaxRates = new List() }; service.Update(subscription.Id, options); ``` ```go <> s, _ := subscription.Get("sub_JzMkw4IV17vNnb", nil) // Building an array containing the subscription item ids // and empty tax_rates slices. When passed to the update // method, this will remove tax_rates for each item. itemsWithEmptyTaxRates := []*stripe.SubscriptionItemsParams{} for _, item := range s.Items.Data { itemsWithEmptyTaxRates = append(itemsWithEmptyTaxRates, &stripe.SubscriptionItemsParams{ ID: stripe.String(item.ID), TaxRates: stripe.StringSlice(nil), }) } params := &stripe.SubscriptionParams{ AutomaticTax: &stripe.SubscriptionAutomaticTaxParams{ Enabled: stripe.Bool(true), }, Items: itemsWithEmptyTaxRates, DefaultTaxRates: stripe.StringSlice(nil), } subscription.Update(s.ID, params) ``` ### Update Subscriptions with subscription schedules If you need to collect tax, and any of your subscriptions include a subscription schedule that sets `automatic_tax[enabled]=false`, you must remove that parameter. To do so, update all phases of the subscription’s schedule by removing `automatic_tax[enabled]=false` and setting `default_settings[automatic_tax][enabled]=true`. When you update a subscription schedule, you need to pass in all current and future phases. To do this, verify the set parameters, then enable Stripe Tax in the subscription schedule. ```dotnet StripeConfiguration.ApiKey = "<>"; var service = new SubscriptionScheduleService(); SubscriptionSchedule subscriptionSchedule = service.Get("<>"); ``` ```go stripe.Key = "<>" params := &stripe.SubscriptionScheduleParams{}; result, err := subscriptionschedule.Get("<>", params); ``` ```java Stripe.apiKey = "<>"; SubscriptionSchedule subscriptionSchedule = SubscriptionSchedule.retrieve("<>"); ``` ```node const stripe = require('stripe')('<>'); const subscriptionSchedule = await stripe.subscriptionSchedules.retrieve( '<>' ); ``` ```python import stripe stripe.api_key = "<>" subscription_schedule = stripe.SubscriptionSchedule.retrieve("<>") ``` ```php $stripe = new \Stripe\StripeClient('<>'); $subscriptionSchedule = $stripe->subscriptionSchedules->retrieve('<>', []); ``` ```ruby Stripe.api_key = '<>' subscription_schedule = Stripe::SubscriptionSchedule.retrieve('<>') ``` To update the subscription schedule after you obtain it, remove the `automatic_tax[enabled]=false` parameter, and pass down the other phases and parameters: ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new SubscriptionScheduleUpdateOptions { Phases = new List { new SubscriptionSchedulePhaseOptions { Items = new List { new SubscriptionSchedulePhaseItemOptions { Price = "price_1GqNdGAJVYItwOKqEHb", Quantity = 1, }, }, StartDate = DateTimeOffset.FromUnixTimeSeconds(1577865600).UtcDateTime, EndDate = DateTimeOffset.FromUnixTimeSeconds(1578038400).UtcDateTime, }, new SubscriptionSchedulePhaseOptions { Items = new List { new SubscriptionSchedulePhaseItemOptions { Price = "price_1GqNdGAJVYItwOKqEHb", Quantity = 2, }, }, StartDate = DateTimeOffset.FromUnixTimeSeconds(1578038400).UtcDateTime, EndDate = DateTimeOffset.FromUnixTimeSeconds(1580544000).UtcDateTime, }, }, DefaultSettings = new SubscriptionScheduleDefaultSettingsOptions { AutomaticTax = new SubscriptionScheduleDefaultSettingsAutomaticTaxOptions { Enabled = true, }, }, }; var service = new SubscriptionScheduleService(); SubscriptionSchedule subscriptionSchedule = service.Update("<>", options); ``` ```go stripe.Key = "<>" params := &stripe.SubscriptionScheduleParams{ Phases: []*stripe.SubscriptionSchedulePhaseParams{ &stripe.SubscriptionSchedulePhaseParams{ Items: []*stripe.SubscriptionSchedulePhaseItemParams{ &stripe.SubscriptionSchedulePhaseItemParams{ Price: stripe.String("price_1GqNdGAJVYItwOKqEHb"), Quantity: stripe.Int64(1), }, }, StartDate: stripe.Int64(1577865600), EndDate: stripe.Int64(1578038400), }, &stripe.SubscriptionSchedulePhaseParams{ Items: []*stripe.SubscriptionSchedulePhaseItemParams{ &stripe.SubscriptionSchedulePhaseItemParams{ Price: stripe.String("price_1GqNdGAJVYItwOKqEHb"), Quantity: stripe.Int64(2), }, }, StartDate: stripe.Int64(1578038400), EndDate: stripe.Int64(1580544000), }, }, DefaultSettings: &stripe.SubscriptionScheduleDefaultSettingsParams{ AutomaticTax: &stripe.SubscriptionAutomaticTaxParams{Enabled: stripe.Bool(true)}, }, }; result, err := subscriptionschedule.Update("<>", params); ``` ```java Stripe.apiKey = "<>"; SubscriptionSchedule resource = SubscriptionSchedule.retrieve("<>"); SubscriptionScheduleUpdateParams params = SubscriptionScheduleUpdateParams.builder() .addPhase( SubscriptionScheduleUpdateParams.Phase.builder() .addItem( SubscriptionScheduleUpdateParams.Phase.Item.builder() .setPrice("price_1GqNdGAJVYItwOKqEHb") .setQuantity(1L) .build() ) .setStartDate(1577865600L) .setEndDate(1578038400L) .build() ) .addPhase( SubscriptionScheduleUpdateParams.Phase.builder() .addItem( SubscriptionScheduleUpdateParams.Phase.Item.builder() .setPrice("price_1GqNdGAJVYItwOKqEHb") .setQuantity(2L) .build() ) .setStartDate(1578038400L) .setEndDate(1580544000L) .build() ) .setDefaultSettings( SubscriptionScheduleUpdateParams.DefaultSettings.builder() .setAutomaticTax( SubscriptionScheduleUpdateParams.DefaultSettings.AutomaticTax.builder() .setEnabled(true) .build() ) .build() ) .build(); SubscriptionSchedule subscriptionSchedule = resource.update(params); ``` ```node const stripe = require('stripe')('<>'); const subscriptionSchedule = await stripe.subscriptionSchedules.update( '<>', { phases: [ { items: [ { price: 'price_1GqNdGAJVYItwOKqEHb', quantity: 1, }, ], start_date: 1577865600, end_date: 1578038400, }, { items: [ { price: 'price_1GqNdGAJVYItwOKqEHb', quantity: 2, }, ], start_date: 1578038400, end_date: 1580544000, }, ], default_settings: { automatic_tax: { enabled: true, }, }, } ); ``` ```python import stripe stripe.api_key = "<>" subscription_schedule = stripe.SubscriptionSchedule.modify( "<>", phases=[ { "items": [{"price": "price_1GqNdGAJVYItwOKqEHb", "quantity": 1}], "start_date": 1577865600, "end_date": 1578038400, }, { "items": [{"price": "price_1GqNdGAJVYItwOKqEHb", "quantity": 2}], "start_date": 1578038400, "end_date": 1580544000, }, ], default_settings={"automatic_tax": {"enabled": True}}, ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $subscriptionSchedule = $stripe->subscriptionSchedules->update( '<>', [ 'phases' => [ [ 'items' => [ [ 'price' => 'price_1GqNdGAJVYItwOKqEHb', 'quantity' => 1, ], ], 'start_date' => 1577865600, 'end_date' => 1578038400, ], [ 'items' => [ [ 'price' => 'price_1GqNdGAJVYItwOKqEHb', 'quantity' => 2, ], ], 'start_date' => 1578038400, 'end_date' => 1580544000, ], ], 'default_settings' => ['automatic_tax' => ['enabled' => true]], ] ); ``` ```ruby Stripe.api_key = '<>' subscription_schedule = Stripe::SubscriptionSchedule.update( '<>', { phases: [ { items: [ { price: 'price_1GqNdGAJVYItwOKqEHb', quantity: 1, }, ], start_date: 1577865600, end_date: 1578038400, }, { items: [ { price: 'price_1GqNdGAJVYItwOKqEHb', quantity: 2, }, ], start_date: 1578038400, end_date: 1580544000, }, ], default_settings: {automatic_tax: {enabled: true}}, }, ) ``` #### Schedule the update If you want to avoid creating a prorated item, you can schedule the update to occur at the start of the next cycle. You can currently only schedule subscription updates with the API: ```ruby <> subscription = Stripe::Subscription.retrieve( '{{SUBSCRIPTION_ID}}', ) schedule = Stripe::SubscriptionSchedule.create({ from_subscription: subscription.id }) Stripe::SubscriptionSchedule.update( schedule.id, { end_behavior: 'release', phases: [ # The first phase contains items for the # latest subscription invoice { items: [ # Prices and tax_rates for each item { price: '{{PRICE_ID}}', tax_rates: [ '{{TAX_RATE_ID}}' ] } ], default_tax_rates: ['{{TAX_RATE_ID}}'], start_date: subscription.current_period_start, end_date: subscription.current_period_end }, # The second phase removes manual tax rates and enables # automatic tax calculation { items: [ # Prices for each item with tax_rates: '' { price: '{{PRICE_ID}}', tax_rates: '' } ], default_tax_rates: '', automatic_tax: {enabled: true}, iterations: 1 } ] } ) ``` ```python <> subscription = stripe.Subscription.retrieve('{{SUBSCRIPTION_ID}}') schedule = stripe.SubscriptionSchedule.create( from_subscription=subscription['id'], ) updated_schedule = stripe.SubscriptionSchedule.modify( schedule['id'], end_behavior = "release", phases=[ # The first phase contains items for the # latest subscription invoice { "items": [ # Prices and tax_rates for each item { "price": "{{PRICE_ID}}", "tax_rates": [ "{{TAX_RATE_ID}}", ] }, ], "default_tax_rates": ["{{TAX_RATE_ID}}"], "start_date": subscription['current_period_start'], "end_date": subscription['current_period_end'], }, # The second phase removes manual tax rates and enables # automatic tax calculation { "items": [ # Prices for each item with tax_rates: "" { "price": "{{PRICE_ID}}", "tax_rates": "" }, ], "default_tax_rates": "", "automatic_tax": {"enabled": True}, "iterations": 1 } ], ) ``` ```php <> $subscription = $stripe->subscriptions->retrieve( '{{SUBSCRIPTION_ID}}', [] ); $schedule = $stripe->subscriptionSchedules->create([ 'from_subscription' => $subscription->id ]); $updatedSchedule = $stripe->subscriptionSchedules->update( $schedule->id, [ 'end_behavior' => 'release', 'phases' => [ # The first phase contains items for the # latest subscription invoice [ 'items' => [ # Prices and tax_rates for each item [ 'price' => '{{PRICE_ID}}', 'tax_rates' => [ '{{TAX_RATE_ID}}' ] ] ], 'default_tax_rates' => ['{{TAX_RATE_ID}}'], 'start_date' => $subscription->current_period_start, 'end_date' => $subscription->current_period_end ], # The second phase removes manual tax rates and enables # automatic tax calculation [ 'items' => [ # Prices for each item with tax_rates => '' [ 'price' => '{{PRICE_ID}}', 'tax_rates' => '' ], ], 'default_tax_rates' => '', 'automatic_tax' => ['enabled' => true], 'iterations' => 1 ] ] ] ); ``` ```javascript <> const subscription = await stripe.subscriptions.retrieve( '{{SUBSCRIPTION_ID}}' ); const schedule = await stripe.subscriptionSchedules.create( {from_subscription: subscription.id} ); await stripe.subscriptionSchedules.update( schedule.id, { end_behavior: 'release', phases: [ // The first phase contains items for the // latest subscription invoice { items: [ // Prices and tax_rates for each item { price: '{{PRICE_ID}}', tax_rates: [ '{{TAX_RATE_ID}}', ] } ], default_tax_rates: ['{{TAX_RATE_ID}}'], start_date: subscription.current_period_start, end_date: subscription.current_period_end }, // The second phase removes manual tax rates and enables // automatic tax calculation { items: [ // Prices for each item with tax_rates: '' { price: '{{PRICE_ID}}', tax_rates: '' }, ], default_tax_rates: '', automatic_tax: {enabled: true}, iterations: 1 } ] } ); ``` ```java <> Subscription subscription = Subscription.retrieve("{{SUBSCRIPTION_ID}}"); Map createParams = new HashMap<>(); createParams.put("from_subscription", subscription.getId()); SubscriptionSchedule subscriptionSchedule = SubscriptionSchedule.create(createParams); ArrayList taxRates = new ArrayList<>(); taxRates.add("{{TAX_RATE_ID}}"); // Prices and tax_rates for each item Map item1 = new HashMap<>(); item1.put("price", "{{PRICE_ID}}"); item1.put("tax_rates", taxRates); ArrayList items1 = new ArrayList<>(); items1.add(item1); ArrayList defaultTaxRates = new ArrayList<>(); defaultTaxRates.add("{{TAX_RATE_ID}}"); // The first phase contains items for the // latest subscription invoice Map phase1 = new HashMap<>(); phase1.put("items", items1); phase1.put("default_tax_rates", defaultTaxRates); phase1.put("start_date", subscription.getCurrentPeriodStart()); phase1.put("end_date", subscription.getCurrentPeriodEnd()); // Prices for each item with tax_rates: "" Map item2 = new HashMap<>(); item2.put("price", "{{PRICE_ID}}"); item2.put("tax_rates", ""); ArrayList items2 = new ArrayList<>(); items2.add(item2); Map automaticTax = new HashMap<>(); automaticTax.put("enabled", true); // The second phase removes manual tax rates and enables // automatic tax calculation Map phase2 = new HashMap<>(); phase2.put("items", items2); phase2.put("default_tax_rates", ""); phase2.put("automatic_tax", automaticTax); phase2.put("iterations", 1); ArrayList phases = new ArrayList<>(); phases.add(phase1); phases.add(phase2); Map updateParams = new HashMap<>(); updateParams.put("end_behavior", "release"); updateParams.put("phases", phases); subscriptionSchedule.update(updateParams); ``` ```dotnet <> var subscriptionService = new SubscriptionService(); var subscription = subscriptionService.Get("{{SUBSCRIPTION_ID}}"); var scheduleService = new SubscriptionScheduleService(); var schedule = scheduleService.Create(new SubscriptionScheduleCreateOptions { FromSubscription = subscription.Id } ); var options = new SubscriptionScheduleUpdateOptions { EndBehavior = "release", Phases = new List { // The first phase contains items for the // latest subscription invoice new SubscriptionSchedulePhaseOptions { Items = new List { // Prices and tax_rates for each item new SubscriptionSchedulePhaseItemOptions { Price = "{{PRICE_ID}}", TaxRates = new List{"{{TAX_RATE_ID}}"}, }, }, DefaultTaxRates = new List{"{{TAX_RATE_ID}}"}, StartDate = subscription.CurrentPeriodStart, EndDate = subscription.CurrentPeriodEnd, }, // The second phase removes manual tax rates and enables // automatic tax calculation new SubscriptionSchedulePhaseOptions { Items = new List { // Prices for each item with TaxRates = new List() new SubscriptionSchedulePhaseItemOptions { Price = "{{PRICE_ID}}", TaxRates = new List(), }, }, DefaultTaxRates = new List(), AutomaticTax = new SubscriptionSchedulePhaseAutomaticTaxOptions { Enabled = true }, Iterations = 1, }, }, }; scheduleService.Update( schedule.Id, options ); ``` ```go <> subscription, _ := subscription.Get("{{SUBSCRIPTION_ID}}", nil) schedule, _ := subscriptionschedule.New(&stripe.SubscriptionScheduleParams{ FromSubscription: stripe.String(subscription.ID), }) params := &stripe.SubscriptionScheduleParams{ EndBehavior: stripe.String("release"), Phases: []*stripe.SubscriptionSchedulePhaseParams{ // The first phase contains items for the // latest subscription invoice { Items: []*stripe.SubscriptionSchedulePhaseItemParams{ // Prices and tax_rates for each item { Price: stripe.String("{{PRICE_ID}}"), TaxRates: stripe.StringSlice([]string{"{{TAX_RATE_ID}}"}), }, }, DefaultTaxRates: stripe.StringSlice([]string{"{{TAX_RATE_ID}}"}), StartDate: stripe.Int64(subscription.CurrentPeriodStart), EndDate: stripe.Int64(subscription.CurrentPeriodEnd), }, // The second phase removes manual tax rates and enables // automatic tax calculation { Items: []*stripe.SubscriptionSchedulePhaseItemParams{ // Prices for each item with TaxRates: stripe.StringSlice(nil) { Price: stripe.String("{{PRICE_ID}}"), TaxRates: stripe.StringSlice(nil), }, }, DefaultTaxRates: stripe.StringSlice(nil), AutomaticTax: &stripe.SubscriptionSchedulePhaseAutomaticTaxParams{ Enabled: stripe.Bool(true), }, Iterations: stripe.Int64(1), }, }, } subscriptionschedule.Update( schedule.ID, params, ) s, _ := subscription.New(params) ``` ## Confirm updates To confirm that you’ve properly updated your subscriptions, create a [preview invoice](https://docs.stripe.com/api/invoices/create_preview.md) for each subscription and inspect the results of its tax calculation. You can retrieve the tax amounts from the [tax](https://docs.stripe.com/api/invoices/object.md#invoice_object-tax) and [total_tax_amounts](https://docs.stripe.com/api/invoices/object.md#invoice_object-total_tax_amounts) fields on the preview invoice, and from the per-line-item [tax_amounts](https://docs.stripe.com/api/invoices/line_item.md#invoice_line_item_object-tax_amounts) fields. The invoice has an [automatic_tax](https://docs.stripe.com/api/invoices/object.md#invoice_object-automatic_tax) field showing the status of the calculation, with one of three possible statuses: | Status | Description | Possible Action | | -------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `complete` | Stripe Tax has successfully assessed the taxes on the payment. | You can retrieve the tax amounts from the tax and `total_tax_amounts` fields on the latest invoice, and from the per-line item `tax_amounts` fields. | | `requires_location_inputs` | Stripe Tax was unable to assess taxes because it didn’t have enough information to determine the customer’s location. | Collect more information from a customer (such as a full street address) and update the [customer.address](https://docs.stripe.com/api/invoices/object.md#invoice_object-customer_address) field. | | `failed` | Internal Stripe error. | Try the request again or contact Stripe support for additional assistance. | ## See Also * [Create new subscriptions with Stripe Tax](https://docs.stripe.com/tax/subscriptions.md) * [Setting tax codes, products, and prices](https://docs.stripe.com/tax/products-prices-tax-codes-tax-behavior.md)