Welcome to the Jose Madrid Salsa developer docs — explore features, APIs, and deployment guides.
Jose Madrid SalsaJMS Docs

Tax Calculation

Automated sales tax calculation via Stripe Tax API with jurisdiction breakdowns, wholesale exemptions, and graceful fallback

Tax Calculation

Sales tax is calculated using the Stripe Tax API, which automatically determines applicable rates based on the shipping address jurisdiction. The system supports tax exemptions for wholesale accounts and gracefully falls back to zero tax if the API fails.

Architecture

tax-calculator.ts
stripe.ts

How It Works

Tax Calculation Input

interface TaxCalculationInput {
  lineItems: Array<{
    amount: number      // Amount in cents
    reference: string   // Product ID or SKU
    taxCode?: string    // Stripe Tax Code (default: txcd_99999999)
  }>
  shippingAddress: {
    line1: string
    city: string
    state: string
    postalCode: string
    country: string
  }
  customerEmail?: string  // For tax exemption lookup
}

Tax Calculation Result

interface TaxCalculationResult {
  taxAmount: number          // Total tax in cents
  taxAmountDecimal: number   // Total tax in dollars
  taxRate: number            // Effective rate as percentage
  taxBreakdown: Array<{
    jurisdiction: string     // e.g., "California", "San Francisco County"
    rate: number             // Jurisdiction-specific rate
    amount: number           // Tax from this jurisdiction
  }>
  taxExempt: boolean         // Whether customer is exempt
}

Tax Exemptions

Before calling Stripe Tax, the system checks if the customer has a wholesale account with tax-exempt status:

async function checkTaxExemption(customerEmail?: string): Promise<boolean> {
  const user = await prisma.user.findUnique({
    where: { email: customerEmail },
    include: { wholesaleAccount: true },
  })

  return (
    user?.wholesaleAccount?.status === 'APPROVED' &&
    !!user.wholesaleAccount.resaleNumber
  )
}

Tax-exempt customers receive a result with taxAmount: 0 and taxExempt: true.

Stripe Tax API

The calculator creates a Stripe Tax calculation with:

  • Line items with amounts and tax codes
  • Customer shipping address as the tax jurisdiction
  • address_source: 'shipping' for destination-based taxation
  • Expanded line_items.data.tax_breakdown for jurisdiction details
const calculation = await stripe.tax.calculations.create({
  currency: 'usd',
  line_items: input.lineItems.map((item) => ({
    amount: item.amount,
    reference: item.reference,
    tax_code: item.taxCode || 'txcd_99999999', // General tangible goods
  })),
  customer_details: {
    address: { ... },
    address_source: 'shipping',
  },
})

Frontend Estimate

The getTaxEstimate() function provides a simplified estimate for real-time UI updates as the user types their address. It calls the full calculateTax() with a placeholder street address since tax is determined by city/state/ZIP.

Error Handling

If Stripe Tax returns an error, the calculator returns zero tax rather than blocking checkout. This ensures the checkout flow is never interrupted by tax calculation failures. Errors are logged for admin review.

Configuration Validation

The validateTaxConfiguration() function performs a test calculation against a known US address (San Francisco, CA 94111). It can be called during app startup or health checks to surface Stripe Tax misconfiguration early.

How is this guide?

Edit on GitHub

Last updated on

On this page