Collect tax with Elements
Learn how to calculate and display taxes using Checkout with elements mode.
Stripe Tax automatically calculates the taxes on purchases when you use Checkout with elements mode (ui_). This integration gives you full control over the payment form layout while Stripe handles tax calculation.
Interested in automatic tax set up for Checkout?
Request to join the preview for no code automatic tax calculation. Available only for one-time payments processed through Stripe Checkout.
If you haven’t set up Checkout with elements mode, complete the Checkout quickstart first.
Calculate and render tax amount
Add tax registrationsDashboardServer-side
Stripe Tax only collects tax in jurisdictions where you have an active registration. Create a registration for each country or state where you’re required to collect tax. The country_options structure varies by country.
curl https://api.stripe.com/v1/tax/registrations \ -u "sk_test_Hrs6SAopgFPF0bZXSN3f6ELN:" \ -d country={{COUNTRY_CODE}} \ -d "country_options[us][state]={{STATE}}" \ -d "country_options[us][type]=state_sales_tax" \ -d active_from=now
Alternatively, add registrations in the Dashboard. Go to the Tax > Registrations. You only need to add a registration once per jurisdiction.
Configure your Checkout Session to collect tax
To start collecting tax:
- Pass automatic_tax[enabled]=true when creating a Checkout Session.
- Specify a tax_code for each line item, or set a preset tax code in the Dashboard.
- Specify a tax_behavior for each line item, or set a default tax behavior in the Dashboard.
This code enables automatic tax calculation using Stripe Tax, a tax code, and a tax behavior. Stripe Tax then uses the tax code and tax behavior to automatically calculate taxes.
curl https://api.stripe.com/v1/checkout/sessions \ -u "sk_test_Hrs6SAopgFPF0bZXSN3f6ELN:" \ -d "line_items[0][price_data][currency]=usd" \ -d "line_items[0][price_data][product_data][name]=T-shirt" \ -d "line_items[0][price_data][product_data][tax_code]=txcd_99999999" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][price_data][tax_behavior]=exclusive" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d ui_mode=elements \ -d return_url={{RETURN_URL}} \ -d "automatic_tax[enabled]=true"
Tax codes
The tax codes associate products with tax rates. Choose the appropriate tax code for your product from the list of tax codes. If a product doesn’t match with any of the tax codes, you can use one of the General codes.
Tax behavior
The tax behavior determines how to present tax to the customer:
- Exclusive: The product price doesn’t include tax, which is added as a separate amount.
- Inclusive: The product price includes any tax amount.
Render the tax amount
Use the useCheckoutElements hook to display the tax amount in your payment form.
import React from 'react'; import {useCheckoutElements} from '@stripe/react-stripe-js'; const CheckoutForm = () => { const checkoutState = useCheckoutElements(); if (checkoutState.type === 'loading') { return ( <div>Loading...</div> ); } else if (checkoutState.type === 'error') { return ( <div>Error: {checkoutState.error.message}</div> ); } const {checkout} = checkoutState; return ( <div> <h2>Checkout Summary</h2> <pre> {JSON.stringify(checkout.lineItems, null, 2)} </pre> <h3>Totals</h3> <pre> Subtotal: {checkout.total.subtotal.amount} {/* Make sure you use the appropriate tax amount type (taxInclusive and/or taxExclusive) for your integration */} Tax: {checkout.total.taxExclusive.amount} Total: {checkout.total.total.amount} </pre> </div> ) };
Collect customer tax IDs
Set up tax ID collection to collect VAT and other business tax IDs during checkout. After enabling collection on your Checkout Session, render the Tax ID Element in your payment form.
Render the Tax ID ElementClient-sidePublic preview
Use Stripe’s Tax ID Element to collect tax IDs.
import {useMemo} from 'react'; import {loadStripe} from '@stripe/stripe-js'; import {CheckoutElementsProvider, TaxIdElement} from '@stripe/react-stripe-js/checkout'; const stripePromise = loadStripe('pk_test_A7jK4iCYHL045qgjjfzAfPxu', { betas: [ 'custom_checkout_tax_id_1', ], }); const App = () => { const fetchClientSecret = useMemo(() => { return fetch('/create-checkout-session', {method: 'POST'}) .then((res) => res.json()) .then((data) => data.clientSecret) }, []); return ( <CheckoutElementsProvider stripe={stripePromise} options={{ clientSecret: fetchClientSecret, }} > <TaxIdElement /> </CheckoutElementsProvider> ); };
Real-time tax ID validation Preview
In addition to the asynchronous validation described above, you can enable synchronous, real-time tax ID verification directly in the Tax ID Element. When you enable it, Stripe verifies tax IDs against government databases as your customer types and displays the result inline before they submit the payment. Stripe currently supports real-time verification for Australian Business Numbers (ABNs), European Value Added Tax (EU VAT), and United Kingdom Value Added Tax (GB VAT) numbers. If a government database is unavailable, Stripe falls back to synchronous format validation and performs full verification asynchronously. This feature is in public preview and requires the custom_ beta.
const taxIdElement = checkout.createTaxIdElement({ ... verification: { taxId: { mode: 'if_supported', }, }, });
When you enable verification, the change event includes the verification. field. Its value can be pending, verified, unverified, or unavailable. The element’s complete status reflects the verification result. See Create a Tax ID Element and Tax ID Element on Change for details.