Skip to content

Offers and purchases

An offer combines billing terms with a purchase. The purchase describes what successful settlement provides; billing describes how the customer pays.

flowchart LR
  accTitle: Offer and purchase composition
  accDescr: An offer revision combines billing terms with a purchase revision containing the benefits delivered after settlement.
  Offer["Offer revision"] --> Billing["Billing terms"]
  Offer --> Purchase["Purchase revision"]
  Billing --> BillingKinds["One-time · subscription · metered · per-seat"]
  Purchase --> Benefits["Access · licensing · downloads · credits · seats · limits · fulfillment"]

The same purchase revision can appear behind multiple compatible offers. For example, monthly and yearly offers can provide the same entitlement while retaining distinct billing terms. SAPA detects conflicting reuse of an offer or purchase key and revision.

  1. Benefit helpers such as Access.entitlements and Licensing.eligibility strictly decode reusable definitions through their public Schemas.
  2. Purchase.parse validates the purchase shape.
  3. Offer.parse checks relationships across billing and benefits.
  4. Offer.register checks identity consistency across a collection in memory.
  5. registerOffers validates installation capabilities and persists the collection through a composed Sapa runtime.

The helpers are effectful parsers, not unchecked object factories. Fixed wire fields are supplied for you: for example, Billing.subscription fixes manual renewal and Licensing.eligibility fixes validity to while_entitled. The underlying Schemas and their cases remain available when you need native Schema construction, matching, or encoding.

Runtime monetary amounts are bigint minor units. 1_499_000n IDR means 1,499,000 rupiah. JSON codecs use canonical decimal strings because JSON cannot represent bigint directly and floating-point numbers are unsuitable for exact money.

Treat (key, revision) as immutable. A copy edit, price change, benefit change, or policy change that alters accepted terms requires a new revision rather than an in-place update.