Open-source billing core · Apache-2.0

Billing your accountant
can actually book.

Revryn computes subscription and usage-based billing in integer minor units and delivers it to e-conomic as accrual-aware drafts — service periods, deferrals, corrections and all. Self-hosted, GraphQL-first, built for engineers at small companies who are also the billing team.

Elixir/Phoenix core · PostgreSQL · one OCI image · Go CLI + MCP server

query Preview($teamId: ID!, $subId: ID!) {
  invoicePreview(teamId: $teamId,
                 subscriptionId: $subId,
                 asOf: "2026-09-01") {
    invoiceDate
    periodStart
    periodEndExclusive      # half-open, always
    netAmountMinor          # integer øre — never a float
    fingerprint             # freeze verifies against this
    blockers                # empty ⇒ freezable
    lines { description quantity amountMinor
            recognition servicePeriodStart }
  }
}

Why this exists

You shipped the product. Now you own the billing spreadsheet.

The float bug you haven't found yet. Somewhere a * 0.25 is quietly losing øre. Revryn bans floating-point money everywhere — the type system and the database enforce it.

Revenue in the wrong month. An annual invoice booked as January revenue makes your numbers lie. Every over-time line here carries the service period e-conomic needs to accrue it correctly.

The retry that double-invoiced a customer. Timeouts against an ERP are a fact of life. Idempotent operation keys and search-before-retry make them boring instead of expensive.

“Can you just check why customer X wasn't billed?” The failure inbox answers that: every stuck operation, classified, with the exact remediation and a copy-pasteable support bundle.

Non-negotiable invariants

Rules the codebase cannot break

These aren't conventions in a wiki — they're enforced by types, database constraints, property tests, and CI. Read them in the feature docs; verify them in the test suite.

Integer money, end to end

Amounts are integer minor units (øre). Intermediate quantities and rates use arbitrary-precision decimals; rounding happens exactly once, half-away-from-zero, at the final line amount. Allocation residuals distribute by largest remainder with a stable tie-break.

Accrual-aware by construction

Every over-time line carries a half-open service period the ERP can defer revenue against; point-in-time lines never do. Your accountant sees September revenue in September — even on annual prepaid invoices.

Booked documents are immutable

Once a document is booked in the ERP it is never edited. Corrections are compensating documents — credit notes, reversing closes — so the audit trail always sums to the truth.

Idempotent, reconciled side effects

Every external write carries a stable operation key, is retried at-least-once, and is verified by reading the ERP back. An outcome-unknown timeout is searched before it is retried — no duplicate invoices.

Deterministic and hash-chained

Frozen invoice intents, credit closes, and audit exports are canonical JSON snapshots with content hashes. Same inputs, same fingerprint, byte for byte — verifiable years later.

Failure is a first-class state

Explicit transition-table state machines back every lifecycle, and a failure inbox classifies every stuck operation: user-fixable, operator-only, or non-retryable — each with a remediation path.

How it works

Catalog → usage → freeze → e-conomic

  1. Model the catalog. Products, plans, and versioned pricing: tiered and graduated seats, metered usage, minimum commits, annual prepaid with 12-as-10, discounts as negative lines.
  2. Ingest usage. Batch or single events over GraphQL with idempotency keys, into monthly partitions. Rating aggregates in SQL at a frozen cutoff — raw events never load into app memory.
  3. Preview, then freeze. Previews are deterministic and fingerprinted. Freezing re-computes and verifies the fingerprint, so what you showed the customer is exactly what gets invoiced.
  4. Sync to e-conomic. Frozen intents become ERP drafts (draft-first; booking stays a human decision). Durable jobs, backoff, read-after-write reconciliation, and a monthly credit close that posts an aggregate finance voucher with evidence attached.

e-conomic stays the system of record for bookkeeping. Revryn is the system of record for why every line exists — and can prove it.

$ revryn invoices preview --subscription sub-1 --as-of 2026-09-01
subscription:  sub-1
period:        2026-09-01 .. 2026-10-01 (excl)
net amount:    250000 DKK (minor units)
fingerprint:   fp-abc

$ revryn invoices freeze --subscription sub-1 \
    --expected-fingerprint fp-abc
$ revryn invoices sync --intent in-1   # → e-conomic draft

The same commands are exposed as an MCP server (revryn mcp serve), so AI agents can operate billing with read-only hints and confirmation gates — same domain commands, same authorization scopes as the GraphQL API and the UI.

Everything documented

Feature docs are the source of truth

Every behavior-changing pull request updates the relevant document in the same change — these pages are generated from the repository's canonical docs/features/, not written by marketing.

Annual prepaid subscriptions supported

Bill a fixed annual amount in advance while preserving the full service period on the invoice line so e-conomic can post the revenue accrual over time. This is the minimal vertical…

Audit export and retention supported

An auditor reconstructs any invoice chain from a self-contained, checksummed evidence package without database access, and every table in the billing schema carries an explicit ret…

Billing runs supported

Deterministic, re-runnable billing: one run per stable run key selects eligible subscriptions at their billing boundary, rates them, records double-billing-guarded charges, and fre…

Corrections and credit notes supported

Correct booked invoices without ever mutating them (INV-001): a correction opens a case linking the original intent to a compensating credit-note intent whose lines are exact or pa…

Customer credit supported

A money-like customer-credit subledger, distinct from invoice/credit-note documents (INV-050): an append-only ledger of integer minor-unit transactions with projections (available/…

Customers and contracts supported

Team-scoped customer master data as immutable versioned snapshots, ERP customer mappings, and contracts as the commercial frame subscriptions and charges live inside.…

ERP synchronization supported

Move frozen invoice intents into the ERP as drafts, verify every external write by read-after-write reconciliation before any state claim (INV-008/009), gate booking behind explici…

Guided demo ERP workspace experimental

A prospective operator can create an isolated Northstar Studio workspace and inspect how Revryn connects commercial billing facts to accounting evidence without supplying e-conomic…

Invoice preview and freeze supported

A deterministic, side-effect-free preview of what a subscription would be billed, frozen on demand into an immutable invoice intent (canonical snapshot + SHA-256) before any extern…

Monthly customer-credit close experimental

Revryn keeps the detailed, append-only customer-credit subledger. Each calendar accounting month, it freezes one close per team and currency and can post its aggregate liability mo…

Operations and failure inbox supported

Durable operations are the authoritative user-visible state of asynchronous work (ERP writes, credit refunds/expiries). Transitions are validated against the §11.3 machine, committ…

Organizations and teams supported

Provide the tenancy model: global users hold explicit memberships in organizations and teams. The team is the tenancy boundary for all business data (INV-034); authorization always…

Passkey authentication supported

Passwordless sign-in with WebAuthn/FIDO2 passkeys as the primary factor, TOTP as an optional step-up factor, and single-use recovery codes as the recovery path. Sessions are revoca…

Product catalog supported

Own products (with accountant-approved revenue-recognition policy), plans with immutable published versions, price components with validated pricing definitions, discounts, and pro…

Subscriptions supported

The subscription lifecycle per SPEC §11.1: idempotent start, versioned quantity/plan changes, two cancellation modes, pause/resume, scheduled activation — plus idempotent one-time …

Usage ingestion supported

Idempotent ingestion of usage measurements, immutable void/replacement corrections, quarantine instead of silent loss, and cutoff-reproducible aggregation feeding metered billing.…

Drop into your stack

Three reference integrations, kept honest by CI

The repo ships full showcase apps — Django, Rails, and Laravel — each integrating through a single billing seam module and certified end-to-end: real UI actions drive seat counts, a live preview renders with its fingerprint, and the invoice reconciles to an ERP draft in CI.

Django 5Rails 8Laravel 13 GraphQLGo CLIMCP

Own your billing. Keep your accountant happy.

One PostgreSQL database, one container image, an fnox-managed secret catalog, and a test suite your auditor can read.