Revenue
Money travels in one place: the revenue block of the envelope.
"revenue": { "amount": "45.00", "currency": "EUR" }
amountis a decimal string with at most four decimal places, never a JSON number:"45.00", not45. A number is refused (revenue_malformed).currencyis an ISO 4217 code.- Only revenue-bearing activities may carry it, and never from a browser key (
revenue_not_allowed). Each activity page says whether it is revenue-bearing and which sign it takes.
| Activity | Sign | What the amount is |
|---|---|---|
issued_ticket | positive | the ticket's price, including products bundled in it |
issued_product | positive | the order-level product's price |
made_cashless_payment | positive | the payment |
refunded_ticket | negative | the refund |
Refunds are new activities, never edits: sums correct themselves. completed_order carries no revenue of its own: the lines do, so an order's revenue is the sum of its tickets and products, and an order that spans events attributes each ticket to its event. total_paid and payment_surcharge on the order are reporting money, not revenue.
The money guard
Money belongs in the revenue block, so that every amount in the stream is typed, signed and in a known currency. Any key in features whose name looks like money (amount, price, total, value, fee, cost, revenue, in any case and language the guard knows) is refused in every activity, open or strict (money_in_features). An activity that needs such a field for reporting declares an exemption: service_fee and scan_amount on issued_ticket, total_paid and payment_surcharge on completed_order, topup_amount on topped_up_wallet. Each page lists them under "money-like names allowed in features".
Amounts in minor units (cents) are the sender's to convert: the Weeztix mapper divides by the currency's exponent, which is 2 for EUR and 0 for JPY.