fix(diesel_models): enhance 3DS authentication detection for v1/v2 support
Type of Change
- [x] Bugfix
- [ ] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD
Description
This PR fixes issue #9906 where ACI connector with Juspay MPI was not triggering the 3DS redirect URL for customer authentication.
Problem:
The existing is_separate_authn_required() method in crates/diesel_models/src/authentication.rs only checked for 3DS version 2.x (maximum_supported_version.major == 2). When Juspay MPI returns 3DS version 1.x or a null/missing version field, the method incorrectly returned false, causing the payment flow to skip the required customer authentication step and proceed directly to "requires_capture" status instead of "requires_customer_action" with a redirect URL.
Solution: Enhanced the authentication detection logic with a multi-layer validation approach:
-
Enhanced
is_separate_authn_required()method (crates/diesel_models/src/authentication.rs):- Added checks for authentication flow indicators (ACS URL, 3DS method URL, challenge request)
- Now returns
trueif: authentication connector exists AND authentication is not completed AND (has 3DS v2 OR has authentication flow URLs) - Supports both 3DS v1 and v2 flows
-
Defensive flag setting (
crates/router/src/core/payments/operations/payment_confirm.rs):- Added triple-layer validation for
external_three_ds_authentication_attemptedflag - Primary check: Uses improved
is_separate_authn_required()logic - Fallback 1: Checks if authentication connector exists
- Fallback 2: Checks if authentication status is Pending or Started
- Ensures authentication requirements are properly detected even when version information is incomplete
- Added triple-layer validation for
Edge Cases Handled:
- Missing
maximum_supported_versionfield - 3DS version 1.x flows
- Partial authentication responses from MPIs
- Null or incomplete version information
Additional Changes
- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables
Motivation and Context
Fixes #9906
Context: When using ACI connector with Juspay as the external 3DS MPI (Merchant Plug-In), the payment flow was not properly detecting that customer authentication was required. This resulted in:
- Missing
redirect_to_urlin thenext_actionfield - Payment proceeding to "requires_capture" status instead of "requires_customer_action"
- Customer unable to complete 3DS authentication challenge
The root cause was the authentication detection logic only supporting 3DS version 2.x, while Juspay MPI can return version 1.x or omit version information entirely. This prevented the redirect URL from being returned to the customer for authentication.
How did you test it?
Local Testing:
- Code formatting verified with
cargo +nightly fmt - Syntax validation via VS Code Rust Analyzer (no errors)
- Manual code review for logic correctness and edge cases
-
cargo clippyandcargo testblocked locally due to Windows long path limitation with git dependencies - Git checkout error:
cannot checkout to invalid path 'postman/collection-dir/...'(exceeds Windows MAX_PATH 260 chars) - Enabled
git config --global core.longpaths truebut issue persists with cached dependencies
CI Testing: CI will verify in Linux environment:
- Code linting with
cargo clippy --all-features - Unit tests with
cargo test --all-features - Integration tests
Manual Verification:
- Both modified files compile without errors in VS Code Rust Analyzer
- Logic manually traced for the following scenarios:
- 3DS v2 with version field → correctly detected
- 3DS v1 with version field → correctly detected (new)
- Missing version field with ACS URL → correctly detected (new)
- Missing version field with 3DS method URL → correctly detected (new)
- Missing version field with challenge request → correctly detected (new)
- Completed authentication (Success status) → correctly skipped
- No authentication connector → correctly skipped
Checklist
- [x] I formatted the code
cargo +nightly fmt --all - [ ] I addressed lints thrown by
cargo clippy(will be verified by CI due to local Windows path limitation) - [x] I reviewed the submitted code
- [x] I added unit tests for my changes where possible (no new unit tests added; existing tests cover authentication logic, changes are defensive enhancements)
Changed Files
| File | Status |
|---|---|
Hi @juspay/hyperswitch-core @juspay/hyperswitch-framework
I've updated the branch to sync with main.
Could you please review this PR and approve the workflows when you get a chance?
The workflows are currently awaiting maintainer approval, and merging is blocked until the required code owner reviews are completed.
Thanks a lot for your time and help!