The billing framework for Swiss software.

Two TypeScript libraries: subkit for subscriptions and invoices, shopkit for your online shop. They run inside your app, with QR-bill, VAT and four languages. Payments go through zahls.ch with TWINT and card, and the data stays in your database.

Try the demo

No per-transaction fee · data in your database

acme.ch/account/billing
Your app<BillingPortal />

Plan & invoices

Acme AG

Basic

active

CHF 9.00 / month

Pro

CHF 19.00 / month

Switch to Pro
Payment methodTWINT

Invoices

2026-0142

15.10.2026 · TWINT

CHF 9.00paid

2026-0141

15.09.2026 · QR

CHF 9.00paid
2
kits: subkit for subscriptions, shopkit for your online shop
4
languages: German, French, Italian, English
0
customer records on our servers
MIT
open source, no per-transaction fee

In use at

  • Thurbeck
  • Brauerei St. Johann
  • Membear

The kits

Pick what your product needs.

Each kit works on its own, and both share one adapter, one customer and one payment provider.

subkitPreview

Subscriptions & invoices

For SaaS, memberships and club fees

Your customers pick a plan and pay by TWINT, card or QR-bill. subkit renews, prorates, sends reminders and matches payments with your bank.

  • Plans, trials, proration
  • Card, TWINT or QR-bill
  • Reminders & retries
  • VAT on every invoice
  • Entitlements & limits
  • Billing portal UI
MonthlyYearly

Pro

CHF 19.00

/ month

14 days free
Choose Pro
TWINTVISAMASTERCARDQR

shopkitPreview

Commerce

For club shops, SMEs, merch and gift cards

Products with variants, cart and checkout with TWINT or on invoice. shopkit reserves stock, works out shipping and VAT per product and sends the order confirmation.

  • Products & variants
  • Cart & checkout with TWINT or invoice
  • Orders & refunds
  • Stock & shipping rates by weight
  • Discount codes
  • Gift vouchers
  • Connection to HS-Soft (WaWiAssist)
  • Swiss Post labels & address check
  • Ordering through AI agents (MCP)
  • Back office to embed
  • Pickup and delivery day with time window

Cart

Club scarf29.00
Home jersey, M89.00
Shipping9.00
TotalCHF 127.00
Pay with TWINT

New in shopkit 0.2 · Ordering through AI agents

Your customers order in the chat.

Your shop becomes an MCP server. Your customers’ agent – Claude, ChatGPT or Cursor – finds products, prices the order with VAT and shipping, and places it. Payment goes through a zahls.ch link or straight to the saved TWINT. For every shopkit shop, no extra service.

  • Sign-in with OAuth – Claude and ChatGPT connect without a token
  • Only the amount the customer confirmed is charged
  • Shipping, pickup or delivery day with time window – the agent asks
  • Payment tokens never reach the model
import { createShopCustomerMcpHandler } from '@agentkit.ch/shopkit/mcp'Guide in the README
AgentMCP · Rösterei Aare

Two bags of the house blend and a descaler, by post please.

search_productshouse blend, descaler

quote_order

2 × House blend 500 g37.00

Descaler12.90

PostPac Priority9.00

TotalCHF 58.90

Pay CHF 58.90 with your saved TWINT?

Yes, please.

place_orderexpectedAmount: 5890

TWINT …

New in shopkit 0.2 · For bakeries

HS-Soft (WaWiAssist) connected.

For bakeries and confectioners on WaWiAssist: products come from WaWiAssist, and every order lands there as a WaWiAssist order – with the pickup day as the order date. Whether placed in the web shop or through an agent.

  • Import with price category, special price, image, declaration, allergens and nutrition
  • Only pickup days on which every article in the cart can be had
  • If HS-Soft is unreachable, shopkit sends the order again later
  • State and resend in the back office and through MCP
import { createHsSoftSync } from '@agentkit.ch/shopkit/hssoft'Guide in the README

Articles → products

WaWiAssist

  • A1Zopf 500 g6.80
  • A7Farmhouse loaf5.20
  • A12Grittibänz4.50

shopkit

  • Zopf 500 gimported
  • Farmhouse loafimported
  • Grittibänzfrom 1.11.

Order → WaWiAssist

shopkit

#2187 · CHF 18.80

Pickup 31.10.2026

WaWiAssist

—

New in shopkit 0.4 · Swiss Post

Swiss Post labels and addresses.

One click in the order and the label with barcode is ready – with the order’s shipping method, billed to your franking licence. At checkout Swiss Post suggests postcode, locality, street and house number and checks the address before the order is placed.

  • PostPac Economy and Priority, bulky goods, Swiss-Express «Moon», VinoLog and A Mail Plus
  • A5, A6 or A7 as PDF or ZPL2 for the label printer
  • Additional services such as signature, fragile or Saturday delivery
  • Tracking number with Track & Trace in the shipping e-mail
import { createSwissPost } from '@agentkit.ch/shopkit/swisspost'Guide in the README

<Checkout />

Street and number

Bahnhofst

Postcode and city

8001 Zürich

Address confirmed by Swiss Post

#1044

A6 · PRI

1.2 kg

Create label

Rösterei Aare

Aarstrasse 12

3011 Bern

PRI

Anna Muster

Bahnhofstrasse 12

8001 Zürich

99.60.123456.00000001

Tracking number —

Don’t vibe-code it

Money is the wrong place to vibe-code.

A coding agent writes you a QR-bill and a TWINT checkout in an hour. The bugs only show up in production: payments booked twice, rounding differences, invoices the bank rejects. Let your agent wire in code that has already proven itself instead.

Vibe-coded billing6 ✗

  • QR reference with a wrong check digitThe banking app rejects the payment.
  • The same webhook arrives twiceThe payment is booked twice.
  • VAT in floating-point numbersRounding differences between invoice and books.
  • Plan change mid-monthProration is off, the customer pays too much.
  • Partial payment in camt.054Invoice marked paid while money is missing.
  • Two checkouts, one item in stockYou sell what you no longer have.

Typical bugs that only show up in production.

With agentkit

Proven code.

Your coding agent doesn’t reinvent billing, it wires in a kit. The code comes from Membear, where it runs in production, and covers exactly these cases.

  • From production at Membear
  • Tested against real Postgres
  • Whole Rappen, idempotent webhooks, compare-and-set

Add subscriptions with QR-bill and TWINT using @agentkit.ch/subkit. Read https://agentkit.ch/llms.txt first.

Features

Everything around the money, done once.

What both kits bring: a coding agent that wires them in, webhooks that count only once, emails in four languages and ready-made screens.

Your coding agent wires it in

llms.txt, typed options and errors with fixed codes. One prompt to a working checkout.

llms.txt
  • Read llms.txt2s
  • Detected Next.js + Drizzle4s
  • Installed @agentkit.ch/subkit9s
  • Added the tables to the schema14s
  • Set up /api/billing21s
  • Tested checkout with TWINT38s

Webhooks that count once

Idempotent webhooks and compare-and-set updates: if the same payment arrives twice, it is still booked only once.

When

A TWINT payment arrives

CHF 19.00 · 2026-0143

Then

  • Mark the invoice as paid
  • Unlock the Pro plan
  • Send the receipt in French
200The same webhook, againignored, already booked

Self-service out of the box.

Drop-in React components for the boring screens, plus a typed client. Headless hooks when you want your own.

import { BillingPortal } from '@agentkit.ch/subkit/react'
  • <BillingPortal />subkit
  • <Checkout />shopkit
  • <Cart />shopkit
  • <OrderStatus />shopkit

Your database, your tables

The kits write to your database through adapters. JOIN them with your own tables – no sync, no silo.

select o.*, c.name from shop_orders o
join customers c on c.id = o.customer_external_id
numberpayment_statuspayment_methodtotal
1039refundedonline2900

Every email, in four languages

Receipts, reminders and order confirmations as HTML and text, with your mailer.

de

Deine Quittung für Pro

Acme AG

fr

Votre commande #1042 est confirmée

Boutique Léman

it

Promemoria: fattura 2026-0142

FC Lugano Nord

46° 48′ N · 8° 14′ E

Swiss by default

Not localised later. Swiss from the first line.

Generic billing libraries think in Stripe, cents and one language. Swiss customers pay by QR-bill and TWINT, expect VAT on every invoice and read it in German, French or Italian. agentkit starts there.

Payment part

Currency

CHF

Amount

228.00

Account / Payable to

CH44 3199 9123 0008 8901 2
Acme AG
Bahnhofstrasse 1
8001 Zürich

Reference

21 00000 00003 13947 14300 09017

Additional information

Invoice 2026-0142 · Club Pro, annual plan
incl. 8.1 % VAT CHF 17.08 · CHE-123.456.789 VAT

Payable by

FC Seebach
Dorfstrasse 12
8052 Zürich
paid
nextReminders, Swiss style

For developers

A library in your app. Not a service in front of it.

Mounted as a route in Next.js, Hono, SvelteKit, Remix or Express – on Node.js, Bun, Deno or at the edge. TypeScript, usable from JavaScript too.

One prompt

Your coding agent reads llms.txt, detects your framework and database, writes the schema and sets up the route.

~/acme

> Add subscriptions with subkit▍

Configuration in code

Plans, payment provider and VAT in one file. No dashboard to keep in sync.

import { createSubscriptions } from '@agentkit.ch/subkit';
import { drizzleAdapter } from '@agentkit.ch/subkit/drizzle';
import { zahlsProvider } from '@agentkit.ch/subkit/zahls';
import { db, env } from './db';

export const billing = createSubscriptions({
  // your Postgres, your tables
  database: drizzleAdapter(db),
  provider: zahlsProvider({ instance: 'acme', apiKey: env.ZAHLS_KEY }),
  plans: [
    { id: 'free', name: 'Free', features: [], limits: {}, prices: {} },
    {
      id: 'pro',
      name: 'Pro',
      features: ['export'],
      limits: {},
      prices: { month: { amount: 1900, currency: 'CHF' } },
    },
  ],
  defaultPlanId: 'free',
  tax: { rateBps: 810 }, // Swiss VAT 8.1 %
});

MIT

Read it, change it, run it yourself.

Your database

Postgres through Drizzle – or your own adapter.

No backend of ours

Nothing phones home.

Whole Rappen

Money is never a floating-point number.

Why agentkit

We have built all of this before.

For Membear, our club management software, we built QR-bills, TWINT via zahls.ch, VAT, bank reconciliation and invoices in four languages. The pitfalls were rarely in the code but in the details: reference numbers, rounding, deadlines, translations.

Then we noticed that every Swiss product rebuilds exactly that. Generic billing tools think in Stripe, cents and English – Switzerland comes, if at all, as a plugin.

So we are extracting the code from production and turning it into kits any TypeScript app can use. Free, and open source under MIT.

The siebenberge team

Open source

Open source under MIT.

subkit and shopkit are on GitHub under the MIT licence, the packages are on npm. Read the code, change it and run it yourself – no per-transaction fee and no dependency on us.

01

MIT licence

Free for commercial use, including closed-source software.

02

No lock-in

The code runs in your app, the data lives in your database. A fork is all it takes to carry on without us.

03

Built in the open

Roadmap, issues and pull requests are public – contributions welcome.

Roadmap

Extracted from production, one kit at a time.

Every kit comes from code that already runs in production and is pulled out once it has proven itself.

  1. 01now

    subkit + shopkit

    on npm

    subkit 0.2 and shopkit 0.4 as @agentkit.ch/subkit and @agentkit.ch/shopkit, the code under MIT on GitHub: QR-bill, bank reconciliation (camt.053 / camt.054), VAT, zahls.ch with TWINT, Drizzle adapter for Postgres. New in shopkit: ordering through AI agents (MCP), the HS-Soft (WaWiAssist) connection, the back office to embed and Swiss Post labels with address check.

  2. 02

    core + CLI

    next

    A shared core with an adapter test suite, a CLI for schema and route, the docs in German too. In shopkit: Swiss Post live tariffs and refunds through zahls.ch.

  3. 03

    Dunning & adapters

    2027

    1st, 2nd and 3rd reminder with fees and a reminder PDF with a new QR-bill. Prisma and Kysely adapters.

Questions

Asked often.

Still unsure? The demos show the kits with their real options.

01What is the difference between subkit and shopkit?

subkit bills recurring payments: plans, subscriptions, trials and invoices – for SaaS, memberships or club fees. shopkit sells products: catalogue, cart, checkout, orders and gift cards. Both share customer data, the payment provider and the QR-bill.

02Do I need both kits?

No. Each kit works on its own. A club with membership fees and a fan shop takes both, a SaaS usually just subkit.

03Can my customers order through an AI agent?

Yes, since shopkit 0.2. createShopCustomerMcpHandler turns your shop into an MCP server: the customer’s agent – Claude, ChatGPT or Cursor – finds products, prices the order with VAT and shipping, and places it. Payment goes through a zahls.ch link or the saved payment method, and only the confirmed amount is charged. Your sign-in decides who orders (OAuth or API key).

04Does shopkit work with HS-Soft (WaWiAssist)?

Yes. @agentkit.ch/shopkit/hssoft imports the articles from WaWiAssist as products and sends every order back as a WaWiAssist order, with the pickup day as the order date. All you need is the API key of your WaWiAssist from HS-Soft.

05Does shopkit create Swiss Post shipping labels?

Yes, since shopkit 0.4. @agentkit.ch/shopkit/swisspost creates the label with barcode from the order – in the back office, through the API or MCP – and sends the customer the tracking number with Track & Trace. At checkout it suggests Swiss Post addresses and checks them. You need a franking licence and access to the Digital Commerce API of Swiss Post. Labels for items abroad and live tariffs are planned.

06Is agentkit really open source?

Yes. subkit and shopkit are on github.com/siebenberge/agentkit under the MIT licence, the packages are on npm. Issues and pull requests are welcome.

07Where does my customers’ data live?

In your database. The kits run as a library inside your app and write to your tables through adapters. There is no agentkit backend and no additional data processor.

08Which payment methods are supported?

TWINT and credit cards through zahls.ch, plus invoices with the Swiss QR-bill. Other providers plug in through the PaymentProvider interface.

09What does agentkit cost?

The kits are free. We take no per-transaction fee – you only pay your payment provider.

10Which frameworks are supported?

TypeScript, usable from JavaScript too. The kits mount as a route in Next.js, Hono, SvelteKit, Remix or Express and run on Node.js, Bun, Deno or at the edge. They write the data to Postgres through the Drizzle adapter; adapters for Prisma and Kysely are planned.

11Can I use it today?

Yes: npm i @agentkit.ch/subkit or npm i @agentkit.ch/shopkit. subkit comes from code that runs in production; shopkit is in preview. Try them without installing: sub.agentkit.ch and shop.agentkit.ch.

Build your product, not your billing.

Copy the setup prompt into your coding agent – or try the kits in the browser first.

Setup prompt for your coding agent

Add subscriptions with QR-bill and TWINT using @agentkit.ch/subkit. Read https://agentkit.ch/llms.txt first.

Try the demo