Adapters
Drizzle
Database adapter for Drizzle ORM
Setup
import { drizzleAdapter } from "@billsdk/drizzle-adapter";
database: drizzleAdapter(db, {
schema,
provider: "pg", // "pg" | "mysql" | "sqlite"
})Schema (PostgreSQL)
import { integer, jsonb, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
export const customer = pgTable("customer", {
id: uuid("id").primaryKey().defaultRandom(),
externalId: text("external_id").unique(),
email: text("email").notNull(),
name: text("name"),
providerCustomerId: text("provider_customer_id"),
metadata: jsonb("metadata"),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at").defaultNow().notNull(),
});
export const subscription = pgTable("subscription", {
id: uuid("id").primaryKey().defaultRandom(),
customerId: uuid("customer_id").references(() => customer.id, { onDelete: "cascade" }).notNull(),
planCode: text("plan_code").notNull(),
interval: text("interval").default("monthly").notNull(),
status: text("status").default("active").notNull(),
providerSubscriptionId: text("provider_subscription_id"),
providerCheckoutSessionId: text("provider_checkout_session_id"),
currentPeriodStart: timestamp("current_period_start").defaultNow().notNull(),
currentPeriodEnd: timestamp("current_period_end").notNull(),
canceledAt: timestamp("canceled_at"),
cancelAt: timestamp("cancel_at"),
trialStart: timestamp("trial_start"),
trialEnd: timestamp("trial_end"),
scheduledPlanCode: text("scheduled_plan_code"),
scheduledInterval: text("scheduled_interval"),
metadata: jsonb("metadata"),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at").defaultNow().notNull(),
});
export const payment = pgTable("payment", {
id: uuid("id").primaryKey().defaultRandom(),
customerId: uuid("customer_id").references(() => customer.id).notNull(),
subscriptionId: uuid("subscription_id"),
type: text("type").notNull(), // "subscription" | "renewal" | "upgrade" | "refund"
status: text("status").notNull(), // "pending" | "succeeded" | "failed" | "refunded"
amount: integer("amount").notNull(),
currency: text("currency").default("usd").notNull(),
providerPaymentId: text("provider_payment_id"),
refundedAmount: integer("refunded_amount"),
metadata: jsonb("metadata"),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at").defaultNow().notNull(),
});For MySQL/SQLite, adapt the types accordingly.
Migrations
npx drizzle-kit push