Plans grant credits, actions spend them — meter generations, API calls, exports, render minutes, or any per-use action through one credit ledger in a left-sidebar member app. Auth, billing and a dedicated admin app already done.
Append-only ledgerBalance-after rowsAtomic debitsNever goes negativePer-action pricingRefund on failureIdempotent by dedupe_keyPeriod grantsconsume_credits_for_action()Balance-gated actionsReconciles by additionAdmin-app grant + auditInsufficient-balance guardAppend-only ledgerBalance-after rowsAtomic debitsNever goes negativePer-action pricingRefund on failureIdempotent by dedupe_keyPeriod grantsconsume_credits_for_action()Balance-gated actionsReconciles by additionAdmin-app grant + auditInsufficient-balance guard
One tap in, zero passwords
Sign in with Apple & Google — built in.
Real OAuth, not a redirect to someone else's invoice. ES256 client secrets, signed state, nonce checks and identity linking — folded into the same passwordless account. No Auth0 bill, no SDK to babysit.
Both built in — and both live on this demo. The real buttons are on the sign-in page; each turns on with one env block.
app.yoursaas.com
Sign in to continue
Continue with Apple
Continue with Google
Signed insession created · credits auto-granted
Metered & honest
Watch the meter, not the invoice.
Every action carries a price. Every price hits one append-only ledger. The balance you see is the balance you have — debited up front, refunded on failure, never negative.
Per-action pricingBalance-after rowsRefund on failure
1,840credits remaining
Report run−4 cr
API lookup−1 cr
Bulk export−120 cr
Webhook fire−2 cr
invoice.paid+2,000 cr
Report run−4 cr
Refund · failed job+4 cr
API lookup−1 cr
Report run−4 cr
API lookup−1 cr
Bulk export−120 cr
Webhook fire−2 cr
invoice.paid+2,000 cr
Report run−4 cr
Refund · failed job+4 cr
API lookup−1 cr
PAY PER RUN
Every action costs credits. Every credit is accounted for.
Wrap any per-run tool in consume_credits_for_action() and the metering is handled for you. Plans top up the balance each period; the ledger records where it went.
One function, metered actions
Wrap an export, a lookup, a render, an AI call or render minutes in consume_credits_for_action() and it debits the balance atomically. No double-spend, no half-charged runs — the deduction and the work commit together or not at all.
An append-only ledger
Every spend and every top-up is a row: amount, action, balance-after, timestamp. Nothing is mutated in place, so a user's history reconciles to the current balance by addition — handy when someone emails asking where 40 credits went.
Per-action pricing, gated by balance
Set the cost per action in one place — a cheap lookup at 1 credit, a heavy render at 25. Tools live in the member sidebar app and open freely; each run is gated by the balance, not a hard tier wall, and a zero balance routes to top-up. Change the price without touching the call sites.
Period top-ups via Stripe
Plans grant a credit allotment each billing cycle. The Stripe webhook credits the ledger on renewal; cancellations stop the top-up, not the account.
Refund a failed run
If an action throws after it charged, credit the same amount straight back to the ledger. The reversal is its own row, so the audit trail stays honest.
Meter from the browser or the API
The same consume_credits_for_action() path backs both a logged-in user clicking 'Run' and a script hitting your API with a key. One balance, one ledger, whether the spend comes from public/api.php or a jQuery button — so usage-based billing works for humans and machines without a second accounting system.
The ledger, line by line
Read the balance backwards — every credit has a row.
Top-ups, spends, and a refund land as append-only rows with a balance-after, so the number on the account is just the column added up.
Action
Type
Amount
Balance after
Scale plan renewal · stripe
+
2,000
2,000
Run premium workflow · web
-
25
1,975
Generate report export · web
-
10
1,965
AI image generation · api_key
-
1
1,964
Refund: export failed mid-run · web
+
10
1,974
Create a note · api_key
-
1
1,973
The ledger, by the numbers
Every credit accounted for, to the row
Usage metering where the books always balance — debits, top-ups and refunds all land in one append-only ledger.
1ledger for spends, top-ups, refunds and admin grants alike
0negative balances possible — a short charge rolls back, never writes
1 rowper event, with the balance-after stamped on every single one
4plan tiers granting 25 to 2,000 credits each billing period — every gated action checks the balance before it runs, with admin grants minted from the admin app
Try before you buy — no card, nothing saved
Click through all seven live demos — including a whole client site built in the CMS.
You're in one now. Hop straight to any other site type — same tab, still a demo: no card needed, no payment is real, and nothing you do is saved.
Each site-type demo is one of the seven ready-to-run profiles in the download — copy the folder, add your keys, ship.
Whatever you decide — a generation, an API call, an export, a render minute. Plans grant credits; each action spends them through one ledger via consume_credits_for_action().
Your call per plan. Period credits top up to a fresh allowance each period by default, and you can switch to rollover in the plan config.
Yes — combine recurring plans that grant credits with one-time purchases for top-up packs.
The starter includes prepared queries, signed Stripe webhooks, CSRF checks, rate limiting, session hardening, setup diagnostics and regression tests. Configure the enabled providers, verify backups and test your own product before launch.
You pay your hosting and service providers directly. Budget for a PHP server, domain, transactional email and payment processing. Image generation/storage and native app store accounts add costs if you enable them. Check provider pricing for your region and expected usage; the template itself is a one-time purchase.
Get started
You’re already inside.
This is a live, fully interactive demo — explore every screen. Nothing you do is saved and no payments are real.