README
PayKit is a payments orchestration framework for TypeScript. It sits between your app and payment providers like Stripe or PayPal, giving you a unified API. Webhooks are verified and normalized automatically. Your database owns the subscriptions, invoices, and usage records — no provider lock-in.
Configuration
import { createPayKit } from "paykitjs"
import { stripe } from "@paykitjs/stripe"
import { drizzleAdapter } from "paykitjs/adapters/drizzle"
export const paykit = createPayKit({
database: drizzleAdapter(db),
providers: [
stripe({
secretKey: env.STRIPE_SECRET_KEY,
webhookSecret: env.STRIPE_WEBHOOK_SECRET,
}),
],
on: {
"subscription.activated": async ({ subscription, customer }) => {
await sendEmail(customer.email, "Welcome to Pro!")
},
"payment.succeeded": async ({ payment }) => {
console.log("Payment received", payment)
},
},
})// app/api/paykit/[...path]/route.ts
import { paykit } from "@/lib/paykit"
// Handles webhooks and client API requests
export const { GET, POST } = paykit.handlerSupported Providers
Features
01Unified API
One API, every provider.
Stripe, PayPal, and regional PSPs behind a single TypeScript interface. Swap providers with config, not rewrites.
+ Custom
02Subscriptions
Provider-native, unified.
Create, cancel, pause, resume — using each provider's own billing engine behind one consistent API.
trialing
active
past_due
canceled
03Checkout
Payments in minutes.
One-time payments, hosted checkout. Pass an amount and description — no product catalog needed.
pk.checkout({ amount: 990 })
URL
04Webhook Engine
Normalized events.
Stripe's invoice.payment_failed and PayPal's BILLING.SUBSCRIPTION.PAYMENT.FAILED both become one typed event.
billing.invoice.failed*
payment.failed
05Your Database
You own the state.
Prisma and Drizzle adapters sync everything to your DB. Business logic reads from your tables, not provider APIs.
prisma
drizzle
+
06Type-Safe
End-to-end types.
Zod-validated inputs, typed events, plugin endpoints that merge into paykit.api.* automatically.
PayKitEvent<"payment.failed">
Unified API
One API for checkout, subscriptions, invoices, and events — regardless of which payment provider you use.
const checkout = await paykit.api.createCheckout({
customerId: "user_123",
amount: 9900, // $99.00
description: "Lifetime License",
successURL: "https://myapp.com/success",
cancelURL: "https://myapp.com/cancel",
attachMethod: true,
});
// redirect user to checkout.urlconst subscription = await paykit.api.createSubscription({
customerId: "user_123",
amount: 2900, // $29/mo
interval: "month",
description: "Pro Plan",
trialDays: 14,
});
// cancel at period end
await paykit.api.cancelSubscription({
id: subscription.id,
mode: "at_period_end",
});const paykit = createPayKit({
// ...
on: {
"subscription.activated": async ({ subscription, customer }) => {
await sendEmail(customer.email, "Welcome to Pro!");
},
"payment.succeeded": async ({ payment }) => {
console.log("Payment received:", payment.id);
},
"invoice.payment_failed": async ({ invoice, error }) => {
await alertTeam(invoice.customerId, error);
},
},
});const invoices = await paykit.api.listInvoices({
customerId: "user_123",
status: "paid",
limit: 10,
});
const invoice = await paykit.api.getInvoice({ id: "inv_abc" });
// invoice.pdfURL → download link
// invoice.total → amount in cents
// invoice.status → "paid"Own your payments with confidence in minutes.