# Collect customer tax IDs with Checkout Learn how to collect VAT and other customer tax IDs with Checkout. # Stripe-hosted page > This is a Stripe-hosted page for when payment-ui is stripe-hosted. View the original doc at https://docs.stripe.com/tax/checkout/tax-ids?payment-ui=stripe-hosted. Displaying a customer’s tax ID and legal business name on *invoices* is a common requirement that you can satisfy by enabling tax ID collection in Checkout. This guide assumes that you’ve already integrated Checkout. If you haven’t, see the [Accept a payment guide](https://docs.stripe.com/payments/accept-a-payment.md). ## Enable Tax ID collection With tax ID collection enabled, Checkout shows and hides the tax ID collection form depending on your customer’s location. If your customer is in a location supported by tax ID collection, Checkout shows a checkbox allowing the customer to indicate that they’re purchasing as a business. When a customer checks the box, Checkout displays fields for them to enter the tax ID and legal entity name for the business. If available, Checkout uses the customer’s shipping address to determine their location, otherwise Checkout uses the customer’s billing address. Customers can only enter one tax ID. ### New Customers To enable tax ID collection for new customers, set [tax_id_collection[enabled]](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-tax_id_collection-enabled) to `true` when creating a Checkout session. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { PriceData = new Stripe.Checkout.SessionLineItemPriceDataOptions { UnitAmount = 1000, ProductData = new Stripe.Checkout.SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, Currency = "eur", }, Quantity = 2, }, }, TaxIdCollection = new Stripe.Checkout.SessionTaxIdCollectionOptions { Enabled = true }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ UnitAmount: stripe.Int64(1000), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, Currency: stripe.String(string(stripe.CurrencyEUR)), }, Quantity: stripe.Int64(2), }, }, TaxIDCollection: &stripe.CheckoutSessionTaxIDCollectionParams{Enabled: stripe.Bool(true)}, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .addLineItem( SessionCreateParams.LineItem.builder() .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setUnitAmount(1000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build() ) .setCurrency("eur") .build() ) .setQuantity(2L) .build() ) .setTaxIdCollection(SessionCreateParams.TaxIdCollection.builder().setEnabled(true).build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ line_items: [ { price_data: { unit_amount: 1000, product_data: { name: 'T-shirt', }, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: { enabled: true, }, mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( line_items=[ { "price_data": {"unit_amount": 1000, "product_data": {"name": "T-shirt"}, "currency": "eur"}, "quantity": 2, }, ], tax_id_collection={"enabled": True}, mode="payment", success_url="https://example.com/success", cancel_url="https://example.com/cancel", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'line_items' => [ [ 'price_data' => [ 'unit_amount' => 1000, 'product_data' => ['name' => 'T-shirt'], 'currency' => 'eur', ], 'quantity' => 2, ], ], 'tax_id_collection' => ['enabled' => true], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ line_items: [ { price_data: { unit_amount: 1000, product_data: {name: 'T-shirt'}, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: {enabled: true}, mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }) ``` This example creates a Session in `payment` mode with tax ID collection enabled. For subscriptions, make the same changes with the [mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode) set to `subscription`. You can additionally configure Checkout to create a new [Customer](https://docs.stripe.com/api/customers/object.md) for you using [customer_creation](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_creation). If you do, Checkout saves any tax ID information collected during a Session to that new *Customer*. If not, the tax ID information will still be available at [customer_details.tax_ids](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-customer_details-tax_ids). ### Existing Customers If you pass an existing Customer when creating a Session, Checkout updates the Customer with any tax ID information collected during the Session. Checkout saves the collected business name onto the Customer’s [name](https://docs.stripe.com/api/customers/object.md#customer_object-name) property, and adds the collected tax ID to the Customer’s [customer.tax_ids](https://docs.stripe.com/api/customers/object.md#customer_object-tax_ids) array. Since the collection of a business name could result in the Customer’s existing [name](https://docs.stripe.com/api/customers/object.md#customer_object-name) being overridden, you must set [customer_update.name](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-name) to `auto` when creating the Session. Checkout only collects tax IDs on Customers that don’t already have an existing tax ID. If a Customer has one or more tax IDs saved, Checkout doesn’t display the tax ID collection form even if tax ID collection is enabled. When collecting tax IDs for existing customers you can either base their location on existing addresses on the customer or the addresses entered during checkout. By default, Checkout looks for existing addresses on the customer to assess their location: ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { Customer = "<>", LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { PriceData = new Stripe.Checkout.SessionLineItemPriceDataOptions { UnitAmount = 1000, ProductData = new Stripe.Checkout.SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, Currency = "eur", }, Quantity = 2, }, }, TaxIdCollection = new Stripe.Checkout.SessionTaxIdCollectionOptions { Enabled = true }, CustomerUpdate = new Stripe.Checkout.SessionCustomerUpdateOptions { Name = "auto" }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ Customer: stripe.String("<>"), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ UnitAmount: stripe.Int64(1000), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, Currency: stripe.String(string(stripe.CurrencyEUR)), }, Quantity: stripe.Int64(2), }, }, TaxIDCollection: &stripe.CheckoutSessionTaxIDCollectionParams{Enabled: stripe.Bool(true)}, CustomerUpdate: &stripe.CheckoutSessionCustomerUpdateParams{Name: stripe.String("auto")}, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .setCustomer("<>") .addLineItem( SessionCreateParams.LineItem.builder() .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setUnitAmount(1000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build() ) .setCurrency("eur") .build() ) .setQuantity(2L) .build() ) .setTaxIdCollection(SessionCreateParams.TaxIdCollection.builder().setEnabled(true).build()) .setCustomerUpdate( SessionCreateParams.CustomerUpdate.builder() .setName(SessionCreateParams.CustomerUpdate.Name.AUTO) .build() ) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ customer: '<>', line_items: [ { price_data: { unit_amount: 1000, product_data: { name: 'T-shirt', }, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: { enabled: true, }, customer_update: { name: 'auto', }, mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( customer="<>", line_items=[ { "price_data": {"unit_amount": 1000, "product_data": {"name": "T-shirt"}, "currency": "eur"}, "quantity": 2, }, ], tax_id_collection={"enabled": True}, customer_update={"name": "auto"}, mode="payment", success_url="https://example.com/success", cancel_url="https://example.com/cancel", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'customer' => '<>', 'line_items' => [ [ 'price_data' => [ 'unit_amount' => 1000, 'product_data' => ['name' => 'T-shirt'], 'currency' => 'eur', ], 'quantity' => 2, ], ], 'tax_id_collection' => ['enabled' => true], 'customer_update' => ['name' => 'auto'], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ customer: '<>', line_items: [ { price_data: { unit_amount: 1000, product_data: {name: 'T-shirt'}, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: {enabled: true}, customer_update: {name: 'auto'}, mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }) ``` If you don’t have the addresses of your existing customers saved, you can base their location on the billing or shipping address entered during Checkout. To specify that you want to use the billing address entered during Checkout to assess the customer’s location, you must set [customer_update.address](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-address) to `auto`. When setting [customer_update.address](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-address) to `auto`, Checkout replaces any previously saved addresses on the customer with the address entered during the session. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { Customer = "<>", LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { PriceData = new Stripe.Checkout.SessionLineItemPriceDataOptions { UnitAmount = 1000, ProductData = new Stripe.Checkout.SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, Currency = "eur", }, Quantity = 2, }, }, TaxIdCollection = new Stripe.Checkout.SessionTaxIdCollectionOptions { Enabled = true }, CustomerUpdate = new Stripe.Checkout.SessionCustomerUpdateOptions { Name = "auto", Address = "auto", }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ Customer: stripe.String("<>"), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ UnitAmount: stripe.Int64(1000), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, Currency: stripe.String(string(stripe.CurrencyEUR)), }, Quantity: stripe.Int64(2), }, }, TaxIDCollection: &stripe.CheckoutSessionTaxIDCollectionParams{Enabled: stripe.Bool(true)}, CustomerUpdate: &stripe.CheckoutSessionCustomerUpdateParams{ Name: stripe.String("auto"), Address: stripe.String("auto"), }, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .setCustomer("<>") .addLineItem( SessionCreateParams.LineItem.builder() .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setUnitAmount(1000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build() ) .setCurrency("eur") .build() ) .setQuantity(2L) .build() ) .setTaxIdCollection(SessionCreateParams.TaxIdCollection.builder().setEnabled(true).build()) .setCustomerUpdate( SessionCreateParams.CustomerUpdate.builder() .setName(SessionCreateParams.CustomerUpdate.Name.AUTO) .setAddress(SessionCreateParams.CustomerUpdate.Address.AUTO) .build() ) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ customer: '<>', line_items: [ { price_data: { unit_amount: 1000, product_data: { name: 'T-shirt', }, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: { enabled: true, }, customer_update: { name: 'auto', address: 'auto', }, mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( customer="<>", line_items=[ { "price_data": {"unit_amount": 1000, "product_data": {"name": "T-shirt"}, "currency": "eur"}, "quantity": 2, }, ], tax_id_collection={"enabled": True}, customer_update={"name": "auto", "address": "auto"}, mode="payment", success_url="https://example.com/success", cancel_url="https://example.com/cancel", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'customer' => '<>', 'line_items' => [ [ 'price_data' => [ 'unit_amount' => 1000, 'product_data' => ['name' => 'T-shirt'], 'currency' => 'eur', ], 'quantity' => 2, ], ], 'tax_id_collection' => ['enabled' => true], 'customer_update' => [ 'name' => 'auto', 'address' => 'auto', ], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ customer: '<>', line_items: [ { price_data: { unit_amount: 1000, product_data: {name: 'T-shirt'}, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: {enabled: true}, customer_update: { name: 'auto', address: 'auto', }, mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }) ``` If you’re collecting shipping addresses for existing customers, you must base their location on the shipping address entered during checkout. To do so, set [customer_update.shipping](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-shipping) to `auto`. When setting [customer_update.shipping](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-shipping) to `auto`, Checkout replaces any previously saved shipping addresses on the customer with the shipping address entered during the session. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { Customer = "cus_HQmikpKnGHkNwW", LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { PriceData = new Stripe.Checkout.SessionLineItemPriceDataOptions { UnitAmount = 1000, ProductData = new Stripe.Checkout.SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, Currency = "eur", }, Quantity = 2, }, }, TaxIdCollection = new Stripe.Checkout.SessionTaxIdCollectionOptions { Enabled = true }, CustomerUpdate = new Stripe.Checkout.SessionCustomerUpdateOptions { Name = "auto", Shipping = "auto", }, ShippingAddressCollection = new Stripe.Checkout.SessionShippingAddressCollectionOptions { AllowedCountries = new List { "DE" }, }, Mode = "payment", SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ Customer: stripe.String("cus_HQmikpKnGHkNwW"), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ UnitAmount: stripe.Int64(1000), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, Currency: stripe.String(string(stripe.CurrencyEUR)), }, Quantity: stripe.Int64(2), }, }, TaxIDCollection: &stripe.CheckoutSessionTaxIDCollectionParams{Enabled: stripe.Bool(true)}, CustomerUpdate: &stripe.CheckoutSessionCustomerUpdateParams{ Name: stripe.String("auto"), Shipping: stripe.String("auto"), }, ShippingAddressCollection: &stripe.CheckoutSessionShippingAddressCollectionParams{ AllowedCountries: []*string{stripe.String("DE")}, }, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .setCustomer("cus_HQmikpKnGHkNwW") .addLineItem( SessionCreateParams.LineItem.builder() .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setUnitAmount(1000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build() ) .setCurrency("eur") .build() ) .setQuantity(2L) .build() ) .setTaxIdCollection(SessionCreateParams.TaxIdCollection.builder().setEnabled(true).build()) .setCustomerUpdate( SessionCreateParams.CustomerUpdate.builder() .setName(SessionCreateParams.CustomerUpdate.Name.AUTO) .setShipping(SessionCreateParams.CustomerUpdate.Shipping.AUTO) .build() ) .setShippingAddressCollection( SessionCreateParams.ShippingAddressCollection.builder() .addAllowedCountry(SessionCreateParams.ShippingAddressCollection.AllowedCountry.DE) .build() ) .setMode(SessionCreateParams.Mode.PAYMENT) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ customer: 'cus_HQmikpKnGHkNwW', line_items: [ { price_data: { unit_amount: 1000, product_data: { name: 'T-shirt', }, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: { enabled: true, }, customer_update: { name: 'auto', shipping: 'auto', }, shipping_address_collection: { allowed_countries: ['DE'], }, mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( customer="cus_HQmikpKnGHkNwW", line_items=[ { "price_data": {"unit_amount": 1000, "product_data": {"name": "T-shirt"}, "currency": "eur"}, "quantity": 2, }, ], tax_id_collection={"enabled": True}, customer_update={"name": "auto", "shipping": "auto"}, shipping_address_collection={"allowed_countries": ["DE"]}, mode="payment", success_url="https://example.com/success", cancel_url="https://example.com/cancel", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'customer' => 'cus_HQmikpKnGHkNwW', 'line_items' => [ [ 'price_data' => [ 'unit_amount' => 1000, 'product_data' => ['name' => 'T-shirt'], 'currency' => 'eur', ], 'quantity' => 2, ], ], 'tax_id_collection' => ['enabled' => true], 'customer_update' => [ 'name' => 'auto', 'shipping' => 'auto', ], 'shipping_address_collection' => ['allowed_countries' => ['DE']], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ customer: 'cus_HQmikpKnGHkNwW', line_items: [ { price_data: { unit_amount: 1000, product_data: {name: 'T-shirt'}, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: {enabled: true}, customer_update: { name: 'auto', shipping: 'auto', }, shipping_address_collection: {allowed_countries: ['DE']}, mode: 'payment', success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', }) ``` The above code example creates a Session in `payment` mode with tax ID collection enabled. For subscriptions, make the same changes with the [mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode) set to `subscription`. ## Require tax ID collection You can optionally configure Checkout to require tax ID collection by setting the [tax_id_collection[required]](https://docs.stripe.com/api/.md#create_checkout_session-tax_id_collection-required) parameter. When set to `if_supported`, Checkout will require tax ID information for payment for customers in [supported billing countries](#supported-types). ## Retrieve Customer Tax ID details after a Session Checkout includes provided tax IDs on the resulting [Session](https://docs.stripe.com/api/checkout/sessions/object.md) object. After each completed Session, Checkout emits a [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) event that you can listen for in a *webhook* endpoint. If you want to retrieve the collected tax ID from the Session object, it’s available under the Session’s [customer_details.tax_ids](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-customer_details-tax_ids) array: ```json { "object": { "id": "cs_test_a1dJwt0TCJTBsDkbK7RcoyJ91vJxe2Y", "object": "checkout.session", ... "customer": "cus_id_of_new_customer", "customer_details": { ... "tax_ids": [ { "type": "eu_vat", "value": "FRAB123456789" } ] }, ... "tax_id_collection": { "enabled": true }, ... } } ``` Checkout also saves collected tax IDs and business names to the [Customer](https://docs.stripe.com/api/customers/object.md) object if one is associated with the Session. A tax ID collected during checkout is accessible under the Customer’s [customer.tax_ids](https://docs.stripe.com/api/customers/object.md#customer_object-tax_ids) array. You can also retrieve all tax IDs saved to a Customer with the [Tax IDs](https://docs.stripe.com/api/tax_ids/list.md) resource by specifying the [owner.type](https://docs.stripe.com/api/tax_ids/list.md#list_tax_ids-owner-type) parameter to `customer` and [owner.customer](https://docs.stripe.com/api/tax_ids/list.md#list_tax_ids-owner-customer) to the Customer’s ID. Every new tax ID includes an associated legal business name, which Checkout saves to the Customer’s [name](https://docs.stripe.com/api/customers/object.md#customer_object-name) property. In doing so, the collected legal business name is always visible on any subscription invoices for that Customer. ## Test your integration In testing environments, you can enter any alphanumeric string that is in the correct format of a supported tax ID type (for example, `DE123456789` for `eu_vat`). For a full list of example tax IDs you can reference our [Customer Tax ID guide](https://docs.stripe.com/billing/customer/tax-ids.md#supported-tax-id). You can also use our [test tax IDs](https://docs.stripe.com/connect/testing.md#test-business-tax-ids) to test various verification state flows. ## Validation During the Checkout Session, Stripe verifies that the provided tax IDs are formatted correctly, but not that they’re valid. You’re responsible for ensuring the validity of customer information collected during checkout. To help, Stripe automatically performs asynchronous validation against government databases for [European Value Added Tax (EU VAT)](https://docs.stripe.com/billing/customer/tax-ids.md#eu-vat) and [United Kingdom Value Added Tax (GB VAT)](https://docs.stripe.com/billing/customer/tax-ids.md#gb-vat) numbers. Learn more about the [validation we perform](https://docs.stripe.com/tax/invoicing/tax-ids.md#validation), and how to consume the status of those checks. If you use Stripe Tax and your customer provides a tax ID, Stripe Tax applies the reverse charge or zero rate according to applicable laws, as long as the tax ID conforms to the necessary number format, regardless of its validity. ## Supported Tax ID types Checkout collects the following tax ID types in the given regions: # Embedded form > This is a Embedded form for when payment-ui is embedded-form. View the original doc at https://docs.stripe.com/tax/checkout/tax-ids?payment-ui=embedded-form. Displaying a customer’s tax ID and legal business name on *invoices* is a common requirement that you can satisfy by enabling tax ID collection in Checkout. This guide assumes that you’ve already integrated Checkout. If you haven’t, see the [Accept a payment guide](https://docs.stripe.com/payments/accept-a-payment.md). ## Enable Tax ID collection With tax ID collection enabled, Checkout shows and hides the tax ID collection form depending on your customer’s location. If your customer is in a location supported by tax ID collection, Checkout shows a checkbox allowing the customer to indicate that they’re purchasing as a business. When a customer checks the box, Checkout displays fields for them to enter the tax ID and legal entity name for the business. If available, Checkout uses the customer’s shipping address to determine their location, otherwise Checkout uses the customer’s billing address. Customers can only enter one tax ID. ### New Customers To enable tax ID collection for new customers, set [tax_id_collection[enabled]](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-tax_id_collection-enabled) to `true` when creating a Checkout session. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { PriceData = new Stripe.Checkout.SessionLineItemPriceDataOptions { UnitAmount = 1000, ProductData = new Stripe.Checkout.SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, Currency = "eur", }, Quantity = 2, }, }, TaxIdCollection = new Stripe.Checkout.SessionTaxIdCollectionOptions { Enabled = true }, Mode = "payment", UiMode = "embedded", ReturnUrl = "https://example.com/return", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ UnitAmount: stripe.Int64(1000), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, Currency: stripe.String(string(stripe.CurrencyEUR)), }, Quantity: stripe.Int64(2), }, }, TaxIDCollection: &stripe.CheckoutSessionTaxIDCollectionParams{Enabled: stripe.Bool(true)}, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), UIMode: stripe.String(string(stripe.CheckoutSessionUIModeEmbedded)), ReturnURL: stripe.String("https://example.com/return"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .addLineItem( SessionCreateParams.LineItem.builder() .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setUnitAmount(1000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build() ) .setCurrency("eur") .build() ) .setQuantity(2L) .build() ) .setTaxIdCollection(SessionCreateParams.TaxIdCollection.builder().setEnabled(true).build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setUiMode(SessionCreateParams.UiMode.EMBEDDED) .setReturnUrl("https://example.com/return") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ line_items: [ { price_data: { unit_amount: 1000, product_data: { name: 'T-shirt', }, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: { enabled: true, }, mode: 'payment', ui_mode: 'embedded', return_url: 'https://example.com/return', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( line_items=[ { "price_data": {"unit_amount": 1000, "product_data": {"name": "T-shirt"}, "currency": "eur"}, "quantity": 2, }, ], tax_id_collection={"enabled": True}, mode="payment", ui_mode="embedded", return_url="https://example.com/return", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'line_items' => [ [ 'price_data' => [ 'unit_amount' => 1000, 'product_data' => ['name' => 'T-shirt'], 'currency' => 'eur', ], 'quantity' => 2, ], ], 'tax_id_collection' => ['enabled' => true], 'mode' => 'payment', 'ui_mode' => 'embedded', 'return_url' => 'https://example.com/return', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ line_items: [ { price_data: { unit_amount: 1000, product_data: {name: 'T-shirt'}, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: {enabled: true}, mode: 'payment', ui_mode: 'embedded', return_url: 'https://example.com/return', }) ``` This example creates a Session in `payment` mode with tax ID collection enabled. For subscriptions, make the same changes with the [mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode) set to `subscription`. You can additionally configure Checkout to create a new [Customer](https://docs.stripe.com/api/customers/object.md) for you using [customer_creation](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_creation). If you do, Checkout saves any tax ID information collected during a Session to that new *Customer*. If not, the tax ID information will still be available at [customer_details.tax_ids](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-customer_details-tax_ids). ### Existing Customers If you pass an existing Customer when creating a Session, Checkout updates the Customer with any tax ID information collected during the Session. Checkout saves the collected business name onto the Customer’s [name](https://docs.stripe.com/api/customers/object.md#customer_object-name) property, and adds the collected tax ID to the Customer’s [customer.tax_ids](https://docs.stripe.com/api/customers/object.md#customer_object-tax_ids) array. Since the collection of a business name could result in the Customer’s existing [name](https://docs.stripe.com/api/customers/object.md#customer_object-name) being overridden, you must set [customer_update.name](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-name) to `auto` when creating the Session. Checkout only collects tax IDs on Customers that don’t already have an existing tax ID. If a Customer has one or more tax IDs saved, Checkout doesn’t display the tax ID collection form even if tax ID collection is enabled. When collecting tax IDs for existing customers you can either base their location on existing addresses on the customer or the addresses entered during checkout. By default, Checkout looks for existing addresses on the customer to assess their location: ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { Customer = "<>", LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { PriceData = new Stripe.Checkout.SessionLineItemPriceDataOptions { UnitAmount = 1000, ProductData = new Stripe.Checkout.SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, Currency = "eur", }, Quantity = 2, }, }, TaxIdCollection = new Stripe.Checkout.SessionTaxIdCollectionOptions { Enabled = true }, CustomerUpdate = new Stripe.Checkout.SessionCustomerUpdateOptions { Name = "auto" }, Mode = "payment", UiMode = "embedded", ReturnUrl = "https://example.com/return", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ Customer: stripe.String("<>"), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ UnitAmount: stripe.Int64(1000), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, Currency: stripe.String(string(stripe.CurrencyEUR)), }, Quantity: stripe.Int64(2), }, }, TaxIDCollection: &stripe.CheckoutSessionTaxIDCollectionParams{Enabled: stripe.Bool(true)}, CustomerUpdate: &stripe.CheckoutSessionCustomerUpdateParams{Name: stripe.String("auto")}, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), UIMode: stripe.String(string(stripe.CheckoutSessionUIModeEmbedded)), ReturnURL: stripe.String("https://example.com/return"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .setCustomer("<>") .addLineItem( SessionCreateParams.LineItem.builder() .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setUnitAmount(1000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build() ) .setCurrency("eur") .build() ) .setQuantity(2L) .build() ) .setTaxIdCollection(SessionCreateParams.TaxIdCollection.builder().setEnabled(true).build()) .setCustomerUpdate( SessionCreateParams.CustomerUpdate.builder() .setName(SessionCreateParams.CustomerUpdate.Name.AUTO) .build() ) .setMode(SessionCreateParams.Mode.PAYMENT) .setUiMode(SessionCreateParams.UiMode.EMBEDDED) .setReturnUrl("https://example.com/return") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ customer: '<>', line_items: [ { price_data: { unit_amount: 1000, product_data: { name: 'T-shirt', }, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: { enabled: true, }, customer_update: { name: 'auto', }, mode: 'payment', ui_mode: 'embedded', return_url: 'https://example.com/return', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( customer="<>", line_items=[ { "price_data": {"unit_amount": 1000, "product_data": {"name": "T-shirt"}, "currency": "eur"}, "quantity": 2, }, ], tax_id_collection={"enabled": True}, customer_update={"name": "auto"}, mode="payment", ui_mode="embedded", return_url="https://example.com/return", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'customer' => '<>', 'line_items' => [ [ 'price_data' => [ 'unit_amount' => 1000, 'product_data' => ['name' => 'T-shirt'], 'currency' => 'eur', ], 'quantity' => 2, ], ], 'tax_id_collection' => ['enabled' => true], 'customer_update' => ['name' => 'auto'], 'mode' => 'payment', 'ui_mode' => 'embedded', 'return_url' => 'https://example.com/return', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ customer: '<>', line_items: [ { price_data: { unit_amount: 1000, product_data: {name: 'T-shirt'}, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: {enabled: true}, customer_update: {name: 'auto'}, mode: 'payment', ui_mode: 'embedded', return_url: 'https://example.com/return', }) ``` If you don’t have the addresses of your existing customers saved, you can base their location on the billing or shipping address entered during Checkout. To specify that you want to use the billing address entered during Checkout to assess the customer’s location, you must set [customer_update.address](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-address) to `auto`. When setting [customer_update.address](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-address) to `auto`, Checkout replaces any previously saved addresses on the customer with the address entered during the session. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { Customer = "<>", LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { PriceData = new Stripe.Checkout.SessionLineItemPriceDataOptions { UnitAmount = 1000, ProductData = new Stripe.Checkout.SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, Currency = "eur", }, Quantity = 2, }, }, TaxIdCollection = new Stripe.Checkout.SessionTaxIdCollectionOptions { Enabled = true }, CustomerUpdate = new Stripe.Checkout.SessionCustomerUpdateOptions { Name = "auto", Address = "auto", }, Mode = "payment", UiMode = "embedded", ReturnUrl = "https://example.com/return", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ Customer: stripe.String("<>"), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ UnitAmount: stripe.Int64(1000), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, Currency: stripe.String(string(stripe.CurrencyEUR)), }, Quantity: stripe.Int64(2), }, }, TaxIDCollection: &stripe.CheckoutSessionTaxIDCollectionParams{Enabled: stripe.Bool(true)}, CustomerUpdate: &stripe.CheckoutSessionCustomerUpdateParams{ Name: stripe.String("auto"), Address: stripe.String("auto"), }, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), UIMode: stripe.String(string(stripe.CheckoutSessionUIModeEmbedded)), ReturnURL: stripe.String("https://example.com/return"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .setCustomer("<>") .addLineItem( SessionCreateParams.LineItem.builder() .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setUnitAmount(1000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build() ) .setCurrency("eur") .build() ) .setQuantity(2L) .build() ) .setTaxIdCollection(SessionCreateParams.TaxIdCollection.builder().setEnabled(true).build()) .setCustomerUpdate( SessionCreateParams.CustomerUpdate.builder() .setName(SessionCreateParams.CustomerUpdate.Name.AUTO) .setAddress(SessionCreateParams.CustomerUpdate.Address.AUTO) .build() ) .setMode(SessionCreateParams.Mode.PAYMENT) .setUiMode(SessionCreateParams.UiMode.EMBEDDED) .setReturnUrl("https://example.com/return") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ customer: '<>', line_items: [ { price_data: { unit_amount: 1000, product_data: { name: 'T-shirt', }, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: { enabled: true, }, customer_update: { name: 'auto', address: 'auto', }, mode: 'payment', ui_mode: 'embedded', return_url: 'https://example.com/return', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( customer="<>", line_items=[ { "price_data": {"unit_amount": 1000, "product_data": {"name": "T-shirt"}, "currency": "eur"}, "quantity": 2, }, ], tax_id_collection={"enabled": True}, customer_update={"name": "auto", "address": "auto"}, mode="payment", ui_mode="embedded", return_url="https://example.com/return", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'customer' => '<>', 'line_items' => [ [ 'price_data' => [ 'unit_amount' => 1000, 'product_data' => ['name' => 'T-shirt'], 'currency' => 'eur', ], 'quantity' => 2, ], ], 'tax_id_collection' => ['enabled' => true], 'customer_update' => [ 'name' => 'auto', 'address' => 'auto', ], 'mode' => 'payment', 'ui_mode' => 'embedded', 'return_url' => 'https://example.com/return', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ customer: '<>', line_items: [ { price_data: { unit_amount: 1000, product_data: {name: 'T-shirt'}, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: {enabled: true}, customer_update: { name: 'auto', address: 'auto', }, mode: 'payment', ui_mode: 'embedded', return_url: 'https://example.com/return', }) ``` If you’re collecting shipping addresses for existing customers, you must base their location on the shipping address entered during checkout. To do so, set [customer_update.shipping](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-shipping) to `auto`. When setting [customer_update.shipping](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-shipping) to `auto`, Checkout replaces any previously saved shipping addresses on the customer with the shipping address entered during the session. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { Customer = "cus_HQmikpKnGHkNwW", LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { PriceData = new Stripe.Checkout.SessionLineItemPriceDataOptions { UnitAmount = 1000, ProductData = new Stripe.Checkout.SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, Currency = "eur", }, Quantity = 2, }, }, TaxIdCollection = new Stripe.Checkout.SessionTaxIdCollectionOptions { Enabled = true }, CustomerUpdate = new Stripe.Checkout.SessionCustomerUpdateOptions { Name = "auto", Shipping = "auto", }, ShippingAddressCollection = new Stripe.Checkout.SessionShippingAddressCollectionOptions { AllowedCountries = new List { "DE" }, }, Mode = "payment", UiMode = "embedded", ReturnUrl = "https://example.com/return", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ Customer: stripe.String("cus_HQmikpKnGHkNwW"), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ UnitAmount: stripe.Int64(1000), ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{ Name: stripe.String("T-shirt"), }, Currency: stripe.String(string(stripe.CurrencyEUR)), }, Quantity: stripe.Int64(2), }, }, TaxIDCollection: &stripe.CheckoutSessionTaxIDCollectionParams{Enabled: stripe.Bool(true)}, CustomerUpdate: &stripe.CheckoutSessionCustomerUpdateParams{ Name: stripe.String("auto"), Shipping: stripe.String("auto"), }, ShippingAddressCollection: &stripe.CheckoutSessionShippingAddressCollectionParams{ AllowedCountries: []*string{stripe.String("DE")}, }, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), UIMode: stripe.String(string(stripe.CheckoutSessionUIModeEmbedded)), ReturnURL: stripe.String("https://example.com/return"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .setCustomer("cus_HQmikpKnGHkNwW") .addLineItem( SessionCreateParams.LineItem.builder() .setPriceData( SessionCreateParams.LineItem.PriceData.builder() .setUnitAmount(1000L) .setProductData( SessionCreateParams.LineItem.PriceData.ProductData.builder() .setName("T-shirt") .build() ) .setCurrency("eur") .build() ) .setQuantity(2L) .build() ) .setTaxIdCollection(SessionCreateParams.TaxIdCollection.builder().setEnabled(true).build()) .setCustomerUpdate( SessionCreateParams.CustomerUpdate.builder() .setName(SessionCreateParams.CustomerUpdate.Name.AUTO) .setShipping(SessionCreateParams.CustomerUpdate.Shipping.AUTO) .build() ) .setShippingAddressCollection( SessionCreateParams.ShippingAddressCollection.builder() .addAllowedCountry(SessionCreateParams.ShippingAddressCollection.AllowedCountry.DE) .build() ) .setMode(SessionCreateParams.Mode.PAYMENT) .setUiMode(SessionCreateParams.UiMode.EMBEDDED) .setReturnUrl("https://example.com/return") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ customer: 'cus_HQmikpKnGHkNwW', line_items: [ { price_data: { unit_amount: 1000, product_data: { name: 'T-shirt', }, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: { enabled: true, }, customer_update: { name: 'auto', shipping: 'auto', }, shipping_address_collection: { allowed_countries: ['DE'], }, mode: 'payment', ui_mode: 'embedded', return_url: 'https://example.com/return', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( customer="cus_HQmikpKnGHkNwW", line_items=[ { "price_data": {"unit_amount": 1000, "product_data": {"name": "T-shirt"}, "currency": "eur"}, "quantity": 2, }, ], tax_id_collection={"enabled": True}, customer_update={"name": "auto", "shipping": "auto"}, shipping_address_collection={"allowed_countries": ["DE"]}, mode="payment", ui_mode="embedded", return_url="https://example.com/return", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'customer' => 'cus_HQmikpKnGHkNwW', 'line_items' => [ [ 'price_data' => [ 'unit_amount' => 1000, 'product_data' => ['name' => 'T-shirt'], 'currency' => 'eur', ], 'quantity' => 2, ], ], 'tax_id_collection' => ['enabled' => true], 'customer_update' => [ 'name' => 'auto', 'shipping' => 'auto', ], 'shipping_address_collection' => ['allowed_countries' => ['DE']], 'mode' => 'payment', 'ui_mode' => 'embedded', 'return_url' => 'https://example.com/return', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ customer: 'cus_HQmikpKnGHkNwW', line_items: [ { price_data: { unit_amount: 1000, product_data: {name: 'T-shirt'}, currency: 'eur', }, quantity: 2, }, ], tax_id_collection: {enabled: true}, customer_update: { name: 'auto', shipping: 'auto', }, shipping_address_collection: {allowed_countries: ['DE']}, mode: 'payment', ui_mode: 'embedded', return_url: 'https://example.com/return', }) ``` This example creates a Session in `payment` mode with tax ID collection enabled. For subscriptions, make the same changes with the [mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode) set to `subscription`. ## Require tax ID collection You can optionally configure Checkout to require tax ID collection by setting the [tax_id_collection[required]](https://docs.stripe.com/api/.md#create_checkout_session-tax_id_collection-required) parameter. When set to `if_supported`, Checkout will require tax ID information for payment for customers in [supported billing countries](#supported-types). ## Retrieve Customer Tax ID details after a Session Checkout includes provided tax IDs on the resulting [Session](https://docs.stripe.com/api/checkout/sessions/object.md) object. After each completed Session, Checkout emits a [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) event that you can listen for in a *webhook* endpoint. If you want to retrieve the collected tax ID from the Session object, it’s available under the Session’s [customer_details.tax_ids](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-customer_details-tax_ids) array: ```json { "object": { "id": "cs_test_a1dJwt0TCJTBsDkbK7RcoyJ91vJxe2Y", "object": "checkout.session", ... "customer": "cus_id_of_new_customer", "customer_details": { ... "tax_ids": [ { "type": "eu_vat", "value": "FRAB123456789" } ] }, ... "tax_id_collection": { "enabled": true }, ... } } ``` Checkout also saves collected tax IDs and business names to the [Customer](https://docs.stripe.com/api/customers/object.md) object if one is associated with the Session. A tax ID collected during checkout is accessible under the Customer’s [customer.tax_ids](https://docs.stripe.com/api/customers/object.md#customer_object-tax_ids) array. You can also retrieve all tax IDs saved to a Customer with the [Tax IDs](https://docs.stripe.com/api/tax_ids/list.md) resource by specifying the [owner.type](https://docs.stripe.com/api/tax_ids/list.md#list_tax_ids-owner-type) parameter to `customer` and [owner.customer](https://docs.stripe.com/api/tax_ids/list.md#list_tax_ids-owner-customer) to the Customer’s ID. Every new tax ID includes an associated legal business name, which Checkout saves to the Customer’s [name](https://docs.stripe.com/api/customers/object.md#customer_object-name) property. In doing so, the collected legal business name is always visible on any subscription invoices for that Customer. ## Test your integration In testing environments, you can enter any alphanumeric string that is in the correct format of a supported tax ID type (for example, `DE123456789` for `eu_vat`). For a full list of example tax IDs you can reference our [Customer Tax ID guide](https://docs.stripe.com/billing/customer/tax-ids.md#supported-tax-id). You can also use our [test tax IDs](https://docs.stripe.com/connect/testing.md#test-business-tax-ids) to test various verification state flows. ## Validation During the Checkout Session, Stripe verifies that the provided tax IDs are formatted correctly, but not that they’re valid. You’re responsible for ensuring the validity of customer information collected during checkout. To help, Stripe automatically performs asynchronous validation against government databases for [European Value Added Tax (EU VAT)](https://docs.stripe.com/billing/customer/tax-ids.md#eu-vat) and [United Kingdom Value Added Tax (GB VAT)](https://docs.stripe.com/billing/customer/tax-ids.md#gb-vat) numbers. Learn more about the [validation we perform](https://docs.stripe.com/tax/invoicing/tax-ids.md#validation), and how to consume the status of those checks. If you use Stripe Tax and your customer provides a tax ID, Stripe Tax applies the reverse charge or zero rate according to applicable laws, as long as the tax ID conforms to the necessary number format, regardless of its validity. ## Supported Tax ID types Checkout collects the following tax ID types in the given regions: # Embedded components > This is a Embedded components for when payment-ui is embedded-components. View the original doc at https://docs.stripe.com/tax/checkout/tax-ids?payment-ui=embedded-components. Displaying a customer’s tax ID and legal business name on *invoices* is a common requirement that you can satisfy by enabling tax ID collection. This guide assumes that you’ve already integrated Elements with the Checkout Sessions API. If you haven’t completed this integration, see the [quickstart](https://docs.stripe.com/checkout/custom/quickstart.md) to get started. ## Enable Tax ID collection ### New Customers To enable tax ID collection for new customers, set [tax_id_collection[enabled]](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-tax_id_collection-enabled) to `true` when creating a Checkout Session. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { UiMode = "custom", LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { Price = "<>", Quantity = 1 }, }, TaxIdCollection = new Stripe.Checkout.SessionTaxIdCollectionOptions { Enabled = true }, Mode = "payment", ReturnUrl = "https://example.com/return", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ UIMode: stripe.String(string(stripe.CheckoutSessionUIModeCustom)), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("<>"), Quantity: stripe.Int64(1), }, }, TaxIDCollection: &stripe.CheckoutSessionTaxIDCollectionParams{Enabled: stripe.Bool(true)}, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), ReturnURL: stripe.String("https://example.com/return"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .setUiMode(SessionCreateParams.UiMode.CUSTOM) .addLineItem( SessionCreateParams.LineItem.builder().setPrice("<>").setQuantity(1L).build() ) .setTaxIdCollection(SessionCreateParams.TaxIdCollection.builder().setEnabled(true).build()) .setMode(SessionCreateParams.Mode.PAYMENT) .setReturnUrl("https://example.com/return") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ ui_mode: 'custom', line_items: [ { price: '<>', quantity: 1, }, ], tax_id_collection: { enabled: true, }, mode: 'payment', return_url: 'https://example.com/return', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( ui_mode="custom", line_items=[{"price": "<>", "quantity": 1}], tax_id_collection={"enabled": True}, mode="payment", return_url="https://example.com/return", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'ui_mode' => 'custom', 'line_items' => [ [ 'price' => '<>', 'quantity' => 1, ], ], 'tax_id_collection' => ['enabled' => true], 'mode' => 'payment', 'return_url' => 'https://example.com/return', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ ui_mode: 'custom', line_items: [ { price: '<>', quantity: 1, }, ], tax_id_collection: {enabled: true}, mode: 'payment', return_url: 'https://example.com/return', }) ``` ### Existing customers Create a Checkout Session with an existing Customer to update the Customer with any tax ID information collected during checkout. The Checkout Session saves the collected business name as the Customer’s [name](https://docs.stripe.com/api/customers/object.md#customer_object-name) and adds the collected tax ID to [customer.tax_ids](https://docs.stripe.com/api/customers/object.md#customer_object-tax_ids). Because the collection of a business name can override the Customer’s existing [name](https://docs.stripe.com/api/customers/object.md#customer_object-name), you must set [customer_update.name](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-name) to `auto` when creating the Checkout Session. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { UiMode = "custom", Customer = "<>", LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { Price = "<>", Quantity = 1 }, }, TaxIdCollection = new Stripe.Checkout.SessionTaxIdCollectionOptions { Enabled = true }, CustomerUpdate = new Stripe.Checkout.SessionCustomerUpdateOptions { Name = "auto" }, Mode = "payment", ReturnUrl = "https://example.com/return", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ UIMode: stripe.String(string(stripe.CheckoutSessionUIModeCustom)), Customer: stripe.String("<>"), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("<>"), Quantity: stripe.Int64(1), }, }, TaxIDCollection: &stripe.CheckoutSessionTaxIDCollectionParams{Enabled: stripe.Bool(true)}, CustomerUpdate: &stripe.CheckoutSessionCustomerUpdateParams{Name: stripe.String("auto")}, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), ReturnURL: stripe.String("https://example.com/return"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .setUiMode(SessionCreateParams.UiMode.CUSTOM) .setCustomer("<>") .addLineItem( SessionCreateParams.LineItem.builder().setPrice("<>").setQuantity(1L).build() ) .setTaxIdCollection(SessionCreateParams.TaxIdCollection.builder().setEnabled(true).build()) .setCustomerUpdate( SessionCreateParams.CustomerUpdate.builder() .setName(SessionCreateParams.CustomerUpdate.Name.AUTO) .build() ) .setMode(SessionCreateParams.Mode.PAYMENT) .setReturnUrl("https://example.com/return") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ ui_mode: 'custom', customer: '<>', line_items: [ { price: '<>', quantity: 1, }, ], tax_id_collection: { enabled: true, }, customer_update: { name: 'auto', }, mode: 'payment', return_url: 'https://example.com/return', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( ui_mode="custom", customer="<>", line_items=[{"price": "<>", "quantity": 1}], tax_id_collection={"enabled": True}, customer_update={"name": "auto"}, mode="payment", return_url="https://example.com/return", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'ui_mode' => 'custom', 'customer' => '<>', 'line_items' => [ [ 'price' => '<>', 'quantity' => 1, ], ], 'tax_id_collection' => ['enabled' => true], 'customer_update' => ['name' => 'auto'], 'mode' => 'payment', 'return_url' => 'https://example.com/return', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ ui_mode: 'custom', customer: '<>', line_items: [ { price: '<>', quantity: 1, }, ], tax_id_collection: {enabled: true}, customer_update: {name: 'auto'}, mode: 'payment', return_url: 'https://example.com/return', }) ``` If you don’t have the addresses of your existing customers saved, you can base their location on the billing or shipping address entered during checkout. To use the billing address entered during checkout to assess the customer’s location, set [customer_update.address](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-address) to `auto`. Setting [customer_update.address](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-address) to `auto` replaces any previously saved addresses on the customer with the address entered during checkout. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { UiMode = "custom", Customer = "<>", LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { Price = "<>", Quantity = 1 }, }, TaxIdCollection = new Stripe.Checkout.SessionTaxIdCollectionOptions { Enabled = true }, CustomerUpdate = new Stripe.Checkout.SessionCustomerUpdateOptions { Name = "auto", Address = "auto", }, Mode = "payment", ReturnUrl = "https://example.com/return", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ UIMode: stripe.String(string(stripe.CheckoutSessionUIModeCustom)), Customer: stripe.String("<>"), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("<>"), Quantity: stripe.Int64(1), }, }, TaxIDCollection: &stripe.CheckoutSessionTaxIDCollectionParams{Enabled: stripe.Bool(true)}, CustomerUpdate: &stripe.CheckoutSessionCustomerUpdateParams{ Name: stripe.String("auto"), Address: stripe.String("auto"), }, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), ReturnURL: stripe.String("https://example.com/return"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .setUiMode(SessionCreateParams.UiMode.CUSTOM) .setCustomer("<>") .addLineItem( SessionCreateParams.LineItem.builder().setPrice("<>").setQuantity(1L).build() ) .setTaxIdCollection(SessionCreateParams.TaxIdCollection.builder().setEnabled(true).build()) .setCustomerUpdate( SessionCreateParams.CustomerUpdate.builder() .setName(SessionCreateParams.CustomerUpdate.Name.AUTO) .setAddress(SessionCreateParams.CustomerUpdate.Address.AUTO) .build() ) .setMode(SessionCreateParams.Mode.PAYMENT) .setReturnUrl("https://example.com/return") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ ui_mode: 'custom', customer: '<>', line_items: [ { price: '<>', quantity: 1, }, ], tax_id_collection: { enabled: true, }, customer_update: { name: 'auto', address: 'auto', }, mode: 'payment', return_url: 'https://example.com/return', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( ui_mode="custom", customer="<>", line_items=[{"price": "<>", "quantity": 1}], tax_id_collection={"enabled": True}, customer_update={"name": "auto", "address": "auto"}, mode="payment", return_url="https://example.com/return", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'ui_mode' => 'custom', 'customer' => '<>', 'line_items' => [ [ 'price' => '<>', 'quantity' => 1, ], ], 'tax_id_collection' => ['enabled' => true], 'customer_update' => [ 'name' => 'auto', 'address' => 'auto', ], 'mode' => 'payment', 'return_url' => 'https://example.com/return', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ ui_mode: 'custom', customer: '<>', line_items: [ { price: '<>', quantity: 1, }, ], tax_id_collection: {enabled: true}, customer_update: { name: 'auto', address: 'auto', }, mode: 'payment', return_url: 'https://example.com/return', }) ``` If you’re collecting shipping addresses for existing customers, you must base their location on the shipping address entered during checkout by setting [customer_update.shipping](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-shipping) to `auto`. Setting [customer_update.shipping](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_update-shipping) to `auto` replaces any previously saved shipping addresses on the customer with the shipping address entered during checkout. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Checkout.SessionCreateOptions { UiMode = "custom", Customer = "<>", LineItems = new List { new Stripe.Checkout.SessionLineItemOptions { Price = "<>", Quantity = 1 }, }, TaxIdCollection = new Stripe.Checkout.SessionTaxIdCollectionOptions { Enabled = true }, CustomerUpdate = new Stripe.Checkout.SessionCustomerUpdateOptions { Name = "auto", Shipping = "auto", }, ShippingAddressCollection = new Stripe.Checkout.SessionShippingAddressCollectionOptions { AllowedCountries = new List { "DE" }, }, Mode = "payment", ReturnUrl = "https://example.com/return", }; var service = new Stripe.Checkout.SessionService(); Stripe.Checkout.Session session = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.CheckoutSessionParams{ UIMode: stripe.String(string(stripe.CheckoutSessionUIModeCustom)), Customer: stripe.String("<>"), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("<>"), Quantity: stripe.Int64(1), }, }, TaxIDCollection: &stripe.CheckoutSessionTaxIDCollectionParams{Enabled: stripe.Bool(true)}, CustomerUpdate: &stripe.CheckoutSessionCustomerUpdateParams{ Name: stripe.String("auto"), Shipping: stripe.String("auto"), }, ShippingAddressCollection: &stripe.CheckoutSessionShippingAddressCollectionParams{ AllowedCountries: []*string{stripe.String("DE")}, }, Mode: stripe.String(string(stripe.CheckoutSessionModePayment)), ReturnURL: stripe.String("https://example.com/return"), }; result, err := session.New(params); ``` ```java Stripe.apiKey = "<>"; SessionCreateParams params = SessionCreateParams.builder() .setUiMode(SessionCreateParams.UiMode.CUSTOM) .setCustomer("<>") .addLineItem( SessionCreateParams.LineItem.builder().setPrice("<>").setQuantity(1L).build() ) .setTaxIdCollection(SessionCreateParams.TaxIdCollection.builder().setEnabled(true).build()) .setCustomerUpdate( SessionCreateParams.CustomerUpdate.builder() .setName(SessionCreateParams.CustomerUpdate.Name.AUTO) .setShipping(SessionCreateParams.CustomerUpdate.Shipping.AUTO) .build() ) .setShippingAddressCollection( SessionCreateParams.ShippingAddressCollection.builder() .addAllowedCountry(SessionCreateParams.ShippingAddressCollection.AllowedCountry.DE) .build() ) .setMode(SessionCreateParams.Mode.PAYMENT) .setReturnUrl("https://example.com/return") .build(); Session session = Session.create(params); ``` ```node const stripe = require('stripe')('<>'); const session = await stripe.checkout.sessions.create({ ui_mode: 'custom', customer: '<>', line_items: [ { price: '<>', quantity: 1, }, ], tax_id_collection: { enabled: true, }, customer_update: { name: 'auto', shipping: 'auto', }, shipping_address_collection: { allowed_countries: ['DE'], }, mode: 'payment', return_url: 'https://example.com/return', }); ``` ```python import stripe stripe.api_key = "<>" session = stripe.checkout.Session.create( ui_mode="custom", customer="<>", line_items=[{"price": "<>", "quantity": 1}], tax_id_collection={"enabled": True}, customer_update={"name": "auto", "shipping": "auto"}, shipping_address_collection={"allowed_countries": ["DE"]}, mode="payment", return_url="https://example.com/return", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $session = $stripe->checkout->sessions->create([ 'ui_mode' => 'custom', 'customer' => '<>', 'line_items' => [ [ 'price' => '<>', 'quantity' => 1, ], ], 'tax_id_collection' => ['enabled' => true], 'customer_update' => [ 'name' => 'auto', 'shipping' => 'auto', ], 'shipping_address_collection' => ['allowed_countries' => ['DE']], 'mode' => 'payment', 'return_url' => 'https://example.com/return', ]); ``` ```ruby Stripe.api_key = '<>' session = Stripe::Checkout::Session.create({ ui_mode: 'custom', customer: '<>', line_items: [ { price: '<>', quantity: 1, }, ], tax_id_collection: {enabled: true}, customer_update: { name: 'auto', shipping: 'auto', }, shipping_address_collection: {allowed_countries: ['DE']}, mode: 'payment', return_url: 'https://example.com/return', }) ``` This example creates a Session in `payment` mode with tax ID collection enabled. For subscriptions, make the same changes with the [mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode) set to `subscription`. ## Build a client-side form Create a form in your web application and use [updateTaxIdInfo](https://docs.stripe.com/js/custom_checkout/react/update_tax_id_info) to collect the customer’s business name and tax ID. ```jsx import {useState} from 'react'; import {useCheckout} from '@stripe/react-stripe-js'; // Create a constant to list out the taxID types you'd like to support in your checkout const TAX_ID_TYPES = ['au_abn', 'eu_vat', ...] as const; const TaxIdCollectionForm = () => { const [isPurchaseAsBusiness, setIsPurchaseAsBusiness] = useState(false); const [isEditing, setIsEditing] = useState(true); const [businessName, setBusinessName] = useState(''); const [taxIdType, setTaxIdType] = useState(''); const [taxIdValue, setTaxIdValue] = useState(''); const [errorMessage, setErrorMessage] = useState(''); const {updateTaxIdInfo} = useCheckout(); const validateAndUpdate = async () => { if (!businessName) { setErrorMessage('Business name is required'); return; } if (!taxIdValue) { setErrorMessage('Tax ID is required'); return; } if (!taxIdType) { setErrorMessage('Please select a tax ID type'); return; } // When all of the values are filled out, call `updateTaxIdInfo` submit it to the session. const res = await updateTaxIdInfo({ taxId: {value: taxIdValue, type: taxIdType}, businessName }); if (res.error) { setErrorMessage(res.error.message); } else { setErrorMessage(''); setIsEditing(false); } }; const handleReset = () => { setBusinessName(''); setTaxIdType(''); setTaxIdValue(''); setErrorMessage(''); }; const onIsPurchaseAsBusinessChange = async (e) => { setIsPurchaseAsBusiness(e.target.checked); if (!isPurchaseAsBusiness) { setErrorMessage(''); setIsEditing(true); // When isPurchaseAsBusiness is false, call this to clear the taxIdInfo in the session. await updateTaxIdInfo(null); } }; return (
{isPurchaseAsBusiness && ( <> {isEditing ? ( <>
setBusinessName(e.target.value.trim())} placeholder="Enter business name" />
setTaxIdValue(e.target.value.trim())} placeholder="Enter tax ID" />
{errorMessage && (
{errorMessage}
)} ) : (
Business Name: {businessName}
Tax ID Type: {taxIdType}
Tax ID: {taxIdValue}
)} )}
); }; ``` Create a form in your web application and use [checkout.updateTaxIdInfo](https://docs.stripe.com/js/custom_checkout/update_tax_id_info) to collect the customer’s business name and tax ID. ```html
``` ```javascript // Create a constant to list out the taxID types you'd like to support in your checkout const TAX_ID_TYPES = ['au_abn', 'eu_vat', ...] as const; // DOM elements const purchaseAsBusinessCheckbox = document.getElementById('purchaseAsBusiness'); const businessFormSection = document.getElementById('businessFormSection'); const editingSection = document.getElementById('editingSection'); const viewingSection = document.getElementById('viewingSection'); const businessNameInput = document.getElementById('businessName'); const taxIdTypeSelect = document.getElementById('taxIdType'); const taxIdInput = document.getElementById('taxId'); const saveButton = document.getElementById('saveButton'); const resetButton = document.getElementById('resetButton'); const editButton = document.getElementById('editButton'); const errorMessageElement = document.getElementById('errorMessage'); const viewBusinessNameElement = document.getElementById('viewBusinessName'); const viewTaxIdTypeElement = document.getElementById('viewTaxIdType'); const viewTaxIdElement = document.getElementById('viewTaxId'); // State variables let isPurchaseAsBusiness = false; let isEditing = true; let businessName = ''; let taxIdType = ''; let taxIdValue = ''; let errorMessage = ''; // Initialize form function initForm() { TAX_ID_TYPES.forEach(type => { const option = document.createElement('option'); option.value = type; option.textContent = type; taxIdTypeSelect.appendChild(option); }); updateDisplay(); } function updateDisplay() { businessFormSection.classList.toggle('hidden', !isPurchaseAsBusiness); if (isPurchaseAsBusiness) { editingSection.classList.toggle('hidden', !isEditing); viewingSection.classList.toggle('hidden', isEditing); if (!isEditing) { viewBusinessNameElement.textContent = `Business Name: ${businessName}`; viewTaxIdTypeElement.textContent = `Tax ID Type: ${taxIdType}`; viewTaxIdElement.textContent = `Tax ID: ${taxIdValue}`; } } errorMessageElement.classList.toggle('hidden', !errorMessage); errorMessageElement.textContent = errorMessage; } // Event: Purchase as business checkbox change purchaseAsBusinessCheckbox.addEventListener('change', async function(e) { isPurchaseAsBusiness = e.target.checked; if (!isPurchaseAsBusiness) { errorMessage = ''; isEditing = true; // When isPurchaseAsBusiness is false, call this to clear the taxIdInfo in the session. await updateTaxIdInfo(null); } updateDisplay(); }); saveButton.addEventListener('click', async function() { businessName = businessNameInput.value.trim(); taxIdType = taxIdTypeSelect.value; taxIdValue = taxIdInput.value.trim(); if (!businessName) { errorMessage = 'Business name is required'; updateDisplay(); return; } if (!taxIdValue) { errorMessage = 'Tax ID is required'; updateDisplay(); return; } if (!taxIdType) { errorMessage = 'Please select a tax ID type'; updateDisplay(); return; } // When all of the values are filled out, call `updateTaxIdInfo` submit it to the session. const res = await updateTaxIdInfo({ taxId: {value: taxIdValue, type: taxIdType}, businessName }); if (res.error) { errorMessage = res.error.message; } else { errorMessage = ''; isEditing = false; } updateDisplay(); }); resetButton.addEventListener('click', function() { businessNameInput.value = ''; taxIdTypeSelect.value = ''; taxIdInput.value = ''; businessName = ''; taxIdType = ''; taxIdValue = ''; errorMessage = ''; updateDisplay(); }); editButton.addEventListener('click', function() { isEditing = true; updateDisplay(); }); initForm(); ``` ## Retrieve Customer Tax ID details after a Session Checkout includes provided tax IDs on the resulting [Session](https://docs.stripe.com/api/checkout/sessions/object.md) object. After each completed Session, Checkout emits a [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) event that you can listen for in a *webhook* endpoint. If you want to retrieve the collected tax ID from the Session object, it’s available under the Session’s [customer_details.tax_ids](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-customer_details-tax_ids) array: ```json { "object": { "id": "cs_test_a1dJwt0TCJTBsDkbK7RcoyJ91vJxe2Y", "object": "checkout.session", ... "customer": "cus_id_of_new_customer", "customer_details": { ... "tax_ids": [ { "type": "eu_vat", "value": "FRAB123456789" } ] }, ... "tax_id_collection": { "enabled": true }, ... } } ``` Checkout also saves collected tax IDs and business names to the [Customer](https://docs.stripe.com/api/customers/object.md) object if one is associated with the Session. A tax ID collected during checkout is accessible under the Customer’s [customer.tax_ids](https://docs.stripe.com/api/customers/object.md#customer_object-tax_ids) array. You can also retrieve all tax IDs saved to a Customer with the [Tax IDs](https://docs.stripe.com/api/tax_ids/list.md) resource by specifying the [owner.type](https://docs.stripe.com/api/tax_ids/list.md#list_tax_ids-owner-type) parameter to `customer` and [owner.customer](https://docs.stripe.com/api/tax_ids/list.md#list_tax_ids-owner-customer) to the Customer’s ID. Every new tax ID includes an associated legal business name, which Checkout saves to the Customer’s [name](https://docs.stripe.com/api/customers/object.md#customer_object-name) property. In doing so, the collected legal business name is always visible on any subscription invoices for that Customer. ## Test your integration In testing environments, you can enter any alphanumeric string that is in the correct format of a supported tax ID type (for example, `DE123456789` for `eu_vat`). For a full list of example tax IDs you can reference our [Customer Tax ID guide](https://docs.stripe.com/billing/customer/tax-ids.md#supported-tax-id). You can also use our [test tax IDs](https://docs.stripe.com/connect/testing.md#test-business-tax-ids) to test various verification state flows. ## Validation During the Checkout Session, Stripe verifies that the provided tax IDs are formatted correctly, but not that they’re valid. You’re responsible for ensuring the validity of customer information collected during checkout. To help, Stripe automatically performs asynchronous validation against government databases for [European Value Added Tax (EU VAT)](https://docs.stripe.com/billing/customer/tax-ids.md#eu-vat) and [United Kingdom Value Added Tax (GB VAT)](https://docs.stripe.com/billing/customer/tax-ids.md#gb-vat) numbers. Learn more about the [validation we perform](https://docs.stripe.com/tax/invoicing/tax-ids.md#validation), and how to consume the status of those checks. If you use Stripe Tax and your customer provides a tax ID, Stripe Tax applies the reverse charge or zero rate according to applicable laws, as long as the tax ID conforms to the necessary number format, regardless of its validity. ## Supported Tax ID types The Checkout Session collects the following tax ID types in the given regions: