Issue #3614433: Name yoyaku's payments in yoyaku's words instead of reading a kessai constant
Yoyaku decided what a payment means to a booking by reading it off a kessai constant. That worked for a security deposit and not for a no-show fee: the fee is charged through chargeToken(), which stamped the checkout payment's kind by default, so on the order it settled the fee was indistinguishable from the payment for the booking. Refunding a waived fee would have read as refunding the booking and cancelled it.
What changed
Kessai now stores a purpose it never reads and requires the caller to name it (kessai #3614434), and orchestra passes the payable's purpose through (orchestra #3614447). So the vocabulary lives here, in PaymentPurpose:
| Purpose | What it is | Ends as |
|---|---|---|
booking |
what the visitor pays for the booking | captured, or refunded if the booking is undone |
guarantee |
what is held against the stored card, and whatever is claimed from it | released when nothing goes wrong, captured or charged when something does |
Two values, not three. The no-show fee is not a third thing: a visitor who never arrived cannot also have damaged anything, so the deposit claim and the fee are two names for claiming the same guarantee, never both at once. What matters is that neither is the booking payment.
Sharing one purpose between the hold and the fee is safe under kessai's idempotency, which I checked rather than assumed: an authorization is reused only from AUTHORIZED or PENDING and a charge only from CAPTURED or PENDING, so a fee charged while a hold is live is not mistaken for it. That is recorded in the class docblock, along with the note that claiming the hold instead of charging afresh would remove the second payment altogether.
The booking payment names itself through the payable the resolver builds, so settlement recognizes it by a value this module chose rather than by a constant of the payment layer or a setting a site can edit.
Testing
23/23 kernel classes green across yoyaku_payment and yoyaku_orchestra, run against merged kessai and orchestra locally. phpcs and cspell clean.
payment.md gains the table of purposes and the rule that settlement answers for the booking payment alone, failure excepted. No translation change: purposes are machine names, and the diff adds no user-facing string.