Quickstart

Create a Stripe client and check your first entitlement.

Set your Stripe secret key:

.env.local
STRIPE_SECRET_KEY=sk_xxx

Install the SDK:

npm install @fuime/billing-sdk

Create the client and check an entitlement:

lib/billing.ts
import { createEnhancedClient } from "@fuime/billing-sdk";
import { stripe } from "@fuime/billing-sdk/stripe";

export const billing = createEnhancedClient({
  provider: stripe({ apiKey: process.env.STRIPE_SECRET_KEY! }),
  cache: { ttlMs: 60_000 }, // Cache for 1 minute
  plans: {
    prod_pro: { features: ["api", "export", "analytics"] },
    prod_enterprise: { features: "*" }, // All features
  },
});
app/api/data/route.ts
import { billing } from "@/lib/billing";

export async function GET(request: Request) {
  const userId = getUserId(request);

  if (!(await billing.hasFeature(userId, "api"))) {
    return Response.json({ error: "Upgrade required" }, { status: 403 });
  }

  // User has API access
  return Response.json({ data: "..." });
}

That's it. The SDK caches entitlements and auto-invalidates when webhooks arrive.

Get full entitlement details

const entitlement = await billing.getEntitlement(userId);
// { active: true, productId: 'prod_pro', periodEnd: Date }

Set up webhooks

Create a webhook endpoint to auto-invalidate the cache:

app/api/webhooks/billing/route.ts
import { billing } from "@/lib/billing";

export async function POST(request: Request) {
  const body = await request.text();
  const signature = request.headers.get("stripe-signature")!;

  const event = await billing.parseWebhook(body, signature);

  // Cache is automatically invalidated for the affected user
  console.log(event.type, event.userId);

  return new Response("ok");
}