Quick Start
Quick Start
This guide will help you set up a basic billing integration with QZPay using Stripe.
Choose Your Setup Method
The CLI provides the fastest way to get started:
-
Install the CLI
Terminal window pnpm add -D @qazuor/qzpay-cli -
Initialize your project
Terminal window pnpm qzpay initThis interactive wizard will:
- Ask which payment provider to use (Stripe, MercadoPago)
- Ask which storage adapter to use (Drizzle)
- Ask which framework to integrate with (Hono, NestJS)
- Create the configuration file
- Generate service files
-
Configure environment variables
Copy the generated
.env.exampleto.env:Terminal window cp .env.example .envFill in your actual credentials:
Terminal window DATABASE_URL=postgresql://user:pass@localhost:5432/billingSTRIPE_SECRET_KEY=sk_test_xxxSTRIPE_WEBHOOK_SECRET=whsec_xxx -
Run database migrations
Terminal window pnpm drizzle-kit push -
Create plans in Stripe
Run the generated plans script:
Terminal window npx tsx plans.ts
Your QZPay setup is ready. The CLI creates a qzpay.config.ts file you can import in your application.
-
Install the packages
Terminal window pnpm add @qazuor/qzpay-core @qazuor/qzpay-stripe @qazuor/qzpay-drizzle stripe drizzle-orm postgres -
Set up the database schema
Configure Drizzle with the QZPay schema:
drizzle.config.ts import { defineConfig } from 'drizzle-kit';export default defineConfig({schema: './node_modules/@qazuor/qzpay-drizzle/dist/schema',out: './drizzle',dialect: 'postgresql',dbCredentials: {url: process.env.DATABASE_URL!}});Run migrations:
Terminal window pnpm drizzle-kit push -
Initialize the billing service
src/billing.ts import { createQZPayBilling } from '@qazuor/qzpay-core';import { createQZPayStripeAdapter } from '@qazuor/qzpay-stripe';import { createQZPayDrizzleAdapter } from '@qazuor/qzpay-drizzle';import { drizzle } from 'drizzle-orm/postgres-js';import postgres from 'postgres';const sql = postgres(process.env.DATABASE_URL!);const db = drizzle(sql);export const billing = createQZPayBilling({storage: createQZPayDrizzleAdapter(db),paymentAdapter: createQZPayStripeAdapter({secretKey: process.env.STRIPE_SECRET_KEY!,webhookSecret: process.env.STRIPE_WEBHOOK_SECRET})}); -
Create your first customer
const customer = await billing.customers.create({email: 'user@example.com',name: 'John Doe',metadata: {userId: 'usr_123'}});console.log('Customer created:', customer.id); -
Create a subscription
// First, ensure you have a plan configured in Stripeconst subscription = await billing.subscriptions.create({customerId: customer.id,planId: 'price_xxx' // Your Stripe price ID});console.log('Subscription created:', subscription.status); -
Handle webhooks
src/routes/webhooks.ts import { Hono } from 'hono';import { createWebhookRouter } from '@qazuor/qzpay-hono';import { createQZPayStripeAdapter } from '@qazuor/qzpay-stripe';import { billing } from '../billing';const stripeAdapter = createQZPayStripeAdapter({secretKey: process.env.STRIPE_SECRET_KEY!,webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!});const app = new Hono();const webhookRouter = createWebhookRouter({billing,paymentAdapter: stripeAdapter});app.route('/webhooks/stripe', webhookRouter);export default app;
Full Example
Here’s a complete example with Hono:
import { Hono } from 'hono';import { createQZPayBilling } from '@qazuor/qzpay-core';import { createQZPayStripeAdapter } from '@qazuor/qzpay-stripe';import { createQZPayDrizzleAdapter } from '@qazuor/qzpay-drizzle';import { createQZPayMiddleware, createBillingRoutes, createWebhookRouter} from '@qazuor/qzpay-hono';import { drizzle } from 'drizzle-orm/postgres-js';import postgres from 'postgres';
// Database setupconst sql = postgres(process.env.DATABASE_URL!);const db = drizzle(sql);
// Create adaptersconst storage = createQZPayDrizzleAdapter(db);const stripeAdapter = createQZPayStripeAdapter({ secretKey: process.env.STRIPE_SECRET_KEY!, webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!});
// Billing setupconst billing = createQZPayBilling({ storage, paymentAdapter: stripeAdapter});
// Event handlersbilling.on('subscription.created', async (event) => { console.log('New subscription:', event.data.id);});
billing.on('payment.succeeded', async (event) => { console.log('Payment received:', event.data.amount);});
// App setupconst app = new Hono();
// Add QZPay middlewareapp.use('*', createQZPayMiddleware({ billing }));
// Mount billing routesconst billingRoutes = createBillingRoutes({ billing });app.route('/api/billing', billingRoutes);
// Mount webhook handlerconst webhookRouter = createWebhookRouter({ billing, paymentAdapter: stripeAdapter});app.route('/webhooks/stripe', webhookRouter);
export default app;Next Steps
- Learn about Core Concepts
- Explore Stripe Integration
- Set up Webhook Handling