If Stripe completes 3D Secure but WooCommerce leaves the order pending, trace one transaction across browser return, PaymentIntent and webhook. Do not retry random checkout settings: the return page can succeed while the server-side event that confirms payment never updates the order.
Capture one correlation set
Keep the WooCommerce order ID, Stripe PaymentIntent/charge ID, browser return time and Stripe event ID. Never log card data.
Read the Stripe event delivery
Check whether the relevant payment event was sent, its HTTP response, attempts and endpoint. A 2xx response only proves receipt; confirm the handler actually reached the intended order.
Compare order notes with gateway state
Order notes should show what WooCommerce believed happened. If Stripe says paid and WooCommerce has no corresponding note, focus on webhook routing, signature, plugin errors or order lookup.
Check duplicate and late events
Events can arrive after the customer returns or more than once. The handler must be idempotent and able to reconcile a late confirmation without creating a second order.
Verify end to end
Run a controlled 3DS payment and confirm: successful authentication, one payment, one WooCommerce order, correct status and no second stock reduction.
Use the payment tracing guide to collect evidence safely, and compare the status path with payment succeeds but order remains pending.
Keep an evidence packet for the exact 3DS attempt
The useful packet is small but specific: order ID, PaymentIntent ID, event ID, event delivery result, order note before/after and the final stock state. That is enough to prove whether authentication, capture, notification or WooCommerce status handling failed without collecting sensitive card information.