Hanzo
Hanzo Skills Reference

Hanzo Billing - Subscription and Payment Management Portal

Hanzo Billing is a multi-org billing portal for managing subscriptions, payments, credits, invoices, and usage across the Hanzo ecosystem. Static-exported Next.js 16 app with `@hanzo/ui` components...

Overview

Hanzo Billing is a multi-org billing portal for managing subscriptions, payments, credits, invoices, and usage across the Hanzo ecosystem. Static-exported Next.js 16 app with @hanzo/ui components, RainbowKit wallet integration, and IAM OIDC/PKCE auth. Served via nginx on K8s. Live at billing.hanzo.ai (also commerce.hanzo.ai).

Why Hanzo Billing?

  • Multi-org: Auto-detects org from hostname (hanzo, lux, zoo, pars) with per-org IAM, branding, and theme
  • Subscription tiers: Developer (free/5credit),Pro(5 credit), Pro (49/mo), Team ($199/mo), Enterprise, Custom
  • Web3 payments: RainbowKit + wagmi + viem for wallet-based payments across 7 chains
  • IAM-integrated: OIDC/PKCE login via Casdoor (hanzo.id, lux.id, zoo.id, pars.id)
  • Commerce API: Backend via api.hanzo.ai for subscriptions, invoices, credits, transactions
  • Static export: next build produces static HTML served by nginx (no Node.js runtime)

Tech Stack

  • Framework: Next.js 16 (static export via output: 'export')
  • UI: @hanzo/ui (billing components), Tailwind CSS 4, Geist font
  • Web3: RainbowKit 2, wagmi 2, viem 2 (Ethereum, Polygon, Optimism, Arbitrum, Base, Avalanche, BSC)
  • Auth: Self-contained OIDC/PKCE module (lib/iam-auth.ts), no external auth package
  • Serving: nginx:alpine with security headers, gzip, health check at /health
  • Image: ghcr.io/hanzoai/billing:latest
  • Dev port: 3005

OSS Base

Repo: hanzoai/billing.

When to use

  • Managing subscription plans and billing for Hanzo/Lux/Zoo/Pars orgs
  • Viewing and paying invoices
  • Adding/managing payment methods (card + crypto wallet)
  • Topping up API credits
  • Viewing transaction history and usage
  • Configuring spend alerts
  • Managing business profile and tax compliance
  • Account member management with role-based access

Hard requirements

  1. Hanzo IAM configured at hanzo.id (or per-org IAM server) for OIDC/PKCE auth
  2. Commerce API at api.hanzo.ai for backend billing operations
  3. GHCR access for container image (ghcr.io/hanzoai/billing)

Quick reference

ItemValue
UIhttps://billing.hanzo.ai
Alt domainhttps://commerce.hanzo.ai
Dev serverpnpm dev (port 3005)
Buildpnpm build (static export to out/)
Imageghcr.io/hanzoai/billing:latest
K8s namespacehanzo
K8s port80 (nginx)
AuthOIDC/PKCE via hanzo.id
Commerce APIapi.hanzo.ai
Repogithub.com/hanzoai/billing
Package@hanzo/billing (private, v0.1.0)

One-file quickstart

Local development

git clone https://github.com/hanzoai/billing.git
cd billing
pnpm install
pnpm dev          # http://localhost:3005

Production build

pnpm build        # Static export to out/
# Serve with nginx or any static file server

Docker

# Build
docker build -t billing .

# Or use pre-built deploy image (requires out/ already built)
docker build -f Dockerfile.deploy -t billing .

# Run
docker run -p 80:80 billing

Core Concepts

Architecture

┌─────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│  billing.hanzo.ai│────>│  Hanzo IAM       │     │  Commerce API   │
│  (Next.js static)│     │  (hanzo.id)      │     │  (api.hanzo.ai) │
│  served by nginx │     │  OIDC/PKCE auth  │     │  billing backend│
└────────┬────────┘     └──────────────────┘     └─────────────────┘

    ┌────┴──────────┐
    │  RainbowKit   │
    │  (7 EVM chains)│
    └───────────────┘

Multi-Org Configuration

The app auto-detects organization from the hostname:

Hostname containsOrgIAM ServerTheme Color
luxLuxlux.id#6366f1 (indigo)
zooZoozoo.id#22c55e (green)
parsParspars.id#f59e0b (amber)
defaultHanzohanzo.id#ffffff (white)

All orgs share api.hanzo.ai as their Commerce API backend.

Auth Flow

Self-contained OIDC/PKCE implementation in lib/iam-auth.ts:

  1. User lands on billing portal, org detected from hostname
  2. If not logged in, starts PKCE flow: generates code_verifier, computes code_challenge
  3. Redirects to IAM authorize endpoint (/oauth/authorize) with S256 challenge
  4. On callback, exchanges authorization code for tokens via /oauth/token
  5. JWT stored in sessionStorage; user info parsed from JWT payload
  6. Also supports implicit flow (access_token in query/hash)

Subscription Plans

Five tiers defined in lib/config.ts, synced with Commerce API:

PlanPriceRequests/minTokens/min
DeveloperFree ($5 credit)60100K
Pro49/mo(49/mo (39 annual)5001M
Team199/mo(199/mo (159 annual)2,0005M
Enterprise$9,999/mo50,000100M
CustomContact salesCustomCustom

App Routes

RoutePurpose
/Main billing dashboard (BillingShell)
/auth/callbackOAuth callback handler
/plansSubscription plan selection
/commerceCommerce dashboard with admin components
/topupCredit top-up page
/transactionsTransaction history
/payment-methodsPayment method management

Key Billing Components (lib/billing/)

  • overview-dashboard.tsx - Main dashboard with balance, usage, plan summary
  • subscription-portal.tsx - Plan selection and management
  • payment-manager.tsx - Card and wallet payment methods
  • invoice-manager.tsx - Invoice viewing and payment
  • cost-explorer.tsx - Detailed cost breakdown
  • credits-panel.tsx - Credit grants and balance
  • transactions-panel.tsx - Transaction history
  • spend-alerts.tsx - Budget alert configuration
  • account-members.tsx - Team member management
  • business-profile-panel.tsx - Business info for invoicing
  • tax-compliance-panel.tsx - Tax ID and compliance
  • card-form.tsx / square-card-form.tsx - Card input forms

Admin Access

Admin emails (admin@hanzo.ai, zach@hanzo.ai, ant@hanzo.ai) have super-user billing access and can grant credits to any user. Checked via isAdminUser() in lib/config.ts.

CI/CD

Three deployment targets from ci.yml:

  1. GitHub Pages: Static export with /billing basePath (for docs/preview)
  2. Docker (GHCR + K8s): Builds ghcr.io/hanzoai/billing:latest, deploys to hanzo namespace
  3. Cloudflare Pages: Optional (gated by DEPLOY_CLOUDFLARE var), credentials fetched from KMS

Troubleshooting

IssueCauseSolution
"Redirecting to sign in" loopIAM callback URL mismatchVerify redirect_uri matches /auth/callback path
Wallet connect failsMissing WalletConnect project IDSet NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID
Wrong org themeHostname detectionCheck getOrgByHost() logic in lib/config.ts
Static export errorSSR code in client componentsUse 'use client' directive, lazy-load wallet providers
GitHub Pages 404Missing basePathSet GITHUB_PAGES=true for /billing prefix
  • hanzo/hanzo-id.md - IAM and authentication (OIDC/PKCE provider)
  • hanzo/hanzo-commerce-api.md - Commerce API backend
  • hanzo/hanzo-ui.md - Shared UI components (@hanzo/ui/billing)
  • hanzo/hanzo-payments.md - Payment processing
  • hanzo/hanzo-cloud.md - Cloud dashboard

How is this guide?

Last updated on

On this page