The payment workflow bridge (orchestra_payment) claims the SETTLED and FAILED payment events for workflow-pinned payments, calling setHandled() so a consumer's default reaction stands down and the workflow stays in charge of the run. The REFUNDED event is not claimed.
When a workflow action refunds a pinned payment (for example on a rejection or cancellation path), a consumer's autonomous cancel-on-refund reaction then runs behind the workflow's back. In the yoyaku booking example this cancels the booking the run still owns, which trips the guard that cancels a running instance whose booking was cancelled externally, so the instance ends cancelled instead of completing normally.
Proposed resolution
Subscribe the bridge to REFUNDED and claim it when the payment carries a pinned token, mirroring the FAILED handler. Nothing is resumed: a refund is a mid-run side effect, not a parked-token outcome, so the run drives its own release and end. A refund on an unpinned payment (issued outside any workflow) is left untouched, so a consumer's cancel-on-refund still applies there.
Tests
Two kernel tests in PaymentBridgeTest: a refund on a workflow-pinned payment is claimed and leaves the parked step untouched; a refund on an unpinned payment is not claimed.
Issue fork orchestra-3609403
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
mably commented