A payment gateway capture, release and refund report failure as a bare boolean, so a caller learns only that the operation failed, not whether it can succeed on a retry. A Worldline capture or cancel run just after an authorization can be refused only because the transaction has not settled into a state that allows it yet (error 50001127, ACTION_NOT_ALLOWED_ON_TRANSACTION), and a later retry succeeds. That is indistinguishable from a permanent decline today.

This changes capture(), release() and refund() to return void and throw a typed exception on failure: GatewayRetryableException when the provider cannot act on the transaction yet, GatewayDeclinedException when it permanently refused. The Worldline gateway classifies each failure by its structured error, and the payment manager propagates the exception instead of swallowing it, advancing the payment state only on success. A caller such as a workflow settlement step can then retry the transient case and escalate the permanent one.

The create operations (authorize, chargeToken) keep their boolean return, since their outcome is recorded as the payment state. Kernel tests cover the manager propagating a decline out of captureHold, releaseHold and refund, and the Worldline gateway mapping a transient error code to retryable and any other to declined.

Issue fork kessai-3609746

Command icon 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

mably created an issue. See original summary.

mably’s picture

Status: Active » Needs review

  • mably committed 4a85935e on 1.x
    task: #3609746 Classify a failed capture, release or refund as retryable...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.