v5.45.0 6 June 2026 Feature

The Grace Gate & the State-Aware Billing Page

Why This Matters

A billing page exists to answer four questions at a glance: what am I on, what will I pay and when, how do I change it, and is something wrong. Until tonight, SpeyBooks answered the first question and guessed at the rest. This release ships the missing pieces as one thing: the grace window becomes real at the API, and the page renders every customer state as a sentence written for that customer. The result is that the only state which says “error” is one where something is actually wrong.


The Grace Gate

New organisations get 7 days of full access before adding a card. This release makes that window real.

  • Application-level subscription gate Organisations without an active subscription, trial, or open grace window now receive a payment-required response across the product, with billing, organisation settings, and bug reporting always reachable. The app routes that response to the billing page, where the situation is explained and the path forward is a button, not an error message.

  • Dunning-aware by design A failed payment does not lock you out. While Stripe retries your card, access continues, because the retry window exists so you can fix the card, and a lock-out would turn a stale card into a cancellation.

This is an operational safeguard at the application layer, working alongside the mechanically enforced billing-history invariants shipped in 5.44.0.


The State-Aware Billing Page

Five situations, five honest summaries:

  • Getting started (grace) Days remaining shown plainly, with what happens at the window’s end. No payment card is displayed, because none exists yet.

  • Trialing One connecting sentence answers everything: the trial end date, the days left, the exact first charge, and the fact that cancelling before that date costs nothing. Founder customers also see their seat number, making the early-adopter offer visible: customer #N of 50, 90-day trial.

  • Active The next billing date now shows with the amount, alongside your actual card.

  • Payment failed A clear banner with the exact time Stripe will retry, “Update card” promoted to the primary action, and the consequence if unresolved stated without euphemism. Most involuntary churn is a stale card meeting a silent failure; this banner is the noise.

  • Cancelled Access-until date, the assurance that your data stays safe, and a one-click path back.

Supporting Changes

  • Your real card, not a placeholder The payment method card previously displayed fixed placeholder details regardless of the card on file. It now shows your actual card brand, last four digits, and expiry, fetched live from Stripe.

  • Card-expiry warning If your card expires before your next charge, an amber warning appears with the update path, before the failure rather than after it.

  • Prices from one source of truth Every price on the page now derives from the live billing data. Hardcoded price text has been removed.

  • New FAQ entry “Will I be charged during my trial?” now has a written answer: no, and cancelling during the trial means you are never charged at all.


API Additions

The billing status endpoint now returns the subscription status in Stripe’s own vocabulary, the founder seat number, the trial end date, the recurring amount in pence, the default card details, and the next payment retry time when a payment has failed. Full payload documentation is on the docs site.


Operational Impact

  • Every customer state renders as a specific explanation rather than a generic page
  • Pre-charge disclosure (date, amount, cancellation terms) shown throughout the trial, meeting card-network reminder standards alongside the upcoming email reminder
  • Zero hardcoded prices on the billing page
  • Placeholder card details eliminated
  • Lapsed organisations land on a conversion path instead of an error

Files Changed

Backend: billing status endpoint, subscription gate middleware, Stripe integration layer, API documentation.

Frontend: billing settings page (full state-aware rewrite), API client.


Known Issues

  • The registration page still displays static plan prices; these will move to the live pricing source in an upcoming release.
  • The invoice list links to the Stripe billing portal; an inline invoice list is planned.

The billing domain now matches the rest of the kernel: it states what is true, for every customer, in every state.