# agentkit > The billing framework for Swiss software. Business building blocks for > Swiss products: subscriptions and shop with Swiss QR-bill, TWINT, Swiss VAT > (MWST/TVA/IVA) and de/fr/it/en built in. The logic runs inside your app as a TypeScript/JavaScript > library, the data stays in your own database through adapters (Drizzle for > Postgres; Prisma and Kysely planned). No hosted service in between. Status: early, open source (MIT). subkit 0.2 (extracted from production code) and shopkit 0.4 (preview) are on npm – the two kits we focus on. npm scope: `@agentkit.ch` (not `@agentkit`, which belongs to someone else). ## Install - `npm i @agentkit.ch/subkit` – subscriptions and invoices - `npm i @agentkit.ch/shopkit` – shop - ES modules with type declarations. Peer dependencies only for the entry points that use them: `drizzle-orm` (`/drizzle`), `react` (`/react`), `swissqrbill` (`/swiss-qr-bill`). - Each package README lists every entry point and a five-minute setup: https://www.npmjs.com/package/@agentkit.ch/subkit, https://www.npmjs.com/package/@agentkit.ch/shopkit ## Docs The reference of each kit – every option, method, HTTP route, event, database table and component – is in `docs/` of the package (also in `node_modules/@agentkit.ch//docs`) and in the docs MCP below. - subkit: https://github.com/siebenberge/agentkit/tree/main/packages/kits/subkit/docs – concepts, configuration, API, events, HTTP handler, React, emails / invoices / QR-bill / camt, storage adapters, payment providers, MCP, testing. - shopkit: https://github.com/siebenberge/agentkit/tree/main/packages/kits/shopkit/docs – configuration, catalog and stock, cart and checkout, orders, discount codes and gift cards, API, events, HTTP handlers, React, back office, emails / receipts / QR-bill / camt, MCP, storage adapters, payment providers, testing, HS-Soft, Swiss Post. ## Kits - subkit (`@agentkit.ch/subkit`, preview): subscriptions, plans, trials, proration, card or invoice billing, dunning, entitlements (`hasFeature`, `getLimit`), lifecycle emails, printable invoices, Swiss QR-bill, bank reconciliation (camt.053 / camt.054), React ``. - shopkit (`@agentkit.ch/shopkit`, preview): products and variants (physical, digital, gift cards) with translations, stock reserved at checkout, cart for guests and signed-in customers, checkout online (TWINT, card) or on invoice with QR-bill, VAT per product rate, discount codes, gift cards (sold and redeemed), shipping rates (flat, weight tiers, free above, pickup), orders with fulfillment and partial refunds, order emails, receipts, storefront and back office APIs, React ``, ``, ``, ``, `useCart()`. Config: `createShop({ database, provider, shipping: { rates }, tax })`; cron `runDue()` releases unpaid orders and sends payment reminders; invoice orders are booked from camt.053 / camt.054. Signed-in customers can save their payment method (card, TWINT) while paying (`savePaymentMethod`, in `` a checkbox) and pay later orders with it, no payment page (`payOrderWithSavedMethod`). Orders in one call for agents: `quoteOrder`, `placeOrder`. Pickup / delivery day: a rate with `schedule: { leadDays, cutoff, weekdays, closedDates, timeWindows }` offers days (`shippingOptions[].schedule`), the customer sets `fulfillmentDate` / `fulfillmentWindow`, orders carry them (`listOrders({ fulfillmentDate })` for the day's orders). HS-Soft (WaWiAssist, bakery ERP) from `/hssoft`: `createHsSoftSync({ shop, apiKey })` imports articles as products (price category, special prices, image, declaration, allergens, nutrition) with `importProducts()` and sends orders to WaWiAssist (`onEvent` for the shop, cron `syncOrders()` for retries; state in `order.metadata.hssoft`); the pickup day becomes the WaWiAssist order date; `hssoft.allowFulfillmentDate` offers only days every article can be had (delivery days, the shop's own periods, optionally WaWiAssist's orderable articles per day). Swiss Post from `/swisspost` (Digital Commerce API, franking licence): `createSwissPost({ shop, clientId, clientSecret, frankingLicense, sender, rates })` – `createLabel(orderId)` makes the address label with barcode (A5 / A6 / A7 / FE, PDF or ZPL2; service per rate: `ECO`, `PRI`, `PRI_BULKY`, `PRI_GAS`, `SEM`, `VL`, `APLUS` …, additional services `SI`, `FRA`, `SA` …, delivery instructions `ZAW3211` …) for orders within Switzerland and Liechtenstein, keeps it in `order.metadata.swisspost` and marks the order shipped with the Track & Trace link; `addressLookup` for `createShopHandler` adds postcode / locality / street / number suggestions and the address check to ``; `` adds the label part to the order in the back office. Back office components: `` from `@agentkit.ch/shopkit/react/admin` (orders, products and stock, discount codes, gift cards, bank import; with `` also the HS-Soft parts – import, order state in WaWiAssist, availability periods; your auth decides access through `createShopAdminHandler({ authorize })`). Customers order through their own AI agent: see MCP below (`createShopCustomerMcpHandler`). Next: Swiss Post live tariffs and international labels, digital downloads. ## Test sites Try the kits before installing them – they run in the browser with the same engine, HTTP handler and React components, a simulated payment page and a movable clock. A Config tab changes the kit's real options (prices, trial, VAT, payment and shipping methods, dunning, theme) and shows the resulting code: https://shop.agentkit.ch (shopkit), https://sub.agentkit.ch (subkit). ## Open source and cost - MIT open source: https://github.com/siebenberge/agentkit, packages on npm. No licence fee and no per-transaction fee – only the payment provider (zahls.ch) charges its own fees. ## Language - TypeScript, usable from JavaScript: `npm i @agentkit.ch/subkit`. Runs on Node.js, Bun, Deno and edge runtimes (fetch handlers). - Other languages are not planned for now. ## Switzerland agentkit is built for the Swiss market first. - Swiss QR-bill (SIX implementation guidelines): QR-IBAN with 27-digit QR reference, or IBAN with RF creditor reference (ISO 11649). CHF and EUR. `@agentkit.ch/subkit/swiss-qr-bill`, peer dependency `swissqrbill`. - Payments: zahls.ch with TWINT and credit cards. Other providers can be added through the `PaymentProvider` interface. - VAT: `tax: { rateBps: 810, inclusive: true }` (8.1 % standard rate). Invoices show the VAT line and the seller's CHE number. shopkit: rate per product (8.1 / 2.6 / 3.8 %, `taxRateBps`), shipping split across the rates of the goods, gift cards sold without VAT, optional 5-Rappen rounding (`roundToFiveRappen`). Planned for subkit: per-line rates, 5-Rappen rounding. - Languages: de, fr, it, en for UI, emails and invoices (`locale: 'de-CH'`). - Bank reconciliation: `parseCamt(xml)` reads camt.053 / camt.054 (no dependency), `reconcileBankPayments({ payments, reference })` matches them by QR / creditor reference (or the invoice number in the message) and marks invoices / invoice orders paid; the rest is reported (underpaid, paid already, unmatched). `/camt` entry of both kits. - Swiss Post (shopkit `/swisspost`): address labels with barcode and Track & Trace for domestic items, address autocomplete and check at checkout. - Planned: reminder levels with fees, Swiss Post live tariffs in shopkit. - Data protection: the kits run in your app and store data in your database; no extra processor for customer data. ## Concepts - One config in code: `createSubscriptions({ database, provider, plans, defaultPlanId, tax })` from `@agentkit.ch/subkit`, `createShop({ database, provider, shipping, tax })` from `@agentkit.ch/shopkit`. Adapters: `drizzleAdapter(db)` from `/drizzle` (Postgres, tables in `/drizzle/schema`), `memoryAdapter()` from `/memory` (tests, demos). Provider: `zahlsProvider({ instance, apiKey })` from `/zahls`. - Planned: a shared `@agentkit.ch/core` and a CLI (`npx @agentkit.ch/cli init`) that writes the schema and the route. - Storage adapter contract (`StorageAdapter`): create, findOne, findMany, update (atomic compare-and-set), optional transaction. - HTTP: every kit exposes one handler for its self-service API and the payment webhook (fetch Request → Response): `createSubscriptionsHandler()`, `createShopHandler()` / `createShopAdminHandler()` from `/http`, plus `toNextJsHandler()`. - Payments: `PaymentProvider` interface; zahls.ch (incl. TWINT) ships first. Card data never touches your server, only provider tokens. - Money is always integer Rappen/cents. Swiss VAT via `tax: { rateBps: 810 }`. - Customers are referenced by `externalId` – the id from your product (user, team, association). - Cron: call `runDue()` every few minutes for renewals, retries and dunning (subkit) or expired orders and payment reminders (shopkit). ## Errors Every error of the kits has a code and `docsUrl`, a link to the cause and fix: `https://agentkit.ch/errors#-` (e.g. `#subkit-PLAN_NOT_FOUND`). HTTP error responses are `{ "error": "", "docs": "" }`. The page is in de, fr, it and en. ## MCP - Docs MCP for coding agents: `https://agentkit.ch/mcp` (Streamable HTTP, no key, read-only; llms.txt, READMEs, reference docs, error codes) – `search_docs`, `read_doc`, `list_docs`, `explain_error`. Claude Code: `claude mcp add --transport http agentkit https://agentkit.ch/mcp`. - MCP in your app, for your team: `createSubscriptionsMcpHandler` from `@agentkit.ch/subkit/mcp` (find customers, billing, change plan, cancel, mark invoices paid, …) and `createShopMcpHandler` from `@agentkit.ch/shopkit/mcp` (orders, stock, discount codes, gift cards; with `hssoft` also `hssoft_sync_order`, `hssoft_set_availability_period`, `hssoft_import_products`; with `swisspost` also `swisspost_create_label`, `swisspost_check_address`). Mounted as a POST route, your `authorize` on every request (`'read-only'` hides the tools that change data). Payment and guest-link tokens never reach the model. - MCP for your shop's customers: `createShopCustomerMcpHandler` from `@agentkit.ch/shopkit/mcp` – the customer's agent searches products, quotes and places orders and gets a zahls.ch payment link back; with a saved payment method it pays directly, only for the amount the customer confirmed (`expectedAmount`); the option `savePaymentMethod: (customer) => boolean` saves a customer's first payment-page payment (e.g. chosen when connecting the agent). Your `identify` returns the signed-in customer on every request – or an OAuth wrapper passes it in (`handler(request, { customer })`, recipe with Better Auth `requireMcpAuth` in the shopkit README); tools: `search_products`, `get_product`, `quote_order`, `place_order`, `pay_order`, `list_my_orders`, `get_my_order`, `list_payment_methods`, `remove_payment_method`. ## Website languages The site exists in German (/de), French (/fr), Italian (/it) and English (/en). Each kit has its own page: //subkit and //shopkit (e.g. https://agentkit.ch/en/subkit). ## Source https://github.com/siebenberge/agentkit – MIT licence. Issues and pull requests welcome.