Describe the bug
When a customer fails an initial payment attempt and then immediately retries and succeeds, the order ends up stuck in Failed status despite the payment being fully processed and charged. The root cause appears to be a delayed or out-of-order webhook from Paytrail's gateway: the failure notification from the first attempt arrives after the second attempt has already been confirmed as successful.
Steps to Reproduce
- Customer initiates checkout and pays with Mastercard → payment is declined
- Customer retries immediately using the same or a different card → payment succeeds
- WooCommerce receives the success callback and moves the order to Processing
- Stock is decremented (in this case going to -1, triggering a move to Backordered)
- Shortly after (~1 minute), a delayed failure webhook from the first payment attempt arrives
- The plugin processes this webhook and moves the order from Backordered → Failed
Expected behaviour
Once an order has reached Processing (or any post-payment status), incoming failure webhooks referencing an older, different transaction ID should be ignored. The plugin should not allow a stale failure notification to override a confirmed successful payment.
Before processing any failure webhook, the plugin should check whether the order already has a completed payment transaction ID recorded. If the incoming webhook's transaction ID differs from the one already stored on the order, the webhook should be discarded (or logged as informational) rather than applied.
Actual behaviour
Order ends up in Failed status even though a valid successful payment transaction exists. The order note log shows:
[16:46] Payment created with provider Mastercard (ID: c47...)
[16:46] Payment failed.
[16:46] Order status: Pending payment → Failed
[16:49] Payment created with provider Mastercard (ID: 88c...)
[16:49] Payment completed with transaction ID 88c...
[16:49] Order status: Failed → Processing
[16:49] Stock decremented: 0 → -1
[16:49] Order status: Processing → Backordered
[16:50] Payment failed. ← stale webhook from first attempt
[16:50] Order status: Backordered → Failed ← incorrectly overrides successful state
- The customer has been charged successfully, but the order appears failed to the merchant
- No fulfillment is triggered; the merchant must manually correct the order status
- Stock level is left incorrect
- This is a silent issue — nothing alerts the merchant that the order needs attention
Describe the bug
When a customer fails an initial payment attempt and then immediately retries and succeeds, the order ends up stuck in Failed status despite the payment being fully processed and charged. The root cause appears to be a delayed or out-of-order webhook from Paytrail's gateway: the failure notification from the first attempt arrives after the second attempt has already been confirmed as successful.
Steps to Reproduce
Expected behaviour
Once an order has reached Processing (or any post-payment status), incoming failure webhooks referencing an older, different transaction ID should be ignored. The plugin should not allow a stale failure notification to override a confirmed successful payment.
Before processing any failure webhook, the plugin should check whether the order already has a completed payment transaction ID recorded. If the incoming webhook's transaction ID differs from the one already stored on the order, the webhook should be discarded (or logged as informational) rather than applied.
Actual behaviour
Order ends up in Failed status even though a valid successful payment transaction exists. The order note log shows: