--- title: Collect taxes for recurring payments subtitle: Learn how to collect and report taxes for recurring payments. route: /billing/taxes/collect-taxes --- # Collect taxes for recurring payments Learn how to collect and report taxes for recurring payments. To calculate tax for recurring payments, Stripe offers Stripe Tax and Tax Rates. - **Stripe Tax**—a paid product that automatically calculates the tax on your transactions without the need to define the rates and rules. Fees only apply after you’ve added at least one location where you’re registered to calculate and remit tax. For more information, see [Stripe Tax](https://stripe.com/tax). - **Tax Rates**—a free feature that allows you to define any number of tax rates for *invoices* (Invoices are statements of amounts owed by a customer. They track the status of payments from draft through paid or otherwise finalized. Subscriptions automatically generate invoices, or you can manually create a one-off invoice), *subscriptions* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis), and one-time payments that use Checkout. Stripe won’t create or maintain any tax rates on your behalf. For more information, see [Tax Rates](https://stripe.com/api/tax_rates) and [how to use them](https://stripe.com/billing/taxes/tax-rates). Stripe Tax allows you to calculate the tax amount on your recurring payments when using Stripe Billing. Use your customer’s location details to preview the tax amount before creating a subscription and then create it with Stripe Tax enabled when your customer is ready to pay. Stripe Tax integrates with Stripe Billing and automatically handles tax calculation with your [pricing model](https://stripe.com/products-prices/pricing-models), [prorations](https://stripe.com/billing/subscriptions/prorations), [discounts](https://stripe.com/billing/subscriptions/coupons), [trials](https://stripe.com/billing/subscriptions/trials), and so on. This guide assumes you’re setting up Stripe Tax and Billing for the first time. See how to [update existing subscriptions](https://stripe.com/tax/subscriptions/update). If you’re using Stripe Checkout to create new subscriptions, see how to [automatically collect tax on Checkout sessions](https://stripe.com/tax/checkout), or watch the short video below: ## Estimate taxes and total [Server-side] #### Before address collection When a customer first enters your checkout flow, you might not have their address information yet. In this case, [create a preview invoice](https://stripe.com/api/invoices/create_preview) and set [customer_details.tax.ip_address](https://stripe.com/api/invoices/create_preview#create_create_preview-customer_details-tax-ip_address) to let Stripe locate them using their IP address. In most cases, Stripe can resolve an IP address to a physical area, but its precision varies and might not reflect your customer’s actual location. We don’t recommend relying on a customer’s IP address to determine their address beyond an initial estimate. Code snippet calling post /v1/invoices/create_preview in curl (resource-based pattern). ```curl curl https://api.stripe.com/v1/invoices/create_preview \ -u "sk_test_BQokikJOvBiI2HlWgH4olfQ2:" \ -d "automatic_tax[enabled]"=true \ -d "customer_details[tax][ip_address]"={{IP_ADDRESS}} \ -d "subscription_details[items][0][price]"="{{PRICE_ID}}" ``` Code snippet calling post /v1/invoices/create_preview in cli (resource-based pattern). ```cli stripe invoices create_preview \ -d "automatic_tax[enabled]"=true \ -d "customer_details[tax][ip_address]"={{IP_ADDRESS}} \ -d "subscription_details[items][0][price]"="{{PRICE_ID}}" ``` Code snippet calling post /v1/invoices/create_preview in ruby (resource-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = 'sk_test_BQokikJOvBiI2HlWgH4olfQ2' invoice = Stripe::Invoice.create_preview({ automatic_tax: {enabled: true}, customer_details: {tax: {ip_address: '{{IP_ADDRESS}}'}}, subscription_details: {items: [{price: '{{PRICE_ID}}'}]}, }) ``` Code snippet calling post /v1/invoices/create_preview in ruby (service-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("sk_test_BQokikJOvBiI2HlWgH4olfQ2") invoice = client.v1.invoices.create_preview({ automatic_tax: {enabled: true}, customer_details: {tax: {ip_address: '{{IP_ADDRESS}}'}}, subscription_details: {items: [{price: '{{PRICE_ID}}'}]}, }) ``` Code snippet calling post /v1/invoices/create_preview in python (resource-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" invoice = stripe.Invoice.create_preview( automatic_tax={"enabled": True}, customer_details={"tax": {"ip_address": "{{IP_ADDRESS}}"}}, subscription_details={"items": [{"price": "{{PRICE_ID}}"}]}, ) ``` Code snippet calling post /v1/invoices/create_preview in python (service-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2") invoice = client.invoices.create_preview({ "automatic_tax": {"enabled": True}, "customer_details": {"tax": {"ip_address": "{{IP_ADDRESS}}"}}, "subscription_details": {"items": [{"price": "{{PRICE_ID}}"}]}, }) ``` Code snippet calling post /v1/invoices/create_preview in php (resource-based pattern). ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); $invoice = $stripe->invoices->createPreview([ 'automatic_tax' => ['enabled' => true], 'customer_details' => ['tax' => ['ip_address' => '{{IP_ADDRESS}}']], 'subscription_details' => ['items' => [['price' => '{{PRICE_ID}}']]], ]); ``` Code snippet calling post /v1/invoices/create_preview in java (resource-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; InvoiceCreatePreviewParams params = InvoiceCreatePreviewParams.builder() .setAutomaticTax( InvoiceCreatePreviewParams.AutomaticTax.builder().setEnabled(true).build() ) .setCustomerDetails( InvoiceCreatePreviewParams.CustomerDetails.builder() .setTax( InvoiceCreatePreviewParams.CustomerDetails.Tax.builder() .setIpAddress("{{IP_ADDRESS}}") .build() ) .build() ) .setSubscriptionDetails( InvoiceCreatePreviewParams.SubscriptionDetails.builder() .addItem( InvoiceCreatePreviewParams.SubscriptionDetails.Item.builder() .setPrice("{{PRICE_ID}}") .build() ) .build() ) .build(); Invoice invoice = Invoice.createPreview(params); ``` Code snippet calling post /v1/invoices/create_preview in java (service-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); InvoiceCreatePreviewParams params = InvoiceCreatePreviewParams.builder() .setAutomaticTax( InvoiceCreatePreviewParams.AutomaticTax.builder().setEnabled(true).build() ) .setCustomerDetails( InvoiceCreatePreviewParams.CustomerDetails.builder() .setTax( InvoiceCreatePreviewParams.CustomerDetails.Tax.builder() .setIpAddress("{{IP_ADDRESS}}") .build() ) .build() ) .setSubscriptionDetails( InvoiceCreatePreviewParams.SubscriptionDetails.builder() .addItem( InvoiceCreatePreviewParams.SubscriptionDetails.Item.builder() .setPrice("{{PRICE_ID}}") .build() ) .build() ) .build(); Invoice invoice = client.invoices().createPreview(params); ``` Code snippet calling post /v1/invoices/create_preview in node (resource-based pattern). ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); const invoice = await stripe.invoices.createPreview({ automatic_tax: { enabled: true, }, customer_details: { tax: { ip_address: '{{IP_ADDRESS}}', }, }, subscription_details: { items: [ { price: '{{PRICE_ID}}', }, ], }, }); ``` Code snippet calling post /v1/invoices/create_preview in go (resource-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" params := &stripe.InvoiceCreatePreviewParams{ AutomaticTax: &stripe.InvoiceCreatePreviewAutomaticTaxParams{ Enabled: stripe.Bool(true), }, CustomerDetails: &stripe.InvoiceCreatePreviewCustomerDetailsParams{ Tax: &stripe.InvoiceCreatePreviewCustomerDetailsTaxParams{ IPAddress: stripe.String("{{IP_ADDRESS}}"), }, }, SubscriptionDetails: &stripe.InvoiceCreatePreviewSubscriptionDetailsParams{ Items: []*stripe.InvoiceCreatePreviewSubscriptionDetailsItemParams{ &stripe.InvoiceCreatePreviewSubscriptionDetailsItemParams{ Price: stripe.String("{{PRICE_ID}}"), }, }, }, }; result, err := invoice.CreatePreview(params); ``` Code snippet calling post /v1/invoices/create_preview in go (service-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); params := &stripe.InvoiceCreatePreviewParams{ AutomaticTax: &stripe.InvoiceCreatePreviewAutomaticTaxParams{ Enabled: stripe.Bool(true), }, CustomerDetails: &stripe.InvoiceCreatePreviewCustomerDetailsParams{ Tax: &stripe.InvoiceCreatePreviewCustomerDetailsTaxParams{ IPAddress: stripe.String("{{IP_ADDRESS}}"), }, }, SubscriptionDetails: &stripe.InvoiceCreatePreviewSubscriptionDetailsParams{ Items: []*stripe.InvoiceCreatePreviewSubscriptionDetailsItemParams{ &stripe.InvoiceCreatePreviewSubscriptionDetailsItemParams{ Price: stripe.String("{{PRICE_ID}}"), }, }, }, }; result, err := sc.V1Invoices.CreatePreview(context.TODO(), params); ``` Code snippet calling post /v1/invoices/create_preview in dotnet (resource-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; var options = new InvoiceCreatePreviewOptions { AutomaticTax = new InvoiceAutomaticTaxOptions { Enabled = true }, CustomerDetails = new InvoiceCustomerDetailsOptions { Tax = new InvoiceCustomerDetailsTaxOptions { IpAddress = "{{IP_ADDRESS}}" }, }, SubscriptionDetails = new InvoiceSubscriptionDetailsOptions { Items = new List { new InvoiceSubscriptionDetailsItemOptions { Price = "{{PRICE_ID}}" }, }, }, }; var service = new InvoiceService(); Invoice invoice = service.CreatePreview(options); ``` Code snippet calling post /v1/invoices/create_preview in dotnet (service-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var options = new InvoiceCreatePreviewOptions { AutomaticTax = new InvoiceAutomaticTaxOptions { Enabled = true }, CustomerDetails = new InvoiceCustomerDetailsOptions { Tax = new InvoiceCustomerDetailsTaxOptions { IpAddress = "{{IP_ADDRESS}}" }, }, SubscriptionDetails = new InvoiceSubscriptionDetailsOptions { Items = new List { new InvoiceSubscriptionDetailsItemOptions { Price = "{{PRICE_ID}}" }, }, }, }; var client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); var service = client.V1.Invoices; Invoice invoice = service.CreatePreview(options); ``` #### After address collection When your customer fills in their address details, set [customer_details.address](https://stripe.com/api/invoices/create_preview#create_create_preview-customer_details-address) also. Use [customer_details.shipping](https://stripe.com/api/invoices/create_preview#create_create_preview-customer_details-shipping) if you’re collecting shipping addresses. Code snippet calling post /v1/invoices/create_preview in curl (resource-based pattern). ```curl curl https://api.stripe.com/v1/invoices/create_preview \ -u "sk_test_BQokikJOvBiI2HlWgH4olfQ2:" \ -d "automatic_tax[enabled]"=true \ -d "customer_details[address][line1]"={{LINE1}} \ -d "customer_details[address][line2]"={{LINE2}} \ -d "customer_details[address][city]"={{CITY}} \ -d "customer_details[address][state]"={{STATE}} \ -d "customer_details[address][postal_code]"={{POSTAL_CODE}} \ -d "customer_details[address][country]"={{COUNTRY}} \ -d "customer_details[tax][ip_address]"={{IP_ADDRESS}} \ -d "subscription_details[items][0][price]"="{{PRICE_ID}}" ``` Code snippet calling post /v1/invoices/create_preview in cli (resource-based pattern). ```cli stripe invoices create_preview \ -d "automatic_tax[enabled]"=true \ -d "customer_details[address][line1]"={{LINE1}} \ -d "customer_details[address][line2]"={{LINE2}} \ -d "customer_details[address][city]"={{CITY}} \ -d "customer_details[address][state]"={{STATE}} \ -d "customer_details[address][postal_code]"={{POSTAL_CODE}} \ -d "customer_details[address][country]"={{COUNTRY}} \ -d "customer_details[tax][ip_address]"={{IP_ADDRESS}} \ -d "subscription_details[items][0][price]"="{{PRICE_ID}}" ``` Code snippet calling post /v1/invoices/create_preview in ruby (resource-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = 'sk_test_BQokikJOvBiI2HlWgH4olfQ2' invoice = Stripe::Invoice.create_preview({ automatic_tax: {enabled: true}, customer_details: { address: { line1: '{{LINE1}}', line2: '{{LINE2}}', city: '{{CITY}}', state: '{{STATE}}', postal_code: '{{POSTAL_CODE}}', country: '{{COUNTRY}}', }, tax: {ip_address: '{{IP_ADDRESS}}'}, }, subscription_details: {items: [{price: '{{PRICE_ID}}'}]}, }) ``` Code snippet calling post /v1/invoices/create_preview in ruby (service-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("sk_test_BQokikJOvBiI2HlWgH4olfQ2") invoice = client.v1.invoices.create_preview({ automatic_tax: {enabled: true}, customer_details: { address: { line1: '{{LINE1}}', line2: '{{LINE2}}', city: '{{CITY}}', state: '{{STATE}}', postal_code: '{{POSTAL_CODE}}', country: '{{COUNTRY}}', }, tax: {ip_address: '{{IP_ADDRESS}}'}, }, subscription_details: {items: [{price: '{{PRICE_ID}}'}]}, }) ``` Code snippet calling post /v1/invoices/create_preview in python (resource-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" invoice = stripe.Invoice.create_preview( automatic_tax={"enabled": True}, customer_details={ "address": { "line1": "{{LINE1}}", "line2": "{{LINE2}}", "city": "{{CITY}}", "state": "{{STATE}}", "postal_code": "{{POSTAL_CODE}}", "country": "{{COUNTRY}}", }, "tax": {"ip_address": "{{IP_ADDRESS}}"}, }, subscription_details={"items": [{"price": "{{PRICE_ID}}"}]}, ) ``` Code snippet calling post /v1/invoices/create_preview in python (service-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2") invoice = client.invoices.create_preview({ "automatic_tax": {"enabled": True}, "customer_details": { "address": { "line1": "{{LINE1}}", "line2": "{{LINE2}}", "city": "{{CITY}}", "state": "{{STATE}}", "postal_code": "{{POSTAL_CODE}}", "country": "{{COUNTRY}}", }, "tax": {"ip_address": "{{IP_ADDRESS}}"}, }, "subscription_details": {"items": [{"price": "{{PRICE_ID}}"}]}, }) ``` Code snippet calling post /v1/invoices/create_preview in php (resource-based pattern). ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); $invoice = $stripe->invoices->createPreview([ 'automatic_tax' => ['enabled' => true], 'customer_details' => [ 'address' => [ 'line1' => '{{LINE1}}', 'line2' => '{{LINE2}}', 'city' => '{{CITY}}', 'state' => '{{STATE}}', 'postal_code' => '{{POSTAL_CODE}}', 'country' => '{{COUNTRY}}', ], 'tax' => ['ip_address' => '{{IP_ADDRESS}}'], ], 'subscription_details' => ['items' => [['price' => '{{PRICE_ID}}']]], ]); ``` Code snippet calling post /v1/invoices/create_preview in java (resource-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; InvoiceCreatePreviewParams params = InvoiceCreatePreviewParams.builder() .setAutomaticTax( InvoiceCreatePreviewParams.AutomaticTax.builder().setEnabled(true).build() ) .setCustomerDetails( InvoiceCreatePreviewParams.CustomerDetails.builder() .setAddress( InvoiceCreatePreviewParams.CustomerDetails.Address.builder() .setLine1("{{LINE1}}") .setLine2("{{LINE2}}") .setCity("{{CITY}}") .setState("{{STATE}}") .setPostalCode("{{POSTAL_CODE}}") .setCountry("{{COUNTRY}}") .build() ) .setTax( InvoiceCreatePreviewParams.CustomerDetails.Tax.builder() .setIpAddress("{{IP_ADDRESS}}") .build() ) .build() ) .setSubscriptionDetails( InvoiceCreatePreviewParams.SubscriptionDetails.builder() .addItem( InvoiceCreatePreviewParams.SubscriptionDetails.Item.builder() .setPrice("{{PRICE_ID}}") .build() ) .build() ) .build(); Invoice invoice = Invoice.createPreview(params); ``` Code snippet calling post /v1/invoices/create_preview in java (service-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); InvoiceCreatePreviewParams params = InvoiceCreatePreviewParams.builder() .setAutomaticTax( InvoiceCreatePreviewParams.AutomaticTax.builder().setEnabled(true).build() ) .setCustomerDetails( InvoiceCreatePreviewParams.CustomerDetails.builder() .setAddress( InvoiceCreatePreviewParams.CustomerDetails.Address.builder() .setLine1("{{LINE1}}") .setLine2("{{LINE2}}") .setCity("{{CITY}}") .setState("{{STATE}}") .setPostalCode("{{POSTAL_CODE}}") .setCountry("{{COUNTRY}}") .build() ) .setTax( InvoiceCreatePreviewParams.CustomerDetails.Tax.builder() .setIpAddress("{{IP_ADDRESS}}") .build() ) .build() ) .setSubscriptionDetails( InvoiceCreatePreviewParams.SubscriptionDetails.builder() .addItem( InvoiceCreatePreviewParams.SubscriptionDetails.Item.builder() .setPrice("{{PRICE_ID}}") .build() ) .build() ) .build(); Invoice invoice = client.invoices().createPreview(params); ``` Code snippet calling post /v1/invoices/create_preview in node (resource-based pattern). ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); const invoice = await stripe.invoices.createPreview({ automatic_tax: { enabled: true, }, customer_details: { address: { line1: '{{LINE1}}', line2: '{{LINE2}}', city: '{{CITY}}', state: '{{STATE}}', postal_code: '{{POSTAL_CODE}}', country: '{{COUNTRY}}', }, tax: { ip_address: '{{IP_ADDRESS}}', }, }, subscription_details: { items: [ { price: '{{PRICE_ID}}', }, ], }, }); ``` Code snippet calling post /v1/invoices/create_preview in go (resource-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" params := &stripe.InvoiceCreatePreviewParams{ AutomaticTax: &stripe.InvoiceCreatePreviewAutomaticTaxParams{ Enabled: stripe.Bool(true), }, CustomerDetails: &stripe.InvoiceCreatePreviewCustomerDetailsParams{ Address: &stripe.InvoiceCreatePreviewCustomerDetailsAddressParams{ Line1: stripe.String("{{LINE1}}"), Line2: stripe.String("{{LINE2}}"), City: stripe.String("{{CITY}}"), State: stripe.String("{{STATE}}"), PostalCode: stripe.String("{{POSTAL_CODE}}"), Country: stripe.String("{{COUNTRY}}"), }, Tax: &stripe.InvoiceCreatePreviewCustomerDetailsTaxParams{ IPAddress: stripe.String("{{IP_ADDRESS}}"), }, }, SubscriptionDetails: &stripe.InvoiceCreatePreviewSubscriptionDetailsParams{ Items: []*stripe.InvoiceCreatePreviewSubscriptionDetailsItemParams{ &stripe.InvoiceCreatePreviewSubscriptionDetailsItemParams{ Price: stripe.String("{{PRICE_ID}}"), }, }, }, }; result, err := invoice.CreatePreview(params); ``` Code snippet calling post /v1/invoices/create_preview in go (service-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); params := &stripe.InvoiceCreatePreviewParams{ AutomaticTax: &stripe.InvoiceCreatePreviewAutomaticTaxParams{ Enabled: stripe.Bool(true), }, CustomerDetails: &stripe.InvoiceCreatePreviewCustomerDetailsParams{ Address: &stripe.InvoiceCreatePreviewCustomerDetailsAddressParams{ Line1: stripe.String("{{LINE1}}"), Line2: stripe.String("{{LINE2}}"), City: stripe.String("{{CITY}}"), State: stripe.String("{{STATE}}"), PostalCode: stripe.String("{{POSTAL_CODE}}"), Country: stripe.String("{{COUNTRY}}"), }, Tax: &stripe.InvoiceCreatePreviewCustomerDetailsTaxParams{ IPAddress: stripe.String("{{IP_ADDRESS}}"), }, }, SubscriptionDetails: &stripe.InvoiceCreatePreviewSubscriptionDetailsParams{ Items: []*stripe.InvoiceCreatePreviewSubscriptionDetailsItemParams{ &stripe.InvoiceCreatePreviewSubscriptionDetailsItemParams{ Price: stripe.String("{{PRICE_ID}}"), }, }, }, }; result, err := sc.V1Invoices.CreatePreview(context.TODO(), params); ``` Code snippet calling post /v1/invoices/create_preview in dotnet (resource-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; var options = new InvoiceCreatePreviewOptions { AutomaticTax = new InvoiceAutomaticTaxOptions { Enabled = true }, CustomerDetails = new InvoiceCustomerDetailsOptions { Address = new AddressOptions { Line1 = "{{LINE1}}", Line2 = "{{LINE2}}", City = "{{CITY}}", State = "{{STATE}}", PostalCode = "{{POSTAL_CODE}}", Country = "{{COUNTRY}}", }, Tax = new InvoiceCustomerDetailsTaxOptions { IpAddress = "{{IP_ADDRESS}}" }, }, SubscriptionDetails = new InvoiceSubscriptionDetailsOptions { Items = new List { new InvoiceSubscriptionDetailsItemOptions { Price = "{{PRICE_ID}}" }, }, }, }; var service = new InvoiceService(); Invoice invoice = service.CreatePreview(options); ``` Code snippet calling post /v1/invoices/create_preview in dotnet (service-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var options = new InvoiceCreatePreviewOptions { AutomaticTax = new InvoiceAutomaticTaxOptions { Enabled = true }, CustomerDetails = new InvoiceCustomerDetailsOptions { Address = new AddressOptions { Line1 = "{{LINE1}}", Line2 = "{{LINE2}}", City = "{{CITY}}", State = "{{STATE}}", PostalCode = "{{POSTAL_CODE}}", Country = "{{COUNTRY}}", }, Tax = new InvoiceCustomerDetailsTaxOptions { IpAddress = "{{IP_ADDRESS}}" }, }, SubscriptionDetails = new InvoiceSubscriptionDetailsOptions { Items = new List { new InvoiceSubscriptionDetailsItemOptions { Price = "{{PRICE_ID}}" }, }, }, }; var client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); var service = client.V1.Invoices; Invoice invoice = service.CreatePreview(options); ``` Check the [automatic_tax.status](https://stripe.com/api/invoices/object#invoice_object-automatic_tax-status) of the invoice. If the status is `requires_location_inputs`, it means that the address details are invalid or insufficient. In this case, prompt your customer to re-enter their address details or provide accurate address details. The invoice [total](https://stripe.com/api/invoices/object#invoice_object-total) is how much your customer pays and [tax](https://stripe.com/api/invoices/object#invoice_object-tax) is the sum of all tax amounts on the invoice. If you want a breakdown of taxes, see [total_tax_amounts](https://stripe.com/api/invoices/object#invoice_object-total_tax_amounts). All amounts are in cents. If the `tax` is zero, make sure that you have a tax registration in your customer’s location. See how to [register for sales tax, VAT, and GST](https://stripe.com/tax/registering) and learn more about [zero tax amounts and reverse charges](https://stripe.com/tax/zero-tax). ## Collect customer information [Client-side] After you have an estimate of the taxes and the total, start collecting customer information including their shipping address (if applicable), billing address, and their payment details. Notice that when you use Stripe Tax, you collect payment details without an Intent. The first step is to [create an Elements object without an Intent](https://stripe.com/js/elements_object/create_without_intent): ```javascript const stripe = Stripe("pk_test_TYooMQauvdEDq54NiTphI7jx"); const elements = stripe.elements({ mode: 'subscription', currency: '{{CURRENCY}}', amount: , }); ``` Next, [create an Address Element](https://stripe.com/js/elements_object/create_address_element) and [a Payment Element](https://stripe.com/js/elements_object/create_payment_element) and [mount](https://stripe.com/js/element/mount) both: ```javascript const addressElement = elements.create('address', { mode: 'billing' // or 'shipping', if you are shipping goods }); addressElement.mount('#address-element'); const paymentElementOptions = { layout: 'accordion'}; const paymentElement = elements.create('payment', paymentElementOptions); paymentElement.mount('#payment-element'); ``` Then you can listen to [change events](https://stripe.com/js/element/events/on_change?type=paymentElement#element_on_change-event) on the Address Element. When the address changes, [re-estimate](https://stripe.com/tax/subscriptions?estimate=after#estimate-taxes-total) the taxes and the total. ```javascript addressElement.on('change', function(event) { // Throttle your requests to avoid overloading your server or hitting // Stripe's rate limits. const { tax, total } = await updateEstimate(event.value.address); elements.update({ amount: total }); // Update your page to display the new tax and total to the user... }); ``` When your customer is entering their address, Address Element fires a `change` event for each keystroke. To avoid overloading your server and hitting Stripe’s [rate limits](https://stripe.com/rate-limits), wait for some time after the last `change` event before re-estimating the taxes and the total. ## Handle submission [Client-side] When your customer submits the form, call [elements.submit()](https://stripe.com/js/elements/submit) to validate the form fields and collect any data required for wallets. You must wait for this function’s promise to resolve before performing any other operations. ```javascript document.querySelector("#form").addEventListener("submit", function(event) { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); const { error: submitError } = await elements.submit(); if (submitError) { // Handle error... return; } const { value: customerDetails } = await addressElement.getValue(); // See the "Save customer details" section below to implement this // server-side. await (customerDetails); // See the "Create subscription" section below to implement this server-side. const { } = await (); const { error: confirmError } = await stripe.confirmPayment({ elements, clientSecret, confirmParams: { return_url: , }, }); if (confirmError) { // Handle error... return; } // Upon a successful confirmation, your user will be redirected to the // return_url you provide before the Promise ever resolves. }); ``` ## Save customer details [Server-side] [Update](https://stripe.com/api/customers/update) your `Customer` object using the details you’ve collected from your customer, so that Stripe Tax can determine their precise location for accurate results. If your customer is in the United States, provide a full address if possible. We use the term “rooftop-accurate” to mean that we can attribute your customer’s location to a specific house or building. This provides greater accuracy, where two houses located side-by-side on the same street might be subject to different tax rates, because of complex jurisdiction boundaries. If you haven’t already created a `Customer` object (for example, when your customer first signs up on your website), you can [create](https://stripe.com/api/customers/create) one now. #### Update customer Code snippet calling post /v1/customers/{customer} in curl (resource-based pattern). ```curl curl https://api.stripe.com/v1/customers/{{CUSTOMER_ID}} \ -u "sk_test_BQokikJOvBiI2HlWgH4olfQ2:" \ -d "address[line1]"={{LINE1}} \ -d "address[line2]"={{LINE2}} \ -d "address[city]"={{CITY}} \ -d "address[state]"={{STATE}} \ -d "address[postal_code]"={{POSTAL_CODE}} \ -d "address[country]"={{COUNTRY}} \ -d "tax[validate_location]"=immediately ``` Code snippet calling post /v1/customers/{customer} in cli (resource-based pattern). ```cli stripe customers update {{CUSTOMER_ID}} \ -d "address[line1]"={{LINE1}} \ -d "address[line2]"={{LINE2}} \ -d "address[city]"={{CITY}} \ -d "address[state]"={{STATE}} \ -d "address[postal_code]"={{POSTAL_CODE}} \ -d "address[country]"={{COUNTRY}} \ -d "tax[validate_location]"=immediately ``` Code snippet calling post /v1/customers/{customer} in ruby (resource-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = 'sk_test_BQokikJOvBiI2HlWgH4olfQ2' customer = Stripe::Customer.update( '{{CUSTOMER_ID}}', { address: { line1: '{{LINE1}}', line2: '{{LINE2}}', city: '{{CITY}}', state: '{{STATE}}', postal_code: '{{POSTAL_CODE}}', country: '{{COUNTRY}}', }, tax: {validate_location: 'immediately'}, }, ) ``` Code snippet calling post /v1/customers/{customer} in ruby (service-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("sk_test_BQokikJOvBiI2HlWgH4olfQ2") customer = client.v1.customers.update( '{{CUSTOMER_ID}}', { address: { line1: '{{LINE1}}', line2: '{{LINE2}}', city: '{{CITY}}', state: '{{STATE}}', postal_code: '{{POSTAL_CODE}}', country: '{{COUNTRY}}', }, tax: {validate_location: 'immediately'}, }, ) ``` Code snippet calling post /v1/customers/{customer} in python (resource-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" customer = stripe.Customer.modify( "{{CUSTOMER_ID}}", address={ "line1": "{{LINE1}}", "line2": "{{LINE2}}", "city": "{{CITY}}", "state": "{{STATE}}", "postal_code": "{{POSTAL_CODE}}", "country": "{{COUNTRY}}", }, tax={"validate_location": "immediately"}, ) ``` Code snippet calling post /v1/customers/{customer} in python (service-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2") customer = client.customers.update( "{{CUSTOMER_ID}}", { "address": { "line1": "{{LINE1}}", "line2": "{{LINE2}}", "city": "{{CITY}}", "state": "{{STATE}}", "postal_code": "{{POSTAL_CODE}}", "country": "{{COUNTRY}}", }, "tax": {"validate_location": "immediately"}, }, ) ``` Code snippet calling post /v1/customers/{customer} in php (resource-based pattern). ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); $customer = $stripe->customers->update( '{{CUSTOMER_ID}}', [ 'address' => [ 'line1' => '{{LINE1}}', 'line2' => '{{LINE2}}', 'city' => '{{CITY}}', 'state' => '{{STATE}}', 'postal_code' => '{{POSTAL_CODE}}', 'country' => '{{COUNTRY}}', ], 'tax' => ['validate_location' => 'immediately'], ] ); ``` Code snippet calling post /v1/customers/{customer} in java (resource-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; Customer resource = Customer.retrieve("{{CUSTOMER_ID}}"); CustomerUpdateParams params = CustomerUpdateParams.builder() .setAddress( CustomerUpdateParams.Address.builder() .setLine1("{{LINE1}}") .setLine2("{{LINE2}}") .setCity("{{CITY}}") .setState("{{STATE}}") .setPostalCode("{{POSTAL_CODE}}") .setCountry("{{COUNTRY}}") .build() ) .setTax( CustomerUpdateParams.Tax.builder() .setValidateLocation(CustomerUpdateParams.Tax.ValidateLocation.IMMEDIATELY) .build() ) .build(); Customer customer = resource.update(params); ``` Code snippet calling post /v1/customers/{customer} in java (service-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); CustomerUpdateParams params = CustomerUpdateParams.builder() .setAddress( CustomerUpdateParams.Address.builder() .setLine1("{{LINE1}}") .setLine2("{{LINE2}}") .setCity("{{CITY}}") .setState("{{STATE}}") .setPostalCode("{{POSTAL_CODE}}") .setCountry("{{COUNTRY}}") .build() ) .setTax( CustomerUpdateParams.Tax.builder() .setValidateLocation(CustomerUpdateParams.Tax.ValidateLocation.IMMEDIATELY) .build() ) .build(); Customer customer = client.customers().update("{{CUSTOMER_ID}}", params); ``` Code snippet calling post /v1/customers/{customer} in node (resource-based pattern). ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); const customer = await stripe.customers.update( '{{CUSTOMER_ID}}', { address: { line1: '{{LINE1}}', line2: '{{LINE2}}', city: '{{CITY}}', state: '{{STATE}}', postal_code: '{{POSTAL_CODE}}', country: '{{COUNTRY}}', }, tax: { validate_location: 'immediately', }, } ); ``` Code snippet calling post /v1/customers/{customer} in go (resource-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" params := &stripe.CustomerParams{ Address: &stripe.AddressParams{ Line1: stripe.String("{{LINE1}}"), Line2: stripe.String("{{LINE2}}"), City: stripe.String("{{CITY}}"), State: stripe.String("{{STATE}}"), PostalCode: stripe.String("{{POSTAL_CODE}}"), Country: stripe.String("{{COUNTRY}}"), }, Tax: &stripe.CustomerTaxParams{ValidateLocation: stripe.String("immediately")}, }; result, err := customer.Update("{{CUSTOMER_ID}}", params); ``` Code snippet calling post /v1/customers/{customer} in go (service-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); params := &stripe.CustomerUpdateParams{ Address: &stripe.AddressParams{ Line1: stripe.String("{{LINE1}}"), Line2: stripe.String("{{LINE2}}"), City: stripe.String("{{CITY}}"), State: stripe.String("{{STATE}}"), PostalCode: stripe.String("{{POSTAL_CODE}}"), Country: stripe.String("{{COUNTRY}}"), }, Tax: &stripe.CustomerUpdateTaxParams{ValidateLocation: stripe.String("immediately")}, Customer: stripe.String("{{CUSTOMER_ID}}"), }; result, err := sc.V1Customers.Update(context.TODO(), params); ``` Code snippet calling post /v1/customers/{customer} in dotnet (resource-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; var options = new CustomerUpdateOptions { Address = new AddressOptions { Line1 = "{{LINE1}}", Line2 = "{{LINE2}}", City = "{{CITY}}", State = "{{STATE}}", PostalCode = "{{POSTAL_CODE}}", Country = "{{COUNTRY}}", }, Tax = new CustomerTaxOptions { ValidateLocation = "immediately" }, }; var service = new CustomerService(); Customer customer = service.Update("{{CUSTOMER_ID}}", options); ``` Code snippet calling post /v1/customers/{customer} in dotnet (service-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var options = new CustomerUpdateOptions { Address = new AddressOptions { Line1 = "{{LINE1}}", Line2 = "{{LINE2}}", City = "{{CITY}}", State = "{{STATE}}", PostalCode = "{{POSTAL_CODE}}", Country = "{{COUNTRY}}", }, Tax = new CustomerTaxOptions { ValidateLocation = "immediately" }, }; var client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); var service = client.V1.Customers; Customer customer = service.Update("{{CUSTOMER_ID}}", options); ``` If your customer has other existing subscriptions with automatic tax enabled and you update their address information, the tax and total amounts on their future invoices might be different. This is because tax rates vary depending on customer location. #### Create customer Code snippet calling post /v1/customers in curl (resource-based pattern). ```curl curl https://api.stripe.com/v1/customers \ -u "sk_test_BQokikJOvBiI2HlWgH4olfQ2:" \ -d "address[line1]"={{LINE1}} \ -d "address[line2]"={{LINE2}} \ -d "address[city]"={{CITY}} \ -d "address[state]"={{STATE}} \ -d "address[postal_code]"={{POSTAL_CODE}} \ -d "address[country]"={{COUNTRY}} \ -d "tax[validate_location]"=immediately ``` Code snippet calling post /v1/customers in cli (resource-based pattern). ```cli stripe customers create \ -d "address[line1]"={{LINE1}} \ -d "address[line2]"={{LINE2}} \ -d "address[city]"={{CITY}} \ -d "address[state]"={{STATE}} \ -d "address[postal_code]"={{POSTAL_CODE}} \ -d "address[country]"={{COUNTRY}} \ -d "tax[validate_location]"=immediately ``` Code snippet calling post /v1/customers in ruby (resource-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = 'sk_test_BQokikJOvBiI2HlWgH4olfQ2' customer = Stripe::Customer.create({ address: { line1: '{{LINE1}}', line2: '{{LINE2}}', city: '{{CITY}}', state: '{{STATE}}', postal_code: '{{POSTAL_CODE}}', country: '{{COUNTRY}}', }, tax: {validate_location: 'immediately'}, }) ``` Code snippet calling post /v1/customers in ruby (service-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("sk_test_BQokikJOvBiI2HlWgH4olfQ2") customer = client.v1.customers.create({ address: { line1: '{{LINE1}}', line2: '{{LINE2}}', city: '{{CITY}}', state: '{{STATE}}', postal_code: '{{POSTAL_CODE}}', country: '{{COUNTRY}}', }, tax: {validate_location: 'immediately'}, }) ``` Code snippet calling post /v1/customers in python (resource-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" customer = stripe.Customer.create( address={ "line1": "{{LINE1}}", "line2": "{{LINE2}}", "city": "{{CITY}}", "state": "{{STATE}}", "postal_code": "{{POSTAL_CODE}}", "country": "{{COUNTRY}}", }, tax={"validate_location": "immediately"}, ) ``` Code snippet calling post /v1/customers in python (service-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2") customer = client.customers.create({ "address": { "line1": "{{LINE1}}", "line2": "{{LINE2}}", "city": "{{CITY}}", "state": "{{STATE}}", "postal_code": "{{POSTAL_CODE}}", "country": "{{COUNTRY}}", }, "tax": {"validate_location": "immediately"}, }) ``` Code snippet calling post /v1/customers in php (resource-based pattern). ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); $customer = $stripe->customers->create([ 'address' => [ 'line1' => '{{LINE1}}', 'line2' => '{{LINE2}}', 'city' => '{{CITY}}', 'state' => '{{STATE}}', 'postal_code' => '{{POSTAL_CODE}}', 'country' => '{{COUNTRY}}', ], 'tax' => ['validate_location' => 'immediately'], ]); ``` Code snippet calling post /v1/customers in java (resource-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; CustomerCreateParams params = CustomerCreateParams.builder() .setAddress( CustomerCreateParams.Address.builder() .setLine1("{{LINE1}}") .setLine2("{{LINE2}}") .setCity("{{CITY}}") .setState("{{STATE}}") .setPostalCode("{{POSTAL_CODE}}") .setCountry("{{COUNTRY}}") .build() ) .setTax( CustomerCreateParams.Tax.builder() .setValidateLocation(CustomerCreateParams.Tax.ValidateLocation.IMMEDIATELY) .build() ) .build(); Customer customer = Customer.create(params); ``` Code snippet calling post /v1/customers in java (service-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); CustomerCreateParams params = CustomerCreateParams.builder() .setAddress( CustomerCreateParams.Address.builder() .setLine1("{{LINE1}}") .setLine2("{{LINE2}}") .setCity("{{CITY}}") .setState("{{STATE}}") .setPostalCode("{{POSTAL_CODE}}") .setCountry("{{COUNTRY}}") .build() ) .setTax( CustomerCreateParams.Tax.builder() .setValidateLocation(CustomerCreateParams.Tax.ValidateLocation.IMMEDIATELY) .build() ) .build(); Customer customer = client.customers().create(params); ``` Code snippet calling post /v1/customers in node (resource-based pattern). ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); const customer = await stripe.customers.create({ address: { line1: '{{LINE1}}', line2: '{{LINE2}}', city: '{{CITY}}', state: '{{STATE}}', postal_code: '{{POSTAL_CODE}}', country: '{{COUNTRY}}', }, tax: { validate_location: 'immediately', }, }); ``` Code snippet calling post /v1/customers in go (resource-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" params := &stripe.CustomerParams{ Address: &stripe.AddressParams{ Line1: stripe.String("{{LINE1}}"), Line2: stripe.String("{{LINE2}}"), City: stripe.String("{{CITY}}"), State: stripe.String("{{STATE}}"), PostalCode: stripe.String("{{POSTAL_CODE}}"), Country: stripe.String("{{COUNTRY}}"), }, Tax: &stripe.CustomerTaxParams{ValidateLocation: stripe.String("immediately")}, }; result, err := customer.New(params); ``` Code snippet calling post /v1/customers in go (service-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); params := &stripe.CustomerCreateParams{ Address: &stripe.AddressParams{ Line1: stripe.String("{{LINE1}}"), Line2: stripe.String("{{LINE2}}"), City: stripe.String("{{CITY}}"), State: stripe.String("{{STATE}}"), PostalCode: stripe.String("{{POSTAL_CODE}}"), Country: stripe.String("{{COUNTRY}}"), }, Tax: &stripe.CustomerCreateTaxParams{ValidateLocation: stripe.String("immediately")}, }; result, err := sc.V1Customers.Create(context.TODO(), params); ``` Code snippet calling post /v1/customers in dotnet (resource-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; var options = new CustomerCreateOptions { Address = new AddressOptions { Line1 = "{{LINE1}}", Line2 = "{{LINE2}}", City = "{{CITY}}", State = "{{STATE}}", PostalCode = "{{POSTAL_CODE}}", Country = "{{COUNTRY}}", }, Tax = new CustomerTaxOptions { ValidateLocation = "immediately" }, }; var service = new CustomerService(); Customer customer = service.Create(options); ``` Code snippet calling post /v1/customers in dotnet (service-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var options = new CustomerCreateOptions { Address = new AddressOptions { Line1 = "{{LINE1}}", Line2 = "{{LINE2}}", City = "{{CITY}}", State = "{{STATE}}", PostalCode = "{{POSTAL_CODE}}", Country = "{{COUNTRY}}", }, Tax = new CustomerTaxOptions { ValidateLocation = "immediately" }, }; var client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); var service = client.V1.Customers; Customer customer = service.Create(options); ``` The [tax.validate_location](https://stripe.com/api/customers/update#update_customer-tax-validate_location) enum value helps you make sure that the tax location of the customer becomes (or remains) valid as a result of this operation. If not, Stripe fails your request with the [customer_tax_location_invalid](https://stripe.com/error-codes#customer-tax-location-invalid) error code. This is important because you can’t create an automatic tax enabled subscription for a customer with an invalid tax location. If you’ve been checking the [automatic_tax.status](https://stripe.com/api/invoices/object#invoice_object-automatic_tax-status) of your preview invoices as [advised](#estimate-taxes-total) previously, this additional validation won’t ever fail. However, it’s good practice to set `tax[validate_location]="immediately"` whenever you’re creating or updating a `Customer` object. ## Create subscription [Server-side] [Create](https://stripe.com/api/subscriptions/create) a subscription with automatic tax enabled. Code snippet calling post /v1/subscriptions in curl (resource-based pattern). ```curl curl https://api.stripe.com/v1/subscriptions \ -u "sk_test_BQokikJOvBiI2HlWgH4olfQ2:" \ -d "automatic_tax[enabled]"=true \ -d customer="{{CUSTOMER_ID}}" \ -d "items[0][price]"="{{PRICE_ID}}" \ -d "payment_settings[save_default_payment_method]"=on_subscription \ -d "expand[0]"="latest_invoice.confirmation_secret" ``` Code snippet calling post /v1/subscriptions in cli (resource-based pattern). ```cli stripe subscriptions create \ -d "automatic_tax[enabled]"=true \ --customer="{{CUSTOMER_ID}}" \ -d "items[0][price]"="{{PRICE_ID}}" \ -d "payment_settings[save_default_payment_method]"=on_subscription \ -d "expand[0]"="latest_invoice.confirmation_secret" ``` Code snippet calling post /v1/subscriptions in ruby (resource-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = 'sk_test_BQokikJOvBiI2HlWgH4olfQ2' subscription = Stripe::Subscription.create({ automatic_tax: {enabled: true}, customer: '{{CUSTOMER_ID}}', items: [{price: '{{PRICE_ID}}'}], payment_settings: {save_default_payment_method: 'on_subscription'}, expand: ['latest_invoice.confirmation_secret'], }) ``` Code snippet calling post /v1/subscriptions in ruby (service-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("sk_test_BQokikJOvBiI2HlWgH4olfQ2") subscription = client.v1.subscriptions.create({ automatic_tax: {enabled: true}, customer: '{{CUSTOMER_ID}}', items: [{price: '{{PRICE_ID}}'}], payment_settings: {save_default_payment_method: 'on_subscription'}, expand: ['latest_invoice.confirmation_secret'], }) ``` Code snippet calling post /v1/subscriptions in python (resource-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" subscription = stripe.Subscription.create( automatic_tax={"enabled": True}, customer="{{CUSTOMER_ID}}", items=[{"price": "{{PRICE_ID}}"}], payment_settings={"save_default_payment_method": "on_subscription"}, expand=["latest_invoice.confirmation_secret"], ) ``` Code snippet calling post /v1/subscriptions in python (service-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2") subscription = client.subscriptions.create({ "automatic_tax": {"enabled": True}, "customer": "{{CUSTOMER_ID}}", "items": [{"price": "{{PRICE_ID}}"}], "payment_settings": {"save_default_payment_method": "on_subscription"}, "expand": ["latest_invoice.confirmation_secret"], }) ``` Code snippet calling post /v1/subscriptions in php (resource-based pattern). ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); $subscription = $stripe->subscriptions->create([ 'automatic_tax' => ['enabled' => true], 'customer' => '{{CUSTOMER_ID}}', 'items' => [['price' => '{{PRICE_ID}}']], 'payment_settings' => ['save_default_payment_method' => 'on_subscription'], 'expand' => ['latest_invoice.confirmation_secret'], ]); ``` Code snippet calling post /v1/subscriptions in java (resource-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; SubscriptionCreateParams params = SubscriptionCreateParams.builder() .setAutomaticTax( SubscriptionCreateParams.AutomaticTax.builder().setEnabled(true).build() ) .setCustomer("{{CUSTOMER_ID}}") .addItem( SubscriptionCreateParams.Item.builder().setPrice("{{PRICE_ID}}").build() ) .setPaymentSettings( SubscriptionCreateParams.PaymentSettings.builder() .setSaveDefaultPaymentMethod( SubscriptionCreateParams.PaymentSettings.SaveDefaultPaymentMethod.ON_SUBSCRIPTION ) .build() ) .addExpand("latest_invoice.confirmation_secret") .build(); Subscription subscription = Subscription.create(params); ``` Code snippet calling post /v1/subscriptions in java (service-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); SubscriptionCreateParams params = SubscriptionCreateParams.builder() .setAutomaticTax( SubscriptionCreateParams.AutomaticTax.builder().setEnabled(true).build() ) .setCustomer("{{CUSTOMER_ID}}") .addItem( SubscriptionCreateParams.Item.builder().setPrice("{{PRICE_ID}}").build() ) .setPaymentSettings( SubscriptionCreateParams.PaymentSettings.builder() .setSaveDefaultPaymentMethod( SubscriptionCreateParams.PaymentSettings.SaveDefaultPaymentMethod.ON_SUBSCRIPTION ) .build() ) .addExpand("latest_invoice.confirmation_secret") .build(); Subscription subscription = client.subscriptions().create(params); ``` Code snippet calling post /v1/subscriptions in node (resource-based pattern). ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); const subscription = await stripe.subscriptions.create({ automatic_tax: { enabled: true, }, customer: '{{CUSTOMER_ID}}', items: [ { price: '{{PRICE_ID}}', }, ], payment_settings: { save_default_payment_method: 'on_subscription', }, expand: ['latest_invoice.confirmation_secret'], }); ``` Code snippet calling post /v1/subscriptions in go (resource-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" params := &stripe.SubscriptionParams{ AutomaticTax: &stripe.SubscriptionAutomaticTaxParams{Enabled: stripe.Bool(true)}, Customer: stripe.String("{{CUSTOMER_ID}}"), Items: []*stripe.SubscriptionItemsParams{ &stripe.SubscriptionItemsParams{Price: stripe.String("{{PRICE_ID}}")}, }, PaymentSettings: &stripe.SubscriptionPaymentSettingsParams{ SaveDefaultPaymentMethod: stripe.String(stripe.SubscriptionPaymentSettingsSaveDefaultPaymentMethodOnSubscription), }, }; params.AddExpand("latest_invoice.confirmation_secret") result, err := subscription.New(params); ``` Code snippet calling post /v1/subscriptions in go (service-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); params := &stripe.SubscriptionCreateParams{ AutomaticTax: &stripe.SubscriptionCreateAutomaticTaxParams{Enabled: stripe.Bool(true)}, Customer: stripe.String("{{CUSTOMER_ID}}"), Items: []*stripe.SubscriptionCreateItemParams{ &stripe.SubscriptionCreateItemParams{Price: stripe.String("{{PRICE_ID}}")}, }, PaymentSettings: &stripe.SubscriptionCreatePaymentSettingsParams{ SaveDefaultPaymentMethod: stripe.String(stripe.SubscriptionPaymentSettingsSaveDefaultPaymentMethodOnSubscription), }, }; params.AddExpand("latest_invoice.confirmation_secret") result, err := sc.V1Subscriptions.Create(context.TODO(), params); ``` Code snippet calling post /v1/subscriptions in dotnet (resource-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; var options = new SubscriptionCreateOptions { AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true }, Customer = "{{CUSTOMER_ID}}", Items = new List { new SubscriptionItemOptions { Price = "{{PRICE_ID}}" }, }, PaymentSettings = new SubscriptionPaymentSettingsOptions { SaveDefaultPaymentMethod = "on_subscription", }, Expand = new List { "latest_invoice.confirmation_secret" }, }; var service = new SubscriptionService(); Subscription subscription = service.Create(options); ``` Code snippet calling post /v1/subscriptions in dotnet (service-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var options = new SubscriptionCreateOptions { AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true }, Customer = "{{CUSTOMER_ID}}", Items = new List { new SubscriptionItemOptions { Price = "{{PRICE_ID}}" }, }, PaymentSettings = new SubscriptionPaymentSettingsOptions { SaveDefaultPaymentMethod = "on_subscription", }, Expand = new List { "latest_invoice.confirmation_secret" }, }; var client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); var service = client.V1.Subscriptions; Subscription subscription = service.Create(options); ``` The [latest_invoice.confirmation_secret.client_secret](https://stripe.com/api/invoices/object#invoice_object-confirmation_secret-client_secrett) is the *client secret* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) of the *payment intent* (API object that represents your intent to collect payment from a customer, tracking charge attempts and payment state changes throughout the process) of the first (and the latest) invoice of the new subscription. You need to pass the client secret to your front end to be able to *confirm* (Confirming a PaymentIntent indicates that the customer intends to pay with the current or provided payment method. Upon confirmation, the PaymentIntent attempts to initiate a payment) the payment intent. Don’t store, log, or expose the client secret to anyone other than the customer. Make sure that you have TLS enabled on any page that includes the client secret. If your customer has a default payment method, the first invoice of the subscription is paid automatically. You can confirm this using [latest_invoice.status](https://stripe.com/api/invoices/object#invoice_object-status) of the subscription. If you want to use the new payment details you collected from your customer in your checkout flow, make sure that the first invoice isn’t paid automatically. Pass `default_incomplete` for the [payment_behavior](https://stripe.com/api/subscriptions/create#create_subscription-payment_behavior) when you’re creating your subscription and confirm the payment intent using [stripe.confirmPayment()](https://stripe.com/js/payment_intents/confirm_payment) as shown. See [Billing collection methods](https://stripe.com/billing/collection-method) for more information. ## Optional: Update your products and prices Stripe Tax uses information stored on *products* (Products represent what your business sells—whether that's a good or a service) and *prices* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions) to calculate tax, such as *tax code* (A tax code is the category of your product for tax purposes) and *tax behavior* (Tax behavior determines whether you want to include taxes in the price ("inclusive") or add them on top ("exclusive")). If you don’t explicitly specify these configurations, Stripe Tax will use the default tax code selected in [Tax Settings](https://dashboard.stripe.com/settings/tax). For more information, see [Specify product tax codes and tax behaviour](https://stripe.com/tax/products-prices-tax-codes-tax-behavior). ## Optional: Handle refunds [Server-side] When you create a refund for an Invoice payment, Stripe Tax automatically reduces your tax liability. Alternatively, you can issue [Credit Notes](https://stripe.com/api/credit_notes/object) to track tax liability decreases and provide records to your customers. #### Refund invoice amount To refund an amount associated with an invoice total, create a Credit Note and a Refund. #### Credit Note with automatic Refund Create a Credit Note and a [Refund](https://stripe.com/api/refunds/object) together by calling [create Credit Note](https://stripe.com/api/credit_notes/create) and providing a `refund_amount` value. Code snippet calling post /v1/credit_notes in curl (resource-based pattern). ```curl curl https://api.stripe.com/v1/credit_notes \ -u "sk_test_BQokikJOvBiI2HlWgH4olfQ2:" \ -d invoice="{{INVOICE_ID}}" \ -d refund_amount=1000 ``` Code snippet calling post /v1/credit_notes in cli (resource-based pattern). ```cli stripe credit_notes create \ --invoice="{{INVOICE_ID}}" \ --refund-amount=1000 ``` Code snippet calling post /v1/credit_notes in ruby (resource-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = 'sk_test_BQokikJOvBiI2HlWgH4olfQ2' credit_note = Stripe::CreditNote.create({ invoice: '{{INVOICE_ID}}', refund_amount: 1000, }) ``` Code snippet calling post /v1/credit_notes in ruby (service-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("sk_test_BQokikJOvBiI2HlWgH4olfQ2") credit_note = client.v1.credit_notes.create({ invoice: '{{INVOICE_ID}}', refund_amount: 1000, }) ``` Code snippet calling post /v1/credit_notes in python (resource-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" credit_note = stripe.CreditNote.create( invoice="{{INVOICE_ID}}", refund_amount=1000, ) ``` Code snippet calling post /v1/credit_notes in python (service-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2") credit_note = client.credit_notes.create({ "invoice": "{{INVOICE_ID}}", "refund_amount": 1000, }) ``` Code snippet calling post /v1/credit_notes in php (resource-based pattern). ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); $creditNote = $stripe->creditNotes->create([ 'invoice' => '{{INVOICE_ID}}', 'refund_amount' => 1000, ]); ``` Code snippet calling post /v1/credit_notes in java (resource-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; CreditNoteCreateParams params = CreditNoteCreateParams.builder() .setInvoice("{{INVOICE_ID}}") .setRefundAmount(1000L) .build(); CreditNote creditNote = CreditNote.create(params); ``` Code snippet calling post /v1/credit_notes in java (service-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); CreditNoteCreateParams params = CreditNoteCreateParams.builder() .setInvoice("{{INVOICE_ID}}") .setRefundAmount(1000L) .build(); CreditNote creditNote = client.creditNotes().create(params); ``` Code snippet calling post /v1/credit_notes in node (resource-based pattern). ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); const creditNote = await stripe.creditNotes.create({ invoice: '{{INVOICE_ID}}', refund_amount: 1000, }); ``` Code snippet calling post /v1/credit_notes in go (resource-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" params := &stripe.CreditNoteParams{ Invoice: stripe.String("{{INVOICE_ID}}"), RefundAmount: stripe.Int64(1000), }; result, err := creditnote.New(params); ``` Code snippet calling post /v1/credit_notes in go (service-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); params := &stripe.CreditNoteCreateParams{ Invoice: stripe.String("{{INVOICE_ID}}"), RefundAmount: stripe.Int64(1000), }; result, err := sc.V1CreditNotes.Create(context.TODO(), params); ``` Code snippet calling post /v1/credit_notes in dotnet (resource-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; var options = new CreditNoteCreateOptions { Invoice = "{{INVOICE_ID}}", RefundAmount = 1000, }; var service = new CreditNoteService(); CreditNote creditNote = service.Create(options); ``` Code snippet calling post /v1/credit_notes in dotnet (service-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var options = new CreditNoteCreateOptions { Invoice = "{{INVOICE_ID}}", RefundAmount = 1000, }; var client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); var service = client.V1.CreditNotes; CreditNote creditNote = service.Create(options); ``` #### Credit Note with manual Refund [Create a Refund](https://stripe.com/api/refunds/create), then include its ID when you create a [Credit Note](https://stripe.com/api/credit_notes/object). In this case, don’t include a `refund_amount` value. Code snippet calling post /v1/credit_notes in curl (resource-based pattern). ```curl curl https://api.stripe.com/v1/credit_notes \ -u "sk_test_BQokikJOvBiI2HlWgH4olfQ2:" \ -d invoice="{{INVOICE_ID}}" \ -d refund="{{REFUND_ID}}" \ -d amount=1000 ``` Stripe Tax automatically distributes the total refund amount between taxes and the net amount. #### Refund invoice line item amount If you want to refund an amount associated with an invoice line item, first calculate the [total](https://stripe.com/api/credit_notes/object#credit_note_object-total) and [total_excluding_tax](https://stripe.com/api/credit_notes/object#credit_note_object-total_excluding_tax) amounts by calling [preview Credit Note](https://stripe.com/api/credit_notes/preview). Code snippet calling get /v1/credit_notes/preview in curl (resource-based pattern). ```curl curl -G https://api.stripe.com/v1/credit_notes/preview \ -u "sk_test_BQokikJOvBiI2HlWgH4olfQ2:" \ -d invoice="{{INVOICE_ID}}" \ -d "lines[0][type]"=invoice_line_item \ -d "lines[0][invoice_line_item]"="{{line item id from invoice}}" \ -d "lines[0][amount]"=1000 ``` Code snippet calling get /v1/credit_notes/preview in cli (resource-based pattern). ```cli stripe credit_notes preview \ --invoice="{{INVOICE_ID}}" \ -d "lines[0][type]"=invoice_line_item \ -d "lines[0][invoice_line_item]"="{{line item id from invoice}}" \ -d "lines[0][amount]"=1000 ``` Code snippet calling get /v1/credit_notes/preview in ruby (resource-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = 'sk_test_BQokikJOvBiI2HlWgH4olfQ2' credit_note = Stripe::CreditNote.preview({ invoice: '{{INVOICE_ID}}', lines: [ { type: 'invoice_line_item', invoice_line_item: '{{line item id from invoice}}', amount: 1000, }, ], }) ``` Code snippet calling get /v1/credit_notes/preview in ruby (service-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("sk_test_BQokikJOvBiI2HlWgH4olfQ2") credit_note = client.v1.credit_notes.preview({ invoice: '{{INVOICE_ID}}', lines: [ { type: 'invoice_line_item', invoice_line_item: '{{line item id from invoice}}', amount: 1000, }, ], }) ``` Code snippet calling get /v1/credit_notes/preview in python (resource-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" credit_note = stripe.CreditNote.preview( invoice="{{INVOICE_ID}}", lines=[ { "type": "invoice_line_item", "invoice_line_item": "{{line item id from invoice}}", "amount": 1000, }, ], ) ``` Code snippet calling get /v1/credit_notes/preview in python (service-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2") credit_note = client.credit_notes.preview({ "invoice": "{{INVOICE_ID}}", "lines": [ { "type": "invoice_line_item", "invoice_line_item": "{{line item id from invoice}}", "amount": 1000, }, ], }) ``` Code snippet calling get /v1/credit_notes/preview in php (resource-based pattern). ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); $creditNote = $stripe->creditNotes->preview([ 'invoice' => '{{INVOICE_ID}}', 'lines' => [ [ 'type' => 'invoice_line_item', 'invoice_line_item' => '{{line item id from invoice}}', 'amount' => 1000, ], ], ]); ``` Code snippet calling get /v1/credit_notes/preview in java (resource-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; CreditNotePreviewParams params = CreditNotePreviewParams.builder() .setInvoice("{{INVOICE_ID}}") .addLine( CreditNotePreviewParams.Line.builder() .setType(CreditNotePreviewParams.Line.Type.INVOICE_LINE_ITEM) .setInvoiceLineItem("{{line item id from invoice}}") .setAmount(1000L) .build() ) .build(); CreditNote creditNote = CreditNote.preview(params); ``` Code snippet calling get /v1/credit_notes/preview in java (service-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); CreditNotePreviewParams params = CreditNotePreviewParams.builder() .setInvoice("{{INVOICE_ID}}") .addLine( CreditNotePreviewParams.Line.builder() .setType(CreditNotePreviewParams.Line.Type.INVOICE_LINE_ITEM) .setInvoiceLineItem("{{line item id from invoice}}") .setAmount(1000L) .build() ) .build(); CreditNote creditNote = client.creditNotes().preview(params); ``` Code snippet calling get /v1/credit_notes/preview in node (resource-based pattern). ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); const creditNote = await stripe.creditNotes.preview({ invoice: '{{INVOICE_ID}}', lines: [ { type: 'invoice_line_item', invoice_line_item: '{{line item id from invoice}}', amount: 1000, }, ], }); ``` Code snippet calling get /v1/credit_notes/preview in go (resource-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" params := &stripe.CreditNotePreviewParams{ Invoice: stripe.String("{{INVOICE_ID}}"), Lines: []*stripe.CreditNotePreviewLineParams{ &stripe.CreditNotePreviewLineParams{ Type: stripe.String("invoice_line_item"), InvoiceLineItem: stripe.String("{{line item id from invoice}}"), Amount: stripe.Int64(1000), }, }, }; result, err := creditnote.Preview(params); ``` Code snippet calling get /v1/credit_notes/preview in go (service-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); params := &stripe.CreditNotePreviewParams{ Invoice: stripe.String("{{INVOICE_ID}}"), Lines: []*stripe.CreditNotePreviewLineParams{ &stripe.CreditNotePreviewLineParams{ Type: stripe.String("invoice_line_item"), InvoiceLineItem: stripe.String("{{line item id from invoice}}"), Amount: stripe.Int64(1000), }, }, }; result, err := sc.V1CreditNotes.Preview(context.TODO(), params); ``` Code snippet calling get /v1/credit_notes/preview in dotnet (resource-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; var options = new CreditNotePreviewOptions { Invoice = "{{INVOICE_ID}}", Lines = new List { new CreditNoteLineOptions { Type = "invoice_line_item", InvoiceLineItem = "{{line item id from invoice}}", Amount = 1000, }, }, }; var service = new CreditNoteService(); CreditNote creditNote = service.Preview(options); ``` Code snippet calling get /v1/credit_notes/preview in dotnet (service-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var options = new CreditNotePreviewOptions { Invoice = "{{INVOICE_ID}}", Lines = new List { new CreditNoteLineOptions { Type = "invoice_line_item", InvoiceLineItem = "{{line item id from invoice}}", Amount = 1000, }, }, }; var client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); var service = client.V1.CreditNotes; CreditNote creditNote = service.Preview(options); ``` Then, create a [Credit Note](https://stripe.com/api/credit_notes/object) and a [Refund](https://stripe.com/api/refunds/object). #### Credit Note with automatic Refund Create a Credit Note and a [Refund](https://stripe.com/api/refunds/object) together by calling [create Credit Note](https://stripe.com/api/credit_notes/create) and providing a `refund_amount` value. Code snippet calling post /v1/credit_notes in curl (resource-based pattern). ```curl curl https://api.stripe.com/v1/credit_notes \ -u "sk_test_BQokikJOvBiI2HlWgH4olfQ2:" \ -d invoice="{{INVOICE_ID}}" \ -d refund_amount=1000 \ -d "lines[0][type]"=invoice_line_item \ -d "lines[0][invoice_line_item]"="{{line item id from invoice}}" \ -d "lines[0][amount]"=1000 ``` #### Credit Note with manual Refund [Create a Refund](https://stripe.com/api/refunds/create) using the `total` calculated by the Credit Note preview, then include its ID when you create a [Credit Note](https://stripe.com/api/credit_notes/object). In this case, don’t include a `refund_amount` value. Code snippet calling post /v1/credit_notes in curl (resource-based pattern). ```curl curl https://api.stripe.com/v1/credit_notes \ -u "sk_test_BQokikJOvBiI2HlWgH4olfQ2:" \ -d invoice="{{INVOICE_ID}}" \ -d refund="{{REFUND_ID}}" \ -d "lines[0][type]"=invoice_line_item \ -d "lines[0][invoice_line_item]"="{{line item id from invoice}}" \ -d "lines[0][amount]"=1000 ``` ## Use webhooks We recommend listening to subscription events with *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) because most subscription activity happens asynchronously. When you start using Stripe Tax, make sure to listen to [invoice.finalization_failed](https://stripe.com/api/events/types#event_types-invoice.finalization_failed) events. If the [automatic_tax.status](https://stripe.com/api/invoices/object#invoice_object-automatic_tax-status) of the invoice is `requires_location_inputs`, it means that the address details of your customer are invalid or insufficient. In this case, Stripe can’t calculate the taxes, can’t finalize the invoice, and can’t collect the payment. Notify your customer to re-enter their address details or provide an accurate address. See [Using webhooks with subscriptions](https://stripe.com/billing/subscriptions/webhooks) to learn more. To collect taxes on a subscription, set [tax rates on the subscription](#static-configuration) or [set the tax rates on invoices as the subscription cycles](#dynamic-configuration). Or, if you use Checkout, you can [specify tax rates in Checkout Sessions](#adding-tax-rates-to-checkout) to apply taxes to subscriptions. ## Setting tax rates on a subscription Subscriptions create draft invoices that stay editable for about an hour. During this time, you can correct the tax rates using the steps outlined below. You can apply taxes at the subscription level and the subscription item level and set up to [five tax rates](https://stripe.com/billing/taxes/tax-rates#using-multiple-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](https://stripe.com/api/subscription_items/object#subscription_item_object-tax_rates-id). The example below updates an existing subscription item with two tax rates: Code snippet calling post /v1/subscription_items/{id} in curl (resource-based pattern). ```curl curl https://api.stripe.com/v1/subscription_items/si_F2yjdxUlCCOAtv \ -u "sk_test_BQokikJOvBiI2HlWgH4olfQ2:" \ -d "tax_rates[]"=txr_1F6kmAAJVYItwOKqV9IWehUH \ -d "tax_rates[]"=txr_2J8lmBBGHJYyuUJqF6QJtkNM ``` Code snippet calling post /v1/subscription_items/{id} in cli (resource-based pattern). ```cli stripe subscription_items update si_F2yjdxUlCCOAtv \ -d "tax_rates[0]"=txr_1F6kmAAJVYItwOKqV9IWehUH \ -d "tax_rates[1]"=txr_2J8lmBBGHJYyuUJqF6QJtkNM ``` Code snippet calling post /v1/subscription_items/{id} in ruby (resource-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = 'sk_test_BQokikJOvBiI2HlWgH4olfQ2' subscription_item = Stripe::SubscriptionItem.update( 'si_F2yjdxUlCCOAtv', {tax_rates: ['txr_1F6kmAAJVYItwOKqV9IWehUH', 'txr_2J8lmBBGHJYyuUJqF6QJtkNM']}, ) ``` Code snippet calling post /v1/subscription_items/{id} in ruby (service-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("sk_test_BQokikJOvBiI2HlWgH4olfQ2") subscription_item = client.v1.subscription_items.update( 'si_F2yjdxUlCCOAtv', {tax_rates: ['txr_1F6kmAAJVYItwOKqV9IWehUH', 'txr_2J8lmBBGHJYyuUJqF6QJtkNM']}, ) ``` Code snippet calling post /v1/subscription_items/{id} in python (resource-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" subscription_item = stripe.SubscriptionItem.modify( "si_F2yjdxUlCCOAtv", tax_rates=["txr_1F6kmAAJVYItwOKqV9IWehUH", "txr_2J8lmBBGHJYyuUJqF6QJtkNM"], ) ``` Code snippet calling post /v1/subscription_items/{id} in python (service-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2") subscription_item = client.subscription_items.update( "si_F2yjdxUlCCOAtv", {"tax_rates": ["txr_1F6kmAAJVYItwOKqV9IWehUH", "txr_2J8lmBBGHJYyuUJqF6QJtkNM"]}, ) ``` Code snippet calling post /v1/subscription_items/{id} in php (resource-based pattern). ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); $subscriptionItem = $stripe->subscriptionItems->update( 'si_F2yjdxUlCCOAtv', ['tax_rates' => ['txr_1F6kmAAJVYItwOKqV9IWehUH', 'txr_2J8lmBBGHJYyuUJqF6QJtkNM']] ); ``` Code snippet calling post /v1/subscription_items/{id} in java (resource-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; SubscriptionItem resource = SubscriptionItem.retrieve("si_F2yjdxUlCCOAtv"); SubscriptionItemUpdateParams params = SubscriptionItemUpdateParams.builder() .addTaxRate("txr_1F6kmAAJVYItwOKqV9IWehUH") .addTaxRate("txr_2J8lmBBGHJYyuUJqF6QJtkNM") .build(); SubscriptionItem subscriptionItem = resource.update(params); ``` Code snippet calling post /v1/subscription_items/{id} in java (service-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); SubscriptionItemUpdateParams params = SubscriptionItemUpdateParams.builder() .addTaxRate("txr_1F6kmAAJVYItwOKqV9IWehUH") .addTaxRate("txr_2J8lmBBGHJYyuUJqF6QJtkNM") .build(); SubscriptionItem subscriptionItem = client.subscriptionItems().update("si_F2yjdxUlCCOAtv", params); ``` Code snippet calling post /v1/subscription_items/{id} in node (resource-based pattern). ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); const subscriptionItem = await stripe.subscriptionItems.update( 'si_F2yjdxUlCCOAtv', { tax_rates: ['txr_1F6kmAAJVYItwOKqV9IWehUH', 'txr_2J8lmBBGHJYyuUJqF6QJtkNM'], } ); ``` Code snippet calling post /v1/subscription_items/{id} in go (resource-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" params := &stripe.SubscriptionItemParams{ TaxRates: []*string{ stripe.String("txr_1F6kmAAJVYItwOKqV9IWehUH"), stripe.String("txr_2J8lmBBGHJYyuUJqF6QJtkNM"), }, }; result, err := subscriptionitem.Update("si_F2yjdxUlCCOAtv", params); ``` Code snippet calling post /v1/subscription_items/{id} in go (service-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); params := &stripe.SubscriptionItemUpdateParams{ TaxRates: []*string{ stripe.String("txr_1F6kmAAJVYItwOKqV9IWehUH"), stripe.String("txr_2J8lmBBGHJYyuUJqF6QJtkNM"), }, Item: stripe.String("si_F2yjdxUlCCOAtv"), }; result, err := sc.V1SubscriptionItems.Update(context.TODO(), params); ``` Code snippet calling post /v1/subscription_items/{id} in dotnet (resource-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; var options = new SubscriptionItemUpdateOptions { TaxRates = new List { "txr_1F6kmAAJVYItwOKqV9IWehUH", "txr_2J8lmBBGHJYyuUJqF6QJtkNM", }, }; var service = new SubscriptionItemService(); SubscriptionItem subscriptionItem = service.Update("si_F2yjdxUlCCOAtv", options); ``` Code snippet calling post /v1/subscription_items/{id} in dotnet (service-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var options = new SubscriptionItemUpdateOptions { TaxRates = new List { "txr_1F6kmAAJVYItwOKqV9IWehUH", "txr_2J8lmBBGHJYyuUJqF6QJtkNM", }, }; var client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); var service = client.V1.SubscriptionItems; SubscriptionItem subscriptionItem = service.Update("si_F2yjdxUlCCOAtv", 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](https://stripe.com/api/subscriptions/object#subscription_object-default_tax_rates). The example below updates an existing subscription with two tax rates: Code snippet calling post /v1/subscriptions/{id} in curl (resource-based pattern). ```curl curl https://api.stripe.com/v1/subscriptions/sub_BVxXIrxAAYb7Fb \ -u "sk_test_BQokikJOvBiI2HlWgH4olfQ2:" \ -d "default_tax_rates[]"=txr_1EO66sClCIKljWvs98IiVfHW \ -d "default_tax_rates[]"=txr_1EEOvcClCIKljWvsqYb9U0MB ``` Code snippet calling post /v1/subscriptions/{id} in cli (resource-based pattern). ```cli stripe subscriptions update sub_BVxXIrxAAYb7Fb \ -d "default_tax_rates[0]"=txr_1EO66sClCIKljWvs98IiVfHW \ -d "default_tax_rates[1]"=txr_1EEOvcClCIKljWvsqYb9U0MB ``` Code snippet calling post /v1/subscriptions/{id} in ruby (resource-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = 'sk_test_BQokikJOvBiI2HlWgH4olfQ2' subscription = Stripe::Subscription.update( 'sub_BVxXIrxAAYb7Fb', {default_tax_rates: ['txr_1EO66sClCIKljWvs98IiVfHW', 'txr_1EEOvcClCIKljWvsqYb9U0MB']}, ) ``` Code snippet calling post /v1/subscriptions/{id} in ruby (service-based pattern). ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("sk_test_BQokikJOvBiI2HlWgH4olfQ2") subscription = client.v1.subscriptions.update( 'sub_BVxXIrxAAYb7Fb', {default_tax_rates: ['txr_1EO66sClCIKljWvs98IiVfHW', 'txr_1EEOvcClCIKljWvsqYb9U0MB']}, ) ``` Code snippet calling post /v1/subscriptions/{id} in python (resource-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" subscription = stripe.Subscription.modify( "sub_BVxXIrxAAYb7Fb", default_tax_rates=["txr_1EO66sClCIKljWvs98IiVfHW", "txr_1EEOvcClCIKljWvsqYb9U0MB"], ) ``` Code snippet calling post /v1/subscriptions/{id} in python (service-based pattern). ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2") subscription = client.subscriptions.update( "sub_BVxXIrxAAYb7Fb", {"default_tax_rates": ["txr_1EO66sClCIKljWvs98IiVfHW", "txr_1EEOvcClCIKljWvsqYb9U0MB"]}, ) ``` Code snippet calling post /v1/subscriptions/{id} in php (resource-based pattern). ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); $subscription = $stripe->subscriptions->update( 'sub_BVxXIrxAAYb7Fb', [ 'default_tax_rates' => [ 'txr_1EO66sClCIKljWvs98IiVfHW', 'txr_1EEOvcClCIKljWvsqYb9U0MB', ], ] ); ``` Code snippet calling post /v1/subscriptions/{id} in java (resource-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; Subscription resource = Subscription.retrieve("sub_BVxXIrxAAYb7Fb"); SubscriptionUpdateParams params = SubscriptionUpdateParams.builder() .addDefaultTaxRate("txr_1EO66sClCIKljWvs98IiVfHW") .addDefaultTaxRate("txr_1EEOvcClCIKljWvsqYb9U0MB") .build(); Subscription subscription = resource.update(params); ``` Code snippet calling post /v1/subscriptions/{id} in java (service-based pattern). ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); SubscriptionUpdateParams params = SubscriptionUpdateParams.builder() .addDefaultTaxRate("txr_1EO66sClCIKljWvs98IiVfHW") .addDefaultTaxRate("txr_1EEOvcClCIKljWvsqYb9U0MB") .build(); Subscription subscription = client.subscriptions().update("sub_BVxXIrxAAYb7Fb", params); ``` Code snippet calling post /v1/subscriptions/{id} in node (resource-based pattern). ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('sk_test_BQokikJOvBiI2HlWgH4olfQ2'); const subscription = await stripe.subscriptions.update( 'sub_BVxXIrxAAYb7Fb', { default_tax_rates: ['txr_1EO66sClCIKljWvs98IiVfHW', 'txr_1EEOvcClCIKljWvsqYb9U0MB'], } ); ``` Code snippet calling post /v1/subscriptions/{id} in go (resource-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2" params := &stripe.SubscriptionParams{ DefaultTaxRates: []*string{ stripe.String("txr_1EO66sClCIKljWvs98IiVfHW"), stripe.String("txr_1EEOvcClCIKljWvsqYb9U0MB"), }, }; result, err := subscription.Update("sub_BVxXIrxAAYb7Fb", params); ``` Code snippet calling post /v1/subscriptions/{id} in go (service-based pattern). ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); params := &stripe.SubscriptionUpdateParams{ DefaultTaxRates: []*string{ stripe.String("txr_1EO66sClCIKljWvs98IiVfHW"), stripe.String("txr_1EEOvcClCIKljWvsqYb9U0MB"), }, SubscriptionExposedID: stripe.String("sub_BVxXIrxAAYb7Fb"), }; result, err := sc.V1Subscriptions.Update(context.TODO(), params); ``` Code snippet calling post /v1/subscriptions/{id} in dotnet (resource-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"; var options = new SubscriptionUpdateOptions { DefaultTaxRates = new List { "txr_1EO66sClCIKljWvs98IiVfHW", "txr_1EEOvcClCIKljWvsqYb9U0MB", }, }; var service = new SubscriptionService(); Subscription subscription = service.Update("sub_BVxXIrxAAYb7Fb", options); ``` Code snippet calling post /v1/subscriptions/{id} in dotnet (service-based pattern). ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var options = new SubscriptionUpdateOptions { DefaultTaxRates = new List { "txr_1EO66sClCIKljWvs98IiVfHW", "txr_1EEOvcClCIKljWvsqYb9U0MB", }, }; var client = new StripeClient("sk_test_BQokikJOvBiI2HlWgH4olfQ2"); var service = client.V1.Subscriptions; Subscription subscription = service.Update("sub_BVxXIrxAAYb7Fb", options); ``` ## Dynamically configuring tax rates on each subscription cycle If you add [extra invoice items](https://stripe.com/billing/invoices/subscription#adding-upcoming-invoice-items), or sell in enough jurisdictions that tax rates change frequently, you can 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* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) event. Stripe [waits approximately one hour](https://stripe.com/billing/subscriptions/webhooks#understand) before finalizing the invoice and attempting payment or sending an email. During that delay, the invoice is a [draft](https://stripe.com/api/invoices/object#invoice_object-status) and can be edited. Follow the process to [assign tax rates](https://stripe.com/invoicing/taxes/tax-rates) to that invoice. If you have credit [prorations](https://stripe.com/billing/subscriptions/prorations), use the `proration_details` parameter in the [(Invoice) Line Item](https://stripe.com/api/invoices/line_item) object to reference to the original debit line items that the credit proration applies to. Use this reference to adjust the tax amounts correctly for credit prorations. ## Adding tax rates to Checkout You can specify [tax rates](https://stripe.com/billing/taxes/tax-rates) (Sales, VAT, GST, and others) in Checkout Sessions to apply taxes to *subscriptions* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis). - Use fixed tax rates when you know the exact tax rate to charge your customers before they start the checkout process (for example, you only sell to customers in the UK and always charge 20% VAT). - With the *Prices* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions) API, you can use dynamic tax rates when you require more information from your customer (for example, their billing or shipping address) before determining the tax rate to charge. With dynamic tax rates, you create tax rates for different regions (for example, a 20% VAT tax rate for customers in the UK and a 7.25% sales tax rate for customers in California, US) and Stripe attempts to match your customer’s location to one of those tax rates. #### Fixed tax rates Set [subscription_data.default_tax_rates](https://stripe.com/api/checkout/sessions/create#create_checkout_session-subscription_data-default_tax_rates) to apply a default tax rate to a subscription started with Checkout. You can also specify [line_items.tax_rates](https://stripe.com/api/checkout/sessions/create#create_checkout_session-line_items-tax_rates) or [subscription_data.items.tax_rates](https://stripe.com/api/checkout/sessions/create#create_checkout_session-subscription_data-items-tax_rates) to apply tax rates to specific plans or invoice line items. #### Dynamic tax rates Pass an array of [tax rates](https://stripe.com/api/tax_rates/object) to [line_items.dynamic_tax_rates](https://stripe.com/api/checkout/sessions/create#create_checkout_session-line_items-dynamic_tax_rates). Each tax rate must have a [supported](https://stripe.com/api/checkout/sessions/create#create_checkout_session-line_items-dynamic_tax_rates) `country`, and for the US, a `state`. This list matches tax rates to your customer’s [shipping address](https://stripe.com/payments/collect-addresses), billing address, or country. The shipping address takes precedence over the billing address for determining the tax rate to charge. If you’re not collecting shipping or billing addresses, your customer’s country (and postal code where applicable) is used to determine the tax rate. If you haven’t passed a tax rate that matches your customer’s shipping address, billing address, or country, no tax rate is applied. [subscription_data.default_tax_rates](https://stripe.com/api/checkout/sessions/create#create_checkout_session-subscription_data-default_tax_rates) and [line_items.tax_rates](https://stripe.com/api/checkout/sessions/create#create_checkout_session-line_items-tax_rates) can’t be used in combination with [line_items.dynamic_tax_rates](https://stripe.com/api/checkout/sessions/create#create_checkout_session-line_items-dynamic_tax_rates). You can use Stripe’s data exports to populate the periodic reports required for remittance. Visit [Tax reporting and remittance](https://stripe.com/billing/taxes/tax-rates#remittance) for more information. ## See also - [Determining customer locations](https://stripe.com/tax/customer-locations) - [Customer tax IDs](https://stripe.com/billing/customer/tax-ids) - [Reporting and filing](https://stripe.com/tax/reports) - [Tax Rates](https://stripe.com/billing/taxes/tax-rates) - [Tax Rates on Invoices](https://stripe.com/invoicing/taxes/tax-rates)