Billing is selected with BILLING_PROVIDER=rxsubscription, configured locally and in Vercel Production on 2026-10-22. The user explicitly requested a fresh start: do not import legacy subscriptions, customers, invoices, or session usage. Existing Stripe entitlements do not carry over. Local development uses a sandbox key; production uses its own secret key. Configuration takes effect in production when the updated application is deployed.
Server-only environment variables:
BILLING_PROVIDER=rxsubscription
RXSUBSCRIPTION_BASE_URL=https://subscription.rxlab.app
RXSUBSCRIPTION_SECRET_KEY=<application secret key>
RXSUBSCRIPTION_PLUS_PLAN_ID=8efd0160-848f-448f-968f-ec2129566829
RXSUBSCRIPTION_AI_USAGE_ITEM=ai_sessions
RXSUBSCRIPTION_NOTIFICATION_USAGE_ITEM=notification_emails
RXSUBSCRIPTION_STORAGE_USAGE_ITEM=release_storage_bytesThe application is GitHub Autopilot / Flowcy, client_e1a643ad5d474aad9430d90d0b7a8f52, matching the current OIDC client. Users are identified by the existing RxLab OIDC subject, never email. Do not put the secret key in a NEXT_PUBLIC variable. Invalid provider values, missing credentials/meters, malformed responses and upstream failures stop billing operations; no local fallback is made after selecting RxSubscription.
Created through Chrome and verified in the usage table:
| Key | Default limit | Reset | Overage |
|---|---|---|---|
| ai_sessions | 50 | Billing period (calendar-month fallback without a subscription) | Block |
| notification_emails | 2 | Calendar day | Block |
The workspace agent created these plans; the current active configuration is:
| Plan | ID | Price | AI sessions | Daily emails |
|---|---|---|---|---|
| Free | ba967012-a135-493f-9c96-3406a36702d0 | USD 0/month | 50 | 2 |
| Plus | 8efd0160-848f-448f-968f-ec2129566829 | USD 10/month | 1,000 | 20 |
Both use group default, no trial, and usage-limit entitlements rather than balance grants. Free has automatic enrollment configured. The plan table visibly confirmed all four allowances. Both plans are active, verified in Chrome and the live sandbox catalog on 2026-10-22. Sandbox and production credentials are stored separately.
The current RxSubscription catalog sets Plus at USD 10/month. Landing-page pricing now matches. No users were subscribed or charged during verification.
/api/v1/usage, preserving null as unlimited.ai_sessions unit before running AI. Workflow step IDs and dependency repair repository/PR/head identity provide retry keys. Admitted sessions count even when later AI execution fails, matching the prior session accounting. Denials never run AI. A process failure after admission but before local session insertion can leave a metered attempt with no local session; retrying the same step does not consume again./api/v1/checkout. Plan checkout returns checkoutUrl (normalized to the UI's url); the portal returns url. Billing actions navigate to dedicated hosted pages; Sonner overlays report loading/failure./api/v1/invoices. The upstream page size/cursor is retained rather than truncating invoices and skipping records.release_storage_bytes (default 5 GiB, never resets, block overage). Bytes are reserved before an upload URL is issued. Confirmation requires the actual size to match the reservation; deletion, repository/release removal, and cleanup release the original operation exactly once. Pending uploads reserve capacity until deleted or cleaned up. File metadata remains local.The user explicitly waived historical plan and usage migration. Enable the configured provider and deploy the integration without importing old billing records. Keep the old database records untouched. Existing external Stripe subscriptions are not automatically cancelled by this switch.
No historical usage is imported. New usage for all configured meters is tracked by RxSubscription. Local rows retain operation keys only for reliable retries and resource metadata.
The local mock is derived from rxtech-lab/rx-subscription-service's app/api/v1/{entitlements,usage,checkout,invoices} and lib/subscription/usage.ts, inspected on 2026-10-22. The published mock lookup was unavailable because the Postman CLI was signed out. This is an authored simulation, not live API verification.
postman simulation run postman/simulations/rxsubscription.sim.yaml --port 4918 --output ndjson
# In a second terminal:
RXSUBSCRIPTION_SIMULATION_URL=http://127.0.0.1:4918/billing bun run test:run lib/services/rxsubscription.integration.test.tsThe integration tests run the real client and services over HTTP with an in-memory local database. They cover usage, concurrency/denial, idempotent retries, unlimited limits, paid/complimentary plans, checkout/portal, invoices, upstream outages, missing meters and notification failure release. The simulation suite skips unless its local URL is explicitly supplied.
Created and read back using the RxSubscription MCP for the Flowcy application:
| Key | Default allowance | Reset | Counts |
|---|---|---|---|
projects | Unlimited | Never | Current projects created after cutover |
docs | Unlimited | Never | Current documents created after cutover, not versions |
dependency_scans | Unlimited | Billing period | Admitted dependency scan attempts |
ci_updates | Unlimited | Billing period | Admitted CI update scan attempts |
These keys are shared application constants; limits and reset policies are owned by RxSubscription. No extra environment variables are required. Failed admitted scans and scans finding no updates count. CI security audits are not charged a second CI-update unit. Installation ownership determines scan billing; a notification recipient does not.
Apply migration 0041_modern_slayback.sql before deploying this code. The allocation table stores operation identities and owners, not local quotas. Projects and documents reserve before creation, release after deletion, and retain failed releases for retry. Project removal also releases contained documents. Notion pruning and explicit purge follow the same release path. The existing release-files cleanup cron reconciles absent resources with allocations older than one hour, including interrupted creations; live resources are retained. This retry step runs even when object storage is not configured. Keep that cron scheduled.
Existing projects/documents are not backfilled. Updating an existing document does not consume a unit. New documents inside an existing project are counted. The mock HTTP lifecycle tests cover creation, version updates, deletion/cascade, failed creation, abandoned allocation recovery, independent meters and denial. Live catalog configuration is verified; production metering has not been deployed or exercised.
billingUsageKey columns identify metered operations. Pre-cutover rows have no operation key and are not imported, per the requested fresh start. Existing stored files remain intact but their bytes are not backfilled into the new meter.POST /api/v1/usage accepts operation: "release" with the original idempotencyKey, user and item. Release reverses the original period, is idempotent, and tombstones delayed consumes. Balance-charged meters are excluded. Concurrent blocked usage is admitted atomically.