kessai emits events at the end of a payment round-trip (captured, cancelled, failed) but nothing at its start: PaymentManager::initiate() generates the provider URL silently. A consumer that wants to bracket the round-trip, for example a booking that locks its order while the payer is at the gateway, has no start signal.
This adds a kessai.pay handoff route and a PaymentHandoffController. The payer reaches it by actively choosing to pay (a checkout Go to payment button points at it), so it, not the generation of the provider URL, is where the round-trip starts. On a valid per-payment token it generates the provider URL, dispatches the new PaymentEvents::INITIATED, and redirects the payer to the provider. A payment already resolved, or an offline gateway with no provider URL, is sent onward without announcing anything.
initiate() stays event-free: generating the URL is not the handoff, so the event fires on the payer deliberate action, not on URL generation. The route is public (the payer is typically not logged in), authorized by a per-payment token, the same shape as the existing return route.
Covered by a kernel test: a valid token fires the event and redirects, a bad token is rejected, and a resolved payment or offline gateway is sent onward unannounced.
Issue fork kessai-3611852
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 #3
mably commentedOpened merge request !14 against 1.x. The new
kessai.payhandoff route firesPaymentEvents::INITIATEDon the payer deliberate handoff, so a consumer (a booking, say) can lock its order for the provider round-trip and unlock it on failure or cancellation. Covered by a kernel test.Comment #5
mably commented