feat(connector): enhance ACI connector with comprehensive 3DS support - DRAFT#8986
Conversation
Changed Files
|
56e983c to
52ae874
Compare
| event_builder.map(|i| i.set_response_body(&response)); | ||
| router_env::logger::info!(connector_response=?response); | ||
|
|
||
| let response_data = if response.redirect.is_some() { |
There was a problem hiding this comment.
We generally keep type transformations in transformers.rs. Could we move this there and implement it using TryFrom for consistency? You can follow the handle_response function of trustpay.rs for any flow for reference.
| event_builder.map(|i| i.set_response_body(&response)); | ||
| router_env::logger::info!(connector_response=?response); | ||
|
|
||
| let authn_flow_type = if response.redirect.is_some() { |
There was a problem hiding this comment.
we can also move the logic written here in transformers.rs.
Ref: https://github.com/juspay/hyperswitch/pull/8986/files#r2285283012
| ), | ||
| connector: "ACI", | ||
| })?, | ||
| None => Ok(PaymentBrand::Visa), |
There was a problem hiding this comment.
Just to clarify - if card_network isn’t present, this defaults to Visa. Do we have any reason for choosing Visa as the fallback?
There was a problem hiding this comment.
Removed the default Visa for the rest flow, but retained it for NetworkToken.
This is because brand is a required field for NetworkToken, and since UAS doesn’t provide this field currently, its value will always be None.
| fn try_from( | ||
| (network_token_data, card_holder_name): (NetworkTokenData, Option<Secret<String>>), | ||
| ) -> Result<Self, Self::Error> { | ||
| let payment_brand = PaymentBrand::Visa; |
There was a problem hiding this comment.
Do we have any reason to hardcode the card brand Visa here? What would happen for Mastercard cards?
| })?, | ||
| card_expiry_month: network_token_data.get_network_token_expiry_month(), | ||
| card_expiry_year: network_token_data.get_expiry_year_4_digit(), | ||
| card_cvv: network_token_data.get_cryptogram().ok_or( |
There was a problem hiding this comment.
I am not sure why the cryptogram is passed in cvv. Could you please clarify? Is it because here it is dynamicCVV - which is essentially a cryptogram ?
There was a problem hiding this comment.
Fair, fixed the value population for cvv.
| PaymentBrand::Visa => "VISA", | ||
| PaymentBrand::Mastercard => "MASTER", | ||
| PaymentBrand::AmericanExpress => "AMEX", | ||
| _ => "VISA", |
There was a problem hiding this comment.
I see if the get_aci_payment_brand function returns JCB, Diners Club, Discover etc. they currently fall into the _ case and VISA will be returned. Do we want this behaviour here?
| PaymentBrand::Visa => "VISA", | ||
| PaymentBrand::Mastercard => "MASTER", | ||
| PaymentBrand::AmericanExpress => "AMEX", | ||
| _ => "VISA", |
There was a problem hiding this comment.
Don't pass visa as default value
bfc3c2f to
f7d12d6
Compare
| } | ||
|
|
||
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||
| pub enum ChallengeIndicator { |
There was a problem hiding this comment.
can we remove this since it's not in use?
- Add standalone 3DS authentication flow with proper /v1/threeDSecure endpoints - Implement AciThreeDSFlow redirect form variant with dual iframe support - Enhance request structures to match reference script specifications - Add network token support and payment brand mapping - Update webhook verification to use HMAC-SHA256 - Implement proper mandate setup functionality - Modernize test suite with ConnectorActions pattern and comprehensive coverage - Add 3DS-specific test scenarios with authentication flow validation
…n and resolved comments
… update status mapping
ede3689
d4351fe to
ede3689
Compare
…ee-ds * 'main' of github.com:juspay/hyperswitch: feat(webhooks): Provide outgoing webhook support for revenue recovery (#9294) feat(connector): Add Peachpayments Template Code (#9363) feat(connector): [Paysafe] Implement card 3ds flow (#9305) feat(router): Add Connector changes for 3ds (v2) (#9117) feat(connector): [ADYEN] Add support to ideal Mandate Webhook (#9347) refactor(core): accept manual retry from profile (#9302) fix(nuvei): nuvei 3ds fix + psync fix (#9279) fix(connector): [checkout] Add US Support for Apple Pay and Google Pay + Enhanced Checkout Response Data (#9356) fix(router): adding connector_customer_id for external vault proxy (#9263) feat(core): Add first_name and last_name as Secret<String> Types. (#9326) feat(injector): injector request formation changes (#9306) fix(revenue-recovery): Update Redis TTL for customer locks after token selection (#9282) chore(version): 2025.09.11.0 refactor(connector): [Paysafe] fix wasm (#9349) refactor(connector): rename RevenueRecoveryRecordBack as InvoiceRecordBack (#9321) feat(connector): [checkout] add support for MOTO payments (#9327) feat(connector): enhance ACI connector with comprehensive 3DS support - DRAFT (#8986) feat(core): [Retry] MIT Retries (#8628)
Type of Change
Summary
This PR enhances the ACI connector with comprehensive 3D Secure (3DS) authentication support and modernizes the test suite, porting behavioral improvements from the
ORCH-2/aci-fixesbranch to be compatible withthe current upstream codebase structure.
Key Changes
/v1/threeDSecureendpoints (PreAuthentication and Authentication)AciThreeDSFlowredirect form variant with dual iframe support for precondition and authentication steps@hyperswitch/tmp/poc-exipay-cnp/scripts/aci/3dsConnectorActionspattern with comprehensive coverage including positive, negative, and 3DS scenariosTechnical Details
Files Modified
crates/hyperswitch_connectors/src/connectors/aci.rs- Main connector implementationcrates/hyperswitch_connectors/src/connectors/aci/transformers.rs- Request/response transformerscrates/hyperswitch_domain_models/src/router_response_types.rs- RedirectForm enum extensioncrates/diesel_models/src/payment_attempt.rs- Database model updatescrates/router/src/services/api.rs- Framework-level redirect handlingcrates/router/tests/connectors/aci.rs- Complete test suite modernizationKey Implementations
AciStandalone3DSRequestwith all required fields including challenge indicators, enrollment flags, and proper card data handlingConnectorActionstrait pattern following project standardsTest Coverage Enhancements
Positive Test Scenarios
Negative Test Scenarios
3DS-Specific Tests
Validation
cargo +nightly fmtformatting checksConnectorActionspattern implementationTest Plan
Additional Changes
How did you test it?
1. Cards payment
Response
3. CIT
Response:
4. Corresponding MIT
Response
5. setup mandate
Response
6. MIT corresponding to setup mandate
Response
7. Network Token flow
I. Create ACI connector
II. Enable UAS for profile
III. create ctp_mastercard
IV. CTP profile update
V. create payment
Response
VI. confirm payment
Response
7. Manual capture
Response:
capture after redirection:
Response
Checklist
cargo +nightly fmt --allcargo clippy