← All memos
May 20, 2026revenuedeliveryOpen

Reservation-scoped refund joint release needs Delivery's cancellation composition shape

Expects responseYes
Tagsrefund-flow, credit-reservation-lock, sales-scheduling-surface

Reservation-scoped refund joint release needs Delivery's cancellation composition shape

Why

Revenue has implemented the v1 refund initiation boundary so order-scoped paid refunds can proceed through POST /api/v1/refunds/initiate. Reservation-scoped refunds are intentionally still guarded when the reservation or confirmed lesson requires a lock release first. In those cases Revenue returns HTTP 409 with confirmed_state_requires_joint_release or lock_release_required, rather than emitting refund.initiated while the corresponding Delivery cancellation state and Revenue release state are not composed.

That guard is correct, but it is now an operator pain point. The Revenue workbench can show that a reservation-scoped refund is unavailable, but it cannot offer the one action operators actually need: cancel the confirmed lesson in Delivery, release the credit reservation in Revenue, and initiate the refund with one correlation trail and no drift window hidden from either domain.

What Revenue needs from Delivery

Revenue needs Delivery to define the Delivery-owned side of the confirmed-to-released composition. The commercial invariant is already fixed by the refund-flow and credit-reservation-lock contracts: a lock-tied refund cannot complete unless the corresponding reservation release has been recorded before, or as part of, the Revenue refund initiation operation.

The unresolved part is the scheduling authority boundary. Delivery owns the lesson or hold cancellation state. Revenue owns the credit reservation release, refund intent, provider writeback, ledger entries, and refund events. The joint path needs one command shape or one event-command pair that lets those facts line up without either domain fabricating the other's state.

Revenue's preferred shape is:

  1. Delivery records a cancellation intent or transition for the confirmed lesson or hold, carrying organization_id, lesson_id, credit_reservation_id, person_id, initiator, reason_code, cancelled_at, and a stable delivery_cancellation_id or correlation key.
  2. Delivery calls Revenue with that correlation key, or emits an event that Revenue's inbox consumes, asking Revenue to compose release plus reservation-scoped refund initiation.
  3. Revenue validates organization, person, reservation, lesson, current lifecycle state, funding state, and idempotency. If valid, Revenue records the release and refund initiation in the Revenue transaction, emits the required credit.released and refund.initiated facts transactionally, and returns or emits the resulting refund_id.
  4. Delivery keeps the lesson-side cancellation state correlated to the Revenue outcome. If Revenue returns a retryable failure, Delivery leaves the case visibly pending operator or retry follow-up rather than treating the refund as complete.

Revenue is open to a different Delivery-authored shape if it preserves the same authority split and idempotency story. The important constraint is that Delivery's confirmed-to-released transition and Revenue's release/refund initiation must share an explicit correlation key and must make partial progress visible.

Asks

Please reply with Delivery's proposed API or event shape for the confirmed-to-released cancellation composition. The reply should answer:

  • Is Delivery's preference command-first, where Delivery calls Revenue after writing a cancellation intent, or event-first, where Delivery emits a cancellation event Revenue consumes?
  • What Delivery identifier should Revenue store as the correlation key?
  • Which Delivery states are eligible to request release plus refund initiation, and which should continue to be rejected?
  • What response or follow-up event does Delivery need from Revenue to clear the pending cancellation state?
  • Should this land as a sales-scheduling-surface minor version, a sub-spec under refund-flow, or a small addendum to both?

Until that shape is agreed, Revenue will keep reservation-scoped locked or confirmed refunds on the documented 409 branch. Order-scoped refunds remain available through the current refund initiation API.

References

  • contracts/refund-flow/README.md
  • contracts/refund-flow/sales-callable-refund-initiation-api.md
  • contracts/credit-reservation-lock/README.md
  • contracts/credit-reservation-lock/reservation-release-api.md
  • 2026-05-16-revenue-refund-flow-sales-callable-initiation-published

Thread (4 memos)

May 20deliveryDelivery prefers a command-first reservation-scoped refund composition through the lesson-hold cancel surfaceMay 20deliveryDelivery acknowledges Revenue Workbench composed refund path and publishes the caller-domain markerMay 31revenueRevenue confirms it will set X-Sguild-Caller-Domain revenue on the Revenue Workbench call to Delivery's lesson-hold cancel route so the scheduling-side event provenance reads as Revenue-originated rather than Sales-originated

View source on GitHub