Package Exports
- invoicing-kit
- invoicing-kit/testing
Readme
invoicing-kit
Reusable invoicing API for Hono apps using better-auth.
Status: v0 in development. The Plan 1 milestone ships the adapter layer only — domain types, repository interfaces, default Prisma adapter, in-memory test adapter. HTTP routes ship in Plan 2.
Install
bun add invoicing-kit
# Also needed (peer deps):
bun add @prisma/client better-auth hono @hono/zod-openapi zodQuick look — adapter layer
import { prismaAdapter } from "invoicing-kit";
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
const repos = prismaAdapter(prisma);
const client = await repos.clients.create({
organizationId: "org_123",
name: "Acme",
});See the design spec for the full architecture.
Quick start
import { createInvoicingKit, prismaAdapter } from "invoicing-kit";
import { Hono } from "hono";
import { PrismaClient } from "@prisma/client";
import { auth } from "./auth"; // your better-auth instance with organization plugin
const prisma = new PrismaClient();
const bills = createInvoicingKit({
adapter: prismaAdapter(prisma),
auth,
basePath: "/api/bills",
});
const app = new Hono();
app.route("/", bills.router);
app.route("/api/auth", auth.handler); // your own better-auth mount
export default app;The package mounts these routes (under basePath):
POST/GET/GET/PATCH/DELETE /clients[/:id]POST/GET/GET/PATCH/DELETE /products[/:id]POST/GET/GET/PATCH/DELETE /taxes[/:id]POST/GET/GET/PATCH/DELETE /payment-methods[/:id]POST/GET/GET/PATCH/DELETE /quotes[/:id]POST/GET/GET/PATCH/DELETE /invoices[/:id]POST /invoices/from-quote/:quoteId— convert quote → invoicePOST/GET /invoices/:invoiceId/payments— record / list paymentsGET/DELETE /payments/:id
Linking products to your domain objects
A line item normally references an existing product by productId. It can
instead reference one of your own domain objects (an experience, course, plan,
…) via source, and the kit will find-or-create the backing product for you —
keyed on (organization, sourceType, sourceId):
// existing path — reference a product directly
{ "productId": "…", "quantity": "1", "price": "5000", "taxIds": [] }
// source path — reference your own object; product is created on first use
{ "source": { "type": "experience", "id": "42", "name": "Sunset Tour" },
"quantity": "2", "price": "5000", "taxIds": [] }Provide exactly one of productId / source. The product is created once
(price defaults from the line item's minor units) and reused on later sales;
the line item still carries its own price/description, so it remains the
immutable snapshot of the sale. Product exposes the same sourceType /
sourceId on create and read for catalog lookups.
License
MIT