Tax

Configure tax rates and tax groups for accurate tax calculation. Support multiple tax rates per country and region, with default rate resolution and tax group assignment.

TaxRate Model

class TaxRate {
  id: string;              // Unique UUID identifier
  name: string;            // Display name (e.g. "German MwSt 19%")
  rate: number;            // Tax rate as percentage (e.g. 19 for 19%)
  country: string;         // ISO 3166-1 country code (e.g. "DE", "US")
  state: string | null;    // Optional state/region code (e.g. "CA", "NY")
  isDefault: boolean;      // Whether this is the default rate for the country
  isActive: boolean;       // Active status (default: true)
}

TaxGroup Model

class TaxGroup {
  id: string;              // Unique UUID identifier
  name: string;            // Group name (e.g. "Reduced Rate", "Zero Rate")
  description: string | null; // Optional description
  isActive: boolean;       // Active status (default: true)
}

Create Tax Rate

Create a country-level tax rate:

import { createTaxService } from "commercio";

const taxService = createTaxService();

// Create German standard VAT rate
const germanVat = await taxService.createTaxRate({
  name: "German MwSt 19%",
  rate: 19,
  country: "DE",
  isDefault: true,
});

console.log(germanVat.id);        // UUID
console.log(germanVat.name);      // "German MwSt 19%"
console.log(germanVat.rate);      // 19
console.log(germanVat.country);   // "DE"
console.log(germanVat.isDefault); // true

Create a state-level tax rate:

// Create US state sales tax
const californiaTax = await taxService.createTaxRate({
  name: "California Sales Tax",
  rate: 7.25,
  country: "US",
  state: "CA",
  isDefault: false,
});

console.log(californiaTax.state); // "CA"

Tax Operations

Get and List Tax Rates

Get by ID:

// Get a tax rate by ID
const taxRate = await taxService.getTaxRateById(taxRateId);

console.log(taxRate.name);
console.log(taxRate.rate);
console.log(taxRate.country);

Get by country:

// Get all tax rates for a country
const germanRates = await taxService.getTaxRatesByCountry("DE");

germanRates.forEach(rate => {
  console.log(`${rate.name}: ${rate.rate}%`);
});

Get default rate:

// Get the default tax rate for a country
const defaultRate = await taxService.getDefaultTaxRate("DE");

console.log(defaultRate.name); // "German MwSt 19%"
console.log(defaultRate.rate); // 19

List all tax rates:

// Get all tax rates
const allRates = await taxService.getAllTaxRates();

allRates.forEach(rate => {
  console.log(`${rate.country} - ${rate.name}: ${rate.rate}%`);
});

Complete Example

import { createServices } from "commercio";

const { taxService } = createServices();

// 1. Create German standard VAT (19%)
const standardVat = await taxService.createTaxRate({
  name: "German MwSt 19%",
  rate: 19,
  country: "DE",
  isDefault: true,
});

// 2. Create German reduced VAT (7%)
const reducedVat = await taxService.createTaxRate({
  name: "German MwSt 7%",
  rate: 7,
  country: "DE",
  isDefault: false,
});

// 3. Set the standard rate as default
await taxService.setDefaultTaxRate(standardVat.id);

// 4. Verify default rate
const defaultRate = await taxService.getDefaultTaxRate("DE");
console.log(defaultRate.rate); // 19

// 5. Calculate tax on an order item (e.g. electronics at 19%)
const electronicsTax = await taxService.calculateTax({
  netAmount: 49900, // $499.00
  taxRateId: standardVat.id,
});
console.log(electronicsTax.taxAmount);   // 9481  ($94.81)
console.log(electronicsTax.grossAmount); // 59381 ($593.81)

// 6. Calculate tax on a book (reduced rate at 7%)
const bookTax = await taxService.calculateTax({
  netAmount: 1999, // $19.99
  taxRateId: reducedVat.id,
});
console.log(bookTax.taxAmount);   // 140   ($1.40)
console.log(bookTax.grossAmount); // 2139  ($21.39)

// 7. Create a tax group for reduced-rate items
const reducedGroup = await taxService.createTaxGroup({
  name: "Reduced Rate",
  description: "Books, food, and other reduced-rate items",
});

// 8. List all German tax rates
const germanRates = await taxService.getTaxRatesByCountry("DE");
console.log(germanRates.length); // 2
germanRates.forEach(rate => {
  console.log(`${rate.name}: ${rate.rate}% (default: ${rate.isDefault})`);
});

Best Practices

1. Set a Default Rate per Country

Always configure a default tax rate for each country you operate in. This ensures tax can be calculated even when no specific rate is assigned:

// Set up defaults for each country
await taxService.createTaxRate({
  name: "US Sales Tax",
  rate: 0, // Federal level, override per state
  country: "US",
  isDefault: true,
});

await taxService.createTaxRate({
  name: "German MwSt",
  rate: 19,
  country: "DE",
  isDefault: true,
});

2. Use Tax Groups for Product Categories

Group products by their tax treatment to simplify rate management:

// Create groups for different tax treatments
const standard = await taxService.createTaxGroup({
  name: "Standard Rate",
  description: "Most goods and services",
});

const reduced = await taxService.createTaxGroup({
  name: "Reduced Rate",
  description: "Food, books, medicine",
});

const zeroRate = await taxService.createTaxGroup({
  name: "Zero Rate",
  description: "Exports and exempt items",
});

3. Handle Tax Calculation Errors

Always handle cases where a tax rate might not be found:

try {
  const result = await taxService.calculateTax({
    netAmount: 10000,
    country: "XX", // Unknown country
  });
} catch (error) {
  if (error.message.includes("not found")) {
    // No default tax rate for this country
    // Fall back to zero tax or prompt user
    console.error("No tax rate configured for this country");
  }
  throw error;
}

4. Keep Tax Rates Up to Date

Tax rates change over time. Deactivate old rates and create new ones rather than modifying existing rates to preserve historical accuracy:

// Tax rate changed: deactivate old, create new
await taxService.deactivateTaxRate(oldRateId);

const newRate = await taxService.createTaxRate({
  name: "Updated VAT 2025",
  rate: 21, // New rate
  country: "DE",
  isDefault: true,
});