Skip to content

15 — Billing & Usage (Blueprint Screen 12, `/app/testimonials/billing`)

Cursor-ready plan: plan status, usage meters, overage behavior, warnings, and upgrade flow for testimonial app billing.

15 — Billing & Usage (Blueprint Screen 12)

Section titled “15 — Billing & Usage (Blueprint Screen 12)”

Source: 02-Implementation-Blueprint.mdScreen 12 - Billing & Usage (/app/testimonials/billing).

Naming note: This is blueprint “Screen 12” (billing). It is not related to the file-number convention of other docs.

Product alignment: 03-Pricing-Options.md — especially Option B (Hybrid Base + Metered Overage, recommended) and Implementation Notes for Billing Screen.

This document is a build spec only. No code changes are implied until a task references this file.

Prerequisites: baseline subscription plumbing already exists in boilerplate (ShopSubscription, one-time charge model, app subscription webhooks), and testimonial usage counters are defined (see section 3).


Merchants open /app/testimonials/billing to see current plan, period usage (requests, storage, processed video minutes), overage behavior and estimated charges, warning states, and a clear upgrade/buy flow.


ItemValue
Suggested fileapp/routes/app.testimonial-billing.jsx (blueprint §6).
URL/app/testimonials/billing.

Auth: authenticate.admin(request); all data is scoped by shopId.

Nav: Billing & Usage link under testimonial section.


From 03-Pricing-Options.md:

  • Use Option B: Hybrid Base + Metered Overage.
  • Starter/Growth/Scale tier examples are already defined.
  • Overages should be explicit and transparent.

2.1 Billable dimensions (from blueprint Screen 12 + pricing notes)

Section titled “2.1 Billable dimensions (from blueprint Screen 12 + pricing notes)”
  1. requests_used
  2. storage_gb_used
  3. processed_video_minutes_used

These are the only required usage counters for v1 UI. Anything else is optional and should not block this screen.


Existing schema currently has chat-era billing fields. For testimonial billing, add dedicated fields/models and avoid mixing semantics.

Section titled “3.1 Recommended model: TestimonialBillingCycle”

One row per shop per billing cycle.

Suggested fields:

  • id, shopId
  • cycleStartAt, cycleEndAt, nextResetAt
  • planCode (starter, growth, scale)
  • requestsIncluded, storageGbIncluded, videoMinutesIncluded
  • requestsUsed, storageGbUsed, videoMinutesUsed
  • overageRequests, overageStorageGb, overageVideoMinutes
  • overageAmountCentsEstimated
  • overageEnabled (boolean)
  • status (open, finalized, invoiced)
  • timestamps

Unique/index:

  • @@unique([shopId, cycleStartAt, cycleEndAt])
  • indexes on (shopId, status), (shopId, cycleEndAt)

Store counters on Shop + derive cycle from ShopSubscription.currentPeriodEnd. This is faster initially but harder for audits/history. Prefer dedicated cycle rows if possible.

Reuse or extend existing plan helper module (e.g., plans.server.js) with testimonial-oriented limits/rates:

  • included limits
  • overage rates
  • whether overage is allowed per plan

Usage counters must update from real events:

  • Requests used: increment when request is actually sent (pipeline from 07), not when scheduled.
  • Storage GB used: computed from successful media assets (fileSizeBytes) from TestimonialMediaAsset.
  • Processed video minutes: sum of durationSec / 60 for video assets that reached processed/ready state.

Choose one and document:

  • Event-driven increments during normal flows, with periodic reconciliation job.
  • Nightly recompute from source tables for accuracy.

Recommended: event-driven + nightly reconciliation for correctness.


Return one payload with:

  • Current plan details
  • Current cycle range and next reset date
  • Usage vs included for 3 meters
  • Overages (units + estimated amount)
  • Warning flags (80%, 100%, overage active)
  • Upgrade CTA target

Example shape:

{
"plan": { "code": "growth", "name": "Growth", "priceUsd": 49 },
"cycle": { "start": "2026-05-01", "end": "2026-05-31", "nextReset": "2026-06-01" },
"usage": {
"requests": { "used": 1730, "included": 2000, "pct": 86.5 },
"storageGb": { "used": 21.4, "included": 25, "pct": 85.6 },
"videoMinutes": { "used": 412, "included": 500, "pct": 82.4 }
},
"overage": {
"enabled": true,
"units": { "requests": 0, "storageGb": 0, "videoMinutes": 0 },
"estimatedCents": 0
},
"alerts": { "warn80": true, "hit100": false, "overageActive": false }
}

Follow blueprint Screen 12 fields exactly:

  1. Current plan card
    • Plan name, monthly price, billing cycle dates
  2. Period usage card group
    • Requests used
    • Storage used (GB)
    • Processed video minutes
    • Each with progress bar + “used / included”
  3. Overage settings/toggles
    • Allow overages toggle (if plan supports)
    • Overage unit rates
    • Estimated overage this cycle
  4. Upgrade CTA
    • Button to plan selection/upgrade flow
  • Show warning at >=80% for each meter
  • Show limit reached at >=100%
  • Show “overage billing active” if any overage units > 0

Use non-blocking banners unless merchant action is required.


Required:

  • toggle_overage_enabled
  • navigate_upgrade

Optional:

  • buy_usage_pack (if you add add-on packs later)

All writes should validate shop ownership and current subscription status.


Reuse existing billing infrastructure patterns in repo (subscription confirm routes/webhooks) but move semantics from chat credits to testimonial meters.

Minimum behavior:

  • If no active subscription: show “Select a plan”.
  • If active: show current plan and allow upgrade/downgrade path.
  • On webhook updates (app_subscriptions/update), refresh plan + cycle data idempotently.

Add a scheduled job (daily) to recompute current cycle usage from source-of-truth tables:

  • sent requests
  • media assets size
  • processed video durations

If mismatch > tolerance, correct the cycle row and log an internal warning.

This avoids drift from partial failures.


10) Testing checklist (acceptance criteria)

Section titled “10) Testing checklist (acceptance criteria)”
  • Current plan and cycle dates render for active shop.
  • Requests/storage/video counters match seeded source tables.
  • 80% and 100% thresholds trigger correct banners.
  • Overages compute expected units and estimated amount.
  • Toggle overage setting persists and reload reflects value.
  • Shop without plan sees upgrade CTA, not broken metrics.
  • Cross-shop access is blocked.

  1. Define testimonial plan limits/rates in plan helper module.
  2. Add billing cycle/counter schema (or chosen lightweight approach).
  3. Wire usage increments from send pipeline (07) and media processing.
  4. Build loader aggregates + page payload.
  5. Build Polaris UI for plan, meters, overage, CTA.
  6. Add overage toggle action.
  7. Add daily reconciliation job.

  • 02-Implementation-Blueprint.mdScreen 12
  • 03-Pricing-Options.md — Option B + billing screen notes
  • 07-email-sms-request-delivery-pipeline.md — sent requests usage source
  • 06-public-submission-page-screen-13.md + media processing path — submission/media usage source

This folder already includes 0514 numbered plans. This file is 15-… to keep sequence stable.