mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-31 01:57:45 +08:00
feat(core): Add cardbrand union fetch logic for click to pay session response (#7858)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: Sahkal Poddar <sahkalpoddar@Sahkals-MacBook-Air.local>
This commit is contained in:
@ -532,6 +532,7 @@ pub(crate) async fn fetch_raw_secrets(
|
||||
network_tokenization_supported_connectors: conf.network_tokenization_supported_connectors,
|
||||
theme: conf.theme,
|
||||
platform: conf.platform,
|
||||
authentication_providers: conf.authentication_providers,
|
||||
open_router: conf.open_router,
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,6 +145,7 @@ pub struct Settings<S: SecretState> {
|
||||
pub network_tokenization_supported_connectors: NetworkTokenizationSupportedConnectors,
|
||||
pub theme: ThemeSettings,
|
||||
pub platform: Platform,
|
||||
pub authentication_providers: AuthenticationProviders,
|
||||
pub open_router: OpenRouter,
|
||||
}
|
||||
|
||||
@ -508,6 +509,31 @@ pub struct CorsSettings {
|
||||
pub allowed_methods: HashSet<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Default)]
|
||||
pub struct AuthenticationProviders {
|
||||
#[serde(deserialize_with = "deserialize_connector_list")]
|
||||
pub click_to_pay: HashSet<enums::Connector>,
|
||||
}
|
||||
|
||||
fn deserialize_connector_list<'a, D>(deserializer: D) -> Result<HashSet<enums::Connector>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'a>,
|
||||
{
|
||||
use serde::de::Error;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Wrapper {
|
||||
connector_list: String,
|
||||
}
|
||||
|
||||
let wrapper = Wrapper::deserialize(deserializer)?;
|
||||
wrapper
|
||||
.connector_list
|
||||
.split(',')
|
||||
.map(|s| s.trim().parse().map_err(D::Error::custom))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Default)]
|
||||
pub struct NetworkTransactionIdSupportedConnectors {
|
||||
#[serde(deserialize_with = "deserialize_hashset")]
|
||||
|
||||
@ -16,7 +16,8 @@ pub mod types;
|
||||
#[cfg(feature = "olap")]
|
||||
use std::collections::HashMap;
|
||||
use std::{
|
||||
collections::HashSet, fmt::Debug, marker::PhantomData, ops::Deref, time::Instant, vec::IntoIter,
|
||||
collections::HashSet, fmt::Debug, marker::PhantomData, ops::Deref, str::FromStr, time::Instant,
|
||||
vec::IntoIter,
|
||||
};
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
@ -4156,6 +4157,7 @@ where
|
||||
key_store,
|
||||
value,
|
||||
payment_data.get_payment_intent(),
|
||||
business_profile.get_id(),
|
||||
)
|
||||
.await?;
|
||||
payment_data.push_sessions_token(session_token);
|
||||
@ -4177,6 +4179,7 @@ pub async fn get_session_token_for_click_to_pay(
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
authentication_product_ids: common_types::payments::AuthenticationConnectorAccountMap,
|
||||
payment_intent: &hyperswitch_domain_models::payments::PaymentIntent,
|
||||
profile_id: &id_type::ProfileId,
|
||||
) -> RouterResult<api_models::payments::SessionToken> {
|
||||
let click_to_pay_mca_id = authentication_product_ids
|
||||
.get_click_to_pay_connector_account_id()
|
||||
@ -4230,12 +4233,16 @@ pub async fn get_session_token_for_click_to_pay(
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let card_brands =
|
||||
get_card_brands_based_on_active_merchant_connector_account(state, profile_id, key_store)
|
||||
.await?;
|
||||
|
||||
Ok(api_models::payments::SessionToken::ClickToPay(Box::new(
|
||||
api_models::payments::ClickToPaySessionResponse {
|
||||
dpa_id: click_to_pay_metadata.dpa_id,
|
||||
dpa_name: click_to_pay_metadata.dpa_name,
|
||||
locale: click_to_pay_metadata.locale,
|
||||
card_brands: click_to_pay_metadata.card_brands,
|
||||
card_brands,
|
||||
acquirer_bin: click_to_pay_metadata.acquirer_bin,
|
||||
acquirer_merchant_id: click_to_pay_metadata.acquirer_merchant_id,
|
||||
merchant_category_code: click_to_pay_metadata.merchant_category_code,
|
||||
@ -4251,6 +4258,63 @@ pub async fn get_session_token_for_click_to_pay(
|
||||
)))
|
||||
}
|
||||
|
||||
#[cfg(feature = "v1")]
|
||||
async fn get_card_brands_based_on_active_merchant_connector_account(
|
||||
state: &SessionState,
|
||||
profile_id: &id_type::ProfileId,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
) -> RouterResult<HashSet<enums::CardNetwork>> {
|
||||
let key_manager_state = &(state).into();
|
||||
let merchant_configured_payment_connectors = state
|
||||
.store
|
||||
.list_enabled_connector_accounts_by_profile_id(
|
||||
key_manager_state,
|
||||
profile_id,
|
||||
key_store,
|
||||
common_enums::ConnectorType::PaymentProcessor,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("error when fetching merchant connector accounts")?;
|
||||
|
||||
let payment_connectors_eligible_for_click_to_pay =
|
||||
state.conf.authentication_providers.click_to_pay.clone();
|
||||
|
||||
let filtered_payment_connector_accounts: Vec<
|
||||
hyperswitch_domain_models::merchant_connector_account::MerchantConnectorAccount,
|
||||
> = merchant_configured_payment_connectors
|
||||
.into_iter()
|
||||
.filter(|account| {
|
||||
enums::Connector::from_str(&account.connector_name)
|
||||
.ok()
|
||||
.map(|connector| payment_connectors_eligible_for_click_to_pay.contains(&connector))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut card_brands = HashSet::new();
|
||||
|
||||
for account in filtered_payment_connector_accounts {
|
||||
if let Some(values) = &account.payment_methods_enabled {
|
||||
for val in values {
|
||||
let payment_methods_enabled: api_models::admin::PaymentMethodsEnabled =
|
||||
serde_json::from_value(val.peek().to_owned()).inspect_err(|err| {
|
||||
logger::error!("Failed to parse Payment methods enabled data set from dashboard because {}", err)
|
||||
})
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
if let Some(payment_method_types) = payment_methods_enabled.payment_method_types {
|
||||
for payment_method_type in payment_method_types {
|
||||
if let Some(networks) = payment_method_type.card_networks {
|
||||
card_brands.extend(networks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(card_brands)
|
||||
}
|
||||
|
||||
fn validate_customer_details_for_click_to_pay(customer_details: &CustomerData) -> RouterResult<()> {
|
||||
match (
|
||||
customer_details.phone.as_ref(),
|
||||
|
||||
@ -1281,7 +1281,6 @@ impl MerchantConnectorAccountInterface for KafkaStore {
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "oltp", feature = "v2"))]
|
||||
async fn list_enabled_connector_accounts_by_profile_id(
|
||||
&self,
|
||||
state: &KeyManagerState,
|
||||
|
||||
@ -189,7 +189,6 @@ where
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
) -> CustomResult<Vec<domain::MerchantConnectorAccount>, errors::StorageError>;
|
||||
|
||||
#[cfg(all(feature = "oltp", feature = "v2"))]
|
||||
async fn list_enabled_connector_accounts_by_profile_id(
|
||||
&self,
|
||||
state: &KeyManagerState,
|
||||
@ -502,7 +501,6 @@ impl MerchantConnectorAccountInterface for Store {
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "oltp", feature = "v2"))]
|
||||
async fn list_enabled_connector_accounts_by_profile_id(
|
||||
&self,
|
||||
state: &KeyManagerState,
|
||||
@ -1067,15 +1065,14 @@ impl MerchantConnectorAccountInterface for MockDb {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "oltp", feature = "v2"))]
|
||||
async fn list_enabled_connector_accounts_by_profile_id(
|
||||
&self,
|
||||
state: &KeyManagerState,
|
||||
profile_id: &common_utils::id_type::ProfileId,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
connector_type: common_enums::ConnectorType,
|
||||
_state: &KeyManagerState,
|
||||
_profile_id: &common_utils::id_type::ProfileId,
|
||||
_key_store: &domain::MerchantKeyStore,
|
||||
_connector_type: common_enums::ConnectorType,
|
||||
) -> CustomResult<Vec<domain::MerchantConnectorAccount>, errors::StorageError> {
|
||||
todo!()
|
||||
Err(errors::StorageError::MockDbError)?
|
||||
}
|
||||
|
||||
#[cfg(feature = "v1")]
|
||||
|
||||
Reference in New Issue
Block a user