JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 975
  • Score
    100M100P100Q95274F

Reusable invoicing API for Hono + better-auth apps

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 zod

Quick 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 → invoice
  • POST/GET /invoices/:invoiceId/payments — record / list payments
  • GET/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