We now have hook_payment_pre_execute(), which was designed to let modules modify payments before execution. One possible use case is adding an extra line item that contains a transaction fee for a certain payment method.
However, because pre execute happens after validation, payments can be modified in such a way that the chosen payment method may not even be able to process the modified payment at all. This is probably an edge case, but it's a potential problem nonetheless (and this is only one use case of hook_payment_pre_execute()).
To solve this, we could add a hook_payment_pre_validate() that fires right before a payment method's validate() method is called. We'd need to properly document that modules are allowed to modify payments in this hook, and that whenever you call validation on a payment, you need to expect the payment to be modified. Payment::availablePaymentMethods() can be updated to pass on cloned Payment objects to the payment method's validate() method, to ensure correct validation for all payment methods. We'd also need to update the documentation for hook_payment_pre_execute() (if we even still need that hook) to say it's no longer meant for modifying payments.
Postponed to version 2.
Comments
Comment #1
xanoOr we could use a hook_payment_alter() instead of hook_payment_pre_validate() and hook_payment_pre_execute().
Comment #2
xanoThe Payment alter event, either through Symfony's event system or as a hook, sounds like a good idea. We can fire the event before validation and execution, and clone the payment before altering it when we're just validating.
Comment #3
xanoComment #4
xanoWe have 'access' and 'pre' hooks for all operations, including execution, now #1980392: Payment operations has been fixed.