# Collect tax on off-Stripe payments Use the Stripe Tax API to calculate and report tax on payments processed outside of Stripe. Use the Stripe Tax API to calculate and report tax on payments you process outside of Stripe. This works with any third-party payment processor or your in-house payment and invoicing systems. > #### Using Stripe for payments? > > If you process payments with Stripe, consider these integrations instead: > > - [Stripe Tax with PaymentIntents](https://docs.stripe.com/tax/payment-intent.md) for automatic tax transaction management - [Stripe Tax with Checkout](https://docs.stripe.com/tax/checkout.md), [Invoicing](https://docs.stripe.com/tax/invoicing.md) or [Subscriptions](https://docs.stripe.com/tax/subscriptions.md) for built-in tax support ## Add registrations Stripe Tax only calculates tax in jurisdictions where you’re registered to collect tax. You must [add your registrations](https://docs.stripe.com/tax/registering.md#add-a-registration) in the Dashboard. ## Optional: Collect customer address [Server-side] The tax you collect typically depends on your customer’s location. For the most accurate tax calculation, collect your customer’s full address. Before collecting an address, you can show your customer an estimate based on their [IP address](https://docs.stripe.com/tax/standalone-tax-api.md#ip-address). The address information that’s 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. - **Other countries**: 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/standalone-tax-api.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. You must [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" ``` #### 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" ``` #### 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" ``` #### 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" ``` #### 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" ``` #### Example - Ship-from address With this beta feature, taxes are levied based on the ship-from address, if you provide a ship-from address in certain states (such as Illinois) and the shipment contains physical goods. If the shipment contains both physical goods and services, taxes are applied to both based on the ship-from address. This example calculates tax based on where the order ships from in Naperville, IL, instead of the business location (outside Illinois) and the ship-to address in Springfield, 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 "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" ``` 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 as the 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. | ### Handle 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" } } ``` If you receive this error, prompt your customer to check the address they entered and fix any typos. ## 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 `order_123456789`, line item references `L1` and `L2` and a shipping cost, looks like this in the itemised Tax exports: | ID | line_item_id | type | currency | transaction_date | | --------------- | ------------ | -------- | -------- | ------------------- | | order_123456789 | L1 | external | usd | 2023-02-23 17:01:16 | | order_123456789 | L2 | external | usd | 2023-02-23 17:01:16 | | order_123456789 | shipping | external | usd | 2023-02-23 17:01:16 | When your customer pays, use the calculation ID to record the Tax collected. You can create the Tax Transaction after the Payment is successfully processed in your system—for example, in your order submission Endpoint or in response to a payment success Callback from your Processor. The example below creates a Transaction and uses a unique Order or Payment reference: ```curl curl https://api.stripe.com/v1/tax/transactions/create_from_calculation \ -u "<>:" \ -d calculation={{TAX_CALCULATION}} \ -d reference=order_12345 \ -d "expand[]=line_items" ``` Store the [tax transaction ID](https://docs.stripe.com/api/tax/transactions/object.md#tax_transaction_object-id) to record Refunds later. You can store the Transaction ID in your database alongside the Order it belongs to. ## 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, you must 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 `order_123456789`, then create the Reversal Transaction with reference `order_123456789-refund`. - Use a Refund ID from your system. For example, `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 that records 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=order_123456789-cancel \ -d "expand[]=line_items" ``` 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": "order_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, you need to [fully reverse](https://docs.stripe.com/tax/off-stripe.md#reversals-void-refund) any previous partial Reversals for the same Transaction to avoid duplicate Refunds. ### Partially refund a sale After issuing a refund 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=order_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 order_123456789 (customer was unhappy)" \ -d "expand[0]=line_items" ``` 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 order_123456789 (customer was unhappy)" }, "reference": "order_123456789-refund_1", "reversal": { "original_transaction": "tax_1MEFAAI6rIcR421eB1YOzACZ" }, "shipping_cost": null, "tax_date": 1670863654, "type": "reversal" } ``` For each line item reversed, you must 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/off-stripe.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 must calculate the amounts refunded. For example, for a sale transaction with `amount=5000` and `amount_tax=500`, after refunding half the line item, you create a partial reversal with line item `amount=-2500` and `amount_tax=-250`. #### Tax reports with partial refunds If you refund a tax amount such that the total tax is no longer proportional to the subtotal, your tax reporting can be unreliable. It won’t automatically adjust the taxable and non-taxable amounts, and won’t reflect the reason for the tax reversal (such as product exempt, customer exempt, or reverse charge). We recommend not refunding partial line item tax amounts. Instead, fully reverse the transaction and create a new one with appropriate inputs for an accurate tax calculation. ### 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=order_234567890-refund_1 \ -d flat_amount=-1650 \ -d "metadata[refund]={{REFUND_ID}}" \ --data-urlencode "metadata[refund_reason]=Refunded 16.50 USD of order_234567890 (customer was unhappy)" \ -d "expand[]=line_items" ``` 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 order_234567890 (customer was unhappy)" }, "reference": "order_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. For 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=order_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 order_234567890 (customer was unhappy)" \ -d "expand[0]=line_items" ``` 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=order_234567890-refund_2 \ -d flat_amount=-1650 \ -d "metadata[refund]={{REFUND_ID}}" \ --data-urlencode "metadata[refund_reason]=Refunded 16.50 USD of order_234567890 (customer was still unhappy)" \ -d "expand[]=line_items" ``` 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": "order_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 a partial refund by creating a [full reversal](https://docs.stripe.com/api/tax/transactions/create_reversal.md#tax_transaction_create_reversal-mode). You might need to do this when: - The payment refund fails 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 that represents 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=order_123456789-refund_1-cancel \ -d "metadata[refund_reason]=User called to cancel because they selected the wrong item" \ -d "expand[]=line_items" ``` 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": "order_123456789-refund_1-cancel", "reversal": { "original_transaction": "tax_1MEFACI6rIcR421eHrjXCSmD" }, "shipping_cost": null, "tax_date": 1670863654, "type": "reversal" } ``` ## Testing Use *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), which is identical in response structure to live mode, to confirm your integration works correctly before going live. > In testing environments, calculations aren’t guaranteed 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 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. > The Tax Transactions page only includes *transactions* and not *calculations*. If you expect to see a calculation and can’t find it on this page, verify that you successfully [created a tax transaction](https://docs.stripe.com/tax/off-stripe.md#tax-transaction) from the calculation. For advanced options like shipping costs, tax-inclusive pricing, IP address estimation, and more, see the [Standalone Tax API reference](https://docs.stripe.com/tax/standalone-tax-api.md). ## See also - [Standalone Tax API](https://docs.stripe.com/tax/standalone-tax-api.md) - [Stripe Tax API, simplified](https://docs.stripe.com/tax/payment-intent/simplified.md) - [Stripe Tax API, custom](https://docs.stripe.com/tax/payment-intent/custom.md) - [Test your tax integration](https://docs.stripe.com/tax/testing.md) - [Reporting and filing](https://docs.stripe.com/tax/reports.md)