Accrue Portal
Mounted customer billing portal for Accrue.
accrue_portal is the customer-facing sibling to accrue and accrue_admin.
It gives host apps a package-owned portal mount for subscriptions, payment
methods, invoices, and local checkout flows when a processor uses
first-party-local-portal semantics.
Hex vs
main: The{:accrue_portal, "~> …"}line tracksaccrue_portal/mix.exs@versionon the branch you are reading (typicallymainon GitHub). Hex.pm publishes that train after release; use HexDocs matched to the resolved Hex version when you need portal docs tied to published artifacts.
For Braintree, both checkout and billing portal sessions return mounted local URLs from your app, not upstream hosted URLs.
Phase 101 keeps the portal boundary session-resolved-customer-only. Hosts that
need emailed-link checkout must add their own /checkout/start?token=...
bootstrap endpoint before redirecting into the mounted portal.
Mount
import AccruePortal.Router
accrue_portal "/billing", session_keys: [:user_token]
Mount accrue_admin "/admin" and accrue_portal "/billing" as sibling scopes.
Requirements
accrueconfigured with a real:repoand:auth_adapter-
host session contains the keys your auth adapter uses for
Accrue.Auth.current_user/1 portal_mount_pathconfig matches the mounted routeportal_base_urlis set to an absolute host URL soAccrue.Billing.create_checkout_session/2andAccrue.Billing.create_billing_portal_session/2return absolute URLs- Plug and LiveView mounts preserve auth/session continuity for the same customer
- Hosted Fields scripts and CSP are ready before the mounted checkout opens
Braintree local checkout
Phase 101 wires Braintree checkout through package-owned Hosted Fields.
Accrue.Billing.create_checkout_session/2 returns a URL under the mounted
portal path, and the checkout page completes the subscription using the same
core Accrue.Billing.subscribe/3 flow as the rest of the library.
This README stays concise by design. Use
accrue/guides/braintree-local-portal.md
for the deeper mounted-path contract, failure semantics, sibling scope
expectations, and the hand-rolled escape hatch.