Skip to content

Commit 9adb425

Browse files
sai-harsha-vardhansahkalhyperswitch-bot[bot]
authored
refactor(router): refactor ctp flow to fetch mca_id and get the connector creds instead of connector_name (#7078)
Co-authored-by: Sahkal Poddar <[email protected]> Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
1 parent bcbc83e commit 9adb425

File tree

16 files changed

+242
-152
lines changed

16 files changed

+242
-152
lines changed

crates/api_models/src/admin.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,8 +1864,9 @@ pub struct ProfileCreate {
18641864
pub is_click_to_pay_enabled: bool,
18651865

18661866
/// Product authentication ids
1867-
#[schema(value_type = Option<Object>, example = r#"{ "key1": "value-1", "key2": "value-2" }"#)]
1868-
pub authentication_product_ids: Option<HashMap<String, id_type::MerchantConnectorAccountId>>,
1867+
#[schema(value_type = Option<Object>, example = r#"{ "click_to_pay": "mca_ushduqwhdohwd", "netcetera": "mca_kwqhudqwd" }"#)]
1868+
pub authentication_product_ids:
1869+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
18691870
}
18701871

18711872
#[nutype::nutype(
@@ -1981,8 +1982,9 @@ pub struct ProfileCreate {
19811982
pub is_click_to_pay_enabled: bool,
19821983

19831984
/// Product authentication ids
1984-
#[schema(value_type = Option<Object>, example = r#"{ "key1": "value-1", "key2": "value-2" }"#)]
1985-
pub authentication_product_ids: Option<HashMap<String, id_type::MerchantConnectorAccountId>>,
1985+
#[schema(value_type = Option<Object>, example = r#"{ "click_to_pay": "mca_ushduqwhdohwd", "netcetera": "mca_kwqhudqwd" }"#)]
1986+
pub authentication_product_ids:
1987+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
19861988
}
19871989

19881990
#[cfg(feature = "v1")]
@@ -2117,8 +2119,9 @@ pub struct ProfileResponse {
21172119
pub is_click_to_pay_enabled: bool,
21182120

21192121
/// Product authentication ids
2120-
#[schema(value_type = Option<Object>, example = r#"{ "key1": "value-1", "key2": "value-2" }"#)]
2121-
pub authentication_product_ids: Option<serde_json::Value>,
2122+
#[schema(value_type = Option<Object>, example = r#"{ "click_to_pay": "mca_ushduqwhdohwd", "netcetera": "mca_kwqhudqwd" }"#)]
2123+
pub authentication_product_ids:
2124+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
21222125
}
21232126

21242127
#[cfg(feature = "v2")]
@@ -2240,8 +2243,9 @@ pub struct ProfileResponse {
22402243
pub is_click_to_pay_enabled: bool,
22412244

22422245
/// Product authentication ids
2243-
#[schema(value_type = Option<Object>, example = r#"{ "key1": "value-1", "key2": "value-2" }"#)]
2244-
pub authentication_product_ids: Option<serde_json::Value>,
2246+
#[schema(value_type = Option<Object>, example = r#"{ "click_to_pay": "mca_ushduqwhdohwd", "netcetera": "mca_kwqhudqwd" }"#)]
2247+
pub authentication_product_ids:
2248+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
22452249
}
22462250

22472251
#[cfg(feature = "v1")]
@@ -2370,8 +2374,9 @@ pub struct ProfileUpdate {
23702374
pub is_click_to_pay_enabled: Option<bool>,
23712375

23722376
/// Product authentication ids
2373-
#[schema(value_type = Option<Object>, example = r#"{ "key1": "value-1", "key2": "value-2" }"#)]
2374-
pub authentication_product_ids: Option<HashMap<String, id_type::MerchantConnectorAccountId>>,
2377+
#[schema(value_type = Option<Object>, example = r#"{ "click_to_pay": "mca_ushduqwhdohwd", "netcetera": "mca_kwqhudqwd" }"#)]
2378+
pub authentication_product_ids:
2379+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
23752380
}
23762381

23772382
#[cfg(feature = "v2")]
@@ -2481,8 +2486,9 @@ pub struct ProfileUpdate {
24812486
pub is_click_to_pay_enabled: Option<bool>,
24822487

24832488
/// Product authentication ids
2484-
#[schema(value_type = Option<Object>, example = r#"{ "key1": "value-1", "key2": "value-2" }"#)]
2485-
pub authentication_product_ids: Option<HashMap<String, id_type::MerchantConnectorAccountId>>,
2489+
#[schema(value_type = Option<Object>, example = r#"{ "click_to_pay": "mca_ushduqwhdohwd", "netcetera": "mca_kwqhudqwd" }"#)]
2490+
pub authentication_product_ids:
2491+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
24862492
}
24872493

24882494
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]

crates/common_enums/src/enums.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3575,12 +3575,33 @@ pub enum StripeChargeType {
35753575
Destination,
35763576
}
35773577

3578+
/// Authentication Products
3579+
#[derive(
3580+
Clone,
3581+
Copy,
3582+
Debug,
3583+
Eq,
3584+
Hash,
3585+
PartialEq,
3586+
serde::Serialize,
3587+
serde::Deserialize,
3588+
strum::Display,
3589+
strum::EnumString,
3590+
ToSchema,
3591+
)]
3592+
#[serde(rename_all = "snake_case")]
3593+
#[strum(serialize_all = "snake_case")]
3594+
pub enum AuthenticationProduct {
3595+
ClickToPay,
3596+
}
3597+
35783598
/// Connector Access Method
35793599
#[derive(
35803600
Clone,
35813601
Copy,
35823602
Debug,
35833603
Eq,
3604+
Hash,
35843605
PartialEq,
35853606
serde::Deserialize,
35863607
serde::Serialize,

crates/common_types/src/payments.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
//! Payment related types
22
3+
use std::collections::HashMap;
4+
35
use common_enums::enums;
4-
use common_utils::{impl_to_sql_from_sql_json, types::MinorUnit};
6+
use common_utils::{errors, impl_to_sql_from_sql_json, types::MinorUnit};
57
use diesel::{sql_types::Jsonb, AsExpression, FromSqlRow};
68
use serde::{Deserialize, Serialize};
79
use utoipa::ToSchema;
@@ -38,3 +40,28 @@ pub struct StripeSplitPaymentRequest {
3840
pub transfer_account_id: String,
3941
}
4042
impl_to_sql_from_sql_json!(StripeSplitPaymentRequest);
43+
44+
#[derive(
45+
Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema,
46+
)]
47+
#[diesel(sql_type = Jsonb)]
48+
#[serde(deny_unknown_fields)]
49+
/// Hashmap to store mca_id's with product names
50+
pub struct AuthenticationConnectorAccountMap(
51+
HashMap<enums::AuthenticationProduct, common_utils::id_type::MerchantConnectorAccountId>,
52+
);
53+
impl_to_sql_from_sql_json!(AuthenticationConnectorAccountMap);
54+
55+
impl AuthenticationConnectorAccountMap {
56+
/// fn to get click to pay connector_account_id
57+
pub fn get_click_to_pay_connector_account_id(
58+
&self,
59+
) -> Result<common_utils::id_type::MerchantConnectorAccountId, errors::ValidationError> {
60+
self.0
61+
.get(&enums::AuthenticationProduct::ClickToPay)
62+
.ok_or(errors::ValidationError::MissingRequiredField {
63+
field_name: "authentication_product_id.click_to_pay".to_string(),
64+
})
65+
.cloned()
66+
}
67+
}

crates/diesel_models/src/business_profile.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ pub struct Profile {
5858
pub is_auto_retries_enabled: Option<bool>,
5959
pub max_auto_retries_enabled: Option<i16>,
6060
pub is_click_to_pay_enabled: bool,
61-
pub authentication_product_ids: Option<serde_json::Value>,
61+
pub authentication_product_ids:
62+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
6263
}
6364

6465
#[cfg(feature = "v1")]
@@ -103,7 +104,8 @@ pub struct ProfileNew {
103104
pub is_auto_retries_enabled: Option<bool>,
104105
pub max_auto_retries_enabled: Option<i16>,
105106
pub is_click_to_pay_enabled: bool,
106-
pub authentication_product_ids: Option<serde_json::Value>,
107+
pub authentication_product_ids:
108+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
107109
}
108110

109111
#[cfg(feature = "v1")]
@@ -145,7 +147,8 @@ pub struct ProfileUpdateInternal {
145147
pub is_auto_retries_enabled: Option<bool>,
146148
pub max_auto_retries_enabled: Option<i16>,
147149
pub is_click_to_pay_enabled: Option<bool>,
148-
pub authentication_product_ids: Option<serde_json::Value>,
150+
pub authentication_product_ids:
151+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
149152
}
150153

151154
#[cfg(feature = "v1")]
@@ -305,7 +308,8 @@ pub struct Profile {
305308
pub is_auto_retries_enabled: Option<bool>,
306309
pub max_auto_retries_enabled: Option<i16>,
307310
pub is_click_to_pay_enabled: bool,
308-
pub authentication_product_ids: Option<serde_json::Value>,
311+
pub authentication_product_ids:
312+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
309313
}
310314

311315
impl Profile {
@@ -365,7 +369,8 @@ pub struct ProfileNew {
365369
pub is_auto_retries_enabled: Option<bool>,
366370
pub max_auto_retries_enabled: Option<i16>,
367371
pub is_click_to_pay_enabled: bool,
368-
pub authentication_product_ids: Option<serde_json::Value>,
372+
pub authentication_product_ids:
373+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
369374
}
370375

371376
#[cfg(feature = "v2")]
@@ -409,7 +414,8 @@ pub struct ProfileUpdateInternal {
409414
pub is_auto_retries_enabled: Option<bool>,
410415
pub max_auto_retries_enabled: Option<i16>,
411416
pub is_click_to_pay_enabled: Option<bool>,
412-
pub authentication_product_ids: Option<serde_json::Value>,
417+
pub authentication_product_ids:
418+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
413419
}
414420

415421
#[cfg(feature = "v2")]

crates/hyperswitch_domain_models/src/business_profile.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ pub struct Profile {
5959
pub is_auto_retries_enabled: bool,
6060
pub max_auto_retries_enabled: Option<i16>,
6161
pub is_click_to_pay_enabled: bool,
62-
pub authentication_product_ids: Option<serde_json::Value>,
62+
pub authentication_product_ids:
63+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
6364
}
6465

6566
#[cfg(feature = "v1")]
@@ -101,7 +102,8 @@ pub struct ProfileSetter {
101102
pub is_auto_retries_enabled: bool,
102103
pub max_auto_retries_enabled: Option<i16>,
103104
pub is_click_to_pay_enabled: bool,
104-
pub authentication_product_ids: Option<serde_json::Value>,
105+
pub authentication_product_ids:
106+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
105107
}
106108

107109
#[cfg(feature = "v1")]
@@ -201,7 +203,8 @@ pub struct ProfileGeneralUpdate {
201203
pub is_auto_retries_enabled: Option<bool>,
202204
pub max_auto_retries_enabled: Option<i16>,
203205
pub is_click_to_pay_enabled: Option<bool>,
204-
pub authentication_product_ids: Option<serde_json::Value>,
206+
pub authentication_product_ids:
207+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
205208
}
206209

207210
#[cfg(feature = "v1")]
@@ -729,7 +732,8 @@ pub struct Profile {
729732
pub version: common_enums::ApiVersion,
730733
pub is_network_tokenization_enabled: bool,
731734
pub is_click_to_pay_enabled: bool,
732-
pub authentication_product_ids: Option<serde_json::Value>,
735+
pub authentication_product_ids:
736+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
733737
}
734738

735739
#[cfg(feature = "v2")]
@@ -771,7 +775,8 @@ pub struct ProfileSetter {
771775
pub is_tax_connector_enabled: bool,
772776
pub is_network_tokenization_enabled: bool,
773777
pub is_click_to_pay_enabled: bool,
774-
pub authentication_product_ids: Option<serde_json::Value>,
778+
pub authentication_product_ids:
779+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
775780
}
776781

777782
#[cfg(feature = "v2")]
@@ -872,7 +877,8 @@ pub struct ProfileGeneralUpdate {
872877
pub order_fulfillment_time_origin: Option<common_enums::OrderFulfillmentTimeOrigin>,
873878
pub is_network_tokenization_enabled: Option<bool>,
874879
pub is_click_to_pay_enabled: Option<bool>,
875-
pub authentication_product_ids: Option<serde_json::Value>,
880+
pub authentication_product_ids:
881+
Option<common_types::payments::AuthenticationConnectorAccountMap>,
876882
}
877883

878884
#[cfg(feature = "v2")]

crates/hyperswitch_domain_models/src/merchant_connector_account.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ impl MerchantConnectorAccount {
5656
pub fn get_id(&self) -> id_type::MerchantConnectorAccountId {
5757
self.merchant_connector_id.clone()
5858
}
59-
6059
pub fn get_connector_account_details(
6160
&self,
6261
) -> error_stack::Result<router_data::ConnectorAuthType, common_utils::errors::ParsingError>
@@ -66,6 +65,11 @@ impl MerchantConnectorAccount {
6665
.clone()
6766
.parse_value("ConnectorAuthType")
6867
}
68+
69+
pub fn get_connector_wallets_details(&self) -> Option<Secret<Value>> {
70+
self.connector_wallets_details.as_deref().cloned()
71+
}
72+
6973
pub fn get_connector_test_mode(&self) -> Option<bool> {
7074
self.test_mode
7175
}
@@ -124,6 +128,11 @@ impl MerchantConnectorAccount {
124128
.clone()
125129
.parse_value("ConnectorAuthType")
126130
}
131+
132+
pub fn get_connector_wallets_details(&self) -> Option<Secret<Value>> {
133+
self.connector_wallets_details.as_deref().cloned()
134+
}
135+
127136
pub fn get_connector_test_mode(&self) -> Option<bool> {
128137
todo!()
129138
}

crates/router/src/consts.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,5 +211,9 @@ pub const DYNAMIC_ROUTING_MAX_VOLUME: u8 = 100;
211211
/// Click To Pay
212212
pub const CLICK_TO_PAY: &str = "click_to_pay";
213213

214+
/// Merchant eligible for authentication service config
215+
pub const AUTHENTICATION_SERVICE_ELIGIBLE_CONFIG: &str =
216+
"merchants_eligible_for_authentication_service";
217+
214218
/// Refund flow identifier used for performing GSM operations
215219
pub const REFUND_FLOW_STR: &str = "refund_flow";

crates/router/src/core/admin.rs

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3626,13 +3626,6 @@ impl ProfileCreateBridge for api::ProfileCreate {
36263626
})
36273627
.transpose()?;
36283628

3629-
let authentication_product_ids = self
3630-
.authentication_product_ids
3631-
.map(serde_json::to_value)
3632-
.transpose()
3633-
.change_context(errors::ApiErrorResponse::InternalServerError)
3634-
.attach_printable("failed to parse product authentication id's to value")?;
3635-
36363629
Ok(domain::Profile::from(domain::ProfileSetter {
36373630
profile_id,
36383631
merchant_id: merchant_account.get_id().clone(),
@@ -3703,7 +3696,7 @@ impl ProfileCreateBridge for api::ProfileCreate {
37033696
is_auto_retries_enabled: self.is_auto_retries_enabled.unwrap_or_default(),
37043697
max_auto_retries_enabled: self.max_auto_retries_enabled.map(i16::from),
37053698
is_click_to_pay_enabled: self.is_click_to_pay_enabled,
3706-
authentication_product_ids,
3699+
authentication_product_ids: self.authentication_product_ids,
37073700
}))
37083701
}
37093702

@@ -3755,13 +3748,6 @@ impl ProfileCreateBridge for api::ProfileCreate {
37553748
})
37563749
.transpose()?;
37573750

3758-
let authentication_product_ids = self
3759-
.authentication_product_ids
3760-
.map(serde_json::to_value)
3761-
.transpose()
3762-
.change_context(errors::ApiErrorResponse::InternalServerError)
3763-
.attach_printable("failed to parse product authentication id's to value")?;
3764-
37653751
Ok(domain::Profile::from(domain::ProfileSetter {
37663752
id: profile_id,
37673753
merchant_id: merchant_id.clone(),
@@ -3819,7 +3805,7 @@ impl ProfileCreateBridge for api::ProfileCreate {
38193805
is_tax_connector_enabled: self.is_tax_connector_enabled,
38203806
is_network_tokenization_enabled: self.is_network_tokenization_enabled,
38213807
is_click_to_pay_enabled: self.is_click_to_pay_enabled,
3822-
authentication_product_ids,
3808+
authentication_product_ids: self.authentication_product_ids,
38233809
}))
38243810
}
38253811
}
@@ -4027,13 +4013,6 @@ impl ProfileUpdateBridge for api::ProfileUpdate {
40274013
})
40284014
.transpose()?;
40294015

4030-
let authentication_product_ids = self
4031-
.authentication_product_ids
4032-
.map(serde_json::to_value)
4033-
.transpose()
4034-
.change_context(errors::ApiErrorResponse::InternalServerError)
4035-
.attach_printable("failed to parse product authentication id's to value")?;
4036-
40374016
Ok(domain::ProfileUpdate::Update(Box::new(
40384017
domain::ProfileGeneralUpdate {
40394018
profile_name: self.profile_name,
@@ -4077,7 +4056,7 @@ impl ProfileUpdateBridge for api::ProfileUpdate {
40774056
is_auto_retries_enabled: self.is_auto_retries_enabled,
40784057
max_auto_retries_enabled: self.max_auto_retries_enabled.map(i16::from),
40794058
is_click_to_pay_enabled: self.is_click_to_pay_enabled,
4080-
authentication_product_ids,
4059+
authentication_product_ids: self.authentication_product_ids,
40814060
},
40824061
)))
40834062
}
@@ -4140,13 +4119,6 @@ impl ProfileUpdateBridge for api::ProfileUpdate {
41404119
})
41414120
.transpose()?;
41424121

4143-
let authentication_product_ids = self
4144-
.authentication_product_ids
4145-
.map(serde_json::to_value)
4146-
.transpose()
4147-
.change_context(errors::ApiErrorResponse::InternalServerError)
4148-
.attach_printable("failed to parse product authentication id's to value")?;
4149-
41504122
Ok(domain::ProfileUpdate::Update(Box::new(
41514123
domain::ProfileGeneralUpdate {
41524124
profile_name: self.profile_name,
@@ -4182,7 +4154,7 @@ impl ProfileUpdateBridge for api::ProfileUpdate {
41824154
.always_collect_shipping_details_from_wallet_connector,
41834155
is_network_tokenization_enabled: self.is_network_tokenization_enabled,
41844156
is_click_to_pay_enabled: self.is_click_to_pay_enabled,
4185-
authentication_product_ids,
4157+
authentication_product_ids: self.authentication_product_ids,
41864158
},
41874159
)))
41884160
}

0 commit comments

Comments
 (0)