Goal: first paying customer on the Blog product. A real person lands on vlozi.app → signs up → pays via Razorpay → publishes a post, with money reaching a business bank account.
Why Blog first: @vlozi/blog is published (v2.0.0+), has a full test suite, and blog-service already enforces credits on publish (creditGuard). It's the lowest-risk paid product. Other modules stay "coming soon" for this launch.
Key finding (2026-05-31): verification against current code showed the serve+charge infra is already built — signup CTAs are wired, and blog publish already debits/refunds credits with an audit trail. The gate to launch is business + payment paperwork and live-secret provisioning, not feature code.
Track A — Business & Payments (the long-pole — start first, runs in parallel)
Razorpay will not pay out until KYC clears, and KYC needs a registered entity + business bank account. This is the critical path.
- Decide the entity. Recommended to start: India Sole Proprietorship + GST (fastest; days, not weeks; Razorpay accepts it; convertible to Pvt Ltd at fundraise). Choose Pvt Ltd/LLP instead only if raising money soon.
- Register the entity and obtain PAN/GST as required for the chosen structure.
- Open a business current account in the entity's name.
- Complete Razorpay KYC on the live account (business proof + bank account + PAN/GST). See
docs/billing/razorpay-setup-guide.md. - Create live Razorpay plans and capture the plan IDs:
- Scripts already exist:
scripts/create-razorpay-plans.mjs,scripts/set-razorpay-plan-ids.sql. - Plan tiers in
core-databaseschema:basic,starter,pro,business(monthly + yearly, INR).
- Scripts already exist:
- Get live Razorpay keys + webhook secret for production provisioning (Track C).
⚠️ Never paste live Razorpay keys (or any live secret) into chat or commit them. Set them only via
wrangler secret(Track C).
Track B — Code (nearly complete)
- Signup loop wired —
apps/websitenav + Hero + FinalCTA link togo.vlozi.app/registerand/login(apps/website/lib/constants.ts). - Blog publish enforces credits —
apps/blog-service/src/routes/admin/posts.ts:id/publishusescreditGuard({ cost: "BLOG_POST_PUBLISH" }): debit, refund-on-failure, idempotent re-publish,creditTransactionsaudit. Covered byapps/blog-service/test/publish-flow.test.ts. - MFA-stuck branch handled — 2FA-enable UI is disabled ("(soon)") in
settings/security/page.tsx, and the email-login MFA branch now throws a clear error instead of a silentnull(api/auth/[...nextauth]/route.ts). For v1, email accounts can't enter the 2FA state; Google OAuth + non-2FA email both work. - (Optional, decide later) Blog scheduled-publishing (currently publish-now only). Defer unless a launch customer needs it; if added, use a Durable Object alarm (per the cron→DO pattern), not a polling cron — pre-launch crons are intentionally paused.
Track C — Provisioning live secrets (blocked on Track A, do right before launch)
Set via wrangler secret put <NAME> per worker. Minimum set for the Blog wedge:
| Service | Where | Secrets |
|---|---|---|
| Neon Postgres | manager, blog-service, gateway | DATABASE_URL (+ service-specific DB URLs) |
| Razorpay (live) | manager | live key id/secret, webhook secret, plan IDs (Track A) |
| Resend | communication | RESEND_API_KEY, RESEND_WEBHOOK_SECRET (vlozi.app already verified) |
| Google OAuth | seller-dashboard (Vercel env) | GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET |
| Gateway/service auth | all workers | GATEWAY_SECRET, INTERNAL_KEY, API_KEY_ENCRYPTION_KEY (manager) |
| Cloudflare | all workers | KV bindings + service bindings (already in wrangler.toml) |
Social OAuth (X/Meta/LinkedIn) is not needed for the Blog wedge.
See docs/billing/DEPLOY-CHECKLIST.md for the billing-specific deploy steps.
Track D — End-to-end verification (gate before charging anyone)
Run the full new-customer loop against production with live keys, as a controlled test (use a real card you control / Razorpay test-then-live discipline):
- From vlozi.app, click Get Started → land on
go.vlozi.app/register. - Sign up via Google OAuth → complete
/onboarding→ land on/dashboardwith a free workspace + base credits provisioned. /dashboard/settings/billing→ start a paid plan → complete the Razorpay modal → confirm the subscription shows active and the webhook fired (/manager/billing/payment/verify).- Open Blog → create and publish a post → confirm credits debit and the post renders via
@vlozi/blog(test againstapps/blog-test). - Drain credits → confirm publish is blocked with a clear upgrade prompt.
- Run existing tests green:
apps/blog-service(incl.publish-flow.test.ts),@vlozi/blogsuite,@repo/core-billing.
Launch gate: when steps 1–6 pass and Track A KYC is live → you can serve and charge real people. That is the moment.
Out of scope for this launch
- Content-Engine, Chatbot, Brain, Contact-Intelligence, Newsletter as paid products (visible as "coming soon" only).
- Stripe / USD billing (schema columns exist, code does not).
- Full email-login MFA verification (deferred; 2FA UI stays disabled for v1).