The Worldline return controller fetches the authoritative outcome from Worldline when the payer returns from the hosted checkout. On any failure to fetch that outcome (a network blip, the API momentarily unavailable), it called PaymentManager::fail(), flipping the still-pending payment to failed.

This defeats the webhook backstop. The server-to-server webhook is the authoritative channel that settles a payment when the payer never returns, and the finalizer it shares only acts on a still-pending payment. Once the return has failed the payment, a later webhook carrying the real captured outcome finds it no longer pending and leaves it failed, so a genuinely paid checkout is stranded as failed with the webhook unable to repair it.

Fix

  • On a transient status-fetch error, log and leave the payment pending, so the webhook (or a back-office reconciliation) still settles it. Only an authoritative negative outcome, through the finalizer, fails a payment.
  • When the client is momentarily unavailable but a checkout session exists, leave the payment pending rather than failing it.
  • Still fail a payment that never obtained a hosted-checkout session, since there is nothing to reconcile.

Tests

Adds a WorldlineReturnTest kernel test: a transient fetch failure leaves the payment pending (the regression), a missing checkout session fails it, and a forged return token is denied.

Issue fork kessai-3610463

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 committed 91e3e697 on 1.x
    fix: #3610463 Do not fail a Worldline payment on a transient return...
mably’s picture

Status: Active » 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.