Billing state, modeled clearly.
Accrue is a Phoenix-era billing library: subscriptions, invoices, checkout, webhooks, and the rest of the Stripe-shaped surface as plain Elixir—not a pile of controllers you fork forever. You keep auth, routes, and product code; Accrue models money and lifecycle and ships a Fake processor so tests and CI stay offline.
If you ship a SaaS on Elixir and want documentation you can hand to a teammate, plus a straight path from “runs on my laptop” to “looks like how we run in prod,” you are in the right place.
Start here
- Organization billing (non-Sigra) — session→billable org path when the Stripe Customer should follow an organization, not only the signed-in user.
- Testing — Fake-first verification posture for host billing flows.
- First Hour — one sitting from deps to a working billing slice.
- Production readiness — ordered checklist before promoting billing to production or live Stripe (webhooks, tenancy, observability, CI vs live lanes).
- Maturity and maintenance — when Accrue is “done enough” for the
1.0.xline, how friction enters planning, and how Hex publishes trigger contract passes. - Troubleshooting — when something already wired misbehaves.
- Webhooks — signing, retries, and operational notes.
- Quickstart — smallest possible skim.
- Demo app README — command parity with Accrue’s CI host gate.
- Release notes and Upgrade — what changed, in plain language, then the formal contract.
- HexDocs — every guide and API page together; use the Guides section as the full index.
Install
Hex vs
main: The{:accrue, "~> …"}line below tracksaccrue/mix.exs@versionon the branch you are reading (typicallymainon GitHub). Hex.pm publishes that train after release; use HexDocs for API docs matched to the Hex version you resolved.
If you also pull accrue_admin, match its ~> to the same train, and rely on a resolved mix.lock in production while you are tracking a single ~> line.
In mix.exs:
defp deps do
[
{:accrue, "~> 1.1.0"}
]
endThen:
mix deps.get
mix accrue.install
After install, pick up the walkthrough from Start here (First Hour) above—no need to duplicate those steps here.
Invoice PDFs are Rendro-first by default, so the normal path no longer
requires Chrome or ChromicPDF on the host. If you need the explicit
Chromic compatibility path or the :invoice_pdf_adapter / :pdf_adapter
split, see PDF Rendering.
Optional checks from the host app:
mix verify— short “tutorial proof” suitemix verify.full— closer to what CI runs- From the repo root:
bash scripts/ci/accrue_host_uat.sh— full host integration gate
What you get
- Billing domain: customers, subscriptions, invoices, charges, refunds, coupons, promotion codes, metered usage.
- Money paths: Checkout, billing portal, and Connect helpers stay behind one processor contract.
Accrue.Billing.create_checkout_session/2andAccrue.Billing.create_billing_portal_session/2are first-party on both Stripe and Braintree, with provider-honest behavior: Stripe returns upstream hosted URLs; Braintree returns mounted first-party local checkout and portal URLs.Accrue.Billing.swap_plan/3,Accrue.Billing.preview_upcoming_invoice/2,Accrue.Billing.update_quantity/3,Accrue.Billing.add_item/3,Accrue.Billing.remove_item/2, andAccrue.Billing.update_item_quantity/3form the official active-subscription-change bundle.preview_upcoming_invoice/2is the canonical path where supported before commit. Stripe is native across that bundle, Fake is the testing/local-only proof lane, and Braintree stays explicitly bounded to swap-only when the host configures:plan_resolverfor app-facingprice_idtranslation. Braintree does not get first-party preview, quantity, or subscription-item support. Stripe remains the default first-user path in production (Fake in test), while Braintree is official only for thegateway subscription coreslice. The required Braintree proof stays hermetic and Fake/mock-backed; any real-provider Braintree smoke is advisory only. For the full support contract, see the canonical processor support matrix. - Operations: webhook ingest, async dispatch, replay, event history, telemetry.
- Product polish: transactional email, invoice PDFs, installer tasks.
The LiveView dashboard ships as the sibling Hex package accrue_admin; pin it to the same version family as accrue when you add the operator UI.
Stability
Your supported integration surface—generated MyApp.Billing, use Accrue.Webhook.Handler, use Accrue.Test, AccrueAdmin.Router, Accrue.Auth, Accrue.ConfigError—is spelled out in Upgrade. Accrue is done enough for the 1.0.x line because the documented facade is the contract: breaking changes on the documented surface go through deprecation, not silent reshuffles, even within the 1.0.x series. Internal schemas, workers, and demo helpers are not that contract. The 1.0.x line still ships additive work and proof tightening, but it does not promise an ever-growing feature roadmap—see Maturity and maintenance. Maintainer cadence is documented in the repository release runbook and Maturity and maintenance.
Generated files are yours after install. Accrue only refreshes pristine stamped copies on installer reruns; it does not stomp files you have edited.
Community
Contributing · Code of Conduct · Security
Keep Stripe credentials and webhook signing secrets in runtime configuration, not in the repo. Use Security for vulnerability reports.