Skip to content

Billing & Plans

Billing is handled via Razorpay Subscriptions. Plans are defined in the plans table in the Central Registry and govern limits across all DotEvolve products.

Plans Table

plans (
  slug              text PRIMARY KEY,
  name              text NOT NULL,
  display_name      text,
  price_monthly     integer,
  price_yearly      integer,
  features          jsonb,
  max_users         integer,   -- -1 = unlimited
  max_workers       integer,
  max_job_steps     integer,
  max_article_attrs integer,
  rate_limit_max    integer,
  rate_limit_window integer,
  razorpay_plan_id  text,
  is_active         boolean
)

Default plans: starter (5 users), growth (20 users), enterprise (unlimited).

Self-Signup Flow

sequenceDiagram
    participant U as User
    participant P as portal.dotevolve.net/signup
    participant PA as Portal API
    participant SB as Supabase Auth
    participant RZP as Razorpay

    U->>P: Fill signup form (org, email, password, app, plan)
    P->>PA: POST /api/v1/tenants/signup
    PA->>SB: Create auth user
    PA->>PA: Create tenant (pending_payment)
    PA->>PA: Create app assignment + user role
    PA->>PA: Sync app_metadata
    PA->>RZP: Create customer + subscription
    RZP-->>PA: subscription_id, customer_id
    PA->>PA: Store Razorpay IDs on tenant
    PA-->>P: 201 Created
    P-->>U: "Signup Successful — Go to Login"

    note over RZP,PA: Later: payment confirmed
    RZP->>PA: POST /api/v1/webhooks/razorpay (subscription.activated)
    PA->>PA: Set tenant status = active
    PA->>PA: Trigger subdomain provisioning

Signup Endpoints

Method Path Auth Description
GET /api/v1/tenants/signup/apps public List apps available for self-signup
GET /api/v1/tenants/signup/plans public List active plans with pricing
POST /api/v1/tenants/signup public Atomic self-signup

Razorpay Webhook Events

Event Action
subscription.activated Set status: active, trigger subdomain provisioning, create alert
subscription.cancelled Set status: suspended, create alert
subscription.halted Set status: suspended, create alert
payment.failed Create alert for Super_Admin and Tenant_Admin

Webhook signatures are verified via HMAC-SHA256 using the Razorpay webhook secret.

Plan Limits in Downstream Services

dot-foot-factory-api fetches plan limits from dot-portal-api at request time (Redis-cached, 15 min TTL):

GET /api/v1/internal/tenants/:tenantId/plan-limits
x-service-secret: <secret>

The response merges plan defaults with tenant-level settings overrides. This replaces the old MongoDB Plan collection.

Billing Reminders

A daily cron job in dot-portal-api queries Razorpay for upcoming renewal dates and sends reminder emails via Resend at 90, 30, 15, 7, 3, 2, and 1 days before the billing date. Cancelled and suspended tenants are skipped.