Autom8ion

Capability

Real books underneath the customer record.

Double-entry from the first posting, because retrofitting balance onto unbalanced history is a reconstruction rather than a migration. Postings are immutable and corrections are reversing entries, because editable history is not an audit trail whatever the report says.

What is built today.

Money that moves without a ledger entry is reconstructed later, and never fully right.

The ledger was built before the first payment could be taken, even with a minimal chart of accounts and nothing posting to it, because the alternative is rebuilding history from provider exports afterwards. Anyone who has done that reconciliation knows how it ends.

The properties were settled before any of it was written, not discovered afterwards: always balanced, postings immutable with corrections as reversing entries, money as integer minor units, currency and rate on every posting, a period close that actually forbids things, and a recognition schedule separate from cash movement — because memberships and travel take money now for revenue earned later, and that is the normal case here rather than an edge case.

  • Without period close, last year's numbers change while somebody is reading them
  • Without immutability, an audit trail is a suggestion
  • Without integer minor units, the errors are small, silent and everywhere
  • Without a captured rate, historical statements cannot be reproduced

Card data never reaches this platform, by design.

The architecture is decided and half of it is built. A payment attempt is tied to your own hosted payment page and the flow always redirects, which keeps the platform's card-handling scope at the minimum available. Provider-verified webhooks, idempotent posting and an automatic fifteen-minute reconciliation sweep for confirmations that never arrived are built.

What is missing is the customer-facing payment page itself. Balances and refunds have their postings; the money-in track is the gap, and we would rather say that than describe it as available. The reference adapter is written from current vendor documentation and has not run against a live account.

  • Idempotency on every charge attempt — a retried payment must never become two payments
  • Webhook verification per provider, each with its own signature scheme
  • The payment webhook route carries no API key at all — it is authenticated purely by signature
  • Reconciliation between provider records and the ledger is a requirement, not a report somebody writes later

Built for the situations a subscription actually hits.

The UK's subscription-contracts rules under the Digital Markets, Competition and Consumers Act 2024 commence in spring 2027. This vertical was built to them beforehand rather than retrofitted afterwards, and the regime was checked rather than recalled — the obvious reading, the EU Digital Markets Act, binds only designated gatekeepers and would have been the wrong thing to build to.

Four rules shape most of the code. A cancellation can never be refused — not in arrears, not mid-term; only the refund varies. Every renewal is a new contract period with its own cooling-off right and its own reminder. The cooling-off window is derived from the dates rather than stored, so it cannot drift. And renewal notices go out as contractual messages, never through the consent-gated campaign engine — a reminder sent that way would reach only the members who opted into marketing, which is a compliance failure that looks like a working feature.

  • Family and group memberships, with seats conferred by invite and a single-use link
  • Seat tiers and membership levels are your vocabulary, held as reference sets on the platform — a gym's are peak and off-peak, a theatre's are full, concession, under-16 and carer
  • A seat may name no tier at all: that is a general seat, not a missing value
  • Extra seats can be their own billable product, and seats can be constrained to one household
  • Nine real situations are driven end to end by the tests, including the holder dying and the contract transferring

Named after the situation, not the mechanism.

Each of these is a test that drives the whole flow, so what is protected is that the situation still works after somebody refactors the machinery underneath it.

Revenue recognised when it is earned, not when the money arrives.

A voucher is deferred revenue until it is redeemed or expires, with the remainder recognised as breakage. A download or a service charge earns at issue. That distinction is the whole point of the module for a finance team: the two look identical at the till and behave completely differently in the accounts.

Every recognition is named against the basket and the line it came from, and the sum recognised for a line can never exceed what was paid for it. Which is a property rather than a report — the ledger cannot be talked into it.

  • eGift vouchers, downloads, licence keys and service charges
  • Codes are bearer instruments: generated once, shown once, stored only as a keyed hash, and looked up by hash over a POST rather than sitting in a URL
  • An unknown code and another tenant's code get exactly the same answer, so the endpoint cannot be used to discover what exists
  • A copy of the database is not a pile of spendable money
  • Every sales vertical implements the same five operations — hold, extend, release, fulfil and cancel — so one storefront can drive all of them

A cart is not an order, and the whole design rests on that.

A cart holds selections — product ids and quantities — and no money at all. An order holds frozen prices, sub-orders and allocation, and it belongs to a person. Abandoning a cart costs nothing; abandoning an order is a refund conversation. Building the order while somebody browsed would turn every abandoned browse into a draft order with frozen prices, and 'basket' would come to mean something that is mostly junk.

So there is exactly one place where a cart becomes an order, at checkout. And no prices are stored in a cart: what it costs is asked for at the total and asked again at checkout, because a price quoted into a cart goes stale while somebody makes up their mind.

  • Two things authorise a request: the API key names your tenancy, the cart token names the cart
  • A wrong token answers exactly like a wrong id, so nobody can discover which carts exist
  • A shopper who is already signed in owns their cart from the first thing they add
  • Everybody else stays anonymous until they claim it or check out — no person record is created for a browser that may never buy
  • A person id in a request body is never treated as identity: sessions are verified by asking the platform, never by decoding a token locally

Built, next and later — for this module specifically.

Questions about commerce

Is this a replacement for my finance system?

It is a real double-entry ledger with a chart of accounts, journals, period close and reconciliation, built so that money taken on the platform has a correct posting at the moment it moves. Whether it replaces your finance system depends entirely on what that system does beyond the ledger, and that is a conversation worth having specifically rather than generally.

Why are the sales verticals separate deployables?

Because they have genuinely different lifecycles — inventory decrements, memberships renew, accommodation and travel hold reservations against time — and a common abstraction invented before seeing all five would very likely be wrong. What they do share is a contract: five operations — hold, extend, release, fulfil and cancel — tagged on the operations rather than fixed to URL names, so one storefront can drive every vertical without knowing what any of them sells.

Can I sell through my own website rather than yours?

Yes, and today that is the only option: the storefront API is built and the branded shopping site that sits on it is not. Your front end calls the API for carts and totals, and checkout hands off to the platform basket. When the branded site lands it will be one client of the same API rather than a replacement for it, so nothing you build now is thrown away.

How do you handle a member who wants to cancel?

You let them. A cancellation can never be refused — not in arrears, not mid-term — and only the refund varies. That is not generosity, it is the UK subscription-contracts regime under the Digital Markets, Competition and Consumers Act 2024, which commences in spring 2027 and which this vertical was built to before it starts rather than retrofitted to afterwards.

Why do renewal reminders not go through the campaign engine?

Because the campaign engine gates on marketing consent, correctly. A renewal reminder is a contractual notice, not marketing — pushed through the consent gate it would reach only the members who opted into marketing, which is a compliance failure that looks like a working feature. Contractual notices have their own path. A hard bounce still stops one, and raises a work item so somebody learns a member is unreachable before the renewal rather than after.

What happens to my books if I leave?

They come with you. A departing tenant's ledger is exported completely and then deleted with everything else, because the obligation to retain accounting records for their statutory period belongs to you as the departing controller rather than to this platform. That makes the export load-bearing rather than a courtesy, and the export states what happened to every store it clears.

Can one basket span several product lines?

Yes — that is precisely why the basket is its own module sitting between the ledger and payments. A single payment covering a voucher, a stay and a membership cannot be orchestrated inside any one of them. Each line becomes a sub-order that is tracked and refunded independently, with pro-rata allocation.

A ledger conversation goes faster with a real chart in front of it — and it is the quickest way to find out where the boundary with your finance system sits.

Bring your chart of accounts.

Book a demo