mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 05:17:02 +08:00
feat(router): collect customer address details based on business profile config regardless of connector required fields (#5418)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -3498,6 +3498,10 @@ impl BusinessProfileCreateBridge for api::BusinessProfileCreate {
|
||||
.or(Some(false)),
|
||||
outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers
|
||||
.map(Into::into),
|
||||
always_collect_billing_details_from_wallet_connector: self
|
||||
.always_collect_billing_details_from_wallet_connector,
|
||||
always_collect_shipping_details_from_wallet_connector: self
|
||||
.always_collect_shipping_details_from_wallet_connector,
|
||||
})
|
||||
}
|
||||
|
||||
@ -3578,13 +3582,17 @@ impl BusinessProfileCreateBridge for api::BusinessProfileCreate {
|
||||
.use_billing_as_payment_method_billing
|
||||
.or(Some(true)),
|
||||
collect_shipping_details_from_wallet_connector: self
|
||||
.collect_shipping_details_from_wallet_connector
|
||||
.collect_shipping_details_from_wallet_connector_if_required
|
||||
.or(Some(false)),
|
||||
collect_billing_details_from_wallet_connector: self
|
||||
.collect_billing_details_from_wallet_connector
|
||||
.collect_billing_details_from_wallet_connector_if_required
|
||||
.or(Some(false)),
|
||||
outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers
|
||||
.map(Into::into),
|
||||
always_collect_billing_details_from_wallet_connector: self
|
||||
.always_collect_billing_details_from_wallet_connector,
|
||||
always_collect_shipping_details_from_wallet_connector: self
|
||||
.always_collect_shipping_details_from_wallet_connector,
|
||||
routing_algorithm_id: None,
|
||||
frm_routing_algorithm_id: None,
|
||||
payout_routing_algorithm_id: None,
|
||||
@ -3856,6 +3864,10 @@ impl BusinessProfileUpdateBridge for api::BusinessProfileUpdate {
|
||||
is_connector_agnostic_mit_enabled: self.is_connector_agnostic_mit_enabled,
|
||||
outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers
|
||||
.map(Into::into),
|
||||
always_collect_billing_details_from_wallet_connector: self
|
||||
.always_collect_billing_details_from_wallet_connector,
|
||||
always_collect_shipping_details_from_wallet_connector: self
|
||||
.always_collect_shipping_details_from_wallet_connector,
|
||||
},
|
||||
)))
|
||||
}
|
||||
@ -3934,9 +3946,9 @@ impl BusinessProfileUpdateBridge for api::BusinessProfileUpdate {
|
||||
extended_card_info_config,
|
||||
use_billing_as_payment_method_billing: self.use_billing_as_payment_method_billing,
|
||||
collect_shipping_details_from_wallet_connector: self
|
||||
.collect_shipping_details_from_wallet_connector,
|
||||
.collect_shipping_details_from_wallet_connector_if_required,
|
||||
collect_billing_details_from_wallet_connector: self
|
||||
.collect_billing_details_from_wallet_connector,
|
||||
.collect_billing_details_from_wallet_connector_if_required,
|
||||
is_connector_agnostic_mit_enabled: self.is_connector_agnostic_mit_enabled,
|
||||
outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers
|
||||
.map(Into::into),
|
||||
@ -3944,6 +3956,10 @@ impl BusinessProfileUpdateBridge for api::BusinessProfileUpdate {
|
||||
.order_fulfillment_time
|
||||
.map(|order_fulfillment_time| order_fulfillment_time.into_inner()),
|
||||
order_fulfillment_time_origin: self.order_fulfillment_time_origin,
|
||||
always_collect_billing_details_from_wallet_connector: self
|
||||
.always_collect_billing_details_from_wallet_connector,
|
||||
always_collect_shipping_details_from_wallet_connector: self
|
||||
.always_collect_shipping_details_from_wallet_connector,
|
||||
},
|
||||
)))
|
||||
}
|
||||
|
||||
@ -60,7 +60,10 @@ use crate::types::domain::types::AsyncLift;
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
use crate::utils::{self};
|
||||
use crate::{
|
||||
configs::settings,
|
||||
configs::{
|
||||
defaults::{get_billing_required_fields, get_shipping_required_fields},
|
||||
settings,
|
||||
},
|
||||
core::{
|
||||
errors::{self, StorageErrorExt},
|
||||
payment_methods::{
|
||||
@ -2898,29 +2901,12 @@ pub async fn list_payment_methods(
|
||||
}
|
||||
}
|
||||
|
||||
let should_send_shipping_details =
|
||||
business_profile.clone().and_then(|business_profile| {
|
||||
business_profile
|
||||
.collect_shipping_details_from_wallet_connector
|
||||
});
|
||||
|
||||
// Remove shipping fields from required fields based on business profile configuration
|
||||
if should_send_shipping_details != Some(true) {
|
||||
let shipping_variants =
|
||||
api_enums::FieldType::get_shipping_variants();
|
||||
|
||||
let keys_to_be_removed = required_fields_hs
|
||||
.iter()
|
||||
.filter(|(_key, value)| {
|
||||
shipping_variants.contains(&value.field_type)
|
||||
})
|
||||
.map(|(key, _value)| key.to_string())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
keys_to_be_removed.iter().for_each(|key_to_be_removed| {
|
||||
required_fields_hs.remove(key_to_be_removed);
|
||||
});
|
||||
}
|
||||
required_fields_hs = should_collect_shipping_or_billing_details_from_wallet_connector(
|
||||
&payment_method,
|
||||
element.payment_experience.as_ref(),
|
||||
business_profile.as_ref(),
|
||||
required_fields_hs.clone(),
|
||||
);
|
||||
|
||||
// get the config, check the enums while adding
|
||||
{
|
||||
@ -3271,11 +3257,22 @@ pub async fn list_payment_methods(
|
||||
|
||||
let collect_shipping_details_from_wallets = business_profile
|
||||
.as_ref()
|
||||
.and_then(|bp| bp.collect_shipping_details_from_wallet_connector);
|
||||
.and_then(|business_profile| {
|
||||
business_profile.always_collect_shipping_details_from_wallet_connector
|
||||
})
|
||||
.or(business_profile.as_ref().and_then(|business_profile| {
|
||||
business_profile.collect_shipping_details_from_wallet_connector
|
||||
}));
|
||||
|
||||
let collect_billing_details_from_wallets = business_profile
|
||||
.as_ref()
|
||||
.and_then(|bp| bp.collect_billing_details_from_wallet_connector);
|
||||
.and_then(|business_profile| {
|
||||
business_profile.always_collect_billing_details_from_wallet_connector
|
||||
})
|
||||
.or(business_profile.as_ref().and_then(|business_profile| {
|
||||
business_profile.collect_billing_details_from_wallet_connector
|
||||
}));
|
||||
|
||||
Ok(services::ApplicationResponse::Json(
|
||||
api::PaymentMethodListResponse {
|
||||
redirect_url: business_profile
|
||||
@ -3320,6 +3317,37 @@ pub async fn list_payment_methods(
|
||||
))
|
||||
}
|
||||
|
||||
fn should_collect_shipping_or_billing_details_from_wallet_connector(
|
||||
payment_method: &api_enums::PaymentMethod,
|
||||
payment_experience_optional: Option<&api_enums::PaymentExperience>,
|
||||
business_profile: Option<&BusinessProfile>,
|
||||
mut required_fields_hs: HashMap<String, RequiredFieldInfo>,
|
||||
) -> HashMap<String, RequiredFieldInfo> {
|
||||
match (payment_method, payment_experience_optional) {
|
||||
(api_enums::PaymentMethod::Wallet, Some(api_enums::PaymentExperience::InvokeSdkClient)) => {
|
||||
let always_send_billing_details = business_profile.and_then(|business_profile| {
|
||||
business_profile.always_collect_billing_details_from_wallet_connector
|
||||
});
|
||||
|
||||
let always_send_shipping_details = business_profile.and_then(|business_profile| {
|
||||
business_profile.always_collect_shipping_details_from_wallet_connector
|
||||
});
|
||||
|
||||
if always_send_billing_details == Some(true) {
|
||||
let billing_details = get_billing_required_fields();
|
||||
required_fields_hs.extend(billing_details)
|
||||
};
|
||||
if always_send_shipping_details == Some(true) {
|
||||
let shipping_details = get_shipping_required_fields();
|
||||
required_fields_hs.extend(shipping_details)
|
||||
};
|
||||
|
||||
required_fields_hs
|
||||
}
|
||||
_ => required_fields_hs,
|
||||
}
|
||||
}
|
||||
|
||||
async fn validate_payment_method_and_client_secret(
|
||||
cs: &String,
|
||||
db: &dyn db::StorageInterface,
|
||||
|
||||
@ -316,43 +316,61 @@ async fn create_applepay_session_token(
|
||||
router_data.request.to_owned(),
|
||||
)?;
|
||||
|
||||
let required_billing_contact_fields = business_profile
|
||||
let required_billing_contact_fields = if business_profile
|
||||
.always_collect_billing_details_from_wallet_connector
|
||||
.unwrap_or(false)
|
||||
{
|
||||
Some(payment_types::ApplePayBillingContactFields(vec![
|
||||
payment_types::ApplePayAddressParameters::PostalAddress,
|
||||
]))
|
||||
} else if business_profile
|
||||
.collect_billing_details_from_wallet_connector
|
||||
.unwrap_or(false)
|
||||
.then_some({
|
||||
let billing_variants = enums::FieldType::get_billing_variants();
|
||||
is_dynamic_fields_required(
|
||||
&state.conf.required_fields,
|
||||
enums::PaymentMethod::Wallet,
|
||||
enums::PaymentMethodType::ApplePay,
|
||||
&connector.connector_name,
|
||||
billing_variants,
|
||||
)
|
||||
.then_some(payment_types::ApplePayBillingContactFields(vec![
|
||||
payment_types::ApplePayAddressParameters::PostalAddress,
|
||||
]))
|
||||
})
|
||||
.flatten();
|
||||
{
|
||||
let billing_variants = enums::FieldType::get_billing_variants();
|
||||
is_dynamic_fields_required(
|
||||
&state.conf.required_fields,
|
||||
enums::PaymentMethod::Wallet,
|
||||
enums::PaymentMethodType::ApplePay,
|
||||
&connector.connector_name,
|
||||
billing_variants,
|
||||
)
|
||||
.then_some(payment_types::ApplePayBillingContactFields(vec![
|
||||
payment_types::ApplePayAddressParameters::PostalAddress,
|
||||
]))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let required_shipping_contact_fields = business_profile
|
||||
let required_shipping_contact_fields = if business_profile
|
||||
.always_collect_shipping_details_from_wallet_connector
|
||||
.unwrap_or(false)
|
||||
{
|
||||
Some(payment_types::ApplePayShippingContactFields(vec![
|
||||
payment_types::ApplePayAddressParameters::PostalAddress,
|
||||
payment_types::ApplePayAddressParameters::Phone,
|
||||
payment_types::ApplePayAddressParameters::Email,
|
||||
]))
|
||||
} else if business_profile
|
||||
.collect_shipping_details_from_wallet_connector
|
||||
.unwrap_or(false)
|
||||
.then_some({
|
||||
let shipping_variants = enums::FieldType::get_shipping_variants();
|
||||
is_dynamic_fields_required(
|
||||
&state.conf.required_fields,
|
||||
enums::PaymentMethod::Wallet,
|
||||
enums::PaymentMethodType::ApplePay,
|
||||
&connector.connector_name,
|
||||
shipping_variants,
|
||||
)
|
||||
.then_some(payment_types::ApplePayShippingContactFields(vec![
|
||||
payment_types::ApplePayAddressParameters::PostalAddress,
|
||||
payment_types::ApplePayAddressParameters::Phone,
|
||||
payment_types::ApplePayAddressParameters::Email,
|
||||
]))
|
||||
})
|
||||
.flatten();
|
||||
{
|
||||
let shipping_variants = enums::FieldType::get_shipping_variants();
|
||||
is_dynamic_fields_required(
|
||||
&state.conf.required_fields,
|
||||
enums::PaymentMethod::Wallet,
|
||||
enums::PaymentMethodType::ApplePay,
|
||||
&connector.connector_name,
|
||||
shipping_variants,
|
||||
)
|
||||
.then_some(payment_types::ApplePayShippingContactFields(vec![
|
||||
payment_types::ApplePayAddressParameters::PostalAddress,
|
||||
payment_types::ApplePayAddressParameters::Phone,
|
||||
payment_types::ApplePayAddressParameters::Email,
|
||||
]))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// If collect_shipping_details_from_wallet_connector is false, we check if
|
||||
// collect_billing_details_from_wallet_connector is true. If it is, then we pass the Email and Phone in
|
||||
@ -655,20 +673,27 @@ fn create_gpay_session_token(
|
||||
expected_format: "gpay_metadata_format".to_string(),
|
||||
})?;
|
||||
|
||||
let is_billing_details_required =
|
||||
if business_profile.collect_billing_details_from_wallet_connector == Some(true) {
|
||||
let billing_variants = enums::FieldType::get_billing_variants();
|
||||
let always_collect_billing_details_from_wallet_connector = business_profile
|
||||
.always_collect_billing_details_from_wallet_connector
|
||||
.unwrap_or(false);
|
||||
|
||||
is_dynamic_fields_required(
|
||||
&state.conf.required_fields,
|
||||
enums::PaymentMethod::Wallet,
|
||||
enums::PaymentMethodType::GooglePay,
|
||||
&connector.connector_name,
|
||||
billing_variants,
|
||||
)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let is_billing_details_required = if always_collect_billing_details_from_wallet_connector {
|
||||
always_collect_billing_details_from_wallet_connector
|
||||
} else if business_profile
|
||||
.collect_billing_details_from_wallet_connector
|
||||
.unwrap_or(false)
|
||||
{
|
||||
let billing_variants = enums::FieldType::get_billing_variants();
|
||||
is_dynamic_fields_required(
|
||||
&state.conf.required_fields,
|
||||
enums::PaymentMethod::Wallet,
|
||||
enums::PaymentMethodType::GooglePay,
|
||||
&connector.connector_name,
|
||||
billing_variants,
|
||||
)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let billing_address_parameters =
|
||||
is_billing_details_required.then_some(payment_types::GpayBillingAddressParameters {
|
||||
@ -708,8 +733,17 @@ fn create_gpay_session_token(
|
||||
total_price: google_pay_amount,
|
||||
};
|
||||
|
||||
let always_collect_shipping_details_from_wallet_connector = business_profile
|
||||
.always_collect_shipping_details_from_wallet_connector
|
||||
.unwrap_or(false);
|
||||
|
||||
let required_shipping_contact_fields =
|
||||
if business_profile.collect_shipping_details_from_wallet_connector == Some(true) {
|
||||
if always_collect_shipping_details_from_wallet_connector {
|
||||
true
|
||||
} else if business_profile
|
||||
.collect_shipping_details_from_wallet_connector
|
||||
.unwrap_or(false)
|
||||
{
|
||||
let shipping_variants = enums::FieldType::get_shipping_variants();
|
||||
|
||||
is_dynamic_fields_required(
|
||||
|
||||
@ -18,6 +18,7 @@ use crate::{
|
||||
connector::{Helcim, Nexinets},
|
||||
core::{
|
||||
errors::{self, RouterResponse, RouterResult},
|
||||
payment_methods::cards::decrypt_generic_data,
|
||||
payments::{self, helpers},
|
||||
utils as core_utils,
|
||||
},
|
||||
@ -25,8 +26,8 @@ use crate::{
|
||||
routes::{metrics, SessionState},
|
||||
services::{self, RedirectForm},
|
||||
types::{
|
||||
self, api,
|
||||
api::ConnectorTransactionId,
|
||||
self,
|
||||
api::{self, ConnectorTransactionId},
|
||||
domain,
|
||||
storage::{self, enums},
|
||||
transformers::{ForeignFrom, ForeignInto, ForeignTryFrom},
|
||||
@ -137,14 +138,13 @@ where
|
||||
|
||||
let unified_address =
|
||||
if let Some(payment_method_info) = payment_data.payment_method_info.clone() {
|
||||
let payment_method_billing =
|
||||
crate::core::payment_methods::cards::decrypt_generic_data::<Address>(
|
||||
state,
|
||||
payment_method_info.payment_method_billing_address,
|
||||
key_store,
|
||||
)
|
||||
.await
|
||||
.attach_printable("unable to decrypt payment method billing address details")?;
|
||||
let payment_method_billing = decrypt_generic_data::<Address>(
|
||||
state,
|
||||
payment_method_info.payment_method_billing_address,
|
||||
key_store,
|
||||
)
|
||||
.await
|
||||
.attach_printable("unable to decrypt payment method billing address details")?;
|
||||
payment_data
|
||||
.address
|
||||
.clone()
|
||||
|
||||
Reference in New Issue
Block a user