Skip to content

Repository files navigation

Static Subscription Billing Lab

An independent, deterministic, dependency-free subscription-billing laboratory with a factual Zuora v1 REST and Orders compatibility subset.

Synthetic and unaffiliated. The visible tenant, Cindercone Billing Lab, all people, organizations, tokens, transactions, and events are fictional. This project is not affiliated with, endorsed by, or operated by Zuora. Static JSON cannot process mutations; the bundled in-memory runtime can.

What is included

  • A coherent USD/UTC tenant fixed at 2026-01-15T12:00:00.000Z.
  • Essentials ($60/month), Growth ($120/month), API Events ($0.002/event in arrears), and Guided Setup ($200 once).
  • Ten fictional accounts spanning active, suspended, canceled, open-balance, and dunning states.
  • Products, plans, charges, contacts, synthetic token-only payment methods, subscriptions and append-only versions, orders and actions, usage, invoices and items, payments and applications, and an event journal.
  • An exhaustive generated schema for all 19 canonical resources: every emitted field declares type, nullability, and runtime mutability, and undeclared fields fail generation or runtime commit.
  • 160 generated .json snapshots under site/api/v1/.
  • An extensionless in-memory REST runtime with OAuth fixture policy, Orders actions, billing, idempotency, ETags, deterministic faults, retries, reset, export, and exact replay.
  • An original responsive operations console and five stepwise scenarios.
  • A Python standard-library generator and Node/Python standard-library tests. There are no install-time or runtime packages.

Quick start

Requirements: Python 3.11+ and Node.js 20+.

python3 build.py --check
python3 -m http.server 4173 --directory site

Open http://localhost:4173/. GitHub Pages serves the same static site. No backend, telemetry, service worker, cookies, or remote assets are used.

Run every test:

python3 -m unittest discover -s tests -p 'test_*.py'
node --test tests/*.test.mjs

Regenerate committed fixtures:

python3 build.py
python3 build.py --check

Generation is staged inside the repository, atomically installed, rollback-safe, stale-file aware, and byte deterministic.

Static API

Static reads include:

api/v1/catalog/products.json
api/v1/accounts/A00000001.json
api/v1/accounts/A00000001/summary.json
api/v1/subscriptions/accounts/A00000001.json
api/v1/subscriptions/A-S00000001.json
api/v1/subscriptions/A-S00000001/versions.json
api/v1/orders/O-00000001.json
api/v1/invoices/INV00000001/items.json
api/v1/payments/PAY00000001.json
api/v1/object/usage.json

These are immutable files. Query parameters do not alter static files. Use the runtime for extensionless pagination, filtering, writes, faults, and virtual time.

Node runtime example

import { readFile } from "node:fs/promises";
import { createBillingTwin } from "./site/billing-twin.mjs";

const seed = JSON.parse(await readFile("./data/seed.json", "utf8"));
const twin = createBillingTwin({ seed });

await twin.fetch("/oauth/token", {
  method: "POST",
  body: {
    grant_type: "client_credentials",
    client_id: "static-lab",
    client_secret: "synthetic-only"
  }
});

const response = await twin.fetch("/v1/accounts?page=1&pageSize=5", {
  headers: { authorization: "Bearer tok_cindercone_lab_access" }
});
console.log((await response.json()).accounts);

Browser runtime example

Serve site/ over HTTP, then use a module:

import { createBillingTwin } from "./billing-twin.mjs";

const seed = await fetch("./data/seed.json").then((response) => response.json());
const twin = createBillingTwin({ seed, requireAuth: false });
const catalog = await twin.fetch("/v1/catalog/products");
console.log(await catalog.json());

twin.fetch never contacts a real tenant. twin.request adds deterministic retries for 429, 503, timeout, and post-commit loss. twin.injectableFetch is suitable for dependency injection.

Repository map

Path Purpose
data/source.json Small authored tenant and catalog source
build.py Deterministic generator, validator, registry builder, and atomic installer
data/schema.json, data/seed.json Exhaustive generated contract and complete seed
site/api/v1/ Generated static REST snapshots
site/billing-twin.mjs Browser/Node runtime
site/ Console, original asset, CSS, manifest, and generated data
tapes/ Portable scenario plans
tests/ Node and Python regression suites
registry.json, manifest.json Hashes, sizes, counts, and release metadata

Documentation

License and trademark

Code and original assets are MIT licensed; see LICENSE. “Zuora” is used only to identify the public API behavior targeted by this compatibility simulator. No Zuora logos, trade dress, screenshots, fonts, CSS, documentation, or OpenAPI material are included.

About

Deterministic, zero-dependency static subscription billing and Zuora API compatibility simulator.

Topics

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages