Database
How PayKit stores and syncs billing state locally.
PayKit uses your app's PostgreSQL database to store billing state. Entitlement checks are fast local queries, not provider API calls. No round-trips to Stripe on every check().
Configuration
Pass a pg.Pool instance or a connection string to createPayKit.
import { Pool } from "pg";
export const paykit = createPayKit({
database: new Pool({
connectionString: process.env.DATABASE_URL,
}),
// ...
});// Or pass a connection string directly
export const paykit = createPayKit({
database: process.env.DATABASE_URL,
// ...
});Tables
PayKit creates tables prefixed with paykit_. The key ones are:
PayKit owns these tables. Don't write to them directly. Use the PayKit API.
Migrations
paykitjs push applies any pending migrations. Run it on initial setup and whenever you update your plan configuration.
pnpm dlx paykitjs pushWhat's synced
PayKit keeps two sources of truth in sync:
From webhooks (provider to database): Subscriptions, invoices, payment methods, and customer-provider ID mappings are synced automatically when provider events arrive.
From your config (code to database): Plans, products, and features are synced from your createPayKit configuration when you run paykitjs push. Each time you change a plan and push, a new version is created. Previous versions are kept so running instances can continue serving existing subscriptions.