Kaláka

Money

Core money scope

Amounts

Ledger

Kind Sign Written by
charge, per fee component (the fixed price; plugin components such as a late fee or a staff discount) ± the materializer
payment (online or another automatic method) − Payments, from payment-method events
refund + Payments, from payment-method events
manual_payment (bank transfer, cash) − an organizer use case
adjustment (correction with a reason) ± an admin use case
feature lines (aid award, sponsor support, wallet, …) ± feature plugins, through an extension point

Tariff snapshot and re-price

Materializer

flowchart LR
  S["Registration snapshot<br/>tariff, choices"] --> R
  F["Registration facts<br/>status, answers, additional forms"] --> R
  X["Extension inputs<br/>aid award, …"] --> R
  PF["Payment facts<br/>read from payment lines only"] --> R
  R["Fee components<br/>target amount per component"] --> MZ["Materializer<br/>target − recorded ≠ 0<br/>→ one new line"]
  MZ --> L[("Ledger<br/>append-only lines")]
  PM["Payment-method plugin<br/>e.g. WooCommerce"] -->|"paid / refunded"| L
  ST["Organizers<br/>cash, bank transfer"] --> L
  L -. "payment facts" .-> PF

Payments

Paying several registrations at once

An account holder pays everything outstanding, e.g. two children in two camps, in one payment. Each event’s money still lands in its own ledger.

sequenceDiagram
  actor H as Account holder
  participant P as Portal
  participant C as Core · Payments
  participant W as WooCommerce plugin
  participant L as Ledger
  H->>P: Pay all outstanding
  P->>C: payment request, one line per registration
  C->>W: create order
  W-->>H: hosted pay page
  H->>W: pays (card, Apple / Google Pay)
  W->>C: paid (order ID)
  C->>L: one payment line per registration
  Note over L: each event's budget stays separate
  C-->>H: payment mail, sent by the sender run

Refunds

An admin-started WooCommerce refund:

  1. writes a refund-request record inside the use case’s transaction (its uniqueness guards against starting the same refund twice);
  2. calls WooCommerce after commit, in the same request, so the admin sees the result right away;
  3. on a definite failure, keeps the status and error on the record, with a retry button;
  4. on a timeout or unknown outcome, leaves the record “in progress” for the admin to check in WooCommerce. It is never retried automatically, which rules out a double refund.

The refund line itself arrives through WooCommerce’s refund event, exactly once.