Apps
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.
To follow along, you'll need the Swell CLI and a Swell account. First, install the CLI and log in.
npm install -g @swell/cli
swell loginNext, clone the example app and push it to your test environment.
git clone git@github.com:swellstores/tax-example-app.git
cd tax-example-app
npm install
swell app pushOnce installed, open Apps > Tax Example > Settings in your test environment dashboard and set the tax rate percentage.
The app declares a tax extension in swell.json, which the app's functions reference by its id:
{
"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"
}
]
}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.
{
"label": "Tax settings",
"description": "Example tax configuration settings",
"fields": [
{
"id": "rate",
"label": "Tax rate %",
"type": "number",
"ui": "float",
"digits": 2
}
]
}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:
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.
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.
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.