@qazuor/qzpay-cli
@qazuor/qzpay-cli
Tooling View on npm @qazuor/qzpay-cli
CLI tool for scaffolding complete QZPay billing setups.
Installation
# Global installationpnpm add -g @qazuor/qzpay-cli
# Or as dev dependencypnpm add -D @qazuor/qzpay-cliCommands
init
The init command scaffolds a complete billing setup through an interactive wizard:
# Interactive modepnpm qzpay init
# Specify output directorypnpm qzpay init --dir ./src/billing
# Skip prompts and use defaultspnpm qzpay init --yesWhat it does
The wizard guides you through:
-
Project Info
- Project name (kebab-case)
- Output directory
- Description (optional)
-
Payment Provider Selection
- Stripe
- MercadoPago
- Both (multi-provider)
-
Storage Adapter
- Drizzle + PostgreSQL (recommended for production)
- In-memory (for development/testing)
-
Framework Integration
- Hono (fast, lightweight)
- NestJS (enterprise)
- Library only (no HTTP layer)
-
Features
- Subscriptions (recurring billing)
- One-time payments
- Usage-based billing
- Marketplace (multi-vendor via Stripe Connect)
- Add-ons
-
Plan Configuration
- Freemium: Free + Pro + Enterprise
- Tiered: Basic + Professional + Agency
- Usage-based: Starter + Growth + Business + Enterprise
- Custom plans
Generated Files
Based on your selections, the CLI generates:
Core Files (Always Generated)
| File | Description |
|---|---|
qzpay.config.ts | Main billing configuration |
.env.example | Environment variables template |
types.ts | TypeScript type definitions |
plans.ts | Plan creation script |
services.ts | Business logic services |
Framework-Specific Files
Hono:
routes.ts- API routeswebhooks.ts- Webhook handlers
NestJS:
billing.module.ts- NestJS modulebilling.service.ts- Injectable servicewebhooks.controller.ts- Webhook controllerwebhooks.ts- Webhook handlers
Generated Configuration
qzpay.config.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';
// Database connectionconst sql = postgres(process.env.DATABASE_URL!);const db = drizzle(sql);
// Create billing instanceexport const billing = createQZPayBilling({ storage: createQZPayDrizzleAdapter(db), paymentAdapter: createQZPayStripeAdapter({ secretKey: process.env.STRIPE_SECRET_KEY! }), livemode: process.env.NODE_ENV === 'production'});
// Event listenersbilling.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);});.env.example
# DatabaseDATABASE_URL=postgresql://user:pass@localhost:5432/billing
# StripeSTRIPE_SECRET_KEY=sk_test_xxxSTRIPE_WEBHOOK_SECRET=whsec_xxxSTRIPE_PUBLISHABLE_KEY=pk_test_xxx
# MercadoPago (if selected)MERCADOPAGO_ACCESS_TOKEN=TEST-xxxMERCADOPAGO_WEBHOOK_SECRET=xxxMERCADOPAGO_PUBLIC_KEY=TEST-xxx
# Server (if framework selected)PORT=3000HOST=localhostservices.ts
import { billing } from './qzpay.config';
// Customer managementexport async function registerCustomer(email: string, name: string) { return billing.customers.create({ email, name });}
export async function getCustomer(customerId: string) { return billing.customers.get(customerId);}
// Subscription managementexport async function subscribeToPlan(customerId: string, planId: string) { return billing.subscriptions.create({ customerId, planId });}
export async function changePlan(subscriptionId: string, newPlanId: string) { return billing.subscriptions.changePlan(subscriptionId, { newPlanId });}
export async function cancelSubscription(subscriptionId: string) { return billing.subscriptions.cancel(subscriptionId, { atPeriodEnd: true });}
// Payment historyexport async function getPaymentHistory(customerId: string) { return billing.payments.getByCustomerId(customerId);}
export async function getInvoices(customerId: string) { return billing.invoices.getByCustomerId(customerId);}plans.ts
Script to create your plans in the payment provider:
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
async function createPlans() { // Create Pro plan const proProduct = await stripe.products.create({ name: 'Pro Plan', description: 'Professional features' });
const proMonthly = await stripe.prices.create({ product: proProduct.id, unit_amount: 2900, // $29.00 currency: 'usd', recurring: { interval: 'month' } });
const proYearly = await stripe.prices.create({ product: proProduct.id, unit_amount: 29000, // $290.00 currency: 'usd', recurring: { interval: 'year' } });
console.log('Plans created!'); console.log('Pro Monthly:', proMonthly.id); console.log('Pro Yearly:', proYearly.id);}
createPlans();Run with: npx tsx plans.ts
After Scaffolding
-
Copy environment variables:
Terminal window cp .env.example .env# Fill in your actual credentials -
Install dependencies:
Terminal window pnpm install -
Create plans in payment provider:
Terminal window npx tsx plans.ts -
Run database migrations (if using Drizzle):
Terminal window pnpm drizzle-kit push -
Start your application:
Terminal window pnpm dev
CLI Options
qzpay init [options]
Options: -d, --dir <directory> Output directory (default: ".") -y, --yes Skip prompts and use defaults -h, --help Display help