# Build a tax integration

Source: https://developers.swell.is/apps/build-a-tax-integration-tutorial

In this tutorial, we'll build a tax calculation integration using a Swell tax extension. The example applies a flat configurable rate, and the same patterns apply to integrating any tax calculation service with Swell.

The scope of the app includes the following:

- A tax extension that provides tax calculation for a store.
- App settings for tax configuration.
- An app function that returns item and order taxes when Swell calculates taxes for a cart or order.

→ Find the full source code for the tax example app on GitHub.

## Getting started

To follow along, you'll need the Swell CLI and a Swell account. First, install the CLI and log in.

```txt
npm install -g @swell/cli

swell login
```

Next, clone the example app and push it to your test environment.

```txt
git clone git@github.com:swellstores/tax-example-app.git

cd tax-example-app

npm install

swell app push
```

Once installed, open Apps > Tax Example > Settings in your test environment dashboard and set the tax rate percentage.

## App configuration

The app declares a tax extension in `swell.json`, which the app's functions reference by its `id`:

`swell.json`

```json
{
  "description": "A tax service example app",
  "id": "tax_example",
  "name": "Tax Example",
  "type": "integration",
  "version": "1.0.0",
  "permissions": [],
  "extensions": [
    {
      "id": "example",
      "type": "tax",
      "description": "An example tax service integration"
    }
  ]
}
```

## Tax settings

The example keeps its configuration simple: a single tax rate percentage the merchant can set. A real integration would typically hold the tax service's API credentials here instead.

`settings/config.json`

```json
{
  "label": "Tax settings",
  "description": "Example tax configuration settings",
  "fields": [
    {
      "id": "rate",
      "label": "Tax rate %",
      "type": "number",
      "ui": "float",
      "digits": 2
    }
  ]
}
```

## Calculating taxes

When Swell calculates taxes for a cart or order — for example, when the customer enters their address at checkout — the platform triggers the `order.taxes` event hook. The app handles it with a single function:

`functions/calculate.ts`

```typescript
import { getAppConfigSettings, roundToDecimals } from "./lib";

export const config: SwellConfig = {
  extension: "example",
  description: "Provide tax rates from Example Tax Service",
  model: {
    events: ["order.taxes"],
    conditions: {},
  },
};

export default async function (req: SwellRequest) {
  const { items } = req.data;
  const settings = await getAppConfigSettings(req);
  const taxRate = roundToDecimals(settings.rate / 100);

  const taxedItems = (items || []).map((item: any) => ({
    id: item.id,
    taxes: [
      {
        id: "example-tax",
        amount: roundToDecimals(item.price_total * taxRate),
      },
    ],
  }));

  const totalTax = taxedItems.reduce((sum: number, item: any) => {
    return sum + item.taxes[0].amount;
  }, 0);

  return {
    items: taxedItems,
    taxes: [
      {
        id: "example-tax",
        amount: roundToDecimals(totalTax),
        rate: taxRate,
      },
    ],
  };
}
```

The handler returns two things: an order-level `taxes` array — each entry with an `id`, `amount`, and `rate` — and optional item-level tax details under `items`, keyed by item id. Swell applies these to the order's tax totals.

The handler receives the order data on `req.data`, including items with prices and the shipping address. A real integration would send these to the tax service's calculation API and map its response into the same shape. Note the consistent use of `roundToDecimals` — keeping rounding consistent between item taxes and the order total avoids off-by-a-cent discrepancies.

## Testing

With the app pushed and a rate configured in settings:

- Add an item to a cart in your test storefront and proceed through checkout — taxes appear on the cart at the configured rate.
- Watch function invocations and errors under Developer > Console (Logs tab), or with the `swell logs` CLI command.

## Next steps

To adapt this app to a real tax service, replace the flat-rate calculation with a call to the service's API using credentials from app settings, and map its response into the taxes arrays. For the complete extension configuration and event reference, see the Extensions guide.

The tax example app is meant as a reference for partners to learn and build from, but it is not ready for production. Review it carefully and verify calculations with your tax provider before using any of it in a live store.
