# Tax API for Sales Tax, GST, and VAT Use Stripe Tax APIs to implement tax calculations in your custom integration. Stripe Tax APIs enable you to calculate tax in custom payment flows. After your customer completes their payment, record the transaction so it appears in Stripe Tax reporting. The examples in this guide use Stripe payments APIs, but you can use the Tax API with any payment processor, or multiple payment processors. Integrate Stripe Tax with [Payment Links](https://docs.stripe.com/tax/payment-links.md), [Checkout](https://docs.stripe.com/tax/checkout.md), [Billing](https://docs.stripe.com/tax/subscriptions.md), and [Invoicing](https://docs.stripe.com/tax/invoicing.md) with no or low code setups. If your custom payment flow uses [PaymentIntents](https://docs.stripe.com/api/payment_intents.md), see [Calculate tax in your custom payment flows](https://docs.stripe.com/tax/payment-intent.md). This integration is in [public preview](https://docs.stripe.com/release-phases.md) and offers receipts and Dashboard support. A diagram providing a high level overview of the tax api integration outlined in this doc (See full diagram at https://docs.stripe.com/tax/custom) ## Get started with a video demo This short video walks through a Stripe Tax API integration that uses PaymentIntents and the Payment Element. [Watch on YouTube](https://www.youtube.com/watch?v=OfHJiC9Iek0) ## Add registrations Stripe Tax only calculates tax in jurisdictions where you’re registered to collect tax and requires you to [add your registrations](https://docs.stripe.com/tax/registering.md#add-a-registration) in the Dashboard. ## Optional: Collect customer address [Client-side] In most cases, the tax you collect depends on your customer’s location. Collecting your customer’s full address gives the most accurate tax calculation result. Before collecting an address, you can show your customer [an estimate based on their IP address](https://docs.stripe.com/tax/custom.md#ip-address). > The examples below use a simple custom address form, but you can also [use the Address Element](https://docs.stripe.com/elements/address-element.md). The Address Element helps you collect addresses from customers with autocomplete and localization features. The form below collects a full postal address: ```html
``` You might pass the address to your server endpoint like this: ```js const address = { line1: document.getElementById('address_line1').value, city: document.getElementById('address_city').value, state: document.getElementById('address_state').value, postal_code: document.getElementById('address_postal_code').value, country: document.getElementById('address_country').value, }; var response = fetch('/preview-cart', { method: 'POST', body: JSON.stringify({address: address}), headers: {'Content-Type': 'application/json'}, }).then(function(response) { return response.json(); }).then(function(responseJson) { // Handle errors, or display calculated tax to your customer. }); ``` The address information required to calculate tax [varies by customer country](https://docs.stripe.com/tax/customer-locations.md#supported-formats): - **United States**: We require your customer’s postal code at a minimum. We recommend providing a full address for the most accurate tax calculation result. - **Canada**: We require your customer’s postal code or province. - **Everywhere else**: We only require your customer’s country code. ## Calculate tax [Server-side] You choose when and how often to [calculate tax](https://docs.stripe.com/api/tax/calculations/create.md). For example, you can: - Show a tax estimate [based on your customer’s IP address](https://docs.stripe.com/tax/custom.md#ip-address) when they enter your checkout flow - Recalculate tax as your customer types their billing or shipping address - Calculate the final tax amount to collect when your customer finishes typing their address Stripe [charges a fee](https://stripe.com/tax/pricing) per tax calculation API call. You can throttle tax calculation API calls to manage your costs. The examples below show how to calculate tax in a variety of scenarios. Stripe Tax only calculates tax in jurisdictions where you’re registered to collect tax and requires you to [add your registrations](https://docs.stripe.com/tax/registering.md#add-a-registration) in the Dashboard. #### Example - United States: tax-exclusive item This example calculates tax for a US shipping address. The line item has a price of 10 USD and uses your account’s [preset tax code](https://docs.stripe.com/tax/set-up.md#preset-tax-code). ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][line1]"="920 5th Ave" \ -d "customer_details[address][city]"=Seattle \ -d "customer_details[address][state]"=WA \ -d "customer_details[address][postal_code]"=98104 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][line1]"="920 5th Ave" \ -d "customer_details[address][city]"=Seattle \ -d "customer_details[address][state]"=WA \ -d "customer_details[address][postal_code]"=98104 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[{"amount": 1000, "reference": "L1"}], customer_details={ "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "shipping", }, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [{"amount": 1000, "reference": "L1"}], "customer_details": { "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "shipping", }, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', ], ], 'customer_details' => [ 'address' => [ 'line1' => '920 5th Ave', 'city' => 'Seattle', 'state' => 'WA', 'postal_code' => '98104', 'country' => 'US', ], 'address_source' => 'shipping', ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "shipping", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "shipping", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` #### Example - United States: multiple items with shipping This example has multiple tax-exclusive line items, and a 5 USD shipping cost. ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_code]"=txcd_99999999 \ -d "line_items[1][amount]"=5000 \ -d "line_items[1][reference]"=L2 \ -d "line_items[1][tax_code]"=txcd_99999999 \ -d "line_items[2][amount]"=9999 \ -d "line_items[2][reference]"=L3 \ -d "line_items[2][tax_code]"=txcd_99999999 \ -d "shipping_cost[amount]"=500 \ -d "customer_details[address][line1]"="920 5th Ave" \ -d "customer_details[address][city]"=Seattle \ -d "customer_details[address][state]"=WA \ -d "customer_details[address][postal_code]"=98104 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_code]"=txcd_99999999 \ -d "line_items[1][amount]"=5000 \ -d "line_items[1][reference]"=L2 \ -d "line_items[1][tax_code]"=txcd_99999999 \ -d "line_items[2][amount]"=9999 \ -d "line_items[2][reference]"=L3 \ -d "line_items[2][tax_code]"=txcd_99999999 \ -d "shipping_cost[amount]"=500 \ -d "customer_details[address][line1]"="920 5th Ave" \ -d "customer_details[address][city]"=Seattle \ -d "customer_details[address][state]"=WA \ -d "customer_details[address][postal_code]"=98104 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_code: 'txcd_99999999', }, { amount: 5000, reference: 'L2', tax_code: 'txcd_99999999', }, { amount: 9999, reference: 'L3', tax_code: 'txcd_99999999', }, ], shipping_cost: {amount: 500}, customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_code: 'txcd_99999999', }, { amount: 5000, reference: 'L2', tax_code: 'txcd_99999999', }, { amount: 9999, reference: 'L3', tax_code: 'txcd_99999999', }, ], shipping_cost: {amount: 500}, customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[ {"amount": 1000, "reference": "L1", "tax_code": "txcd_99999999"}, {"amount": 5000, "reference": "L2", "tax_code": "txcd_99999999"}, {"amount": 9999, "reference": "L3", "tax_code": "txcd_99999999"}, ], shipping_cost={"amount": 500}, customer_details={ "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "shipping", }, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [ {"amount": 1000, "reference": "L1", "tax_code": "txcd_99999999"}, {"amount": 5000, "reference": "L2", "tax_code": "txcd_99999999"}, {"amount": 9999, "reference": "L3", "tax_code": "txcd_99999999"}, ], "shipping_cost": {"amount": 500}, "customer_details": { "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "shipping", }, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', 'tax_code' => 'txcd_99999999', ], [ 'amount' => 5000, 'reference' => 'L2', 'tax_code' => 'txcd_99999999', ], [ 'amount' => 9999, 'reference' => 'L3', 'tax_code' => 'txcd_99999999', ], ], 'shipping_cost' => ['amount' => 500], 'customer_details' => [ 'address' => [ 'line1' => '920 5th Ave', 'city' => 'Seattle', 'state' => 'WA', 'postal_code' => '98104', 'country' => 'US', ], 'address_source' => 'shipping', ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .setTaxCode("txcd_99999999") .build() ) .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(5000L) .setReference("L2") .setTaxCode("txcd_99999999") .build() ) .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(9999L) .setReference("L3") .setTaxCode("txcd_99999999") .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder().setAmount(500L).build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .setTaxCode("txcd_99999999") .build() ) .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(5000L) .setReference("L2") .setTaxCode("txcd_99999999") .build() ) .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(9999L) .setReference("L3") .setTaxCode("txcd_99999999") .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder().setAmount(500L).build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_code: 'txcd_99999999', }, { amount: 5000, reference: 'L2', tax_code: 'txcd_99999999', }, { amount: 9999, reference: 'L3', tax_code: 'txcd_99999999', }, ], shipping_cost: { amount: 500, }, customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), TaxCode: stripe.String("txcd_99999999"), }, &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(5000), Reference: stripe.String("L2"), TaxCode: stripe.String("txcd_99999999"), }, &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(9999), Reference: stripe.String("L3"), TaxCode: stripe.String("txcd_99999999"), }, }, ShippingCost: &stripe.TaxCalculationShippingCostParams{Amount: stripe.Int64(500)}, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), TaxCode: stripe.String("txcd_99999999"), }, &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(5000), Reference: stripe.String("L2"), TaxCode: stripe.String("txcd_99999999"), }, &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(9999), Reference: stripe.String("L3"), TaxCode: stripe.String("txcd_99999999"), }, }, ShippingCost: &stripe.TaxCalculationCreateShippingCostParams{Amount: stripe.Int64(500)}, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1", TaxCode = "txcd_99999999", }, new Stripe.Tax.CalculationLineItemOptions { Amount = 5000, Reference = "L2", TaxCode = "txcd_99999999", }, new Stripe.Tax.CalculationLineItemOptions { Amount = 9999, Reference = "L3", TaxCode = "txcd_99999999", }, }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { Amount = 500 }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "shipping", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1", TaxCode = "txcd_99999999", }, new Stripe.Tax.CalculationLineItemOptions { Amount = 5000, Reference = "L2", TaxCode = "txcd_99999999", }, new Stripe.Tax.CalculationLineItemOptions { Amount = 9999, Reference = "L3", TaxCode = "txcd_99999999", }, }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { Amount = 500 }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "shipping", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` #### Example - United States: item with quantity In New York clothing isn’t subject to sales tax if each item is less than 110 USD. This example has a clothing line item with a total price of 150 USD and a quantity of 3. This means that each item of clothing is 50 USD and sales tax is exempt. ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=15000 \ -d "line_items[0][quantity]"=3 \ -d "line_items[0][reference]"=Clothing \ -d "line_items[0][tax_code]"=txcd_30011000 \ -d "shipping_cost[amount]"=500 \ -d "customer_details[address][state]"=NY \ -d "customer_details[address][postal_code]"=10001 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=15000 \ -d "line_items[0][quantity]"=3 \ -d "line_items[0][reference]"=Clothing \ -d "line_items[0][tax_code]"=txcd_30011000 \ -d "shipping_cost[amount]"=500 \ -d "customer_details[address][state]"=NY \ -d "customer_details[address][postal_code]"=10001 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 15000, quantity: 3, reference: 'Clothing', tax_code: 'txcd_30011000', }, ], shipping_cost: {amount: 500}, customer_details: { address: { state: 'NY', postal_code: '10001', country: 'US', }, address_source: 'shipping', }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 15000, quantity: 3, reference: 'Clothing', tax_code: 'txcd_30011000', }, ], shipping_cost: {amount: 500}, customer_details: { address: { state: 'NY', postal_code: '10001', country: 'US', }, address_source: 'shipping', }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[ { "amount": 15000, "quantity": 3, "reference": "Clothing", "tax_code": "txcd_30011000", }, ], shipping_cost={"amount": 500}, customer_details={ "address": {"state": "NY", "postal_code": "10001", "country": "US"}, "address_source": "shipping", }, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [ { "amount": 15000, "quantity": 3, "reference": "Clothing", "tax_code": "txcd_30011000", }, ], "shipping_cost": {"amount": 500}, "customer_details": { "address": {"state": "NY", "postal_code": "10001", "country": "US"}, "address_source": "shipping", }, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 15000, 'quantity' => 3, 'reference' => 'Clothing', 'tax_code' => 'txcd_30011000', ], ], 'shipping_cost' => ['amount' => 500], 'customer_details' => [ 'address' => [ 'state' => 'NY', 'postal_code' => '10001', 'country' => 'US', ], 'address_source' => 'shipping', ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(15000L) .setQuantity(3L) .setReference("Clothing") .setTaxCode("txcd_30011000") .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder().setAmount(500L).build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setState("NY") .setPostalCode("10001") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(15000L) .setQuantity(3L) .setReference("Clothing") .setTaxCode("txcd_30011000") .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder().setAmount(500L).build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setState("NY") .setPostalCode("10001") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 15000, quantity: 3, reference: 'Clothing', tax_code: 'txcd_30011000', }, ], shipping_cost: { amount: 500, }, customer_details: { address: { state: 'NY', postal_code: '10001', country: 'US', }, address_source: 'shipping', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(15000), Quantity: stripe.Int64(3), Reference: stripe.String("Clothing"), TaxCode: stripe.String("txcd_30011000"), }, }, ShippingCost: &stripe.TaxCalculationShippingCostParams{Amount: stripe.Int64(500)}, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ State: stripe.String("NY"), PostalCode: stripe.String("10001"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(15000), Quantity: stripe.Int64(3), Reference: stripe.String("Clothing"), TaxCode: stripe.String("txcd_30011000"), }, }, ShippingCost: &stripe.TaxCalculationCreateShippingCostParams{Amount: stripe.Int64(500)}, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ State: stripe.String("NY"), PostalCode: stripe.String("10001"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 15000, Quantity = 3, Reference = "Clothing", TaxCode = "txcd_30011000", }, }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { Amount = 500 }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { State = "NY", PostalCode = "10001", Country = "US", }, AddressSource = "shipping", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 15000, Quantity = 3, Reference = "Clothing", TaxCode = "txcd_30011000", }, }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { Amount = 500 }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { State = "NY", PostalCode = "10001", Country = "US", }, AddressSource = "shipping", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` #### Example - Europe: tax-inclusive item This example calculates tax for a billing address in Ireland, where tax is typically included in prices for non-business customers. The line item has a price of 29.99 EUR and uses tax code `txcd_10302000` (ebook). ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=eur \ -d "line_items[0][amount]"=2999 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_behavior]"=inclusive \ -d "line_items[0][tax_code]"=txcd_10302000 \ -d "customer_details[address][country]"=IE \ -d "customer_details[address_source]"=billing ``` ```cli stripe tax calculations create \ --currency=eur \ -d "line_items[0][amount]"=2999 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_behavior]"=inclusive \ -d "line_items[0][tax_code]"=txcd_10302000 \ -d "customer_details[address][country]"=IE \ -d "customer_details[address_source]"=billing ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'eur', line_items: [ { amount: 2999, reference: 'L1', tax_behavior: 'inclusive', tax_code: 'txcd_10302000', }, ], customer_details: { address: {country: 'IE'}, address_source: 'billing', }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'eur', line_items: [ { amount: 2999, reference: 'L1', tax_behavior: 'inclusive', tax_code: 'txcd_10302000', }, ], customer_details: { address: {country: 'IE'}, address_source: 'billing', }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="eur", line_items=[ { "amount": 2999, "reference": "L1", "tax_behavior": "inclusive", "tax_code": "txcd_10302000", }, ], customer_details={"address": {"country": "IE"}, "address_source": "billing"}, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "eur", "line_items": [ { "amount": 2999, "reference": "L1", "tax_behavior": "inclusive", "tax_code": "txcd_10302000", }, ], "customer_details": {"address": {"country": "IE"}, "address_source": "billing"}, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'eur', 'line_items' => [ [ 'amount' => 2999, 'reference' => 'L1', 'tax_behavior' => 'inclusive', 'tax_code' => 'txcd_10302000', ], ], 'customer_details' => [ 'address' => ['country' => 'IE'], 'address_source' => 'billing', ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("eur") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(2999L) .setReference("L1") .setTaxBehavior(CalculationCreateParams.LineItem.TaxBehavior.INCLUSIVE) .setTaxCode("txcd_10302000") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCountry("IE") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("eur") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(2999L) .setReference("L1") .setTaxBehavior(CalculationCreateParams.LineItem.TaxBehavior.INCLUSIVE) .setTaxCode("txcd_10302000") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCountry("IE") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'eur', line_items: [ { amount: 2999, reference: 'L1', tax_behavior: 'inclusive', tax_code: 'txcd_10302000', }, ], customer_details: { address: { country: 'IE', }, address_source: 'billing', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyEUR), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(2999), Reference: stripe.String("L1"), TaxBehavior: stripe.String("inclusive"), TaxCode: stripe.String("txcd_10302000"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{Country: stripe.String("IE")}, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyEUR), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(2999), Reference: stripe.String("L1"), TaxBehavior: stripe.String("inclusive"), TaxCode: stripe.String("txcd_10302000"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{Country: stripe.String("IE")}, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "eur", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 2999, Reference = "L1", TaxBehavior = "inclusive", TaxCode = "txcd_10302000", }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Country = "IE" }, AddressSource = "billing", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "eur", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 2999, Reference = "L1", TaxBehavior = "inclusive", TaxCode = "txcd_10302000", }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Country = "IE" }, AddressSource = "billing", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` #### Example - Europe: multiple items with shipping This example calculates tax for a shipping address in Ireland, where tax is typically included in prices for non-business customers. The item being shipped has a price of 59.99 EUR, and a shipping cost of 5 EUR. Since both amounts are tax-inclusive, the customer always pays 64.99 EUR. ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=eur \ -d "line_items[0][amount]"=5999 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_behavior]"=inclusive \ -d "line_items[0][tax_code]"=txcd_99999999 \ -d "shipping_cost[amount]"=500 \ -d "shipping_cost[tax_behavior]"=inclusive \ -d "customer_details[address][line1]"="123 Some House" \ -d "customer_details[address][city]"=Dublin \ -d "customer_details[address][country]"=IE \ -d "customer_details[address_source]"=shipping ``` ```cli stripe tax calculations create \ --currency=eur \ -d "line_items[0][amount]"=5999 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_behavior]"=inclusive \ -d "line_items[0][tax_code]"=txcd_99999999 \ -d "shipping_cost[amount]"=500 \ -d "shipping_cost[tax_behavior]"=inclusive \ -d "customer_details[address][line1]"="123 Some House" \ -d "customer_details[address][city]"=Dublin \ -d "customer_details[address][country]"=IE \ -d "customer_details[address_source]"=shipping ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'eur', line_items: [ { amount: 5999, reference: 'L1', tax_behavior: 'inclusive', tax_code: 'txcd_99999999', }, ], shipping_cost: { amount: 500, tax_behavior: 'inclusive', }, customer_details: { address: { line1: '123 Some House', city: 'Dublin', country: 'IE', }, address_source: 'shipping', }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'eur', line_items: [ { amount: 5999, reference: 'L1', tax_behavior: 'inclusive', tax_code: 'txcd_99999999', }, ], shipping_cost: { amount: 500, tax_behavior: 'inclusive', }, customer_details: { address: { line1: '123 Some House', city: 'Dublin', country: 'IE', }, address_source: 'shipping', }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="eur", line_items=[ { "amount": 5999, "reference": "L1", "tax_behavior": "inclusive", "tax_code": "txcd_99999999", }, ], shipping_cost={"amount": 500, "tax_behavior": "inclusive"}, customer_details={ "address": {"line1": "123 Some House", "city": "Dublin", "country": "IE"}, "address_source": "shipping", }, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "eur", "line_items": [ { "amount": 5999, "reference": "L1", "tax_behavior": "inclusive", "tax_code": "txcd_99999999", }, ], "shipping_cost": {"amount": 500, "tax_behavior": "inclusive"}, "customer_details": { "address": {"line1": "123 Some House", "city": "Dublin", "country": "IE"}, "address_source": "shipping", }, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'eur', 'line_items' => [ [ 'amount' => 5999, 'reference' => 'L1', 'tax_behavior' => 'inclusive', 'tax_code' => 'txcd_99999999', ], ], 'shipping_cost' => [ 'amount' => 500, 'tax_behavior' => 'inclusive', ], 'customer_details' => [ 'address' => [ 'line1' => '123 Some House', 'city' => 'Dublin', 'country' => 'IE', ], 'address_source' => 'shipping', ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("eur") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(5999L) .setReference("L1") .setTaxBehavior(CalculationCreateParams.LineItem.TaxBehavior.INCLUSIVE) .setTaxCode("txcd_99999999") .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder() .setAmount(500L) .setTaxBehavior(CalculationCreateParams.ShippingCost.TaxBehavior.INCLUSIVE) .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("123 Some House") .setCity("Dublin") .setCountry("IE") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("eur") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(5999L) .setReference("L1") .setTaxBehavior(CalculationCreateParams.LineItem.TaxBehavior.INCLUSIVE) .setTaxCode("txcd_99999999") .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder() .setAmount(500L) .setTaxBehavior(CalculationCreateParams.ShippingCost.TaxBehavior.INCLUSIVE) .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("123 Some House") .setCity("Dublin") .setCountry("IE") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'eur', line_items: [ { amount: 5999, reference: 'L1', tax_behavior: 'inclusive', tax_code: 'txcd_99999999', }, ], shipping_cost: { amount: 500, tax_behavior: 'inclusive', }, customer_details: { address: { line1: '123 Some House', city: 'Dublin', country: 'IE', }, address_source: 'shipping', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyEUR), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(5999), Reference: stripe.String("L1"), TaxBehavior: stripe.String("inclusive"), TaxCode: stripe.String("txcd_99999999"), }, }, ShippingCost: &stripe.TaxCalculationShippingCostParams{ Amount: stripe.Int64(500), TaxBehavior: stripe.String(stripe.TaxCalculationShippingCostTaxBehaviorInclusive), }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("123 Some House"), City: stripe.String("Dublin"), Country: stripe.String("IE"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyEUR), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(5999), Reference: stripe.String("L1"), TaxBehavior: stripe.String("inclusive"), TaxCode: stripe.String("txcd_99999999"), }, }, ShippingCost: &stripe.TaxCalculationCreateShippingCostParams{ Amount: stripe.Int64(500), TaxBehavior: stripe.String(stripe.TaxCalculationShippingCostTaxBehaviorInclusive), }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("123 Some House"), City: stripe.String("Dublin"), Country: stripe.String("IE"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "eur", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 5999, Reference = "L1", TaxBehavior = "inclusive", TaxCode = "txcd_99999999", }, }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { Amount = 500, TaxBehavior = "inclusive", }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "123 Some House", City = "Dublin", Country = "IE", }, AddressSource = "shipping", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "eur", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 5999, Reference = "L1", TaxBehavior = "inclusive", TaxCode = "txcd_99999999", }, }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { Amount = 500, TaxBehavior = "inclusive", }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "123 Some House", City = "Dublin", Country = "IE", }, AddressSource = "shipping", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` #### Example - Ship-from address (Beta) If you provide a ship-from address in certain states, such as Illinois, and the shipment contains physical goods, taxes are levied based on that address. If the shipment contains both physical goods and services, taxes are applied to both based on the ship-from address. In this example, the business is located outside Illinois and the ship-to address is in Springfield, IL. However, because the order is shipped from Naperville, IL, Stripe calculates tax based on this address. ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_behavior]"=exclusive \ -d "line_items[0][tax_code]"=txcd_99999999 \ -d "shipping_cost[amount]"=500 \ -d "shipping_cost[tax_behavior]"=exclusive \ -d "customer_details[address][city]"=Springfield \ -d "customer_details[address][state]"=IL \ -d "customer_details[address][postal_code]"=62704 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=billing \ -d "ship_from_details[address][city]"=Naperville \ -d "ship_from_details[address][state]"=IL \ -d "ship_from_details[address][postal_code]"=60540 \ -d "ship_from_details[address][country]"=US ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_behavior]"=exclusive \ -d "line_items[0][tax_code]"=txcd_99999999 \ -d "shipping_cost[amount]"=500 \ -d "shipping_cost[tax_behavior]"=exclusive \ -d "customer_details[address][city]"=Springfield \ -d "customer_details[address][state]"=IL \ -d "customer_details[address][postal_code]"=62704 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=billing \ -d "ship_from_details[address][city]"=Naperville \ -d "ship_from_details[address][state]"=IL \ -d "ship_from_details[address][postal_code]"=60540 \ -d "ship_from_details[address][country]"=US ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_behavior: 'exclusive', tax_code: 'txcd_99999999', }, ], shipping_cost: { amount: 500, tax_behavior: 'exclusive', }, customer_details: { address: { city: 'Springfield', state: 'IL', postal_code: '62704', country: 'US', }, address_source: 'billing', }, ship_from_details: { address: { city: 'Naperville', state: 'IL', postal_code: '60540', country: 'US', }, }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_behavior: 'exclusive', tax_code: 'txcd_99999999', }, ], shipping_cost: { amount: 500, tax_behavior: 'exclusive', }, customer_details: { address: { city: 'Springfield', state: 'IL', postal_code: '62704', country: 'US', }, address_source: 'billing', }, ship_from_details: { address: { city: 'Naperville', state: 'IL', postal_code: '60540', country: 'US', }, }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[ { "amount": 1000, "reference": "L1", "tax_behavior": "exclusive", "tax_code": "txcd_99999999", }, ], shipping_cost={"amount": 500, "tax_behavior": "exclusive"}, customer_details={ "address": { "city": "Springfield", "state": "IL", "postal_code": "62704", "country": "US", }, "address_source": "billing", }, ship_from_details={ "address": { "city": "Naperville", "state": "IL", "postal_code": "60540", "country": "US", }, }, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [ { "amount": 1000, "reference": "L1", "tax_behavior": "exclusive", "tax_code": "txcd_99999999", }, ], "shipping_cost": {"amount": 500, "tax_behavior": "exclusive"}, "customer_details": { "address": { "city": "Springfield", "state": "IL", "postal_code": "62704", "country": "US", }, "address_source": "billing", }, "ship_from_details": { "address": { "city": "Naperville", "state": "IL", "postal_code": "60540", "country": "US", }, }, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', 'tax_behavior' => 'exclusive', 'tax_code' => 'txcd_99999999', ], ], 'shipping_cost' => [ 'amount' => 500, 'tax_behavior' => 'exclusive', ], 'customer_details' => [ 'address' => [ 'city' => 'Springfield', 'state' => 'IL', 'postal_code' => '62704', 'country' => 'US', ], 'address_source' => 'billing', ], 'ship_from_details' => [ 'address' => [ 'city' => 'Naperville', 'state' => 'IL', 'postal_code' => '60540', 'country' => 'US', ], ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .setTaxBehavior(CalculationCreateParams.LineItem.TaxBehavior.EXCLUSIVE) .setTaxCode("txcd_99999999") .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder() .setAmount(500L) .setTaxBehavior(CalculationCreateParams.ShippingCost.TaxBehavior.EXCLUSIVE) .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCity("Springfield") .setState("IL") .setPostalCode("62704") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .build() ) .setShipFromDetails( CalculationCreateParams.ShipFromDetails.builder() .setAddress( CalculationCreateParams.ShipFromDetails.Address.builder() .setCity("Naperville") .setState("IL") .setPostalCode("60540") .setCountry("US") .build() ) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .setTaxBehavior(CalculationCreateParams.LineItem.TaxBehavior.EXCLUSIVE) .setTaxCode("txcd_99999999") .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder() .setAmount(500L) .setTaxBehavior(CalculationCreateParams.ShippingCost.TaxBehavior.EXCLUSIVE) .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCity("Springfield") .setState("IL") .setPostalCode("62704") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .build() ) .setShipFromDetails( CalculationCreateParams.ShipFromDetails.builder() .setAddress( CalculationCreateParams.ShipFromDetails.Address.builder() .setCity("Naperville") .setState("IL") .setPostalCode("60540") .setCountry("US") .build() ) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_behavior: 'exclusive', tax_code: 'txcd_99999999', }, ], shipping_cost: { amount: 500, tax_behavior: 'exclusive', }, customer_details: { address: { city: 'Springfield', state: 'IL', postal_code: '62704', country: 'US', }, address_source: 'billing', }, ship_from_details: { address: { city: 'Naperville', state: 'IL', postal_code: '60540', country: 'US', }, }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), TaxBehavior: stripe.String("exclusive"), TaxCode: stripe.String("txcd_99999999"), }, }, ShippingCost: &stripe.TaxCalculationShippingCostParams{ Amount: stripe.Int64(500), TaxBehavior: stripe.String(stripe.TaxCalculationShippingCostTaxBehaviorExclusive), }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ City: stripe.String("Springfield"), State: stripe.String("IL"), PostalCode: stripe.String("62704"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), }, ShipFromDetails: &stripe.TaxCalculationShipFromDetailsParams{ Address: &stripe.AddressParams{ City: stripe.String("Naperville"), State: stripe.String("IL"), PostalCode: stripe.String("60540"), Country: stripe.String("US"), }, }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), TaxBehavior: stripe.String("exclusive"), TaxCode: stripe.String("txcd_99999999"), }, }, ShippingCost: &stripe.TaxCalculationCreateShippingCostParams{ Amount: stripe.Int64(500), TaxBehavior: stripe.String(stripe.TaxCalculationShippingCostTaxBehaviorExclusive), }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ City: stripe.String("Springfield"), State: stripe.String("IL"), PostalCode: stripe.String("62704"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), }, ShipFromDetails: &stripe.TaxCalculationCreateShipFromDetailsParams{ Address: &stripe.AddressParams{ City: stripe.String("Naperville"), State: stripe.String("IL"), PostalCode: stripe.String("60540"), Country: stripe.String("US"), }, }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1", TaxBehavior = "exclusive", TaxCode = "txcd_99999999", }, }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { Amount = 500, TaxBehavior = "exclusive", }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { City = "Springfield", State = "IL", PostalCode = "62704", Country = "US", }, AddressSource = "billing", }, ShipFromDetails = new Stripe.Tax.CalculationShipFromDetailsOptions { Address = new AddressOptions { City = "Naperville", State = "IL", PostalCode = "60540", Country = "US", }, }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1", TaxBehavior = "exclusive", TaxCode = "txcd_99999999", }, }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { Amount = 500, TaxBehavior = "exclusive", }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { City = "Springfield", State = "IL", PostalCode = "62704", Country = "US", }, AddressSource = "billing", }, ShipFromDetails = new Stripe.Tax.CalculationShipFromDetailsOptions { Address = new AddressOptions { City = "Naperville", State = "IL", PostalCode = "60540", Country = "US", }, }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` The [calculation response](https://docs.stripe.com/api/tax/calculations/object.md) contains amounts you can display to your customer, and use to take payment: | Attribute | Description | | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [amount_total](https://docs.stripe.com/api/tax/calculations/object.md#tax_calculation_object-amount_total) | The grand total after calculating tax. Use this to set the PaymentIntent [amount](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-amount) to charge your customer. | | [tax_amount_exclusive](https://docs.stripe.com/api/tax/calculations/object.md#tax_calculation_object-tax_amount_exclusive) | The amount of tax added on top of your line item amounts and shipping cost. This tax amount increases the `amount_total`. Use this to show your customer the amount of tax added to the transaction subtotal. | | [tax_amount_inclusive](https://docs.stripe.com/api/tax/calculations/object.md#tax_calculation_object-tax_amount_inclusive) | The amount of tax that’s included in your line item amounts and shipping cost (if using tax-inclusive pricing). This tax amount doesn’t increase the `amount_total`. Use this to show your customer the tax included in the total they’re paying. | | [tax_breakdown](https://docs.stripe.com/api/tax/calculations/object.md#tax_calculation_object-tax_breakdown) | A list of tax amounts broken out by country or state tax rate. Use this to show your customer the specific taxes you’re collecting. | ### Handling customer location errors The calculation returns the `customer_tax_location_invalid` error code if your customer’s address is invalid or isn’t precise enough to calculate tax: ```json { "error": { "doc_url": "https://docs.stripe.com/error-codes#customer-tax-location-invalid","code": "customer_tax_location_invalid", "message": "We could not determine the customer's tax location based on the provided customer address.", "param": "customer_details[address]", "type": "invalid_request_error" } } ``` When you receive this error, prompt your customer to check the address they’ve entered and fix any typos. ### Use calculation with another processor If you process transactions outside of Stripe, you can skip the following steps and apply the calculation to your externally-processed transactions. ## Create tax transaction [Server-side] Creating a tax transaction records the tax you’ve collected from your customer, so that later you can [download exports and generate reports](https://docs.stripe.com/tax/reports.md) to help with filing your taxes. You can [create a transaction](https://docs.stripe.com/api/tax/transactions/create_from_calculation.md) from a calculation until the [expires_at](https://docs.stripe.com/api/tax/calculations/object.md#tax_calculation_object-expires_at) timestamp, 90 days after it’s created. Attempting to use it after this time returns an error. > The transaction is considered effective on the date when create_from_calculation is called, and tax amounts won’t be recalculated. When creating a tax transaction, you must provide a unique `reference` for the tax transaction and each line item. The references appear in tax exports to help you reconcile the tax you collected with the orders in your system. For example, a tax transaction with reference `pi_123456789`, line item references `L1` and `L2`, and a shipping cost, looks like this in the itemized tax exports: | ID | line_item_id | type | currency | transaction_date | … | | ------------ | ------------ | -------- | -------- | ------------------- | - | | pi_123456789 | L1 | external | usd | 2023-02-23 17:01:16 | … | | pi_123456789 | L2 | external | usd | 2023-02-23 17:01:16 | … | | pi_123456789 | shipping | external | usd | 2023-02-23 17:01:16 | … | When your customer pays, use the calculation ID to record the tax collected. Two ways to do this are: - If your server has an endpoint where your customer submits their order, you can create the tax transaction after the order is successfully submitted. - Listen for the [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) webhook event. Retrieve the calculation ID from the PaymentIntent `metadata`. The example below creates a transaction and uses the PaymentIntent ID as the unique reference: ```curl curl https://api.stripe.com/v1/tax/transactions/create_from_calculation \ -u "<>:" \ -d calculation={{TAX_CALCULATION}} \ -d reference="{{PAYMENTINTENT_ID}}" \ -d "expand[]"=line_items ``` ```cli stripe tax transactions create_from_calculation \ --calculation={{TAX_CALCULATION}} \ --reference="{{PAYMENTINTENT_ID}}" \ -d "expand[0]"=line_items ``` ```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 = '<>' transaction = Stripe::Tax::Transaction.create_from_calculation({ calculation: '{{TAX_CALCULATION}}', reference: '{{PAYMENTINTENT_ID}}', expand: ['line_items'], }) ``` ```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("<>") transaction = client.v1.tax.transactions.create_from_calculation({ calculation: '{{TAX_CALCULATION}}', reference: '{{PAYMENTINTENT_ID}}', expand: ['line_items'], }) ``` ```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 = "<>" transaction = stripe.tax.Transaction.create_from_calculation( calculation="{{TAX_CALCULATION}}", reference="{{PAYMENTINTENT_ID}}", expand=["line_items"], ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. transaction = client.v1.tax.transactions.create_from_calculation({ "calculation": "{{TAX_CALCULATION}}", "reference": "{{PAYMENTINTENT_ID}}", "expand": ["line_items"], }) ``` ```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('<>'); $transaction = $stripe->tax->transactions->createFromCalculation([ 'calculation' => '{{TAX_CALCULATION}}', 'reference' => '{{PAYMENTINTENT_ID}}', 'expand' => ['line_items'], ]); ``` ```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 = "<>"; TransactionCreateFromCalculationParams params = TransactionCreateFromCalculationParams.builder() .setCalculation("{{TAX_CALCULATION}}") .setReference("{{PAYMENTINTENT_ID}}") .addExpand("line_items") .build(); Transaction transaction = Transaction.createFromCalculation(params); ``` ```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("<>"); TransactionCreateFromCalculationParams params = TransactionCreateFromCalculationParams.builder() .setCalculation("{{TAX_CALCULATION}}") .setReference("{{PAYMENTINTENT_ID}}") .addExpand("line_items") .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Transaction transaction = client.v1().tax().transactions().createFromCalculation(params); ``` ```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')('<>'); const transaction = await stripe.tax.transactions.createFromCalculation({ calculation: '{{TAX_CALCULATION}}', reference: '{{PAYMENTINTENT_ID}}', expand: ['line_items'], }); ``` ```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 = "<>" params := &stripe.TaxTransactionCreateFromCalculationParams{ Calculation: stripe.String("{{TAX_CALCULATION}}"), Reference: stripe.String("{{PAYMENTINTENT_ID}}"), } params.AddExpand("line_items") result, err := transaction.CreateFromCalculation(params) ``` ```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("<>") params := &stripe.TaxTransactionCreateFromCalculationParams{ Calculation: stripe.String("{{TAX_CALCULATION}}"), Reference: stripe.String("{{PAYMENTINTENT_ID}}"), } params.AddExpand("line_items") result, err := sc.V1TaxTransactions.CreateFromCalculation(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.TransactionCreateFromCalculationOptions { Calculation = "{{TAX_CALCULATION}}", Reference = "{{PAYMENTINTENT_ID}}", Expand = new List { "line_items" }, }; var service = new Stripe.Tax.TransactionService(); Stripe.Tax.Transaction transaction = service.CreateFromCalculation(options); ``` ```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 Stripe.Tax.TransactionCreateFromCalculationOptions { Calculation = "{{TAX_CALCULATION}}", Reference = "{{PAYMENTINTENT_ID}}", Expand = new List { "line_items" }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Transactions; Stripe.Tax.Transaction transaction = service.CreateFromCalculation(options); ``` Store the [tax transaction ID](https://docs.stripe.com/api/tax/transactions/object.md#tax_transaction_object-id) so that later you can record refunds. You can store the transaction ID in your database or in the PaymentIntent’s metadata: ```curl curl https://api.stripe.com/v1/payment_intents/{{PAYMENTINTENT_ID}} \ -u "<>:" \ -d "metadata[tax_transaction]"={{TAX_TRANSACTION}} ``` ```cli stripe payment_intents update {{PAYMENTINTENT_ID}} \ -d "metadata[tax_transaction]"={{TAX_TRANSACTION}} ``` ```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 = '<>' payment_intent = Stripe::PaymentIntent.update( '{{PAYMENTINTENT_ID}}', {metadata: {tax_transaction: '{{TAX_TRANSACTION}}'}}, ) ``` ```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("<>") payment_intent = client.v1.payment_intents.update( '{{PAYMENTINTENT_ID}}', {metadata: {tax_transaction: '{{TAX_TRANSACTION}}'}}, ) ``` ```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 = "<>" payment_intent = stripe.PaymentIntent.modify( "{{PAYMENTINTENT_ID}}", metadata={"tax_transaction": "{{TAX_TRANSACTION}}"}, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. payment_intent = client.v1.payment_intents.update( "{{PAYMENTINTENT_ID}}", {"metadata": {"tax_transaction": "{{TAX_TRANSACTION}}"}}, ) ``` ```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('<>'); $paymentIntent = $stripe->paymentIntents->update( '{{PAYMENTINTENT_ID}}', ['metadata' => ['tax_transaction' => '{{TAX_TRANSACTION}}']] ); ``` ```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 = "<>"; PaymentIntent resource = PaymentIntent.retrieve("{{PAYMENTINTENT_ID}}"); PaymentIntentUpdateParams params = PaymentIntentUpdateParams.builder() .putMetadata("tax_transaction", "{{TAX_TRANSACTION}}") .build(); PaymentIntent paymentIntent = resource.update(params); ``` ```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("<>"); PaymentIntentUpdateParams params = PaymentIntentUpdateParams.builder() .putMetadata("tax_transaction", "{{TAX_TRANSACTION}}") .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. PaymentIntent paymentIntent = client.v1().paymentIntents().update("{{PAYMENTINTENT_ID}}", params); ``` ```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')('<>'); const paymentIntent = await stripe.paymentIntents.update( '{{PAYMENTINTENT_ID}}', { metadata: { tax_transaction: '{{TAX_TRANSACTION}}', }, } ); ``` ```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 = "<>" params := &stripe.PaymentIntentParams{} params.AddMetadata("tax_transaction", "{{TAX_TRANSACTION}}") result, err := paymentintent.Update("{{PAYMENTINTENT_ID}}", params) ``` ```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("<>") params := &stripe.PaymentIntentUpdateParams{ Intent: stripe.String("{{PAYMENTINTENT_ID}}"), } params.AddMetadata("tax_transaction", "{{TAX_TRANSACTION}}") result, err := sc.V1PaymentIntents.Update(context.TODO(), params) ``` ```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 = "<>"; var options = new PaymentIntentUpdateOptions { Metadata = new Dictionary { { "tax_transaction", "{{TAX_TRANSACTION}}" }, }, }; var service = new PaymentIntentService(); PaymentIntent paymentIntent = service.Update("{{PAYMENTINTENT_ID}}", options); ``` ```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 PaymentIntentUpdateOptions { Metadata = new Dictionary { { "tax_transaction", "{{TAX_TRANSACTION}}" }, }, }; var client = new StripeClient("<>"); var service = client.V1.PaymentIntents; PaymentIntent paymentIntent = service.Update("{{PAYMENTINTENT_ID}}", options); ``` ## Record refunds [Server-side] After creating a tax transaction to record a sale to your customer, you might need to record refunds. These are also represented as tax transactions, with `type=reversal`. Reversal transactions offset an earlier transaction by having amounts with opposite signs. For example, a transaction that recorded a sale for 50 USD might later have a full reversal of -50 USD. When you issue a refund (using Stripe or outside of Stripe) you need to create a reversal tax transaction with a unique `reference`. Common strategies include: - Append a suffix to the original reference. For example, if the original transaction has reference `pi_123456789`, then create the reversal transaction with reference `pi_123456789-refund`. - Use the ID of the [Stripe refund](https://docs.stripe.com/api/refunds/object.md) or a refund ID from your system. For example, `re_3MoslRBUZ691iUZ41bsYVkOg` or `myRefund_456`. Choose the approach that works best for how you reconcile your customer orders with your [tax exports](https://docs.stripe.com/tax/reports.md). ### Fully refund a sale When you fully refund a sale in your system, create a reversal transaction with `mode=full`. In the example below, `tax_1MEFAAI6rIcR421eB1YOzACZ` is the tax transaction recording the sale to your customer: ```curl curl https://api.stripe.com/v1/tax/transactions/create_reversal \ -u "<>:" \ -d mode=full \ -d original_transaction=tax_1MEFAAI6rIcR421eB1YOzACZ \ -d reference=pi_123456789-cancel \ -d "expand[]"=line_items ``` ```cli stripe tax transactions create_reversal \ --mode=full \ --original-transaction=tax_1MEFAAI6rIcR421eB1YOzACZ \ --reference=pi_123456789-cancel \ -d "expand[0]"=line_items ``` ```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 = '<>' transaction = Stripe::Tax::Transaction.create_reversal({ mode: 'full', original_transaction: 'tax_1MEFAAI6rIcR421eB1YOzACZ', reference: 'pi_123456789-cancel', expand: ['line_items'], }) ``` ```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("<>") transaction = client.v1.tax.transactions.create_reversal({ mode: 'full', original_transaction: 'tax_1MEFAAI6rIcR421eB1YOzACZ', reference: 'pi_123456789-cancel', expand: ['line_items'], }) ``` ```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 = "<>" transaction = stripe.tax.Transaction.create_reversal( mode="full", original_transaction="tax_1MEFAAI6rIcR421eB1YOzACZ", reference="pi_123456789-cancel", expand=["line_items"], ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. transaction = client.v1.tax.transactions.create_reversal({ "mode": "full", "original_transaction": "tax_1MEFAAI6rIcR421eB1YOzACZ", "reference": "pi_123456789-cancel", "expand": ["line_items"], }) ``` ```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('<>'); $transaction = $stripe->tax->transactions->createReversal([ 'mode' => 'full', 'original_transaction' => 'tax_1MEFAAI6rIcR421eB1YOzACZ', 'reference' => 'pi_123456789-cancel', 'expand' => ['line_items'], ]); ``` ```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 = "<>"; TransactionCreateReversalParams params = TransactionCreateReversalParams.builder() .setMode(TransactionCreateReversalParams.Mode.FULL) .setOriginalTransaction("tax_1MEFAAI6rIcR421eB1YOzACZ") .setReference("pi_123456789-cancel") .addExpand("line_items") .build(); Transaction transaction = Transaction.createReversal(params); ``` ```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("<>"); TransactionCreateReversalParams params = TransactionCreateReversalParams.builder() .setMode(TransactionCreateReversalParams.Mode.FULL) .setOriginalTransaction("tax_1MEFAAI6rIcR421eB1YOzACZ") .setReference("pi_123456789-cancel") .addExpand("line_items") .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Transaction transaction = client.v1().tax().transactions().createReversal(params); ``` ```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')('<>'); const transaction = await stripe.tax.transactions.createReversal({ mode: 'full', original_transaction: 'tax_1MEFAAI6rIcR421eB1YOzACZ', reference: 'pi_123456789-cancel', expand: ['line_items'], }); ``` ```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 = "<>" params := &stripe.TaxTransactionCreateReversalParams{ Mode: stripe.String("full"), OriginalTransaction: stripe.String("tax_1MEFAAI6rIcR421eB1YOzACZ"), Reference: stripe.String("pi_123456789-cancel"), } params.AddExpand("line_items") result, err := transaction.CreateReversal(params) ``` ```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("<>") params := &stripe.TaxTransactionCreateReversalParams{ Mode: stripe.String("full"), OriginalTransaction: stripe.String("tax_1MEFAAI6rIcR421eB1YOzACZ"), Reference: stripe.String("pi_123456789-cancel"), } params.AddExpand("line_items") result, err := sc.V1TaxTransactions.CreateReversal(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.TransactionCreateReversalOptions { Mode = "full", OriginalTransaction = "tax_1MEFAAI6rIcR421eB1YOzACZ", Reference = "pi_123456789-cancel", Expand = new List { "line_items" }, }; var service = new Stripe.Tax.TransactionService(); Stripe.Tax.Transaction transaction = service.CreateReversal(options); ``` ```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 Stripe.Tax.TransactionCreateReversalOptions { Mode = "full", OriginalTransaction = "tax_1MEFAAI6rIcR421eB1YOzACZ", Reference = "pi_123456789-cancel", Expand = new List { "line_items" }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Transactions; Stripe.Tax.Transaction transaction = service.CreateReversal(options); ``` This returns the full reversal transaction that’s created: ```json { "id": "tax_1MEFtXI6rIcR421e0KTGXvCK", "object": "tax.transaction", "created": 1670866467, "currency": "eur", "customer": null, "customer_details": { "address": { "city": null, "country": "IE", "line1": null, "line2": null, "postal_code": null, "state": null }, "address_source": "billing", "ip_address": null, "tax_ids": [], "taxability_override": "none" }, "line_items": { "object": "list", "data": [ { "id": "tax_li_MyCIgTuP9F9mEU", "object": "tax.transaction_line_item", "amount": -4999, "amount_tax": -1150, "livemode": false, "metadata": { }, "quantity": 1, "reference": "L1", "reversal": { "original_line_item": "tax_li_MyBXPByrSUwm6r" }, "tax_behavior": "exclusive", "tax_code": "txcd_10000000", "type": "reversal" }, { "id": "tax_li_MyCIUNXExXmJKU", "object": "tax.transaction_line_item", "amount": -1090, "amount_tax": -90, "livemode": false, "metadata": { }, "quantity": 1, "reference": "L2", "reversal": { "original_line_item": "tax_li_MyBX3Wu3qd2mXj" }, "tax_behavior": "exclusive", "tax_code": "txcd_10000000", "type": "reversal" } ], "has_more": false, "total_count": 2, "url": "/v1/tax/transactions/tax_1MEFtXI6rIcR421e0KTGXvCK/line_items" }, "livemode": false, "metadata": { }, "reference": "pi_123456789-cancel", "reversal": { "original_transaction": "tax_1MEFAAI6rIcR421eB1YOzACZ" }, "shipping_cost": null, "tax_date": 1670863654, "type": "reversal" } ``` Fully reversing a transaction doesn’t affect previous partial reversals. When you record a full reversal, make sure you [fully reverse](https://docs.stripe.com/tax/custom.md#reversals-void-refund) any previous partial reversals for the same transaction to avoid duplicate refunds. ### Partially refund a sale After [issuing a refund](https://docs.stripe.com/api/refunds/create.md) to your customer, create a reversal tax transaction with `mode=partial`. This allows you to record a partial refund by providing the line item amounts refunded. You can create up to 30 partial reversals for each sale. Reversing more than the amount of tax you collected returns an error. The example below records a refund of only the first line item in the original transaction: ```curl curl https://api.stripe.com/v1/tax/transactions/create_reversal \ -u "<>:" \ -d mode=partial \ -d original_transaction=tax_1MEFAAI6rIcR421eB1YOzACZ \ -d reference=pi_123456789-refund_1 \ -d "line_items[0][original_line_item]"=tax_li_MyBXPByrSUwm6r \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][amount]"=-4999 \ -d "line_items[0][amount_tax]"=-1150 \ -d "metadata[refund]"="{{REFUND_ID}}" \ --data-urlencode "metadata[refund_reason]"="Refunded line 1 of pi_123456789 (customer was unhappy)" \ -d "expand[0]"=line_items ``` ```cli stripe tax transactions create_reversal \ --mode=partial \ --original-transaction=tax_1MEFAAI6rIcR421eB1YOzACZ \ --reference=pi_123456789-refund_1 \ -d "line_items[0][original_line_item]"=tax_li_MyBXPByrSUwm6r \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][amount]"=-4999 \ -d "line_items[0][amount_tax]"=-1150 \ -d "metadata[refund]"="{{REFUND_ID}}" \ -d "metadata[refund_reason]"="Refunded line 1 of pi_123456789 (customer was unhappy)" \ -d "expand[0]"=line_items ``` ```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 = '<>' transaction = Stripe::Tax::Transaction.create_reversal({ mode: 'partial', original_transaction: 'tax_1MEFAAI6rIcR421eB1YOzACZ', reference: 'pi_123456789-refund_1', line_items: [ { original_line_item: 'tax_li_MyBXPByrSUwm6r', reference: 'L1', amount: -4999, amount_tax: -1150, }, ], metadata: { refund: '{{REFUND_ID}}', refund_reason: 'Refunded line 1 of pi_123456789 (customer was unhappy)', }, expand: ['line_items'], }) ``` ```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("<>") transaction = client.v1.tax.transactions.create_reversal({ mode: 'partial', original_transaction: 'tax_1MEFAAI6rIcR421eB1YOzACZ', reference: 'pi_123456789-refund_1', line_items: [ { original_line_item: 'tax_li_MyBXPByrSUwm6r', reference: 'L1', amount: -4999, amount_tax: -1150, }, ], metadata: { refund: '{{REFUND_ID}}', refund_reason: 'Refunded line 1 of pi_123456789 (customer was unhappy)', }, expand: ['line_items'], }) ``` ```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 = "<>" transaction = stripe.tax.Transaction.create_reversal( mode="partial", original_transaction="tax_1MEFAAI6rIcR421eB1YOzACZ", reference="pi_123456789-refund_1", line_items=[ { "original_line_item": "tax_li_MyBXPByrSUwm6r", "reference": "L1", "amount": -4999, "amount_tax": -1150, }, ], metadata={ "refund": "{{REFUND_ID}}", "refund_reason": "Refunded line 1 of pi_123456789 (customer was unhappy)", }, expand=["line_items"], ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. transaction = client.v1.tax.transactions.create_reversal({ "mode": "partial", "original_transaction": "tax_1MEFAAI6rIcR421eB1YOzACZ", "reference": "pi_123456789-refund_1", "line_items": [ { "original_line_item": "tax_li_MyBXPByrSUwm6r", "reference": "L1", "amount": -4999, "amount_tax": -1150, }, ], "metadata": { "refund": "{{REFUND_ID}}", "refund_reason": "Refunded line 1 of pi_123456789 (customer was unhappy)", }, "expand": ["line_items"], }) ``` ```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('<>'); $transaction = $stripe->tax->transactions->createReversal([ 'mode' => 'partial', 'original_transaction' => 'tax_1MEFAAI6rIcR421eB1YOzACZ', 'reference' => 'pi_123456789-refund_1', 'line_items' => [ [ 'original_line_item' => 'tax_li_MyBXPByrSUwm6r', 'reference' => 'L1', 'amount' => -4999, 'amount_tax' => -1150, ], ], 'metadata' => [ 'refund' => '{{REFUND_ID}}', 'refund_reason' => 'Refunded line 1 of pi_123456789 (customer was unhappy)', ], 'expand' => ['line_items'], ]); ``` ```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 = "<>"; TransactionCreateReversalParams params = TransactionCreateReversalParams.builder() .setMode(TransactionCreateReversalParams.Mode.PARTIAL) .setOriginalTransaction("tax_1MEFAAI6rIcR421eB1YOzACZ") .setReference("pi_123456789-refund_1") .addLineItem( TransactionCreateReversalParams.LineItem.builder() .setOriginalLineItem("tax_li_MyBXPByrSUwm6r") .setReference("L1") .setAmount(-4999L) .setAmountTax(-1150L) .build() ) .putMetadata("refund", "{{REFUND_ID}}") .putMetadata( "refund_reason", "Refunded line 1 of pi_123456789 (customer was unhappy)" ) .addExpand("line_items") .build(); Transaction transaction = Transaction.createReversal(params); ``` ```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("<>"); TransactionCreateReversalParams params = TransactionCreateReversalParams.builder() .setMode(TransactionCreateReversalParams.Mode.PARTIAL) .setOriginalTransaction("tax_1MEFAAI6rIcR421eB1YOzACZ") .setReference("pi_123456789-refund_1") .addLineItem( TransactionCreateReversalParams.LineItem.builder() .setOriginalLineItem("tax_li_MyBXPByrSUwm6r") .setReference("L1") .setAmount(-4999L) .setAmountTax(-1150L) .build() ) .putMetadata("refund", "{{REFUND_ID}}") .putMetadata( "refund_reason", "Refunded line 1 of pi_123456789 (customer was unhappy)" ) .addExpand("line_items") .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Transaction transaction = client.v1().tax().transactions().createReversal(params); ``` ```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')('<>'); const transaction = await stripe.tax.transactions.createReversal({ mode: 'partial', original_transaction: 'tax_1MEFAAI6rIcR421eB1YOzACZ', reference: 'pi_123456789-refund_1', line_items: [ { original_line_item: 'tax_li_MyBXPByrSUwm6r', reference: 'L1', amount: -4999, amount_tax: -1150, }, ], metadata: { refund: '{{REFUND_ID}}', refund_reason: 'Refunded line 1 of pi_123456789 (customer was unhappy)', }, expand: ['line_items'], }); ``` ```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 = "<>" params := &stripe.TaxTransactionCreateReversalParams{ Mode: stripe.String("partial"), OriginalTransaction: stripe.String("tax_1MEFAAI6rIcR421eB1YOzACZ"), Reference: stripe.String("pi_123456789-refund_1"), LineItems: []*stripe.TaxTransactionCreateReversalLineItemParams{ &stripe.TaxTransactionCreateReversalLineItemParams{ OriginalLineItem: stripe.String("tax_li_MyBXPByrSUwm6r"), Reference: stripe.String("L1"), Amount: stripe.Int64(-4999), AmountTax: stripe.Int64(-1150), }, }, } params.AddMetadata("refund", "{{REFUND_ID}}") params.AddMetadata( "refund_reason", "Refunded line 1 of pi_123456789 (customer was unhappy)") params.AddExpand("line_items") result, err := transaction.CreateReversal(params) ``` ```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("<>") params := &stripe.TaxTransactionCreateReversalParams{ Mode: stripe.String("partial"), OriginalTransaction: stripe.String("tax_1MEFAAI6rIcR421eB1YOzACZ"), Reference: stripe.String("pi_123456789-refund_1"), LineItems: []*stripe.TaxTransactionCreateReversalLineItemParams{ &stripe.TaxTransactionCreateReversalLineItemParams{ OriginalLineItem: stripe.String("tax_li_MyBXPByrSUwm6r"), Reference: stripe.String("L1"), Amount: stripe.Int64(-4999), AmountTax: stripe.Int64(-1150), }, }, } params.AddMetadata("refund", "{{REFUND_ID}}") params.AddMetadata( "refund_reason", "Refunded line 1 of pi_123456789 (customer was unhappy)") params.AddExpand("line_items") result, err := sc.V1TaxTransactions.CreateReversal(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.TransactionCreateReversalOptions { Mode = "partial", OriginalTransaction = "tax_1MEFAAI6rIcR421eB1YOzACZ", Reference = "pi_123456789-refund_1", LineItems = new List { new Stripe.Tax.TransactionLineItemOptions { OriginalLineItem = "tax_li_MyBXPByrSUwm6r", Reference = "L1", Amount = -4999, AmountTax = -1150, }, }, Metadata = new Dictionary { { "refund", "{{REFUND_ID}}" }, { "refund_reason", "Refunded line 1 of pi_123456789 (customer was unhappy)" }, }, Expand = new List { "line_items" }, }; var service = new Stripe.Tax.TransactionService(); Stripe.Tax.Transaction transaction = service.CreateReversal(options); ``` ```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 Stripe.Tax.TransactionCreateReversalOptions { Mode = "partial", OriginalTransaction = "tax_1MEFAAI6rIcR421eB1YOzACZ", Reference = "pi_123456789-refund_1", LineItems = new List { new Stripe.Tax.TransactionLineItemOptions { OriginalLineItem = "tax_li_MyBXPByrSUwm6r", Reference = "L1", Amount = -4999, AmountTax = -1150, }, }, Metadata = new Dictionary { { "refund", "{{REFUND_ID}}" }, { "refund_reason", "Refunded line 1 of pi_123456789 (customer was unhappy)" }, }, Expand = new List { "line_items" }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Transactions; Stripe.Tax.Transaction transaction = service.CreateReversal(options); ``` This returns the partial reversal transaction that’s created: ```json { "id": "tax_1MEFACI6rIcR421eHrjXCSmD", "object": "tax.transaction", "created": 1670863656, "currency": "eur", ... "line_items": { "object": "list", "data": [ { "id": "tax_li_MyBXC98AhtaR37", "object": "tax.transaction_line_item", "amount": -4999, "amount_tax": -1150, "livemode": false, "metadata": { }, "quantity": 1, "reference": "L1", "reversal": { "original_line_item": "tax_li_MyBXPByrSUwm6r" }, "tax_behavior": "exclusive", "tax_code": "txcd_10000000", "type": "reversal" } ], "has_more": false, "total_count": 1, "url": "/v1/tax/transactions/tax_1MEFACI6rIcR421eHrjXCSmD/line_items" }, "livemode": false, "metadata": { "refund": "{{REFUND_ID}}", "description": "Refunding pi_123456789 (customer was unhappy)" }, "reference": "pi_123456789-refund_1", "reversal": { "original_transaction": "tax_1MEFAAI6rIcR421eB1YOzACZ" }, "shipping_cost": null, "tax_date": 1670863654, "type": "reversal" } ``` For each line item reversed you need to provide the `amount` and `amount_tax` reversed. The `amount` is tax-inclusive if the original calculation line item was tax-inclusive. How `amount` and `amount_tax` are determined depends on your situation: - If your transactions always have a single line item, use [full reversals](https://docs.stripe.com/tax/custom.md#reversals-full) instead. - If you always refund entire line items, use the original transaction line item `amount` and `amount_tax`, but with negative signs. - If you refund parts of line items, you need to calculate the amounts refunded. For example, for a sale transaction with `amount=5000` and `amount_tax=500`, after refunding half the line item you’d create a partial reversal with line item `amount=-2500` and `amount_tax=-250`. ### Partially refund a sale by a flat amount Alternatively, you can create a reversal with `mode=partial` by specifying a flat after-tax amount to refund. The amount distributes across each line item and shipping cost proportionally, depending on the remaining amount left to refund on each. In the example below, the transaction has two line items: one 10 USD item and one 20 USD item, both taxed at 10%. The total amount of the transaction is 33.00 USD. A refund for a flat 16.50 USD is recorded: ```curl curl https://api.stripe.com/v1/tax/transactions/create_reversal \ -u "<>:" \ -d mode=partial \ -d original_transaction=tax_1NVcKqBUZ691iUZ4xMZtcGYt \ -d reference=pi_234567890-refund_1 \ -d flat_amount=-1650 \ -d "metadata[refund]"="{{REFUND_ID}}" \ --data-urlencode "metadata[refund_reason]"="Refunded $16.50 of pi_234567890 (customer was unhappy)" \ -d "expand[]"=line_items ``` ```cli stripe tax transactions create_reversal \ --mode=partial \ --original-transaction=tax_1NVcKqBUZ691iUZ4xMZtcGYt \ --reference=pi_234567890-refund_1 \ --flat-amount=-1650 \ -d "metadata[refund]"="{{REFUND_ID}}" \ -d "metadata[refund_reason]"="Refunded $16.50 of pi_234567890 (customer was unhappy)" \ -d "expand[0]"=line_items ``` ```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 = '<>' transaction = Stripe::Tax::Transaction.create_reversal({ mode: 'partial', original_transaction: 'tax_1NVcKqBUZ691iUZ4xMZtcGYt', reference: 'pi_234567890-refund_1', flat_amount: -1650, metadata: { refund: '{{REFUND_ID}}', refund_reason: 'Refunded $16.50 of pi_234567890 (customer was unhappy)', }, expand: ['line_items'], }) ``` ```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("<>") transaction = client.v1.tax.transactions.create_reversal({ mode: 'partial', original_transaction: 'tax_1NVcKqBUZ691iUZ4xMZtcGYt', reference: 'pi_234567890-refund_1', flat_amount: -1650, metadata: { refund: '{{REFUND_ID}}', refund_reason: 'Refunded $16.50 of pi_234567890 (customer was unhappy)', }, expand: ['line_items'], }) ``` ```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 = "<>" transaction = stripe.tax.Transaction.create_reversal( mode="partial", original_transaction="tax_1NVcKqBUZ691iUZ4xMZtcGYt", reference="pi_234567890-refund_1", flat_amount=-1650, metadata={ "refund": "{{REFUND_ID}}", "refund_reason": "Refunded $16.50 of pi_234567890 (customer was unhappy)", }, expand=["line_items"], ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. transaction = client.v1.tax.transactions.create_reversal({ "mode": "partial", "original_transaction": "tax_1NVcKqBUZ691iUZ4xMZtcGYt", "reference": "pi_234567890-refund_1", "flat_amount": -1650, "metadata": { "refund": "{{REFUND_ID}}", "refund_reason": "Refunded $16.50 of pi_234567890 (customer was unhappy)", }, "expand": ["line_items"], }) ``` ```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('<>'); $transaction = $stripe->tax->transactions->createReversal([ 'mode' => 'partial', 'original_transaction' => 'tax_1NVcKqBUZ691iUZ4xMZtcGYt', 'reference' => 'pi_234567890-refund_1', 'flat_amount' => -1650, 'metadata' => [ 'refund' => '{{REFUND_ID}}', 'refund_reason' => 'Refunded $16.50 of pi_234567890 (customer was unhappy)', ], 'expand' => ['line_items'], ]); ``` ```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 = "<>"; TransactionCreateReversalParams params = TransactionCreateReversalParams.builder() .setMode(TransactionCreateReversalParams.Mode.PARTIAL) .setOriginalTransaction("tax_1NVcKqBUZ691iUZ4xMZtcGYt") .setReference("pi_234567890-refund_1") .setFlatAmount(-1650L) .putMetadata("refund", "{{REFUND_ID}}") .putMetadata( "refund_reason", "Refunded $16.50 of pi_234567890 (customer was unhappy)" ) .addExpand("line_items") .build(); Transaction transaction = Transaction.createReversal(params); ``` ```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("<>"); TransactionCreateReversalParams params = TransactionCreateReversalParams.builder() .setMode(TransactionCreateReversalParams.Mode.PARTIAL) .setOriginalTransaction("tax_1NVcKqBUZ691iUZ4xMZtcGYt") .setReference("pi_234567890-refund_1") .setFlatAmount(-1650L) .putMetadata("refund", "{{REFUND_ID}}") .putMetadata( "refund_reason", "Refunded $16.50 of pi_234567890 (customer was unhappy)" ) .addExpand("line_items") .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Transaction transaction = client.v1().tax().transactions().createReversal(params); ``` ```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')('<>'); const transaction = await stripe.tax.transactions.createReversal({ mode: 'partial', original_transaction: 'tax_1NVcKqBUZ691iUZ4xMZtcGYt', reference: 'pi_234567890-refund_1', flat_amount: -1650, metadata: { refund: '{{REFUND_ID}}', refund_reason: 'Refunded $16.50 of pi_234567890 (customer was unhappy)', }, expand: ['line_items'], }); ``` ```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 = "<>" params := &stripe.TaxTransactionCreateReversalParams{ Mode: stripe.String("partial"), OriginalTransaction: stripe.String("tax_1NVcKqBUZ691iUZ4xMZtcGYt"), Reference: stripe.String("pi_234567890-refund_1"), FlatAmount: stripe.Int64(-1650), } params.AddMetadata("refund", "{{REFUND_ID}}") params.AddMetadata( "refund_reason", "Refunded $16.50 of pi_234567890 (customer was unhappy)") params.AddExpand("line_items") result, err := transaction.CreateReversal(params) ``` ```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("<>") params := &stripe.TaxTransactionCreateReversalParams{ Mode: stripe.String("partial"), OriginalTransaction: stripe.String("tax_1NVcKqBUZ691iUZ4xMZtcGYt"), Reference: stripe.String("pi_234567890-refund_1"), FlatAmount: stripe.Int64(-1650), } params.AddMetadata("refund", "{{REFUND_ID}}") params.AddMetadata( "refund_reason", "Refunded $16.50 of pi_234567890 (customer was unhappy)") params.AddExpand("line_items") result, err := sc.V1TaxTransactions.CreateReversal(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.TransactionCreateReversalOptions { Mode = "partial", OriginalTransaction = "tax_1NVcKqBUZ691iUZ4xMZtcGYt", Reference = "pi_234567890-refund_1", FlatAmount = -1650, Metadata = new Dictionary { { "refund", "{{REFUND_ID}}" }, { "refund_reason", "Refunded $16.50 of pi_234567890 (customer was unhappy)" }, }, Expand = new List { "line_items" }, }; var service = new Stripe.Tax.TransactionService(); Stripe.Tax.Transaction transaction = service.CreateReversal(options); ``` ```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 Stripe.Tax.TransactionCreateReversalOptions { Mode = "partial", OriginalTransaction = "tax_1NVcKqBUZ691iUZ4xMZtcGYt", Reference = "pi_234567890-refund_1", FlatAmount = -1650, Metadata = new Dictionary { { "refund", "{{REFUND_ID}}" }, { "refund_reason", "Refunded $16.50 of pi_234567890 (customer was unhappy)" }, }, Expand = new List { "line_items" }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Transactions; Stripe.Tax.Transaction transaction = service.CreateReversal(options); ``` This returns the partial reversal transaction that’s created: ```json { "id": "tax_1NVcQYBUZ691iUZ4SBPukGa6", "object": "tax.transaction", "created": 1689780994, "currency": "usd", ... "line_items": { "object": "list", "data": [ { "id": "tax_li_OICqymcWjlbevq", "object": "tax.transaction_line_item", "amount": -500, "amount_tax": -50, "livemode": false, "metadata": {}, "product": null, "quantity": 1, "reference": "refund_li_1", "reversal": { "original_line_item": "tax_li_OICmRXkFuWr8Df" }, "tax_behavior": "exclusive", "tax_code": "txcd_10103000", "type": "reversal" }, { "id": "tax_li_OICq2H1qHjwyzX", "object": "tax.transaction_line_item", "amount": -1000, "amount_tax": -100, "livemode": false, "metadata": {}, "product": null, "quantity": 1, "reference": "refund_li_2", "reversal": { "original_line_item": "tax_li_OICmxhnSJxF7rY" }, "tax_behavior": "exclusive", "tax_code": "txcd_10103000", "type": "reversal" } ], "has_more": false, "total_count": 2, "url": "/v1/tax/transactions/tax_1NVcQYBUZ691iUZ4SBPukGa6/line_items" }, "livemode": false, "metadata": { "refund": "{{REFUND_ID}}", "description": "Refunding pi_234567890 (customer was unhappy)" }, "reference": "pi_234567890-refund_1", "reversal": { "original_transaction": "tax_1NVcKqBUZ691iUZ4xMZtcGYt" }, "shipping_cost": null, "tax_date": 1670863654, "type": "reversal" } ``` For each line item and shipping cost in the original transaction, the refunded amounts and tax are calculated as follows: 1. First, we calculate the total remaining funds in the transaction available to refund. Because this transaction hasn’t had any other reversals recorded, the total amount is 33.00 USD. 1. Next, we calculate the total amount to refund for each line item. We base this calculation on the proportion of the item’s total available amount to refund versus the total remaining amount of the transaction. For example, the 10 USD item, which has 11.00 USD total remaining to refund, represents 33.33% of the transaction’s remaining total, so the total amount to refund is `-16.50 USD * 33.33% = -5.50 USD`. 1. Finally, the total amount to refund is divided between `amount` and `amount_tax`. We also do this proportionally, depending on how much tax is available to refund in the line item compared to the total funds left to refund. Using the 10 USD item example, tax (1.00 USD) represents 9.09% of the total remaining to refund (11.00 USD), so the `amount_tax` is `-5.50 USD * 9.09% = -0.50 USD`. The flat amount distributes according to what’s *left* to refund in the transaction, not what was originally recorded. Consider this example: instead of recording a refund for a flat 16.50 USD, you first record a partial reversal for the total amount of the 10 USD item: ```curl curl https://api.stripe.com/v1/tax/transactions/create_reversal \ -u "<>:" \ -d mode=partial \ -d original_transaction=tax_1NVcKqBUZ691iUZ4xMZtcGYt \ -d reference=pi_234567890-refund_1 \ -d "line_items[0][original_line_item]"=tax_li_OICmRXkFuWr8Df \ -d "line_items[0][reference]"=partial_refund_l1 \ -d "line_items[0][amount]"=-1000 \ -d "line_items[0][amount_tax]"=-100 \ -d "metadata[refund]"="{{REFUND_ID}}" \ --data-urlencode "metadata[refund_reason]"="Refunded line 1 of pi_234567890 (customer was unhappy)" \ -d "expand[0]"=line_items ``` ```cli stripe tax transactions create_reversal \ --mode=partial \ --original-transaction=tax_1NVcKqBUZ691iUZ4xMZtcGYt \ --reference=pi_234567890-refund_1 \ -d "line_items[0][original_line_item]"=tax_li_OICmRXkFuWr8Df \ -d "line_items[0][reference]"=partial_refund_l1 \ -d "line_items[0][amount]"=-1000 \ -d "line_items[0][amount_tax]"=-100 \ -d "metadata[refund]"="{{REFUND_ID}}" \ -d "metadata[refund_reason]"="Refunded line 1 of pi_234567890 (customer was unhappy)" \ -d "expand[0]"=line_items ``` ```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 = '<>' transaction = Stripe::Tax::Transaction.create_reversal({ mode: 'partial', original_transaction: 'tax_1NVcKqBUZ691iUZ4xMZtcGYt', reference: 'pi_234567890-refund_1', line_items: [ { original_line_item: 'tax_li_OICmRXkFuWr8Df', reference: 'partial_refund_l1', amount: -1000, amount_tax: -100, }, ], metadata: { refund: '{{REFUND_ID}}', refund_reason: 'Refunded line 1 of pi_234567890 (customer was unhappy)', }, expand: ['line_items'], }) ``` ```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("<>") transaction = client.v1.tax.transactions.create_reversal({ mode: 'partial', original_transaction: 'tax_1NVcKqBUZ691iUZ4xMZtcGYt', reference: 'pi_234567890-refund_1', line_items: [ { original_line_item: 'tax_li_OICmRXkFuWr8Df', reference: 'partial_refund_l1', amount: -1000, amount_tax: -100, }, ], metadata: { refund: '{{REFUND_ID}}', refund_reason: 'Refunded line 1 of pi_234567890 (customer was unhappy)', }, expand: ['line_items'], }) ``` ```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 = "<>" transaction = stripe.tax.Transaction.create_reversal( mode="partial", original_transaction="tax_1NVcKqBUZ691iUZ4xMZtcGYt", reference="pi_234567890-refund_1", line_items=[ { "original_line_item": "tax_li_OICmRXkFuWr8Df", "reference": "partial_refund_l1", "amount": -1000, "amount_tax": -100, }, ], metadata={ "refund": "{{REFUND_ID}}", "refund_reason": "Refunded line 1 of pi_234567890 (customer was unhappy)", }, expand=["line_items"], ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. transaction = client.v1.tax.transactions.create_reversal({ "mode": "partial", "original_transaction": "tax_1NVcKqBUZ691iUZ4xMZtcGYt", "reference": "pi_234567890-refund_1", "line_items": [ { "original_line_item": "tax_li_OICmRXkFuWr8Df", "reference": "partial_refund_l1", "amount": -1000, "amount_tax": -100, }, ], "metadata": { "refund": "{{REFUND_ID}}", "refund_reason": "Refunded line 1 of pi_234567890 (customer was unhappy)", }, "expand": ["line_items"], }) ``` ```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('<>'); $transaction = $stripe->tax->transactions->createReversal([ 'mode' => 'partial', 'original_transaction' => 'tax_1NVcKqBUZ691iUZ4xMZtcGYt', 'reference' => 'pi_234567890-refund_1', 'line_items' => [ [ 'original_line_item' => 'tax_li_OICmRXkFuWr8Df', 'reference' => 'partial_refund_l1', 'amount' => -1000, 'amount_tax' => -100, ], ], 'metadata' => [ 'refund' => '{{REFUND_ID}}', 'refund_reason' => 'Refunded line 1 of pi_234567890 (customer was unhappy)', ], 'expand' => ['line_items'], ]); ``` ```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 = "<>"; TransactionCreateReversalParams params = TransactionCreateReversalParams.builder() .setMode(TransactionCreateReversalParams.Mode.PARTIAL) .setOriginalTransaction("tax_1NVcKqBUZ691iUZ4xMZtcGYt") .setReference("pi_234567890-refund_1") .addLineItem( TransactionCreateReversalParams.LineItem.builder() .setOriginalLineItem("tax_li_OICmRXkFuWr8Df") .setReference("partial_refund_l1") .setAmount(-1000L) .setAmountTax(-100L) .build() ) .putMetadata("refund", "{{REFUND_ID}}") .putMetadata( "refund_reason", "Refunded line 1 of pi_234567890 (customer was unhappy)" ) .addExpand("line_items") .build(); Transaction transaction = Transaction.createReversal(params); ``` ```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("<>"); TransactionCreateReversalParams params = TransactionCreateReversalParams.builder() .setMode(TransactionCreateReversalParams.Mode.PARTIAL) .setOriginalTransaction("tax_1NVcKqBUZ691iUZ4xMZtcGYt") .setReference("pi_234567890-refund_1") .addLineItem( TransactionCreateReversalParams.LineItem.builder() .setOriginalLineItem("tax_li_OICmRXkFuWr8Df") .setReference("partial_refund_l1") .setAmount(-1000L) .setAmountTax(-100L) .build() ) .putMetadata("refund", "{{REFUND_ID}}") .putMetadata( "refund_reason", "Refunded line 1 of pi_234567890 (customer was unhappy)" ) .addExpand("line_items") .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Transaction transaction = client.v1().tax().transactions().createReversal(params); ``` ```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')('<>'); const transaction = await stripe.tax.transactions.createReversal({ mode: 'partial', original_transaction: 'tax_1NVcKqBUZ691iUZ4xMZtcGYt', reference: 'pi_234567890-refund_1', line_items: [ { original_line_item: 'tax_li_OICmRXkFuWr8Df', reference: 'partial_refund_l1', amount: -1000, amount_tax: -100, }, ], metadata: { refund: '{{REFUND_ID}}', refund_reason: 'Refunded line 1 of pi_234567890 (customer was unhappy)', }, expand: ['line_items'], }); ``` ```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 = "<>" params := &stripe.TaxTransactionCreateReversalParams{ Mode: stripe.String("partial"), OriginalTransaction: stripe.String("tax_1NVcKqBUZ691iUZ4xMZtcGYt"), Reference: stripe.String("pi_234567890-refund_1"), LineItems: []*stripe.TaxTransactionCreateReversalLineItemParams{ &stripe.TaxTransactionCreateReversalLineItemParams{ OriginalLineItem: stripe.String("tax_li_OICmRXkFuWr8Df"), Reference: stripe.String("partial_refund_l1"), Amount: stripe.Int64(-1000), AmountTax: stripe.Int64(-100), }, }, } params.AddMetadata("refund", "{{REFUND_ID}}") params.AddMetadata( "refund_reason", "Refunded line 1 of pi_234567890 (customer was unhappy)") params.AddExpand("line_items") result, err := transaction.CreateReversal(params) ``` ```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("<>") params := &stripe.TaxTransactionCreateReversalParams{ Mode: stripe.String("partial"), OriginalTransaction: stripe.String("tax_1NVcKqBUZ691iUZ4xMZtcGYt"), Reference: stripe.String("pi_234567890-refund_1"), LineItems: []*stripe.TaxTransactionCreateReversalLineItemParams{ &stripe.TaxTransactionCreateReversalLineItemParams{ OriginalLineItem: stripe.String("tax_li_OICmRXkFuWr8Df"), Reference: stripe.String("partial_refund_l1"), Amount: stripe.Int64(-1000), AmountTax: stripe.Int64(-100), }, }, } params.AddMetadata("refund", "{{REFUND_ID}}") params.AddMetadata( "refund_reason", "Refunded line 1 of pi_234567890 (customer was unhappy)") params.AddExpand("line_items") result, err := sc.V1TaxTransactions.CreateReversal(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.TransactionCreateReversalOptions { Mode = "partial", OriginalTransaction = "tax_1NVcKqBUZ691iUZ4xMZtcGYt", Reference = "pi_234567890-refund_1", LineItems = new List { new Stripe.Tax.TransactionLineItemOptions { OriginalLineItem = "tax_li_OICmRXkFuWr8Df", Reference = "partial_refund_l1", Amount = -1000, AmountTax = -100, }, }, Metadata = new Dictionary { { "refund", "{{REFUND_ID}}" }, { "refund_reason", "Refunded line 1 of pi_234567890 (customer was unhappy)" }, }, Expand = new List { "line_items" }, }; var service = new Stripe.Tax.TransactionService(); Stripe.Tax.Transaction transaction = service.CreateReversal(options); ``` ```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 Stripe.Tax.TransactionCreateReversalOptions { Mode = "partial", OriginalTransaction = "tax_1NVcKqBUZ691iUZ4xMZtcGYt", Reference = "pi_234567890-refund_1", LineItems = new List { new Stripe.Tax.TransactionLineItemOptions { OriginalLineItem = "tax_li_OICmRXkFuWr8Df", Reference = "partial_refund_l1", Amount = -1000, AmountTax = -100, }, }, Metadata = new Dictionary { { "refund", "{{REFUND_ID}}" }, { "refund_reason", "Refunded line 1 of pi_234567890 (customer was unhappy)" }, }, Expand = new List { "line_items" }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Transactions; Stripe.Tax.Transaction transaction = service.CreateReversal(options); ``` After this, you record a 16.50 USD flat amount reversal: ```curl curl https://api.stripe.com/v1/tax/transactions/create_reversal \ -u "<>:" \ -d mode=partial \ -d original_transaction=tax_1NVcKqBUZ691iUZ4xMZtcGYt \ -d reference=pi_234567890-refund_2 \ -d flat_amount=-1650 \ -d "metadata[refund]"="{{REFUND_ID}}" \ --data-urlencode "metadata[refund_reason]"="Refunded $16.50 of pi_234567890 (customer was still unhappy)" \ -d "expand[]"=line_items ``` ```cli stripe tax transactions create_reversal \ --mode=partial \ --original-transaction=tax_1NVcKqBUZ691iUZ4xMZtcGYt \ --reference=pi_234567890-refund_2 \ --flat-amount=-1650 \ -d "metadata[refund]"="{{REFUND_ID}}" \ -d "metadata[refund_reason]"="Refunded $16.50 of pi_234567890 (customer was still unhappy)" \ -d "expand[0]"=line_items ``` ```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 = '<>' transaction = Stripe::Tax::Transaction.create_reversal({ mode: 'partial', original_transaction: 'tax_1NVcKqBUZ691iUZ4xMZtcGYt', reference: 'pi_234567890-refund_2', flat_amount: -1650, metadata: { refund: '{{REFUND_ID}}', refund_reason: 'Refunded $16.50 of pi_234567890 (customer was still unhappy)', }, expand: ['line_items'], }) ``` ```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("<>") transaction = client.v1.tax.transactions.create_reversal({ mode: 'partial', original_transaction: 'tax_1NVcKqBUZ691iUZ4xMZtcGYt', reference: 'pi_234567890-refund_2', flat_amount: -1650, metadata: { refund: '{{REFUND_ID}}', refund_reason: 'Refunded $16.50 of pi_234567890 (customer was still unhappy)', }, expand: ['line_items'], }) ``` ```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 = "<>" transaction = stripe.tax.Transaction.create_reversal( mode="partial", original_transaction="tax_1NVcKqBUZ691iUZ4xMZtcGYt", reference="pi_234567890-refund_2", flat_amount=-1650, metadata={ "refund": "{{REFUND_ID}}", "refund_reason": "Refunded $16.50 of pi_234567890 (customer was still unhappy)", }, expand=["line_items"], ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. transaction = client.v1.tax.transactions.create_reversal({ "mode": "partial", "original_transaction": "tax_1NVcKqBUZ691iUZ4xMZtcGYt", "reference": "pi_234567890-refund_2", "flat_amount": -1650, "metadata": { "refund": "{{REFUND_ID}}", "refund_reason": "Refunded $16.50 of pi_234567890 (customer was still unhappy)", }, "expand": ["line_items"], }) ``` ```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('<>'); $transaction = $stripe->tax->transactions->createReversal([ 'mode' => 'partial', 'original_transaction' => 'tax_1NVcKqBUZ691iUZ4xMZtcGYt', 'reference' => 'pi_234567890-refund_2', 'flat_amount' => -1650, 'metadata' => [ 'refund' => '{{REFUND_ID}}', 'refund_reason' => 'Refunded $16.50 of pi_234567890 (customer was still unhappy)', ], 'expand' => ['line_items'], ]); ``` ```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 = "<>"; TransactionCreateReversalParams params = TransactionCreateReversalParams.builder() .setMode(TransactionCreateReversalParams.Mode.PARTIAL) .setOriginalTransaction("tax_1NVcKqBUZ691iUZ4xMZtcGYt") .setReference("pi_234567890-refund_2") .setFlatAmount(-1650L) .putMetadata("refund", "{{REFUND_ID}}") .putMetadata( "refund_reason", "Refunded $16.50 of pi_234567890 (customer was still unhappy)" ) .addExpand("line_items") .build(); Transaction transaction = Transaction.createReversal(params); ``` ```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("<>"); TransactionCreateReversalParams params = TransactionCreateReversalParams.builder() .setMode(TransactionCreateReversalParams.Mode.PARTIAL) .setOriginalTransaction("tax_1NVcKqBUZ691iUZ4xMZtcGYt") .setReference("pi_234567890-refund_2") .setFlatAmount(-1650L) .putMetadata("refund", "{{REFUND_ID}}") .putMetadata( "refund_reason", "Refunded $16.50 of pi_234567890 (customer was still unhappy)" ) .addExpand("line_items") .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Transaction transaction = client.v1().tax().transactions().createReversal(params); ``` ```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')('<>'); const transaction = await stripe.tax.transactions.createReversal({ mode: 'partial', original_transaction: 'tax_1NVcKqBUZ691iUZ4xMZtcGYt', reference: 'pi_234567890-refund_2', flat_amount: -1650, metadata: { refund: '{{REFUND_ID}}', refund_reason: 'Refunded $16.50 of pi_234567890 (customer was still unhappy)', }, expand: ['line_items'], }); ``` ```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 = "<>" params := &stripe.TaxTransactionCreateReversalParams{ Mode: stripe.String("partial"), OriginalTransaction: stripe.String("tax_1NVcKqBUZ691iUZ4xMZtcGYt"), Reference: stripe.String("pi_234567890-refund_2"), FlatAmount: stripe.Int64(-1650), } params.AddMetadata("refund", "{{REFUND_ID}}") params.AddMetadata( "refund_reason", "Refunded $16.50 of pi_234567890 (customer was still unhappy)") params.AddExpand("line_items") result, err := transaction.CreateReversal(params) ``` ```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("<>") params := &stripe.TaxTransactionCreateReversalParams{ Mode: stripe.String("partial"), OriginalTransaction: stripe.String("tax_1NVcKqBUZ691iUZ4xMZtcGYt"), Reference: stripe.String("pi_234567890-refund_2"), FlatAmount: stripe.Int64(-1650), } params.AddMetadata("refund", "{{REFUND_ID}}") params.AddMetadata( "refund_reason", "Refunded $16.50 of pi_234567890 (customer was still unhappy)") params.AddExpand("line_items") result, err := sc.V1TaxTransactions.CreateReversal(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.TransactionCreateReversalOptions { Mode = "partial", OriginalTransaction = "tax_1NVcKqBUZ691iUZ4xMZtcGYt", Reference = "pi_234567890-refund_2", FlatAmount = -1650, Metadata = new Dictionary { { "refund", "{{REFUND_ID}}" }, { "refund_reason", "Refunded $16.50 of pi_234567890 (customer was still unhappy)" }, }, Expand = new List { "line_items" }, }; var service = new Stripe.Tax.TransactionService(); Stripe.Tax.Transaction transaction = service.CreateReversal(options); ``` ```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 Stripe.Tax.TransactionCreateReversalOptions { Mode = "partial", OriginalTransaction = "tax_1NVcKqBUZ691iUZ4xMZtcGYt", Reference = "pi_234567890-refund_2", FlatAmount = -1650, Metadata = new Dictionary { { "refund", "{{REFUND_ID}}" }, { "refund_reason", "Refunded $16.50 of pi_234567890 (customer was still unhappy)" }, }, Expand = new List { "line_items" }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Transactions; Stripe.Tax.Transaction transaction = service.CreateReversal(options); ``` This returns the partial reversal transaction: ```json { "id": "tax_1NVxFIBUZ691iUZ4saOIloxB", "object": "tax.transaction", "created": 1689861020, "currency": "usd", ... "line_items": { "object": "list", "data": [ { "id": "tax_li_OIYM8xd8BzrATd", "object": "tax.transaction_line_item", "amount": 0, "amount_tax": 0, "livemode": false, "metadata": {}, "product": null, "quantity": 1, "reference": "refund_li_1", "reversal": { "original_line_item": "tax_li_OICmRXkFuWr8Df" }, "tax_behavior": "exclusive", "tax_code": "txcd_10103000", "type": "reversal" }, { "id": "tax_li_OIYMNBH6s8oQj9", "object": "tax.transaction_line_item", "amount": -1500, "amount_tax": -150, "livemode": false, "metadata": {}, "product": null, "quantity": 1, "reference": "refund_li_2", "reversal": { "original_line_item": "tax_li_OICmxhnSJxF7rY" }, "tax_behavior": "exclusive", "tax_code": "txcd_10103000", "type": "reversal" } ], "has_more": false, "total_count": 2, "url": "/v1/tax/transactions/tax_1NVxFIBUZ691iUZ4saOIloxB/line_items" }, "livemode": false, "metadata": {}, "reference": "pi_234567890-refund_2", "reversal": { "original_transaction": "tax_1NVcKqBUZ691iUZ4xMZtcGYt" }, "shipping_cost": null, "tax_date": 1670863654, "type": "reversal" } ``` Because the total amount remaining in the transaction is now 22.00 USD and the 10 USD item is completely refunded, the 16.50 USD distributes entirely to the 20 USD item. The 16.50 USD then distributes, using the logic from step 3, into `amount = -15.00 USD` and `amount_tax = -1.50 USD`. Meanwhile, the 10 USD item in the transaction records a refund of 0 USD. ### Undo a partial refund Tax transactions are immutable but you can cancel out a partial refund by creating a [full reversal](https://docs.stripe.com/api/tax/transactions/create_reversal.md#tax_transaction_create_reversal-mode) of it. You might need to do this when: - The payment [refund fails](https://docs.stripe.com/refunds.md#failed-refunds) and you haven’t provided the good or service to your customer - The wrong order is refunded or the wrong amounts are refunded - The original sale is fully refunded and the partial refunds are no longer valid In the example below, `tax_1MEFACI6rIcR421eHrjXCSmD` is the transaction representing the partial refund: ```curl curl https://api.stripe.com/v1/tax/transactions/create_reversal \ -u "<>:" \ -d mode=full \ -d original_transaction=tax_1MEFACI6rIcR421eHrjXCSmD \ -d reference=pi_123456789-refund_1-cancel \ -d "metadata[refund_reason]"="User called to cancel because they picked the wrong item" \ -d "expand[]"=line_items ``` ```cli stripe tax transactions create_reversal \ --mode=full \ --original-transaction=tax_1MEFACI6rIcR421eHrjXCSmD \ --reference=pi_123456789-refund_1-cancel \ -d "metadata[refund_reason]"="User called to cancel because they picked the wrong item" \ -d "expand[0]"=line_items ``` ```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 = '<>' transaction = Stripe::Tax::Transaction.create_reversal({ mode: 'full', original_transaction: 'tax_1MEFACI6rIcR421eHrjXCSmD', reference: 'pi_123456789-refund_1-cancel', metadata: {refund_reason: 'User called to cancel because they picked the wrong item'}, expand: ['line_items'], }) ``` ```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("<>") transaction = client.v1.tax.transactions.create_reversal({ mode: 'full', original_transaction: 'tax_1MEFACI6rIcR421eHrjXCSmD', reference: 'pi_123456789-refund_1-cancel', metadata: {refund_reason: 'User called to cancel because they picked the wrong item'}, expand: ['line_items'], }) ``` ```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 = "<>" transaction = stripe.tax.Transaction.create_reversal( mode="full", original_transaction="tax_1MEFACI6rIcR421eHrjXCSmD", reference="pi_123456789-refund_1-cancel", metadata={"refund_reason": "User called to cancel because they picked the wrong item"}, expand=["line_items"], ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. transaction = client.v1.tax.transactions.create_reversal({ "mode": "full", "original_transaction": "tax_1MEFACI6rIcR421eHrjXCSmD", "reference": "pi_123456789-refund_1-cancel", "metadata": { "refund_reason": "User called to cancel because they picked the wrong item", }, "expand": ["line_items"], }) ``` ```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('<>'); $transaction = $stripe->tax->transactions->createReversal([ 'mode' => 'full', 'original_transaction' => 'tax_1MEFACI6rIcR421eHrjXCSmD', 'reference' => 'pi_123456789-refund_1-cancel', 'metadata' => [ 'refund_reason' => 'User called to cancel because they picked the wrong item', ], 'expand' => ['line_items'], ]); ``` ```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 = "<>"; TransactionCreateReversalParams params = TransactionCreateReversalParams.builder() .setMode(TransactionCreateReversalParams.Mode.FULL) .setOriginalTransaction("tax_1MEFACI6rIcR421eHrjXCSmD") .setReference("pi_123456789-refund_1-cancel") .putMetadata( "refund_reason", "User called to cancel because they picked the wrong item" ) .addExpand("line_items") .build(); Transaction transaction = Transaction.createReversal(params); ``` ```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("<>"); TransactionCreateReversalParams params = TransactionCreateReversalParams.builder() .setMode(TransactionCreateReversalParams.Mode.FULL) .setOriginalTransaction("tax_1MEFACI6rIcR421eHrjXCSmD") .setReference("pi_123456789-refund_1-cancel") .putMetadata( "refund_reason", "User called to cancel because they picked the wrong item" ) .addExpand("line_items") .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Transaction transaction = client.v1().tax().transactions().createReversal(params); ``` ```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')('<>'); const transaction = await stripe.tax.transactions.createReversal({ mode: 'full', original_transaction: 'tax_1MEFACI6rIcR421eHrjXCSmD', reference: 'pi_123456789-refund_1-cancel', metadata: { refund_reason: 'User called to cancel because they picked the wrong item', }, expand: ['line_items'], }); ``` ```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 = "<>" params := &stripe.TaxTransactionCreateReversalParams{ Mode: stripe.String("full"), OriginalTransaction: stripe.String("tax_1MEFACI6rIcR421eHrjXCSmD"), Reference: stripe.String("pi_123456789-refund_1-cancel"), } params.AddMetadata( "refund_reason", "User called to cancel because they picked the wrong item") params.AddExpand("line_items") result, err := transaction.CreateReversal(params) ``` ```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("<>") params := &stripe.TaxTransactionCreateReversalParams{ Mode: stripe.String("full"), OriginalTransaction: stripe.String("tax_1MEFACI6rIcR421eHrjXCSmD"), Reference: stripe.String("pi_123456789-refund_1-cancel"), } params.AddMetadata( "refund_reason", "User called to cancel because they picked the wrong item") params.AddExpand("line_items") result, err := sc.V1TaxTransactions.CreateReversal(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.TransactionCreateReversalOptions { Mode = "full", OriginalTransaction = "tax_1MEFACI6rIcR421eHrjXCSmD", Reference = "pi_123456789-refund_1-cancel", Metadata = new Dictionary { { "refund_reason", "User called to cancel because they picked the wrong item" }, }, Expand = new List { "line_items" }, }; var service = new Stripe.Tax.TransactionService(); Stripe.Tax.Transaction transaction = service.CreateReversal(options); ``` ```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 Stripe.Tax.TransactionCreateReversalOptions { Mode = "full", OriginalTransaction = "tax_1MEFACI6rIcR421eHrjXCSmD", Reference = "pi_123456789-refund_1-cancel", Metadata = new Dictionary { { "refund_reason", "User called to cancel because they picked the wrong item" }, }, Expand = new List { "line_items" }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Transactions; Stripe.Tax.Transaction transaction = service.CreateReversal(options); ``` This returns the full reversal transaction that’s created: ```json { "id": "tax_1MEFADI6rIcR421e94fNTOCK", "object": "tax.transaction", "created": 1670863657, "currency": "eur", ... "line_items": { "object": "list", "data": [ { "id": "tax_li_MyBXMOlwenCyFB", "object": "tax.transaction_line_item", "amount": 4999, "amount_tax": 1150, "livemode": false, "metadata": { }, "quantity": 1, "reference": "L1", "reversal": { "original_line_item": "tax_li_MyBXC98AhtaR37" }, "tax_behavior": "exclusive", "tax_code": "txcd_10000000", "type": "reversal" } ], "has_more": false, "total_count": 1, "url": "/v1/tax/transactions/tax_1MEFADI6rIcR421e94fNTOCK/line_items" }, "livemode": false, "metadata": { "refund_reason": "User called to cancel because they picked the wrong item" }, "reference": "pi_123456789-refund_1-cancel", "reversal": { "original_transaction": "tax_1MEFACI6rIcR421eHrjXCSmD" }, "shipping_cost": null, "tax_date": 1670863654, "type": "reversal" } ``` ## Testing The response structure in *sandboxes* (A sandbox is an isolated test environment that allows you to test Stripe functionality in your account without affecting your live integration. Use sandboxes to safely experiment with new features and changes) is identical to live mode so that you can confirm your integration is working correctly before going live. > We don’t guarantee calculations in testing environments to return up-to-date taxation results. > > You’re limited to 1,000 tax calculations per day. If you need a higher limit, contact [Stripe support](https://support.stripe.com/contact). > > For guidance on automated testing and strategies to avoid rate limits in testing environments, see [Automated testing](https://docs.stripe.com/automated-testing.md). ## View tax transactions in the Dashboard You can view all tax transactions for your account on the [Tax Transactions](https://dashboard.stripe.com/test/tax/transactions) page in the Dashboard. Click an individual transaction to see a detailed breakdown of calculated tax by jurisdiction, and by the individual products included in the transaction. > This page only includes *transactions* and not *calculations*. If you expect a calculation to be visible but can’t find it on this page, check that you’ve successfully [created a tax transaction](https://docs.stripe.com/tax/custom.md#tax-transaction) from the calculation. ## Optional: Integration examples You can calculate tax for your customer before collecting payment method details and [creating a PaymentIntent](https://docs.stripe.com/payments/accept-a-payment.md?platform=web&ui=elements#web-create-intent). For example, you could display a shopping cart total when they provide their postal code. In the example below, your server defines a `/preview-cart` endpoint, where the customer’s address is sent from your client-side form. The server combines the cart’s line items and the customer’s address to calculate tax. #### Node.js ```javascript // 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')('<>'); const express = require('express'); const app = express(); // Parse the request body as JSON. app.use(express.json()); app.post('/preview-cart', async (req, res) => { const cart = ...; // Load the cart/order from your system // Convert each cart item to a Stripe line item object const lineItems = cart.items.map( cartItem => ({ reference: cartItem.id, amount: cartItem.unitPrice * cartItem.quantity, quantity: cartItem.quantity }) ); // Get the customer's address from the request body const address = req.body.address; // Create a tax calculation using the Stripe API const calculation = await stripe.tax.calculations.create({ currency: cart.currency, line_items: lineItems, customer_details: { address: { line1: address.line1, city: address.city, state: address.state, postal_code: address.postal_code, country: address.country, }, address_source: "billing" }, expand: ['line_items.data.tax_breakdown'] }); // Return the tax amount as a JSON response res.json({ tax_amount: calculation.tax_amount_exclusive }); }); app.listen(4242, () => { console.log('Running on port 4242'); }); ``` #### Java ```java package com.stripe.sample; import static spark.Spark.post; import static spark.Spark.port; import static spark.Spark.staticFiles; import com.stripe.Stripe; import com.stripe.exception.StripeException; import com.stripe.model.tax.Calculation; import com.stripe.param.tax.CalculationCreateParams; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Server { public static void main(String[] args) throws StripeException { port(4242); // 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 = "<>"; post("/preview-cart", (request, response) -> { var cart = ...; // Load the cart/order from your system // Convert each cart item to a Stripe line item object List lineItems = cart.getItems().stream() .map(cartItem -> CalculationCreateParams.LineItem .builder() .setReference(cartItem.id()) .setAmount(cartItem.unitPrice() * cartItem.quantity()) .setQuantity(cartItem.quantity()) .build()).collect(Collectors.toList()); // Get the customer's address from the request body var userAddress = ...; // Convert the customer's address to a Stripe customer address object CalculationCreateParams.CustomerDetails.Address address = CalculationCreateParams.CustomerDetails.Address .builder() .setLine1(userAddress.getLine1()) .setLine2(userAddress.getLine2()) .setCity(userAddress.getCity()) .setCountry(userAddress.getCountry()) .setPostalCode(userAddress.getPostalCode()) .build(); // Create a tax calculation using the Stripe API CalculationCreateParams params = CalculationCreateParams .builder() .setCurrency(cart.getCurrency()) .addAllLineItem(lineItems) .setCustomerDetails( CalculationCreateParams.CustomerDetails .builder() .setAddress(address) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .build() ) .addExpand("line_items.data.tax_breakdown") .build(); Calculation calculation = Calculation.create(params); // Return the tax amount as a JSON response return Map.of( "tax_amount", calculation.getTaxAmountExclusive() ); } } } ``` #### Ruby ```ruby require 'stripe' require 'sinatra' # 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 = '<>' set :static, true set :port, 4242 post '/preview-cart' do payload = JSON.parse(request.body.read) # Parse the request body as JSON. cart = ... # Load the cart/order from your system # Convert each cart item to a Stripe line item object line_items = cart.items.map do |cart_item| { reference: cart_item.id, amount: cart_item.unit_price * cart_item.quantity, quantity: cart_item.quantity } end # Get the customer's address from the request body address = payload['address'] # Create a tax calculation using the Stripe API calculation = Stripe::Tax::Calculation.create({ currency: cart.currency, line_items: line_items, customer_details: { address: { line1: address['line1'], line2: address['line2'], city: address['city'], state: address['state'], postal_code: address['postal_code'], country: address['country'], }, address_source: 'billing', }, expand: ['line_items.data.tax_breakdown'], }) # Return the tax amount as a JSON response { tax_amount: calculation.tax_amount_exclusive }.to_json end ``` #### PHP ```php >'); $app->post('/preview-cart', function($request, $response) { $cart = ...; // Load the cart/order from your system // Convert each cart item to a Stripe line item object $lineItems = array_map(fn($cartItem) => [ 'reference' => $cartItem->id, 'amount' => $cartItem->quantity * $cartItem->unitPrice, 'quantity' => $cartItem->quantity, ], $cart->getItems()); // Get the customer's address from the request body $address = $request->getParsedBody()['address']; // Create a tax calculation using the Stripe API $calculation = $stripe->tax->calculations->create([ 'currency' => $cart->currency, 'line_items' => $line_items, 'customer_details' => [ 'address' => [ 'line1' => $address['line1'], 'line2' => $address['line2'], 'city' => $address['city'], 'state' => $address['state'], 'postal_code' => $address['postal_code'], 'country' => $address['country'], ], 'address_source' => 'billing', ], 'expand' => ['line_items.data.tax_breakdown'], ]); # Return the tax amount as a JSON response return $response->withJson([ 'tax_amount' => $calculation->tax_amount_exclusive ]); }); ``` #### Python ```python from flask import Flask, request import stripe # 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 = '<>' app = Flask(__name__, static_url_path='', static_folder='public') @app.route('/preview-cart', methods=['POST']) def preview_cart(): # Load the cart/order from your system cart = ... # Convert each cart item to a Stripe line item object line_items = [{ 'reference': cart_item.id, 'amount': cart_item.unit_price * cart_item.quantity, 'quantity': cart_item.quantity } for cart_item in cart.items] # Get the customer's address from the request body address = request.json['address'] # Create a tax calculation using the Stripe API calculation = stripe.tax.Calculation.create( currency=cart.currency, line_items=line_items, customer_details={ 'address': { 'line1': address.get('line1', ''), 'line2': address.get('line2', ''), 'city': address.get('city', ''), 'state': address.get('state', ''), 'postal_code': address.get('postal_code', ''), 'country': address.get('country', ''), }, 'address_source': 'billing' }, expand=['line_items.data.tax_breakdown'] ) # Return the tax amount as a JSON response return { 'tax_amount': calculation['tax_amount_exclusive'] } if __name__ == '__main__': app.run(port=4242) ``` #### Go ```go package main import ( "log" "encoding/json" "io/ioutil" "net/http" "github.com/stripe/stripe-go/v74" "github.com/stripe/stripe-go/v74/tax/calculation" "github.com/stripe/stripe-go/v74" ) func main() { // 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 = "<>" http.Handle("/", http.FileServer(http.Dir("public"))) http.HandleFunc("/preview-cart", previewCart) addr := "localhost:4242" log.Printf("Listening on %s", addr) log.Fatal(http.ListenAndServe(addr, nil)) } type RequestBody struct { Address map[string]string `json:"address"` } func previewCart(w http.ResponseWriter, r *http.Request) { cart := ... // Load the cart/order from your system // Convert each cart item to a Stripe line item object var lineItems []*stripe.TaxCalculationLineItemParams for _, cartItem := range cart.Items { item := &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(cartItem.UnitPrice * cartItem.Quantity), Reference: stripe.String(cartItem.Id), Quantity: stripe.Int64(cartItem.Quantity), } lineItems = append(lineItems, item) } // Get the customer's address from the request body body, err := ioutil.ReadAll(r.Body) if err != nil { panic(err) } var parsedBody RequestBody err = json.Unmarshal([]byte(body), &parsedBody) if err != nil { http.Error(w, "Invalid address parameter", http.StatusBadRequest) return } address := parsedBody.Address // Create a tax calculation using the Stripe API params := &stripe.TaxCalculationParams{ Currency: stripe.String(cart.Currency), LineItems: lineItems, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String(address["line1"]), Line2: stripe.String(address["line2"]), City: stripe.String(address["city"]), State: stripe.String(address["state"]), PostalCode: stripe.String(address["postal_code"]), Country: stripe.String(address["country"]), }, AddressSource: stripe.String(string(stripe.TaxCalculationCustomerDetailsAddressSourceBilling)), }, }; params.AddExpand("line_items.data.tax_breakdown") result, _ := calculation.New(params); // Return the tax amount as a JSON response data := map[string]interface{}{ "tax_amount": result.TaxAmountExclusive, } json.NewEncoder(w).Encode(data) } ``` #### .NET ```dotnet using System.Collections.Generic; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Stripe; using Stripe.Tax; namespace server.Controllers { public class Program { public static void Main(string[] args) { WebHost.CreateDefaultBuilder(args) .UseUrls("http://0.0.0.0:4242") .UseWebRoot("public") .UseStartup() .Build() .Run(); } } public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc().AddNewtonsoftJson(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 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 = "<>"; if (env.IsDevelopment()) app.UseDeveloperExceptionPage(); app.UseRouting(); app.UseStaticFiles(); app.UseEndpoints(endpoints => endpoints.MapControllers()); } } [Route("preview-cart")] [ApiController] public class PreviewCartController : Controller { [HttpPost] public ActionResult Preview([FromBody] Address address) { var cart = ...; // Load the cart/order from your system // Convert each cart item to a Stripe line item object var lineItems = new List(); foreach (var cartItem in cart.Items) { lineItems.Add(new CalculationLineItemOptions { Reference = cartItem.Id, Amount = cartItem.Quantity * cartItem.UnitPrice, Quantity = cartItem.Quantity }); } // Create a tax calculation using the Stripe API var options = new CalculationCreateOptions { Currency = cart.Currency, LineItems = LineItems, CustomerDetails = new CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = address.Line1, Line2 = address.Line2, City = address.City, State = address.State, PostalCode = address.PostalCode, Country = address.Country, }, AddressSource = "billing", }, Expand = new List { "line_items.data.tax_breakdown" }, }; var service = new CalculationService(); var calculation = service.Create(options); // Return the tax amount as a JSON response var preview = new Dictionary { { "tax_amount", calculation.TaxAmountExclusive }, }; return Json(preview); } } } ``` When you’re ready to take payment, create a PaymentIntent from the tax calculation result. Store the tax calculation ID in the PaymentIntent’s [metadata](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-metadata) or in your own database so you can create a tax transaction when your customer completes payment. The example below shows a server endpoint that calculates tax, creates (or updates) a PaymentIntent, and returns the result to the client. You can then display the tax to your customer. Use the `client_secret` to [take the payment](https://docs.stripe.com/payments/accept-a-payment.md?platform=web&ui=elements#web-collect-payment-details). #### Node.js ```javascript // 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')('<>'); const express = require('express'); const app = express(); // Parse the request body as JSON. app.use(express.json()); app.post('/calculate-cart', async (req, res) => { const cart = ...; // Load the cart/order from your system // Create a tax calculation using the Stripe API const calculation = await stripe.tax.calculations.create(...); let paymentIntent; // Update the PaymentIntent if one already exists for this cart. if (cart.paymentIntent) { paymentIntent = await stripe.paymentIntents.update(cart.paymentIntent, { amount: calculation.amount_total, metadata: {tax_calculation: calculation.id}, }); } else { paymentIntent = await stripe.paymentIntents.create({ currency: cart.currency, amount: calculation.amount_total, metadata: {tax_calculation: calculation.id}, // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: {enabled: true}, }); } // Store PaymentIntent ID in cart or customer session. cart.paymentIntent = paymentIntent.id; // Return calculated amounts and PaymentIntent secret to the client. res.json({ total: calculation.amount_total, tax_amount: calculation.tax_amount_exclusive, client_secret: paymentIntent.client_secret }); }); app.listen(4242, () => { console.log('Running on port 4242'); }); ``` #### Java ```java package com.stripe.sample; import static spark.Spark.post; import static spark.Spark.port; import static spark.Spark.staticFiles; import com.stripe.Stripe; import com.stripe.exception.StripeException; import com.stripe.model.PaymentIntent; import com.stripe.model.tax.Calculation; import com.stripe.param.PaymentIntentCreateParams; import com.stripe.param.PaymentIntentUpdateParams; import com.stripe.param.tax.CalculationCreateParams; public class Server { public static void main(String[] args) throws StripeException { port(4242); // 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 = "<>"; post("/calculate-cart", (request, response) -> { var cart = ...; // Load the cart/order from your system // Create a tax calculation using the Stripe API CalculationCreateParams params = ...; Calculation calculation = Calculation.create(params); PaymentIntent paymentIntent; // Update the PaymentIntent if one already exists for this cart. if (cart.paymentIntent != null){ paymentIntent = PaymentIntent.retrieve(cart.paymentIntent); PaymentIntentUpdateParams params = PaymentIntentUpdateParams.builder() .setAmount(calculation.getAmountTotal()) .putMetadata("tax_calculation", calculation.getId()) .build(); paymentIntent = paymentIntent.update(params); } else { PaymentIntentCreateParams params = PaymentIntentCreateParams.builder() .setAmount(calculation.getAmountTotal()) .setCurrency(cart.getCurrency()) // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. .setAutomaticPaymentMethods( PaymentIntentCreateParams.AutomaticPaymentMethods.builder() .setEnabled(true) .build() ) .putMetadata("tax_calculation", calculation.getId()) .build(); paymentIntent = PaymentIntent.create(params); } // Store PaymentIntent ID in cart or customer session. cart.setPaymentIntent(paymentIntent.getId()); return Map.of( "total", calculation.getAmountTotal(), "tax_amount", calculation.getTaxAmountExclusive(), "client_secret", paymentIntent.getClientSecret() ); }); } } ``` #### Ruby ```ruby require 'stripe' require 'sinatra' # 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 = '<>' set :static, true set :port, 4242 post '/calculate-cart' do cart = ... # Load the cart/order from your system # Create a tax calculation using the Stripe API calculation = Stripe::Tax::Calculation.create(...) # Update the PaymentIntent if one already exists for this cart. if cart.payment_intent.present? payment_intent = Stripe::PaymentIntent.update( cart.payment_intent, { amount: calculation.amount_total, metadata: {tax_calculation: calculation.id}, }, ) else payment_intent = Stripe::PaymentIntent.create({ amount: calculation.amount_total, currency: cart.currency, # In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: {enabled: true}, metadata: {tax_calculation: calculation.id}, }) end # Store PaymentIntent ID in cart or customer session. cart.payment_intent = payment_intent.id # Return calculated amounts and PaymentIntent secret to the client. result = { total: calculation.amount_total, tax_amount: calculation.tax_amount_exclusive, client_secret: payment_intent.client_secret } result.to_json end ``` #### PHP ```php >'); $app->post('/calculate-cart', function($request, $response) { $cart = $body['cart']; // Load the cart/order from your system // Create a tax calculation using the Stripe API $calculation = $stripe->tax->calculations->create(...) // Update the PaymentIntent if one already exists for this cart. if ($cart->paymentIntent) { $paymentIntent = $stripe->paymentIntents->update($cart->paymentIntent, [ 'amount' => $calculation->amount_total, 'metadata' => [ 'tax_calculation' => $calculation->id ] ]); } else { $paymentIntent = $stripe->paymentIntents->create([ 'amount' => $calculation->amount_total, 'currency' => $cart->currency, // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. 'automatic_payment_methods' => [ 'enabled' => true, ], 'metadata' => [ 'tax_calculation' => $calculation->id ] ]); } // Store PaymentIntent ID in cart or customer session. $cart->paymentIntent = $paymentIntent->id; // Return calculated amounts and PaymentIntent secret to the client. return $response->withJson([ 'total' => $calculation->amount_total, 'tax_amount' => $calculation->tax_amount_exclusive, 'client_secret' => $calculation->client_secret ]); }); ``` #### Python ```python import os from flask import Flask, request import stripe # 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 = '<>' app = Flask(__name__, static_url_path='', static_folder='public') @app.route('/calculate-cart', methods=['POST']) def calculate_cart(): # Load the cart/order from your system cart = ... # Create a tax calculation using the Stripe API calculation = stripe.tax.Calculation.create( #... ) payment_intent = None # Update the PaymentIntent if one already exists for this cart. if cart.payment_intent: payment_intent = stripe.PaymentIntent.modify( cart.payment_intent, amount=calculation.amount_total, metadata={"tax_calculation": calculation.id}, ) else: payment_intent = stripe.PaymentIntent.create( amount=calculation.amount_total, currency=cart.currency, # In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods={"enabled": True}, metadata={"tax_calculation": calculation.id}, ) # Store PaymentIntent ID in cart or customer session. cart.payment_intent = payment_intent.id # Return calculated amounts and PaymentIntent secret to the client. return { 'total': calculation.amount_total, 'tax_amount': calculation.tax_amount_exclusive, 'client_secret': payment_intent.client_secret } if __name__ == '__main__': app.run(port=4242) ``` #### Go ```go package main import ( "log" "encoding/json" "net/http" "github.com/stripe/stripe-go/v74" "github.com/stripe/stripe-go/v74/paymentintent" "github.com/stripe/stripe-go/v74/tax/calculation" ) func main() { // 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 = "<>" http.Handle("/", http.FileServer(http.Dir("public"))) http.HandleFunc("/calculate-cart", calculateCart) addr := "localhost:4242" log.Printf("Listening on %s", addr) log.Fatal(http.ListenAndServe(addr, nil)) } func calculateCart(w http.ResponseWriter, r *http.Request) { cart := ... // Load the cart/order from your system // Create a tax calculation using the Stripe API calculation, _ := calculation.New(...); // Update the PaymentIntent if one already exists for this cart. if cart.PaymentIntent != nil { params := &stripe.PaymentIntentParams{ Amount: &calculation.AmountTotal, } params.AddMetadata("tax_calculation", calculation.ID) pi, _ := paymentintent.Update(cart.PaymentIntent, params,) } else { params := &stripe.PaymentIntentParams{ Currency: stripe.String(string(cart.Currency)), Amount: &calculation.AmountTotal, // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. AutomaticPaymentMethods: &stripe.PaymentIntentAutomaticPaymentMethodsParams{ Enabled: stripe.Bool(true), }, } params.AddMetadata("tax_calculation", calculation.ID) pi, _ := paymentintent.New(params) } // Store PaymentIntent ID in cart or customer session. cart.SetPaymentIntent(pi.ID) result := map[string]interface{}{ "total": calculation.AmountTotal, "tax_amount": calculation.TaxAmountExclusive, "client_secret": pi.ClientSecret, } json.NewEncoder(w).Encode(result) } ``` #### .NET ```dotnet using System.Collections.Generic; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Stripe; using Stripe.Tax; namespace server.Controllers { public class Program { public static void Main(string[] args) { WebHost.CreateDefaultBuilder(args) .UseUrls("http://0.0.0.0:4242") .UseWebRoot("public") .UseStartup() .Build() .Run(); } } public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc().AddNewtonsoftJson(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 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 = "<>"; if (env.IsDevelopment()) app.UseDeveloperExceptionPage(); app.UseRouting(); app.UseStaticFiles(); app.UseEndpoints(endpoints => endpoints.MapControllers()); } } [Route("calculate-cart")] [ApiController] public class CalculateCartController : Controller { [HttpPost] public ActionResult Calculate([FromBody] Address address) { var cart = ...; // load cart from your system // Create a tax calculation using the Stripe API var taxService = new CalculationService(); var calculation = taxService.Create(...); var paymentService = new PaymentIntentService(); PaymentIntent paymentIntent; // Update the PaymentIntent if one already exists for this cart. if (cart.PaymentIntent != null) { var options = new PaymentIntentUpdateOptions { Amount = calculation.AmountTotal, Metadata = new Dictionary { { "tax_calculation", calculation.Id }, }, }; paymentIntent = paymentService.Update(cart.PaymentIntent, options); } else { var options = new PaymentIntentCreateOptions { Amount = calculation.AmountTotal, Currency = cart.Currency, // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. AutomaticPaymentMethods = new PaymentIntentAutomaticPaymentMethodsOptions { Enabled = true, }, Metadata = new Dictionary { { "tax_calculation", calculation.Id }, }, }; paymentIntent = paymentService.Create(options); } // Store PaymentIntent ID in cart or customer session. cart.PaymentIntent = paymentIntent.Id; var result = new Dictionary { { "total", calculation.AmountTotal }, { "tax_amount", calculation.TaxAmountExclusive }, { "client_secret", paymentIntent.ClientSecret }, }; return Json(result); } } } ``` If your integration uses the Payment Element, [fetch updates from the server](https://docs.stripe.com/payments/accept-a-payment.md?platform=web&ui=elements#fetch-updates) after updating the PaymentIntent. ## Optional: Calculate tax on shipping costs [Server-side] To calculate tax on shipping costs, use the `shipping_cost` parameter: ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][line1]"="920 5th Ave" \ -d "customer_details[address][city]"=Seattle \ -d "customer_details[address][state]"=WA \ -d "customer_details[address][postal_code]"=98104 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping \ -d "shipping_cost[amount]"=500 \ -d "shipping_cost[tax_code]"=txcd_92010001 ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][line1]"="920 5th Ave" \ -d "customer_details[address][city]"=Seattle \ -d "customer_details[address][state]"=WA \ -d "customer_details[address][postal_code]"=98104 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping \ -d "shipping_cost[amount]"=500 \ -d "shipping_cost[tax_code]"=txcd_92010001 ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, shipping_cost: { amount: 500, tax_code: 'txcd_92010001', }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, shipping_cost: { amount: 500, tax_code: 'txcd_92010001', }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[{"amount": 1000, "reference": "L1"}], customer_details={ "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "shipping", }, shipping_cost={"amount": 500, "tax_code": "txcd_92010001"}, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [{"amount": 1000, "reference": "L1"}], "customer_details": { "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "shipping", }, "shipping_cost": {"amount": 500, "tax_code": "txcd_92010001"}, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', ], ], 'customer_details' => [ 'address' => [ 'line1' => '920 5th Ave', 'city' => 'Seattle', 'state' => 'WA', 'postal_code' => '98104', 'country' => 'US', ], 'address_source' => 'shipping', ], 'shipping_cost' => [ 'amount' => 500, 'tax_code' => 'txcd_92010001', ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder() .setAmount(500L) .setTaxCode("txcd_92010001") .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder() .setAmount(500L) .setTaxCode("txcd_92010001") .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, shipping_cost: { amount: 500, tax_code: 'txcd_92010001', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, ShippingCost: &stripe.TaxCalculationShippingCostParams{ Amount: stripe.Int64(500), TaxCode: stripe.String("txcd_92010001"), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, ShippingCost: &stripe.TaxCalculationCreateShippingCostParams{ Amount: stripe.Int64(500), TaxCode: stripe.String("txcd_92010001"), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "shipping", }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { Amount = 500, TaxCode = "txcd_92010001", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "shipping", }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { Amount = 500, TaxCode = "txcd_92010001", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` Pass the ID of an existing [ShippingRate](https://docs.stripe.com/api/shipping_rates/object.md) to use its `amount`, `tax_code`, and `tax_behavior`: ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][line1]"="920 5th Ave" \ -d "customer_details[address][city]"=Seattle \ -d "customer_details[address][state]"=WA \ -d "customer_details[address][postal_code]"=98104 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping \ -d "shipping_cost[shipping_rate]"=shr_1Mlh8YI6rIcR421eUr9SJzAD ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][line1]"="920 5th Ave" \ -d "customer_details[address][city]"=Seattle \ -d "customer_details[address][state]"=WA \ -d "customer_details[address][postal_code]"=98104 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping \ -d "shipping_cost[shipping_rate]"=shr_1Mlh8YI6rIcR421eUr9SJzAD ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, shipping_cost: {shipping_rate: 'shr_1Mlh8YI6rIcR421eUr9SJzAD'}, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, shipping_cost: {shipping_rate: 'shr_1Mlh8YI6rIcR421eUr9SJzAD'}, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[{"amount": 1000, "reference": "L1"}], customer_details={ "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "shipping", }, shipping_cost={"shipping_rate": "shr_1Mlh8YI6rIcR421eUr9SJzAD"}, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [{"amount": 1000, "reference": "L1"}], "customer_details": { "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "shipping", }, "shipping_cost": {"shipping_rate": "shr_1Mlh8YI6rIcR421eUr9SJzAD"}, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', ], ], 'customer_details' => [ 'address' => [ 'line1' => '920 5th Ave', 'city' => 'Seattle', 'state' => 'WA', 'postal_code' => '98104', 'country' => 'US', ], 'address_source' => 'shipping', ], 'shipping_cost' => ['shipping_rate' => 'shr_1Mlh8YI6rIcR421eUr9SJzAD'], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder() .setShippingRate("shr_1Mlh8YI6rIcR421eUr9SJzAD") .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder() .setShippingRate("shr_1Mlh8YI6rIcR421eUr9SJzAD") .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, shipping_cost: { shipping_rate: 'shr_1Mlh8YI6rIcR421eUr9SJzAD', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, ShippingCost: &stripe.TaxCalculationShippingCostParams{ ShippingRate: stripe.String("shr_1Mlh8YI6rIcR421eUr9SJzAD"), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, ShippingCost: &stripe.TaxCalculationCreateShippingCostParams{ ShippingRate: stripe.String("shr_1Mlh8YI6rIcR421eUr9SJzAD"), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "shipping", }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { ShippingRate = "shr_1Mlh8YI6rIcR421eUr9SJzAD", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "shipping", }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { ShippingRate = "shr_1Mlh8YI6rIcR421eUr9SJzAD", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` ## Optional: Estimate taxes with an IP address [Server-side] If you provide your customer’s [IP address](https://docs.stripe.com/api/tax/calculations/create.md#calculate_tax-customer_details-ip_address), we geolocate it and use that location as your customer’s location. Use this to show your customer a tax estimate before they provide their postal address. > Because the location of an IP address could be some distance from the actual location of your customer, we recommend against using an IP address to determine the *final* amount of tax to collect. ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[ip_address]"="127.0.0.1" ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[ip_address]"="127.0.0.1" ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: {ip_address: '127.0.0.1'}, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: {ip_address: '127.0.0.1'}, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[{"amount": 1000, "reference": "L1"}], customer_details={"ip_address": "127.0.0.1"}, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [{"amount": 1000, "reference": "L1"}], "customer_details": {"ip_address": "127.0.0.1"}, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', ], ], 'customer_details' => ['ip_address' => '127.0.0.1'], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder().setIpAddress("127.0.0.1").build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder().setIpAddress("127.0.0.1").build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { ip_address: '127.0.0.1', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ IPAddress: stripe.String("127.0.0.1"), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ IPAddress: stripe.String("127.0.0.1"), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { IpAddress = "127.0.0.1", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { IpAddress = "127.0.0.1", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` ## Optional: Collect customer tax IDs [Server-side] In some cases, such as the cross-border supply of services, your business customer might have to account for tax on a [reverse charge](https://docs.stripe.com/tax/zero-tax.md#reverse-charges) basis. You don’t collect the tax, and instead must issue an invoice with the text “Tax to be paid on reverse charge basis”. This informs your customer that they’re responsible for any tax on their purchase. Provide your customer’s [tax IDs](https://docs.stripe.com/api/tax/calculations/create.md#calculate_tax-customer_details-tax_ids) to automatically determine when reverse charge applies: ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][country]"=IE \ -d "customer_details[address_source]"=billing \ -d "customer_details[tax_ids][0][type]"=eu_vat \ -d "customer_details[tax_ids][0][value]"=DE123456789 ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][country]"=IE \ -d "customer_details[address_source]"=billing \ -d "customer_details[tax_ids][0][type]"=eu_vat \ -d "customer_details[tax_ids][0][value]"=DE123456789 ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: {country: 'IE'}, address_source: 'billing', tax_ids: [ { type: 'eu_vat', value: 'DE123456789', }, ], }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: {country: 'IE'}, address_source: 'billing', tax_ids: [ { type: 'eu_vat', value: 'DE123456789', }, ], }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[{"amount": 1000, "reference": "L1"}], customer_details={ "address": {"country": "IE"}, "address_source": "billing", "tax_ids": [{"type": "eu_vat", "value": "DE123456789"}], }, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [{"amount": 1000, "reference": "L1"}], "customer_details": { "address": {"country": "IE"}, "address_source": "billing", "tax_ids": [{"type": "eu_vat", "value": "DE123456789"}], }, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', ], ], 'customer_details' => [ 'address' => ['country' => 'IE'], 'address_source' => 'billing', 'tax_ids' => [ [ 'type' => 'eu_vat', 'value' => 'DE123456789', ], ], ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCountry("IE") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .addTaxId( CalculationCreateParams.CustomerDetails.TaxId.builder() .setType(CalculationCreateParams.CustomerDetails.TaxId.Type.EU_VAT) .setValue("DE123456789") .build() ) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCountry("IE") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .addTaxId( CalculationCreateParams.CustomerDetails.TaxId.builder() .setType(CalculationCreateParams.CustomerDetails.TaxId.Type.EU_VAT) .setValue("DE123456789") .build() ) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { country: 'IE', }, address_source: 'billing', tax_ids: [ { type: 'eu_vat', value: 'DE123456789', }, ], }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{Country: stripe.String("IE")}, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), TaxIDs: []*stripe.TaxCalculationCustomerDetailsTaxIDParams{ &stripe.TaxCalculationCustomerDetailsTaxIDParams{ Type: stripe.String(stripe.TaxCalculationCustomerDetailsTaxIDTypeEUVAT), Value: stripe.String("DE123456789"), }, }, }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{Country: stripe.String("IE")}, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), TaxIDs: []*stripe.TaxCalculationCreateCustomerDetailsTaxIDParams{ &stripe.TaxCalculationCreateCustomerDetailsTaxIDParams{ Type: stripe.String(stripe.TaxCalculationCustomerDetailsTaxIDTypeEUVAT), Value: stripe.String("DE123456789"), }, }, }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Country = "IE" }, AddressSource = "billing", TaxIds = new List { new Stripe.Tax.CalculationCustomerDetailsTaxIdOptions { Type = "eu_vat", Value = "DE123456789", }, }, }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Country = "IE" }, AddressSource = "billing", TaxIds = new List { new Stripe.Tax.CalculationCustomerDetailsTaxIdOptions { Type = "eu_vat", Value = "DE123456789", }, }, }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` If you provide a tax ID with an invalid format, the calculation returns error code `tax_id_invalid`: ```json { "error": { "code": "tax_id_invalid", "doc_url": "https://docs.stripe.com/error-codes#tax-id-invalid", "message": "Invalid value for eu_vat.", "param": "customer_details[tax_ids][0][value]", "type": "invalid_request_error" } } ``` The Tax API doesn’t automatically validate tax IDs against government databases. To validate a tax ID before calculating tax you need to use [Customer tax ID validation](https://docs.stripe.com/billing/customer/tax-ids.md#validation). ## Optional: Tax-inclusive pricing [Server-side] By default, tax is calculated on top of the line item and shipping cost amounts you provide. Set the [line item](https://docs.stripe.com/api/tax/calculations/create.md#calculate_tax-line_items-tax_behavior) or [shipping cost](https://docs.stripe.com/api/tax/calculations/create.md#calculate_tax-shipping_cost-tax_behavior) `tax_behavior` to `inclusive` to calculate the tax included in your prices. In the example below the customer always pays 100 EUR: ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=eur \ -d "line_items[0][amount]"=10000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_behavior]"=inclusive \ -d "line_items[0][tax_code]"=txcd_10103000 \ -d "customer_details[address][country]"=IE \ -d "customer_details[address_source]"=billing ``` ```cli stripe tax calculations create \ --currency=eur \ -d "line_items[0][amount]"=10000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_behavior]"=inclusive \ -d "line_items[0][tax_code]"=txcd_10103000 \ -d "customer_details[address][country]"=IE \ -d "customer_details[address_source]"=billing ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'eur', line_items: [ { amount: 10000, reference: 'L1', tax_behavior: 'inclusive', tax_code: 'txcd_10103000', }, ], customer_details: { address: {country: 'IE'}, address_source: 'billing', }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'eur', line_items: [ { amount: 10000, reference: 'L1', tax_behavior: 'inclusive', tax_code: 'txcd_10103000', }, ], customer_details: { address: {country: 'IE'}, address_source: 'billing', }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="eur", line_items=[ { "amount": 10000, "reference": "L1", "tax_behavior": "inclusive", "tax_code": "txcd_10103000", }, ], customer_details={"address": {"country": "IE"}, "address_source": "billing"}, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "eur", "line_items": [ { "amount": 10000, "reference": "L1", "tax_behavior": "inclusive", "tax_code": "txcd_10103000", }, ], "customer_details": {"address": {"country": "IE"}, "address_source": "billing"}, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'eur', 'line_items' => [ [ 'amount' => 10000, 'reference' => 'L1', 'tax_behavior' => 'inclusive', 'tax_code' => 'txcd_10103000', ], ], 'customer_details' => [ 'address' => ['country' => 'IE'], 'address_source' => 'billing', ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("eur") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(10000L) .setReference("L1") .setTaxBehavior(CalculationCreateParams.LineItem.TaxBehavior.INCLUSIVE) .setTaxCode("txcd_10103000") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCountry("IE") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("eur") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(10000L) .setReference("L1") .setTaxBehavior(CalculationCreateParams.LineItem.TaxBehavior.INCLUSIVE) .setTaxCode("txcd_10103000") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCountry("IE") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'eur', line_items: [ { amount: 10000, reference: 'L1', tax_behavior: 'inclusive', tax_code: 'txcd_10103000', }, ], customer_details: { address: { country: 'IE', }, address_source: 'billing', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyEUR), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(10000), Reference: stripe.String("L1"), TaxBehavior: stripe.String("inclusive"), TaxCode: stripe.String("txcd_10103000"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{Country: stripe.String("IE")}, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyEUR), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(10000), Reference: stripe.String("L1"), TaxBehavior: stripe.String("inclusive"), TaxCode: stripe.String("txcd_10103000"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{Country: stripe.String("IE")}, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "eur", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 10000, Reference = "L1", TaxBehavior = "inclusive", TaxCode = "txcd_10103000", }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Country = "IE" }, AddressSource = "billing", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "eur", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 10000, Reference = "L1", TaxBehavior = "inclusive", TaxCode = "txcd_10103000", }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Country = "IE" }, AddressSource = "billing", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` The response returns the tax included: ```json { ... "amount_total": 10000, ... "tax_amount_exclusive": 0,"tax_amount_inclusive": 1870, "tax_breakdown": [ { "amount": 1870, "inclusive": true, "tax_rate_details": { "country": "IE", "percentage_decimal": "23.0", "state": null, "tax_type": "vat" }, "taxability_reason": "standard_rated", "taxable_amount": 8130 } ], ... } ``` ## Optional: Use an existing Product object [Server-side] You can provide a [Product](https://docs.stripe.com/api/products/object.md) object for each line item. If the product has a [tax_code](https://docs.stripe.com/api/products/object.md#product_object-tax_code), Stripe uses it as the line item’s `tax_code`, if it’s not already populated. Other product values, including the `tax_behavior` and `price`, aren’t used during tax calculation. ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][product]"="{{PRODUCT_ID}}" \ -d "customer_details[address][country]"=IE \ -d "customer_details[address_source]"=billing ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][product]"="{{PRODUCT_ID}}" \ -d "customer_details[address][country]"=IE \ -d "customer_details[address_source]"=billing ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', product: '{{PRODUCT_ID}}', }, ], customer_details: { address: {country: 'IE'}, address_source: 'billing', }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', product: '{{PRODUCT_ID}}', }, ], customer_details: { address: {country: 'IE'}, address_source: 'billing', }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[{"amount": 1000, "reference": "L1", "product": "{{PRODUCT_ID}}"}], customer_details={"address": {"country": "IE"}, "address_source": "billing"}, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [{"amount": 1000, "reference": "L1", "product": "{{PRODUCT_ID}}"}], "customer_details": {"address": {"country": "IE"}, "address_source": "billing"}, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', 'product' => '{{PRODUCT_ID}}', ], ], 'customer_details' => [ 'address' => ['country' => 'IE'], 'address_source' => 'billing', ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .setProduct("{{PRODUCT_ID}}") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCountry("IE") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .setProduct("{{PRODUCT_ID}}") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCountry("IE") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', product: '{{PRODUCT_ID}}', }, ], customer_details: { address: { country: 'IE', }, address_source: 'billing', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), Product: stripe.String("{{PRODUCT_ID}}"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{Country: stripe.String("IE")}, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), Product: stripe.String("{{PRODUCT_ID}}"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{Country: stripe.String("IE")}, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1", Product = "{{PRODUCT_ID}}", }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Country = "IE" }, AddressSource = "billing", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1", Product = "{{PRODUCT_ID}}", }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Country = "IE" }, AddressSource = "billing", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` ## Optional: Use an existing Customer object [Server-side] If you provide a [Customer](https://docs.stripe.com/api/customers/object.md) object, we automatically copy and use the Customer’s address and tax IDs for the calculation: - If the Customer `shipping` is present, it’s copied to `customer_details.address`. - Otherwise, if the Customer `address` is present, it’s copied to `customer_details.address`. - Otherwise, if the Customer `tax.ip_address` is present, it’s copied to `customer_details.ip_address`. - Otherwise, if the Customer `tax.tax_exempt` is present, it’s copied to `customer_details.taxability_override`. The Customer’s [tax IDs](https://docs.stripe.com/api/customer_tax_ids.md) are copied to `customer_details.tax_ids`. ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d customer="{{CUSTOMER_ID}}" ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ --customer="{{CUSTOMER_ID}}" ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer: '{{CUSTOMER_ID}}', }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer: '{{CUSTOMER_ID}}', }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[{"amount": 1000, "reference": "L1"}], customer="{{CUSTOMER_ID}}", ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [{"amount": 1000, "reference": "L1"}], "customer": "{{CUSTOMER_ID}}", }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', ], ], 'customer' => '{{CUSTOMER_ID}}', ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomer("{{CUSTOMER_ID}}") .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomer("{{CUSTOMER_ID}}") .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer: '{{CUSTOMER_ID}}', }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, Customer: stripe.String("{{CUSTOMER_ID}}"), } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, Customer: stripe.String("{{CUSTOMER_ID}}"), } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, Customer = "{{CUSTOMER_ID}}", }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, Customer = "{{CUSTOMER_ID}}", }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` ## Optional: Override customer taxability [Server-side] In some cases, such as when your business customer is tax-exempt, you don’t collect tax. You can provide the tax exemption to Stripe Tax using the [taxability_override](https://docs.stripe.com/api/tax/calculations/create.md#calculate_tax-customer_details-taxability_override) parameter. To provide the customer taxability override to your calculations: ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][line1]"="920 5th Ave" \ -d "customer_details[address][city]"=Seattle \ -d "customer_details[address][state]"=WA \ -d "customer_details[address][postal_code]"=98104 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=billing \ -d "customer_details[taxability_override]"=customer_exempt ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][line1]"="920 5th Ave" \ -d "customer_details[address][city]"=Seattle \ -d "customer_details[address][state]"=WA \ -d "customer_details[address][postal_code]"=98104 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=billing \ -d "customer_details[taxability_override]"=customer_exempt ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'billing', taxability_override: 'customer_exempt', }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'billing', taxability_override: 'customer_exempt', }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[{"amount": 1000, "reference": "L1"}], customer_details={ "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "billing", "taxability_override": "customer_exempt", }, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [{"amount": 1000, "reference": "L1"}], "customer_details": { "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "billing", "taxability_override": "customer_exempt", }, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', ], ], 'customer_details' => [ 'address' => [ 'line1' => '920 5th Ave', 'city' => 'Seattle', 'state' => 'WA', 'postal_code' => '98104', 'country' => 'US', ], 'address_source' => 'billing', 'taxability_override' => 'customer_exempt', ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .setTaxabilityOverride( CalculationCreateParams.CustomerDetails.TaxabilityOverride.CUSTOMER_EXEMPT ) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .setTaxabilityOverride( CalculationCreateParams.CustomerDetails.TaxabilityOverride.CUSTOMER_EXEMPT ) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'billing', taxability_override: 'customer_exempt', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), TaxabilityOverride: stripe.String(stripe.TaxCalculationCustomerDetailsTaxabilityOverrideCustomerExempt), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), TaxabilityOverride: stripe.String(stripe.TaxCalculationCustomerDetailsTaxabilityOverrideCustomerExempt), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "billing", TaxabilityOverride = "customer_exempt", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "billing", TaxabilityOverride = "customer_exempt", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` ### Reverse charge Some regions, such as the European Union, implement a “reverse charge” scheme where the customer is responsible for accounting for tax if they’re purchasing as a business. For Stripe Tax to apply the correct tax treatment, we recommend you collect [Tax IDs](https://docs.stripe.com/tax/custom.md#tax-ids) from your customers. Sometimes you might not have your customer’s tax IDs or you’ve separately determined that the reverse charge scheme applies. In such scenarios you can use `taxability_override` to force Stripe Tax to apply the reverse charge scheme. To provide the customer taxability override to your calculations: ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=eur \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][country]"=IE \ -d "customer_details[address_source]"=billing \ -d "customer_details[taxability_override]"=reverse_charge ``` ```cli stripe tax calculations create \ --currency=eur \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][country]"=IE \ -d "customer_details[address_source]"=billing \ -d "customer_details[taxability_override]"=reverse_charge ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'eur', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: {country: 'IE'}, address_source: 'billing', taxability_override: 'reverse_charge', }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'eur', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: {country: 'IE'}, address_source: 'billing', taxability_override: 'reverse_charge', }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="eur", line_items=[{"amount": 1000, "reference": "L1"}], customer_details={ "address": {"country": "IE"}, "address_source": "billing", "taxability_override": "reverse_charge", }, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "eur", "line_items": [{"amount": 1000, "reference": "L1"}], "customer_details": { "address": {"country": "IE"}, "address_source": "billing", "taxability_override": "reverse_charge", }, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'eur', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', ], ], 'customer_details' => [ 'address' => ['country' => 'IE'], 'address_source' => 'billing', 'taxability_override' => 'reverse_charge', ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("eur") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCountry("IE") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .setTaxabilityOverride( CalculationCreateParams.CustomerDetails.TaxabilityOverride.REVERSE_CHARGE ) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("eur") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCountry("IE") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .setTaxabilityOverride( CalculationCreateParams.CustomerDetails.TaxabilityOverride.REVERSE_CHARGE ) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'eur', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { country: 'IE', }, address_source: 'billing', taxability_override: 'reverse_charge', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyEUR), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{Country: stripe.String("IE")}, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), TaxabilityOverride: stripe.String(stripe.TaxCalculationCustomerDetailsTaxabilityOverrideReverseCharge), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyEUR), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{Country: stripe.String("IE")}, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), TaxabilityOverride: stripe.String(stripe.TaxCalculationCustomerDetailsTaxabilityOverrideReverseCharge), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "eur", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Country = "IE" }, AddressSource = "billing", TaxabilityOverride = "reverse_charge", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "eur", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Country = "IE" }, AddressSource = "billing", TaxabilityOverride = "reverse_charge", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` ## Optional: Specify a ship-from location [Server-side] If you ship goods from a location other than your main place of business, you can provide that address for tax calculations. To provide a ship-from location, use the `ship_from_details` parameter. In this example, the user is based in Florida, their customer is based in Springfield, IL, and the user is shipping the goods from Naperville, IL: ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_behavior]"=exclusive \ -d "line_items[0][tax_code]"=txcd_99999999 \ -d "customer_details[address][city]"=Springfield \ -d "customer_details[address][state]"=IL \ -d "customer_details[address][postal_code]"=62704 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=billing \ -d "ship_from_details[address][city]"=Naperville \ -d "ship_from_details[address][state]"=IL \ -d "ship_from_details[address][postal_code]"=60540 \ -d "ship_from_details[address][country]"=US ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_behavior]"=exclusive \ -d "line_items[0][tax_code]"=txcd_99999999 \ -d "customer_details[address][city]"=Springfield \ -d "customer_details[address][state]"=IL \ -d "customer_details[address][postal_code]"=62704 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=billing \ -d "ship_from_details[address][city]"=Naperville \ -d "ship_from_details[address][state]"=IL \ -d "ship_from_details[address][postal_code]"=60540 \ -d "ship_from_details[address][country]"=US ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_behavior: 'exclusive', tax_code: 'txcd_99999999', }, ], customer_details: { address: { city: 'Springfield', state: 'IL', postal_code: '62704', country: 'US', }, address_source: 'billing', }, ship_from_details: { address: { city: 'Naperville', state: 'IL', postal_code: '60540', country: 'US', }, }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_behavior: 'exclusive', tax_code: 'txcd_99999999', }, ], customer_details: { address: { city: 'Springfield', state: 'IL', postal_code: '62704', country: 'US', }, address_source: 'billing', }, ship_from_details: { address: { city: 'Naperville', state: 'IL', postal_code: '60540', country: 'US', }, }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[ { "amount": 1000, "reference": "L1", "tax_behavior": "exclusive", "tax_code": "txcd_99999999", }, ], customer_details={ "address": { "city": "Springfield", "state": "IL", "postal_code": "62704", "country": "US", }, "address_source": "billing", }, ship_from_details={ "address": { "city": "Naperville", "state": "IL", "postal_code": "60540", "country": "US", }, }, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [ { "amount": 1000, "reference": "L1", "tax_behavior": "exclusive", "tax_code": "txcd_99999999", }, ], "customer_details": { "address": { "city": "Springfield", "state": "IL", "postal_code": "62704", "country": "US", }, "address_source": "billing", }, "ship_from_details": { "address": { "city": "Naperville", "state": "IL", "postal_code": "60540", "country": "US", }, }, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', 'tax_behavior' => 'exclusive', 'tax_code' => 'txcd_99999999', ], ], 'customer_details' => [ 'address' => [ 'city' => 'Springfield', 'state' => 'IL', 'postal_code' => '62704', 'country' => 'US', ], 'address_source' => 'billing', ], 'ship_from_details' => [ 'address' => [ 'city' => 'Naperville', 'state' => 'IL', 'postal_code' => '60540', 'country' => 'US', ], ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .setTaxBehavior(CalculationCreateParams.LineItem.TaxBehavior.EXCLUSIVE) .setTaxCode("txcd_99999999") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCity("Springfield") .setState("IL") .setPostalCode("62704") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .build() ) .setShipFromDetails( CalculationCreateParams.ShipFromDetails.builder() .setAddress( CalculationCreateParams.ShipFromDetails.Address.builder() .setCity("Naperville") .setState("IL") .setPostalCode("60540") .setCountry("US") .build() ) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .setTaxBehavior(CalculationCreateParams.LineItem.TaxBehavior.EXCLUSIVE) .setTaxCode("txcd_99999999") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setCity("Springfield") .setState("IL") .setPostalCode("62704") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.BILLING) .build() ) .setShipFromDetails( CalculationCreateParams.ShipFromDetails.builder() .setAddress( CalculationCreateParams.ShipFromDetails.Address.builder() .setCity("Naperville") .setState("IL") .setPostalCode("60540") .setCountry("US") .build() ) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_behavior: 'exclusive', tax_code: 'txcd_99999999', }, ], customer_details: { address: { city: 'Springfield', state: 'IL', postal_code: '62704', country: 'US', }, address_source: 'billing', }, ship_from_details: { address: { city: 'Naperville', state: 'IL', postal_code: '60540', country: 'US', }, }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), TaxBehavior: stripe.String("exclusive"), TaxCode: stripe.String("txcd_99999999"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ City: stripe.String("Springfield"), State: stripe.String("IL"), PostalCode: stripe.String("62704"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), }, ShipFromDetails: &stripe.TaxCalculationShipFromDetailsParams{ Address: &stripe.AddressParams{ City: stripe.String("Naperville"), State: stripe.String("IL"), PostalCode: stripe.String("60540"), Country: stripe.String("US"), }, }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), TaxBehavior: stripe.String("exclusive"), TaxCode: stripe.String("txcd_99999999"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ City: stripe.String("Springfield"), State: stripe.String("IL"), PostalCode: stripe.String("62704"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceBilling), }, ShipFromDetails: &stripe.TaxCalculationCreateShipFromDetailsParams{ Address: &stripe.AddressParams{ City: stripe.String("Naperville"), State: stripe.String("IL"), PostalCode: stripe.String("60540"), Country: stripe.String("US"), }, }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1", TaxBehavior = "exclusive", TaxCode = "txcd_99999999", }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { City = "Springfield", State = "IL", PostalCode = "62704", Country = "US", }, AddressSource = "billing", }, ShipFromDetails = new Stripe.Tax.CalculationShipFromDetailsOptions { Address = new AddressOptions { City = "Naperville", State = "IL", PostalCode = "60540", Country = "US", }, }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1", TaxBehavior = "exclusive", TaxCode = "txcd_99999999", }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { City = "Springfield", State = "IL", PostalCode = "62704", Country = "US", }, AddressSource = "billing", }, ShipFromDetails = new Stripe.Tax.CalculationShipFromDetailsOptions { Address = new AddressOptions { City = "Naperville", State = "IL", PostalCode = "60540", Country = "US", }, }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` The response returns tax calculated based on the shipping origin of the order (Naperville, IL) instead of the destination (Springfield, IL) or the seller’s business origin: ```json { ... "amount_total": 1078, ... "tax_amount_exclusive": 78, ... "tax_breakdown": [ { "amount": 78, "inclusive": true,"tax_rate_details": { "country": "US", "percentage_decimal": "7.75", "state": "IL", "tax_type": "sales_tax" }, "taxability_reason": "standard_rated", "taxable_amount": 1000 } ], ... } ``` To learn more about how we calculate taxes in these scenarios, see the [Stripe Tax documentation](https://docs.stripe.com/tax/calculating.md). ## Optional: Calculate the retail delivery fee [Server-side] Stripe Tax supports calculating the retail delivery fee in Minnesota and Colorado. After you add a tax registration of the type `state_retail_delivery_fee` in the supported states, the retail delivery fee gets calculated on tax calculations. ```curl curl https://api.stripe.com/v1/tax/registrations \ -u "<>:" \ -d country=US \ -d "country_options[us][state]"=CO \ -d "country_options[us][type]"=state_retail_delivery_fee \ -d active_from=now ``` ```cli stripe tax registrations create \ --country=US \ -d "country_options[us][state]"=CO \ -d "country_options[us][type]"=state_retail_delivery_fee \ --active-from=now ``` ```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 = '<>' registration = Stripe::Tax::Registration.create({ country: 'US', country_options: { us: { state: 'CO', type: 'state_retail_delivery_fee', }, }, active_from: 'now', }) ``` ```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("<>") registration = client.v1.tax.registrations.create({ country: 'US', country_options: { us: { state: 'CO', type: 'state_retail_delivery_fee', }, }, active_from: 'now', }) ``` ```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 = "<>" registration = stripe.tax.Registration.create( country="US", country_options={"us": {"state": "CO", "type": "state_retail_delivery_fee"}}, active_from="now", ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. registration = client.v1.tax.registrations.create({ "country": "US", "country_options": {"us": {"state": "CO", "type": "state_retail_delivery_fee"}}, "active_from": "now", }) ``` ```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('<>'); $registration = $stripe->tax->registrations->create([ 'country' => 'US', 'country_options' => [ 'us' => [ 'state' => 'CO', 'type' => 'state_retail_delivery_fee', ], ], 'active_from' => 'now', ]); ``` ```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 = "<>"; RegistrationCreateParams params = RegistrationCreateParams.builder() .setCountry("US") .setCountryOptions( RegistrationCreateParams.CountryOptions.builder() .setUs( RegistrationCreateParams.CountryOptions.Us.builder() .setState("CO") .setType( RegistrationCreateParams.CountryOptions.Us.Type.STATE_RETAIL_DELIVERY_FEE ) .build() ) .build() ) .setActiveFrom(RegistrationCreateParams.ActiveFrom.NOW) .build(); Registration registration = Registration.create(params); ``` ```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("<>"); RegistrationCreateParams params = RegistrationCreateParams.builder() .setCountry("US") .setCountryOptions( RegistrationCreateParams.CountryOptions.builder() .setUs( RegistrationCreateParams.CountryOptions.Us.builder() .setState("CO") .setType( RegistrationCreateParams.CountryOptions.Us.Type.STATE_RETAIL_DELIVERY_FEE ) .build() ) .build() ) .setActiveFrom(RegistrationCreateParams.ActiveFrom.NOW) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Registration registration = client.v1().tax().registrations().create(params); ``` ```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')('<>'); const registration = await stripe.tax.registrations.create({ country: 'US', country_options: { us: { state: 'CO', type: 'state_retail_delivery_fee', }, }, active_from: 'now', }); ``` ```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 = "<>" params := &stripe.TaxRegistrationParams{ Country: stripe.String("US"), CountryOptions: &stripe.TaxRegistrationCountryOptionsParams{ US: &stripe.TaxRegistrationCountryOptionsUSParams{ State: stripe.String("CO"), Type: stripe.String(stripe.TaxRegistrationCountryOptionsUSTypeStateRetailDeliveryFee), }, }, ActiveFromNow: stripe.Bool(true), } result, err := registration.New(params) ``` ```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("<>") params := &stripe.TaxRegistrationCreateParams{ Country: stripe.String("US"), CountryOptions: &stripe.TaxRegistrationCreateCountryOptionsParams{ US: &stripe.TaxRegistrationCreateCountryOptionsUSParams{ State: stripe.String("CO"), Type: stripe.String(stripe.TaxRegistrationCountryOptionsUSTypeStateRetailDeliveryFee), }, }, ActiveFromNow: stripe.Bool(true), } result, err := sc.V1TaxRegistrations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.RegistrationCreateOptions { Country = "US", CountryOptions = new Stripe.Tax.RegistrationCountryOptionsOptions { Us = new Stripe.Tax.RegistrationCountryOptionsUsOptions { State = "CO", Type = "state_retail_delivery_fee", }, }, ActiveFrom = Stripe.Tax.RegistrationActiveFrom.Now, }; var service = new Stripe.Tax.RegistrationService(); Stripe.Tax.Registration registration = service.Create(options); ``` ```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 Stripe.Tax.RegistrationCreateOptions { Country = "US", CountryOptions = new Stripe.Tax.RegistrationCountryOptionsOptions { Us = new Stripe.Tax.RegistrationCountryOptionsUsOptions { State = "CO", Type = "state_retail_delivery_fee", }, }, ActiveFrom = Stripe.Tax.RegistrationActiveFrom.Now, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Registrations; Stripe.Tax.Registration registration = service.Create(options); ``` To calculate, call the tax calculations API using a physical item product tax code, such as `txcd_30011000`, which represents “Clothing & Footwear.” You can find the physical item tax codes in our [Product tax codes documentation](https://docs.stripe.com/tax/tax-codes.md?type=physical). Not all physical items trigger the retail delivery fee to be calculated. Refer to the states documentation on when the tax applies: - [Retail Delivery Fee—Colorado](https://docs.stripe.com/tax/supported-countries/united-states/colorado.md#other-taxes) - [Retail Delivery Fee—Minnesota](https://docs.stripe.com/tax/supported-countries/united-states/minnesota.md#other-taxes) ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_behavior]"=exclusive \ -d "line_items[0][tax_code]"=txcd_30011000 \ -d "shipping_cost[amount]"=400 \ -d "customer_details[address][line1]"="1437 Bannock St Room 451" \ -d "customer_details[address][city]"=Springfield \ -d "customer_details[address][state]"=CO \ -d "customer_details[address][postal_code]"=80202 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_behavior]"=exclusive \ -d "line_items[0][tax_code]"=txcd_30011000 \ -d "shipping_cost[amount]"=400 \ -d "customer_details[address][line1]"="1437 Bannock St Room 451" \ -d "customer_details[address][city]"=Springfield \ -d "customer_details[address][state]"=CO \ -d "customer_details[address][postal_code]"=80202 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_behavior: 'exclusive', tax_code: 'txcd_30011000', }, ], shipping_cost: {amount: 400}, customer_details: { address: { line1: '1437 Bannock St Room 451', city: 'Springfield', state: 'CO', postal_code: '80202', country: 'US', }, address_source: 'shipping', }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_behavior: 'exclusive', tax_code: 'txcd_30011000', }, ], shipping_cost: {amount: 400}, customer_details: { address: { line1: '1437 Bannock St Room 451', city: 'Springfield', state: 'CO', postal_code: '80202', country: 'US', }, address_source: 'shipping', }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[ { "amount": 1000, "reference": "L1", "tax_behavior": "exclusive", "tax_code": "txcd_30011000", }, ], shipping_cost={"amount": 400}, customer_details={ "address": { "line1": "1437 Bannock St Room 451", "city": "Springfield", "state": "CO", "postal_code": "80202", "country": "US", }, "address_source": "shipping", }, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [ { "amount": 1000, "reference": "L1", "tax_behavior": "exclusive", "tax_code": "txcd_30011000", }, ], "shipping_cost": {"amount": 400}, "customer_details": { "address": { "line1": "1437 Bannock St Room 451", "city": "Springfield", "state": "CO", "postal_code": "80202", "country": "US", }, "address_source": "shipping", }, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', 'tax_behavior' => 'exclusive', 'tax_code' => 'txcd_30011000', ], ], 'shipping_cost' => ['amount' => 400], 'customer_details' => [ 'address' => [ 'line1' => '1437 Bannock St Room 451', 'city' => 'Springfield', 'state' => 'CO', 'postal_code' => '80202', 'country' => 'US', ], 'address_source' => 'shipping', ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .setTaxBehavior(CalculationCreateParams.LineItem.TaxBehavior.EXCLUSIVE) .setTaxCode("txcd_30011000") .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder().setAmount(400L).build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("1437 Bannock St Room 451") .setCity("Springfield") .setState("CO") .setPostalCode("80202") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .setTaxBehavior(CalculationCreateParams.LineItem.TaxBehavior.EXCLUSIVE) .setTaxCode("txcd_30011000") .build() ) .setShippingCost( CalculationCreateParams.ShippingCost.builder().setAmount(400L).build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("1437 Bannock St Room 451") .setCity("Springfield") .setState("CO") .setPostalCode("80202") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_behavior: 'exclusive', tax_code: 'txcd_30011000', }, ], shipping_cost: { amount: 400, }, customer_details: { address: { line1: '1437 Bannock St Room 451', city: 'Springfield', state: 'CO', postal_code: '80202', country: 'US', }, address_source: 'shipping', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), TaxBehavior: stripe.String("exclusive"), TaxCode: stripe.String("txcd_30011000"), }, }, ShippingCost: &stripe.TaxCalculationShippingCostParams{Amount: stripe.Int64(400)}, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("1437 Bannock St Room 451"), City: stripe.String("Springfield"), State: stripe.String("CO"), PostalCode: stripe.String("80202"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), TaxBehavior: stripe.String("exclusive"), TaxCode: stripe.String("txcd_30011000"), }, }, ShippingCost: &stripe.TaxCalculationCreateShippingCostParams{Amount: stripe.Int64(400)}, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("1437 Bannock St Room 451"), City: stripe.String("Springfield"), State: stripe.String("CO"), PostalCode: stripe.String("80202"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1", TaxBehavior = "exclusive", TaxCode = "txcd_30011000", }, }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { Amount = 400 }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "1437 Bannock St Room 451", City = "Springfield", State = "CO", PostalCode = "80202", Country = "US", }, AddressSource = "shipping", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1", TaxBehavior = "exclusive", TaxCode = "txcd_30011000", }, }, ShippingCost = new Stripe.Tax.CalculationShippingCostOptions { Amount = 400 }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "1437 Bannock St Room 451", City = "Springfield", State = "CO", PostalCode = "80202", Country = "US", }, AddressSource = "shipping", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` The response returns tax calculated with the retail delivery fee (Colorado). It’s an additional entry in the `tax_breakdown` object, with`tax_breakdown.tax_rate_details.rate_type` set to `flat_amount`: ```json { ... "amount_total": 2165, ... "tax_amount_exclusive": 165, ... "tax_breakdown": [ { "amount": 88, "inclusive": false, "tax_rate_details": { "percentage_decimal": "8.81", "rate_type": "percentage", "tax_type": "sales_tax", ... }, "taxability_reason": "standard_rated", "taxable_amount": 1000 }, ... { "amount": 29, "inclusive": false,"tax_rate_details": { "flat_amount": { "amount": 29, "currency": "usd" }, "percentage_decimal": "0.0", "rate_type": "flat_amount", "tax_type": "retail_delivery_fee", ... }, "taxability_reason": "standard_rated", "taxable_amount": 1000 } ], ... } ``` ## Optional: Detailed line item tax breakdowns [Server-side] The top-level [tax_breakdown](https://docs.stripe.com/api/tax/calculations/object.md#tax_calculation_object-tax_breakdown) is always returned and provides a simple breakdown suitable for displaying a list of taxes at checkout or on a receipt. You can use the [taxability_reason](https://docs.stripe.com/api/tax/calculations/object.md#tax_calculation_object-line_items-data-tax_breakdown-taxability_reason) to understand why tax isn’t being applied while building your integration. For example, `not_collecting` means that you’re not collecting tax in the country or state where tax would be due. Adding [tax registrations](https://docs.stripe.com/tax/set-up.md#add-registrations) to your account settings tells Stripe where you’re collecting tax. If you have already added registration for Washington, the taxability reason displayed in your result is `standard_rated`, which indicates that the product is taxed at the standard rate. Expand the line item [tax_breakdown](https://docs.stripe.com/api/tax/calculations/object.md#tax_calculation_object-line_items-data-tax_breakdown) attribute to get a detailed breakdown, including local taxes and attributes explaining the reason for each tax. - The `tax_type` field from [tax_rate_details](https://docs.stripe.com/api/tax/calculations/object.md#tax_calculation_object-line_items-data-tax_breakdown-tax_rate_details) is a high-level tax type indication that might not always match the type returned in reports and transaction exports. For example, it doesn’t distinguish between US sales tax and US use tax. - Use the `display_name` field from [tax_rate_details](https://docs.stripe.com/api/tax/calculations/object.md#tax_calculation_object-line_items-data-tax_breakdown-tax_rate_details) in your Checkout flow to show all of the taxes. The taxes are localized based on customer location and product tax information. For example, if VAT is applied for Germany because the customer is in Germany and the product is taxed at the destination, such as [txcd_10103001: Software as a service (SaaS) for business use](https://docs.stripe.com/tax/tax-codes.md?tax_code=txcd_10103001), we show `Umsatzsteuer (USt)`, which is the German representation for VAT. If VAT is applied for France because the head office address is set to France and the product is taxed at the origin, such as [txcd_20030000: General - Services](https://docs.stripe.com/tax/tax-codes.md?tax_code=txcd_20030000), we show `Taxe sur la valeur ajoutée (TVA)`, which is the French representation of VAT. ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][line1]"="920 5th Ave" \ -d "customer_details[address][city]"=Seattle \ -d "customer_details[address][state]"=WA \ -d "customer_details[address][postal_code]"=98104 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping \ -d "expand[0]"="line_items.data.tax_breakdown" ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "customer_details[address][line1]"="920 5th Ave" \ -d "customer_details[address][city]"=Seattle \ -d "customer_details[address][state]"=WA \ -d "customer_details[address][postal_code]"=98104 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping \ -d "expand[0]"="line_items.data.tax_breakdown" ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, expand: ['line_items.data.tax_breakdown'], }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, expand: ['line_items.data.tax_breakdown'], }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[{"amount": 1000, "reference": "L1"}], customer_details={ "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "shipping", }, expand=["line_items.data.tax_breakdown"], ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [{"amount": 1000, "reference": "L1"}], "customer_details": { "address": { "line1": "920 5th Ave", "city": "Seattle", "state": "WA", "postal_code": "98104", "country": "US", }, "address_source": "shipping", }, "expand": ["line_items.data.tax_breakdown"], }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', ], ], 'customer_details' => [ 'address' => [ 'line1' => '920 5th Ave', 'city' => 'Seattle', 'state' => 'WA', 'postal_code' => '98104', 'country' => 'US', ], 'address_source' => 'shipping', ], 'expand' => ['line_items.data.tax_breakdown'], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .addExpand("line_items.data.tax_breakdown") .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("920 5th Ave") .setCity("Seattle") .setState("WA") .setPostalCode("98104") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .addExpand("line_items.data.tax_breakdown") .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', }, ], customer_details: { address: { line1: '920 5th Ave', city: 'Seattle', state: 'WA', postal_code: '98104', country: 'US', }, address_source: 'shipping', }, expand: ['line_items.data.tax_breakdown'], }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } params.AddExpand("line_items.data.tax_breakdown") result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("920 5th Ave"), City: stripe.String("Seattle"), State: stripe.String("WA"), PostalCode: stripe.String("98104"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } params.AddExpand("line_items.data.tax_breakdown") result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "shipping", }, Expand = new List { "line_items.data.tax_breakdown" }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1" }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "920 5th Ave", City = "Seattle", State = "WA", PostalCode = "98104", Country = "US", }, AddressSource = "shipping", }, Expand = new List { "line_items.data.tax_breakdown" }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` ```json { ... "tax_breakdown": [ { "amount": 103, "inclusive": false, "tax_rate_details": { "country": "US", "percentage_decimal": "10.25", "state": "WA", "tax_type": "sales_tax" },"taxability_reason": "standard_rated", "taxable_amount": 1000 } ], "line_items": { "object": "list", "data": [ { "id": "tax_li_O84jA8hvV7ZyAa", "object": "tax.calculation_line_item", "amount": 1000, "amount_tax": 103, "product": null, "quantity": 1, "reference": "L1", "tax_behavior": "exclusive", "tax_breakdown": [ { "amount": 65, "jurisdiction": { "country": "US", "display_name": "Washington", "level": "state", "state": "WA" }, "sourcing": "destination", "tax_rate_details": { "display_name": "Retail Sales and Use Tax", "percentage_decimal": "6.5", "tax_type": "sales_tax" },"taxability_reason": "standard_rated", "taxable_amount": 1000 }, { "amount": 0, "jurisdiction": { "country": "US", "display_name": "KING", "level": "county", "state": "WA" }, "sourcing": "destination", "tax_rate_details": null,"taxability_reason": "not_subject_to_tax", "taxable_amount": 0 }, { "amount": 22, "jurisdiction": { "country": "US", "display_name": "SEATTLE", "level": "city", "state": "WA" }, "sourcing": "destination", "tax_rate_details": { "display_name": "Local Sales and Use Tax", "percentage_decimal": "2.2", "tax_type": "sales_tax" },"taxability_reason": "standard_rated", "taxable_amount": 1000 }, { "amount": 14, "jurisdiction": { "country": "US", "display_name": "REGIONAL TRANSIT AUTHORITY", "level": "district", "state": "WA" }, "sourcing": "destination", "tax_rate_details": { "display_name": "Local Sales and Use Tax", "percentage_decimal": "1.4", "tax_type": "sales_tax" },"taxability_reason": "standard_rated", "taxable_amount": 1000 }, { "amount": 2, "jurisdiction": { "country": "US", "display_name": "SEATTLE TRANSPORTATION BENEFIT DISTRICT", "level": "district", "state": "WA" }, "sourcing": "destination", "tax_rate_details": { "display_name": "Local Sales and Use Tax", "percentage_decimal": "0.15", "tax_type": "sales_tax" },"taxability_reason": "standard_rated", "taxable_amount": 1000 } ], "tax_code": "txcd_10000000" } ], "has_more": false, "total_count": 1, "url": "/v1/tax/calculations/taxcalc_1NLoZvBUZ691iUZ4z4cTW6tQ/line_items" }, ... } ``` ## Optional: Troubleshoot common errors [Server-side] ### Resolve invalid tax code errors If you get the error `Invalid tax code`, see [Product tax codes](https://docs.stripe.com/tax/tax-codes.md) for the list of available tax codes. Then follow these steps to resolve the issue: 1. **Check the tax code**: Ensure that you’re using a valid tax code from the [list of available tax codes](https://docs.stripe.com/tax/tax-codes.md). Common mistakes include: - Using an empty string or `null` as the tax code - Misspelling the tax code - Using a non-existent tax code 1. **Update your code**: Make sure you pass a valid tax code when creating a `TaxCalculation`. For example: ```curl curl https://api.stripe.com/v1/tax/calculations \ -u "<>:" \ -d currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_code]"=txcd_10000000 \ -d "customer_details[address][line1]"="354 Oyster Point Blvd" \ -d "customer_details[address][city]"="South San Francisco" \ -d "customer_details[address][state]"=CA \ -d "customer_details[address][postal_code]"=94080 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping ``` ```cli stripe tax calculations create \ --currency=usd \ -d "line_items[0][amount]"=1000 \ -d "line_items[0][reference]"=L1 \ -d "line_items[0][tax_code]"=txcd_10000000 \ -d "customer_details[address][line1]"="354 Oyster Point Blvd" \ -d "customer_details[address][city]"="South San Francisco" \ -d "customer_details[address][state]"=CA \ -d "customer_details[address][postal_code]"=94080 \ -d "customer_details[address][country]"=US \ -d "customer_details[address_source]"=shipping ``` ```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 = '<>' calculation = Stripe::Tax::Calculation.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_code: 'txcd_10000000', }, ], customer_details: { address: { line1: '354 Oyster Point Blvd', city: 'South San Francisco', state: 'CA', postal_code: '94080', country: 'US', }, address_source: 'shipping', }, }) ``` ```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("<>") calculation = client.v1.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_code: 'txcd_10000000', }, ], customer_details: { address: { line1: '354 Oyster Point Blvd', city: 'South San Francisco', state: 'CA', postal_code: '94080', country: 'US', }, address_source: 'shipping', }, }) ``` ```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 = "<>" calculation = stripe.tax.Calculation.create( currency="usd", line_items=[{"amount": 1000, "reference": "L1", "tax_code": "txcd_10000000"}], customer_details={ "address": { "line1": "354 Oyster Point Blvd", "city": "South San Francisco", "state": "CA", "postal_code": "94080", "country": "US", }, "address_source": "shipping", }, ) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. calculation = client.v1.tax.calculations.create({ "currency": "usd", "line_items": [{"amount": 1000, "reference": "L1", "tax_code": "txcd_10000000"}], "customer_details": { "address": { "line1": "354 Oyster Point Blvd", "city": "South San Francisco", "state": "CA", "postal_code": "94080", "country": "US", }, "address_source": "shipping", }, }) ``` ```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('<>'); $calculation = $stripe->tax->calculations->create([ 'currency' => 'usd', 'line_items' => [ [ 'amount' => 1000, 'reference' => 'L1', 'tax_code' => 'txcd_10000000', ], ], 'customer_details' => [ 'address' => [ 'line1' => '354 Oyster Point Blvd', 'city' => 'South San Francisco', 'state' => 'CA', 'postal_code' => '94080', 'country' => 'US', ], 'address_source' => 'shipping', ], ]); ``` ```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 = "<>"; CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .setTaxCode("txcd_10000000") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("354 Oyster Point Blvd") .setCity("South San Francisco") .setState("CA") .setPostalCode("94080") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .build(); Calculation calculation = Calculation.create(params); ``` ```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("<>"); CalculationCreateParams params = CalculationCreateParams.builder() .setCurrency("usd") .addLineItem( CalculationCreateParams.LineItem.builder() .setAmount(1000L) .setReference("L1") .setTaxCode("txcd_10000000") .build() ) .setCustomerDetails( CalculationCreateParams.CustomerDetails.builder() .setAddress( CalculationCreateParams.CustomerDetails.Address.builder() .setLine1("354 Oyster Point Blvd") .setCity("South San Francisco") .setState("CA") .setPostalCode("94080") .setCountry("US") .build() ) .setAddressSource(CalculationCreateParams.CustomerDetails.AddressSource.SHIPPING) .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Calculation calculation = client.v1().tax().calculations().create(params); ``` ```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')('<>'); const calculation = await stripe.tax.calculations.create({ currency: 'usd', line_items: [ { amount: 1000, reference: 'L1', tax_code: 'txcd_10000000', }, ], customer_details: { address: { line1: '354 Oyster Point Blvd', city: 'South San Francisco', state: 'CA', postal_code: '94080', country: 'US', }, address_source: 'shipping', }, }); ``` ```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 = "<>" params := &stripe.TaxCalculationParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationLineItemParams{ &stripe.TaxCalculationLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), TaxCode: stripe.String("txcd_10000000"), }, }, CustomerDetails: &stripe.TaxCalculationCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("354 Oyster Point Blvd"), City: stripe.String("South San Francisco"), State: stripe.String("CA"), PostalCode: stripe.String("94080"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } result, err := calculation.New(params) ``` ```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("<>") params := &stripe.TaxCalculationCreateParams{ Currency: stripe.String(stripe.CurrencyUSD), LineItems: []*stripe.TaxCalculationCreateLineItemParams{ &stripe.TaxCalculationCreateLineItemParams{ Amount: stripe.Int64(1000), Reference: stripe.String("L1"), TaxCode: stripe.String("txcd_10000000"), }, }, CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{ Address: &stripe.AddressParams{ Line1: stripe.String("354 Oyster Point Blvd"), City: stripe.String("South San Francisco"), State: stripe.String("CA"), PostalCode: stripe.String("94080"), Country: stripe.String("US"), }, AddressSource: stripe.String(stripe.TaxCalculationCustomerDetailsAddressSourceShipping), }, } result, err := sc.V1TaxCalculations.Create(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1", TaxCode = "txcd_10000000", }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "354 Oyster Point Blvd", City = "South San Francisco", State = "CA", PostalCode = "94080", Country = "US", }, AddressSource = "shipping", }, }; var service = new Stripe.Tax.CalculationService(); Stripe.Tax.Calculation calculation = service.Create(options); ``` ```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 Stripe.Tax.CalculationCreateOptions { Currency = "usd", LineItems = new List { new Stripe.Tax.CalculationLineItemOptions { Amount = 1000, Reference = "L1", TaxCode = "txcd_10000000", }, }, CustomerDetails = new Stripe.Tax.CalculationCustomerDetailsOptions { Address = new AddressOptions { Line1 = "354 Oyster Point Blvd", City = "South San Francisco", State = "CA", PostalCode = "94080", Country = "US", }, AddressSource = "shipping", }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Calculations; Stripe.Tax.Calculation calculation = service.Create(options); ``` 1. **Use the default tax code**: Stripe Tax uses a default tax code for calculations when a specific tax code isn’t provided. You can view and update this default in your Tax Settings. To update the default tax code using the API: ```curl curl https://api.stripe.com/v1/tax/settings \ -u "<>:" \ -d "defaults[tax_code]"=txcd_10000000 ``` ```cli stripe tax settings update \ -d "defaults[tax_code]"=txcd_10000000 ``` ```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 = '<>' settings = Stripe::Tax::Settings.update({defaults: {tax_code: 'txcd_10000000'}}) ``` ```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("<>") settings = client.v1.tax.settings.update({defaults: {tax_code: 'txcd_10000000'}}) ``` ```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 = "<>" settings = stripe.tax.Settings.modify(defaults={"tax_code": "txcd_10000000"}) ``` ```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("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. settings = client.v1.tax.settings.update({"defaults": {"tax_code": "txcd_10000000"}}) ``` ```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('<>'); $settings = $stripe->tax->settings->update([ 'defaults' => ['tax_code' => 'txcd_10000000'], ]); ``` ```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 = "<>"; SettingsUpdateParams params = SettingsUpdateParams.builder() .setDefaults( SettingsUpdateParams.Defaults.builder().setTaxCode("txcd_10000000").build() ) .build(); Settings settings = Settings.update(params); ``` ```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("<>"); SettingsUpdateParams params = SettingsUpdateParams.builder() .setDefaults( SettingsUpdateParams.Defaults.builder().setTaxCode("txcd_10000000").build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Settings settings = client.v1().tax().settings().update(params); ``` ```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')('<>'); const settings = await stripe.tax.settings.update({ defaults: { tax_code: 'txcd_10000000', }, }); ``` ```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 = "<>" params := &stripe.TaxSettingsParams{ Defaults: &stripe.TaxSettingsDefaultsParams{TaxCode: stripe.String("txcd_10000000")}, } result, err := settings.Update(params) ``` ```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("<>") params := &stripe.TaxSettingsUpdateParams{ Defaults: &stripe.TaxSettingsUpdateDefaultsParams{ TaxCode: stripe.String("txcd_10000000"), }, } result, err := sc.V1TaxSettings.Update(context.TODO(), params) ``` ```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 = "<>"; var options = new Stripe.Tax.SettingsUpdateOptions { Defaults = new Stripe.Tax.SettingsDefaultsOptions { TaxCode = "txcd_10000000" }, }; var service = new Stripe.Tax.SettingsService(); Stripe.Tax.Settings settings = service.Update(options); ``` ```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 Stripe.Tax.SettingsUpdateOptions { Defaults = new Stripe.Tax.SettingsDefaultsOptions { TaxCode = "txcd_10000000" }, }; var client = new StripeClient("<>"); var service = client.V1.Tax.Settings; Stripe.Tax.Settings settings = service.Update(options); ``` This default tax code applies when no specific tax code is provided for a product or in a tax calculation request. 1. **Review your product catalog**: If you’re using tax codes associated with products in your Stripe product catalog, ensure the tax codes are correctly assigned to your products. 1. **Check for data inconsistencies**: Ensure the tax code is correctly passed from your database or front end to your server-side code that makes the API call to Stripe. For more accurate tax calculations, use the most specific tax code that applies to your product or service. If you’re unsure which tax code to use, consult the [tax codes documentation](https://docs.stripe.com/tax/tax-codes.md). If you continue to experience issues, review the [Tax Settings API documentation](https://docs.stripe.com/api/tax/settings.md). ## See also - [Use Stripe Tax with Connect](https://docs.stripe.com/tax/connect.md)