-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Description
Bug Description
Race condition in Worldpay 3DS DDC flow causes bodyDoesNotMatchSchema
errors. 8-second timeout in WorldpayDDCForm
JS fires before legitimate DDC completion, sending collectionReference
to wrong endpoint (/3dsChallenges
vs /3dsDeviceData
).
Expected Behavior
DDC collectionReference
sent to /3dsDeviceData
endpoint only. Payment state transitions: DeviceDataCollectionPending
→ AuthenticationPending
→ Charged
.
Actual Behavior
Timeout fires → empty redirect → state advances to AuthenticationPending
→ late collectionReference
sent to /3dsChallenges
→ Worldpay rejects with $.collectionReference
validation error.
Steps To Reproduce
- Trigger Worldpay 3DS payment with DDC delay >8s
- Observe timeout in
api.rs:build_redirection_form()
- Check logs for missing
PaymentsStart
between redirects - Verify
bodyDoesNotMatchSchema
error
Context For The Bug
File: crates/router/src/services/api.rs
Line: window.setTimeout(submitCollectionReference, 8000);
in WorldpayDDCForm
Impact: Intermittent 3DS failures when DDC >8s
Log Evidence: 11.6s gap between DDC form serve and timeout redirect proves race condition.
Environment
Worldpay connector, 3DS flow with DDC
Have you spent some time checking if this bug has been raised before?
- I checked and didn't find a similar issue
Have you read the Contributing Guidelines?
- I have read the Contributing Guidelines
Are you willing to submit a PR?
Yes, I am willing to submit a PR!
Fix Plan:
Client-side (api.rs
):
- Increase timeout:
8000
→10000
- Add
ddcProcessed
flag to prevent multiple submissions - Handle 3 cases: DDC within 10s (normal), DDC never returns (empty submission), DDC after 10s (ignore)
Server-side (worldpay.rs
):
- Accept empty
collectionReference
inDeviceDataCollectionPending
state - Ignore late DDC submissions when already in
AuthenticationPending
state - Add validation to prevent sending
collectionReference
to/3dsChallenges
endpoint