Mindlap
← All projects

Web + MCP

Billing Builder

An embeddable, agent-built billing widget - plans, paid-feature gating, and live billing state - that drops into any MindLap app.

Want the product? Enter your email to try it live.

About this project

Billing Builder is an embeddable billing layer for MindLap apps, generated end-to-end by the agent factory. It models plans, billing types, payment methods, and per-feature entitlements, then exposes a billing-state resolution API so any product can check in real time whether a user can activate a paid feature. The frontend ships as a self-contained widget - a billing page plus an embed entry point with its own routing - built on reusable primitives aligned to the Halo design system, while the backend covers schema migrations, repository primitives, and a billing summary aggregation that rolls usage into a single state endpoint.

Demo

At a glance

8.2h

Agent hours

87M

Tokens

2

Laps

11

Stories

87M

tokens

Others · 100%

Tokens by stage

Implement

50M

Code Review

7M

Fix

8M

Merge

21M

Auth Review

1M

Pipeline

Stage

Runs

Tokens

Duration

Implement

20

50M

3.7h

Code Review

14

7M

1.4h

Fix

3

8M

1.5h

Merge

7

21M

1.6h

Auth Review

1

1M

0.1h

Engines used

Others

Tokens

87M

Runs

45

Agent hours

8.2h

Success

48.9%

Agent team

developer

28 runs · 6.7h

13 passed · 15 failed

engineering_manager

15 runs · 1.5h

9 passed · 6 failed

Artifacts

PRD

markdown

BillingBuilder - Product Requirements Document


1. Overview

1.1 Problem Statement

Product teams building SaaS, API, and infrastructure products need a way to attach pricing and billing to individual features without building custom checkout infrastructure from scratch. Wiring up a payment flow per feature requires significant engineering effort: designing pricing pages, integrating with a payment processor, handling subscriptions and proration, managing entitlements, and tracking usage.

BillingBuilder solves this by giving product owners a no-code configuration wizard that produces embeddable billing pages, fully integrated with Razorpay, ready to drop into any existing product.

1.2 Product Vision

A self-serve tool that lets any product owner configure pricing and generate a production-ready billing page for any product feature in under 15 minutes, without writing code.

1.3 Scope (v1)

  • Single organisation (not a multi-tenant SaaS platform)
  • One billing unit (meter) per feature config
  • Razorpay as the payment processor (Subscriptions for recurring, Orders for one-time)
  • Embeddable billing page delivered as iframe, JS snippet, or React component
  • Post-authentication end-user interactions only

Note: Multi-tenancy, multiple meters per feature, and additional payment processors are explicitly out of scope for v1.

1.4 Out of Scope (v1)

  • Multi-tenant mode (multiple companies using BillingBuilder)
  • Multiple simultaneous usage meters per feature
  • Payment processors other than Razorpay
  • Pre-authentication public-facing marketing pricing pages
  • Revenue dashboards and analytics beyond basic subscriber counts
  • Custom billing cycles (quarterly, bi-annual, etc.)

2. Users and Roles

BillingBuilder serves two distinct user types with separate surfaces.

RoleWho they arePrimary surfaceKey actions
Product Owner (Admin)Internal team member configuring billing for a product featureAdmin Config DashboardCreate/edit configs, define tiers, publish embed code
End User (Customer)Authenticated user of the product owner's app, post-loginEmbedded Billing PageSubscribe, upgrade, downgrade, cancel, view invoices

3. Admin Configuration Flow

The admin creates a billing config via a 7-step wizard. Configs are saved as drafts until explicitly published.

3.1 Step 1 - Feature Identifier

  • Feature ID - internal lowercase slug (e.g. ai-summarize). Unique within the org, validated on input.
  • Feature Flag Key - exact key checked by the backend to gate access. Flipped ON on activation and OFF on cancellation.
  • Display Name - user-facing title shown on the billing page.
  • Description - optional subtitle. Communicates feature value before plan selection.

3.2 Step 2 - Billing Unit

Each feature has exactly one unit (single meter).

  • Standard Catalog - pre-built units: API calls, Tokens, Seats / Users, GB storage, GB bandwidth, Events, Renders, Minutes, Tasks, Messages, Credits, Documents, Queries, Workflows.
  • Custom Unit - custom label (e.g. "Frames processed") and optional plural form.

3.3 Step 3 - Billing Method

MethodDescriptionBest for
Flat subscriptionFixed price per billing period, independent of usageUnlimited access, seat-based features
MeteredCharge per unit consumed; backend reports usage via APIAPI, compute, AI inference features
TieredPrice per unit changes at defined volume bracketsFeatures where heavier users pay less per unit
Credits / PrepaidUsers buy credit packs upfront; usage deducts from balanceUnpredictable usage, prepaid wallet model
One-time chargeSingle payment; entitlement is time-bounded or perpetualTools, templates, one-off access grants

Selecting "One-time charge" skips Step 5 (Trial Period), since trials only apply to recurring subscriptions.

3.4 Step 4 - Define Tiers

Per-tier configuration: Name, Base price ($), Billing period (Monthly and/or Annual - a toggle appears on the billing page if any tier offers both), Included units, Overage price ($ per unit) (leave blank to hard-cap), Hard-cap toggle, Recommended flag.

Razorpay Plan sync - On publish, one Razorpay Plan is created per tier × billing period combination. Plan IDs are stored on the Tier record. Plan creation is idempotent. A price change creates a new Plan; existing subscribers migrate at their next renewal.

3.5 Step 5 - Trial Period

Optional free trial for recurring tiers. Skipped for one-time billing.

  • Trial duration - number of days (0 = no trial).
  • Per-tier application - trial enabled/disabled independently per tier.

Trial mechanics: Razorpay collects the payment mandate at trial start (no charge during trial). Status is trial until trialEndsAt; feature flag enabled immediately. End user notified 3 days before expiry; first charge date displayed at signup. On trial end, subscription auto-converts to paid and the first charge is collected.

3.6 Step 6 - Preview

A live render of the billing page using the admin's actual tier config. No real payments in preview mode. Toggle Desktop / Mobile viewports. Captures the billing recurrence setting: Recurring (Razorpay Subscription) or One-time (Razorpay Order).

3.7 Step 7 - Embed and Publish

TypeHow it worksBest for
iframeURL with signed config JWT. Append orgId, userId, authToken as query params.Quickest integration; no frontend dependency
JS Snippet<script> tag mounting a shadow-DOM component into a <div>. Context via window.BillingConfig.Teams wanting more layout control
React Componentnpm package. Props: token, orgId, userId. Auth token from app session.React apps; tight integration with app state
Export JSONFull config as structured JSON for AI-assisted analysis (Claude, Gemini, etc.).Config audits, documentation, pricing review

Config token and publish action - Publishing generates a signed HS256 JWT encoding featureId, config version, and allowed origins. Allowed origins must be configured before publishing. Publish increments the config version, syncs Razorpay Plans, activates the embed token, and sets status to live. Rollback to any previous version is available post-publish.


4. End-User Billing Page

The billing page is an embeddable component loaded post-authentication in the product owner's app. The host app passes orgId, userId, and a signed auth JWT.

4.1 Entry and State Detection

  • JWT validated server-side on load. Invalid or expired token shows an error state with no data leaked.
  • Page queries active Subscription for (featureId, orgId).
  • No subscription → Checkout view.
  • Active or trial subscription → Management view.
  • Cancelled but not yet expired → Management view with expiry notice and reactivate option.

4.2 Checkout Flow

Tier comparison - All tiers displayed side by side: name, price, billing period, included units, overage rate, trial info, CTA. Tiers with a trial show "Start free trial"; others show "Select plan". Monthly/annual toggle appears if any tier offers both periods. Recommended tier visually emphasised.

Plan selection and payment - On selection the user sees the exact first charge date and amount. Recurring: backend creates a Razorpay Subscription, frontend opens Razorpay Checkout for mandate + first payment. One-time: backend creates a Razorpay Order and opens Checkout.

Entitlement activation - On successful webhook: Subscription record created, feature flag flipped ON for orgId, confirmation shown, page transitions to Management. Webhook handlers use razorpaySubscriptionId as idempotency key.

4.3 Management View

  • Current tier name, price, next renewal date
  • Trial countdown if applicable (with first charge date)
  • End-of-period usage summary (units consumed in current billing period)
  • Invoice history (links to Razorpay-generated invoices)
  • Actions: Change tier, Cancel subscription

4.4 Tier Change (Upgrade / Downgrade)

Proration amount shown before confirmation.

  • Upgrade: prorated charge collected immediately via Razorpay subscription update API.
  • Downgrade: credit applied to next invoice. No immediate charge. New tier effective immediately.
  • On confirmation: Razorpay subscription plan updated, Subscription record updated, feature flag payload updated if tiers gate different capabilities.

4.5 Cancellation Flow

Pre-cancellation screen shows last access date, what will be lost, and (if multiple tiers exist) a downgrade alternative. On confirmation: backend calls POST /subscriptions/:id/cancel with {cancel_at_cycle_end: true}. Status stays active until period end. On the period-end webhook, feature flag is flipped OFF and status set to cancelled. User can reactivate before period end.


5. Data Model

5.1 Feature

featureId (PK, slug), featureFlagKey, displayName, description?, billingUnit, billingMethod (flat|metered|tiered|credits|one-time), recurrence (recurring|one-time), trialDays (0 = none, recurring only), configVersion, status (draft|live|archived), embedToken, publishedAt?.

5.2 Tier

tierId (PK), featureId (FK), name, basePrice, billingPeriod (monthly|annual), includedUnits? (null = unlimited), overagePricePerUnit? (null = hard-cap), hardCap, recommended, displayOrder, razorpayPlanId? (null until published).

5.3 Subscription

subscriptionId (PK), featureId (FK), tierId (FK), orgId (FK), razorpaySubscriptionId?, status (trial|active|paused|cancelled|expired), currentPeriodStart, currentPeriodEnd, cancelAtPeriodEnd, trialEndsAt?.

5.4 UsageEvent

eventId (PK), featureId (FK), orgId, quantity, idempotencyKey (unique per org+feature), reportedAt, periodBucket (YYYY-MM).


6. API Surface

6.1 Feature Config API (Admin)

MethodEndpointDescription
POST/featuresCreate a new feature config (draft)
GET/features/:featureIdFetch config and all tiers
PATCH/features/:featureIdUpdate config fields (draft only)
POST/features/:featureId/publishPublish; syncs Razorpay Plans; increments version
POST/features/:featureId/rollbackRoll back to a previous config version
GET/features/:featureId/previewReturn preview render data (no payments)
GET/features/:featureId/exportReturn full config as JSON for AI analysis

6.2 Billing Page API (End-User, Authenticated)

MethodEndpointDescription
GET/billing/:featureId/stateFetch subscription state and all tiers for org
POST/billing/:featureId/subscribeCreate Razorpay Subscription or Order; return checkout data
POST/billing/:featureId/change-tierUpdate Razorpay subscription plan; apply proration
POST/billing/:featureId/cancelCancel subscription at period end
POST/billing/:featureId/reactivateRe-enable cancelled subscription before period end
GET/billing/:featureId/invoicesReturn Razorpay invoice list for the org

6.3 Usage Reporting API

MethodEndpointDescription
POST/usageReport usage events (batch supported)
GET/usage/:featureId/:orgId/summaryEnd-of-period usage aggregation for billing page display

6.4 Webhook Events (Razorpay → BillingBuilder)

EventAction
subscription.chargedCreate/activate Subscription record; flip feature flag ON
subscription.completedSet status = cancelled; flip feature flag OFF
subscription.haltedSet status = paused; notify org of payment failure
payment.capturedActivate entitlement for one-time purchases
payment.failedLog failure; surface error to end user on billing page

All webhook handlers must be idempotent. Use razorpaySubscriptionId (or razorpayOrderId for one-time) as the idempotency key. A dead-letter queue captures failed executions for retry.


7. Razorpay Integration

  • 7.1 Recurring Subscriptions - One Razorpay Plan per tier × billing period on publish. At checkout, backend creates a Subscription (plan_id, total_count, start_at); subscription_id returned to frontend, which opens Razorpay Checkout. User authorises autopay mandate + first payment in one step. Trials: mandate collected on start_at; first charge fires after trial.
  • 7.2 One-time Payments - Razorpay Order created at checkout; frontend opens Checkout with order_id. On payment.captured, entitlement activated for the configured duration or perpetually.
  • 7.3 Tier Change (Proration) - Upgrade: PATCH /subscriptions/:id with new plan_id, Razorpay charges prorated difference immediately. Downgrade: credits prorated difference to next invoice. Billing page must fetch and display the proration amount before executing.
  • 7.4 Cancellation - POST /subscriptions/:id/cancel with {cancel_at_cycle_end: true}. Razorpay stops auto-renewal; subscription stays active until period end, then fires subscription.completed, triggering feature-flag deactivation.

8. Embed System

  • 8.1 Config Token - Publishing generates a signed HS256 JWT encoding featureId, configVersion, orgAllowlist, originAllowlist. Validated on every billing page API request. Tokens are versioned - older tokens continue to resolve to the config version they were issued for.
  • 8.2 Context Passing - iframe: query params ?orgId=&userId=&authToken=. JS Snippet: window.BillingConfig = { orgId, userId, authToken } or data- attributes. React: props token, orgId, userId.
  • 8.3 Security - Config JWT signing secret never exposed client-side. All billing page API calls authenticated against the signed auth JWT. Origin allowlist enforced on every embed load (403 for non-allowlisted). Invalid/expired/revoked tokens render an error state - no data leaked.

9. JSON Export for AI Analysis

The Export JSON option generates a machine-readable snapshot of the full billing config for pasting into an AI assistant for pricing analysis and documentation.

9.1 JSON Contents: featureId, featureFlagKey, displayName, billingUnit, billingMethod, recurrence, trialDays, all tier definitions (name, basePrice, billingPeriod, includedUnits, overagePricePerUnit, hardCap, recommended), Razorpay Plan IDs per tier, configVersion, publishedAt.


10. Non-Functional Requirements

  • 10.1 Security - Admin endpoints require internal admin auth; end-user billing calls require a valid auth JWT. Config JWTs signed HS256, secret in a secrets manager. Origin allowlists enforced on embed load and every API call.
  • 10.2 Reliability and Idempotency - Idempotent webhook handlers; idempotent Razorpay Plan creation; feature-flag flips retried on failure; dead-letter queue for unprocessable events.
  • 10.3 Versioning - Every publish increments configVersion; the embed token encodes the version; old tokens resolve to their pinned version; admins can roll back; existing subscribers stay on their version until they change plans.
  • 10.4 Performance - Billing page renders subscription state and tier data in under 800ms for 95% of requests. Usage ingestion (POST /usage) is asynchronous and must not block the product's critical path.

11. Open Questions

  1. Should a feature support both monthly and annual billing on the same tier, or should each period be a separate tier? (Product, Open)
  2. What currency should pricing be in? Is multi-currency a v1 requirement? (Product, Open)
  3. How should proration be surfaced for annual plan tier changes where the credit/charge could be large? (Design, Open)
  4. Should cancellation offer an immediate-effect option (forfeiting remaining period)? (Product, Open)
  5. What retention strategy should be shown on cancellation (e.g. win-back offer)? (Product, Open)
  6. Should the JSON export include subscriber counts per tier for richer AI analysis? (Engineering, Open)

12. Appendix

  • 12.1 Billing Unit Catalog (v1): API calls, Tokens, Seats / Users, GB storage, GB bandwidth, Events, Renders, Minutes, Tasks, Messages, Workflows, Credits, Documents, Queries.
  • 12.2 Feature Config Status Transitions: draft → live (publish) | live → archived (manual) | any version ← previous version (rollback). Archived configs are read-only; existing subscriptions run until they naturally end.
  • 12.3 Subscription Status Transitions: trial → active (trial end + first charge) | active → cancelled (at period end) | active → paused (payment failure) | paused → active (retry success) | cancelled → active (reactivated before period end) | active → expired (one-time entitlement elapsed).

Laps & stories

mindlap
AboutFAQPrivacyTerms

© 2026 mindlap