Installation

how to install and configure PayKit in your app

Steps

1

Install the package

Let's start by adding PayKit to your project:

pnpm add paykitjs
2

Create the PayKit instance

Create a file named paykit.ts anywhere in your app.

Usually you would put it somewhere in src/, src/lib/.

Import createPayKit and export your paykit instance. This is the main server entry point for all billing.

paykit.ts
import { createPayKit } from "paykitjs";

export const paykit = createPayKit({
  // ...
});
3

Configure Stripe

PayKit uses Stripe for billing. Pass your Stripe keys directly to the PayKit instance.

paykit.ts
export const paykit = createPayKit({
  // ...
  stripe: {
    secretKey: process.env.STRIPE_SECRET_KEY!,
    webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
  },
});
4

Configure database

PayKit needs a database to store billing state, such as subscriptions. You can create a separate database, or simply plug it into the app's own db.

Pass a connection string directly, or pg.Pool.

paykit.ts
import { Pool } from "pg";

export const paykit = createPayKit({
  // ...
  database: new Pool({
    connectionString: process.env.DATABASE_URL!,
  }),
});

It works by creating a few tables prefixed with paykit_. You can learn more here.

5

Mount request handler

To handle webhooks and client API requests, you need to set up a request handler on your server.

Create a new file or route in your framework's designated catch-all route handler. This route should handle requests for the path /paykit/* (unless you've configured a different base path).

src/app/paykit/[[...slug]]/route.ts
import { paykitHandler } from "paykitjs/handlers/next";
import { paykit } from "@/lib/paykit";

export const { GET, POST } = paykitHandler(paykit);
6

Create client instance

The client-side library helps you interact with the server. PayKit client sdk suitable for almost all modern frameworks, including React.

src/lib/paykit-client.ts
import { createPayKitClient } from "paykitjs/client";
import type { paykit } from "@/server/paykit";

export const paykitClient = createPayKitClient<typeof paykit>();

To use client we also need to authenticate incoming requests on the server, to do this, add the identify option to your server instance.

paykit.ts
export const paykit = createPayKit({
  // ...
  identify: async ({ headers }) => {
    const session = await auth.api.getSession({ headers });
    if (!session) return null;
    return {
      customerId: session.user.id,
      email: session.user.email,
      name: session.user.name,
      // Just pass user's data, and Stripe customer gets synced automatically!
    };
  },
});
7

Define your products

Optionally. PayKit provides a code-first way to create your plans, and a very useful usage billing with track() and report() out of the box.

By defining you products in code don't have to touch Stripe's dashboard at all. It automatically syncs your pricing with your provider, and you unlock a full type-safety with inferred ID types!

products.ts
import { feature, plan } from "paykitjs";

const messages = feature({ id: "messages", type: "metered" });
const proModels = feature({ id: "pro_models", type: "boolean" });

export const free = plan({
  id: "free",
  name: "Free",
  group: "base",
  default: true,
  includes: [
    messages({ limit: 100, reset: "month" })
  ],
});

export const pro = plan({
  id: "pro",
  name: "Pro",
  group: "base",
  price: { amount: 19, interval: "month" },
  includes: [
    messages({ limit: 2000, reset: "month" }), 
    proModels()
  ],
});

Then pass your products to the main options:

paykit.ts
import { free, pro } from "./products";

export const paykit = createPayKit({
  // ...
  products: [free, pro],
});

This is an example setup for AI chat app. Read further on how to build your own billing config.

8

Push changes to DB

PayKit includes a CLI tool to keep your database in sync with your configuration.

pnpm dlx paykitjs push

This applies database migrations and syncs your plan definitions to provider's products.
Run it once on setup, and every time after you change your products configuration.
For production deployments, see the CLI reference.

On this page