feat(payment_methods): pass required_billing_contact_fields field in /session call based on dynamic fields (#4601)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Shankar Singh C
2024-05-13 19:32:00 +05:30
committed by GitHub
parent cfab2af7d4
commit 348cd744dc
10 changed files with 246 additions and 6 deletions

View File

@ -538,6 +538,7 @@ impl TryFrom<types::PaymentsSessionResponseRouterData<BluesnapWalletTokenRespons
merchant_capabilities: Some(payment_request_data.merchant_capabilities),
supported_networks: Some(payment_request_data.supported_networks),
merchant_identifier: Some(session_token_data.merchant_identifier),
required_billing_contact_fields: None,
}),
connector: "bluesnap".to_string(),
delayed_session_token: false,

View File

@ -550,6 +550,7 @@ impl<F>
merchant_capabilities: None,
supported_networks: None,
merchant_identifier: None,
required_billing_contact_fields: None,
},
),
connector: "payme".to_string(),

View File

@ -1223,6 +1223,7 @@ pub fn get_apple_pay_session<F, T>(
),
total: apple_pay_init_result.total.into(),
merchant_identifier: None,
required_billing_contact_fields: None,
}),
connector: "trustpay".to_string(),
delayed_session_token: true,
@ -1326,6 +1327,8 @@ impl From<GpayAllowedMethodsParameters> for api_models::payments::GpayAllowedMet
Self {
allowed_auth_methods: value.allowed_auth_methods,
allowed_card_networks: value.allowed_card_networks,
billing_address_required: None,
billing_address_parameters: None,
}
}
}

View File

@ -11,9 +11,13 @@ use crate::{
payments::{self, access_token, helpers, transformers, PaymentData},
},
headers, logger,
routes::{self, metrics},
routes::{self, app::settings, metrics},
services,
types::{self, api, domain},
types::{
self,
api::{self, enums},
domain,
},
utils::OptionExt,
};
@ -78,6 +82,39 @@ impl Feature<api::Session, types::PaymentsSessionData> for types::PaymentsSessio
}
}
/// This function checks if for a given connector, payment_method and payment_method_type,
/// the list of required_field_type is present in dynamic fields
fn is_dynamic_fields_required(
required_fields: &settings::RequiredFields,
payment_method: enums::PaymentMethod,
payment_method_type: enums::PaymentMethodType,
connector: &types::Connector,
required_field_type: Vec<enums::FieldType>,
) -> bool {
required_fields
.0
.get(&payment_method)
.and_then(|pm_type| pm_type.0.get(&payment_method_type))
.and_then(|required_fields_for_connector| {
required_fields_for_connector.fields.get(connector)
})
.map(|required_fields_final| {
required_fields_final
.non_mandate
.iter()
.any(|(_, val)| required_field_type.contains(&val.field_type))
|| required_fields_final
.mandate
.iter()
.any(|(_, val)| required_field_type.contains(&val.field_type))
|| required_fields_final
.common
.iter()
.any(|(_, val)| required_field_type.contains(&val.field_type))
})
.unwrap_or(false)
}
fn get_applepay_metadata(
connector_metadata: Option<common_utils::pii::SecretSerdeValue>,
) -> RouterResult<payment_types::ApplepaySessionTokenMetadata> {
@ -247,6 +284,20 @@ async fn create_applepay_session_token(
router_data.request.to_owned(),
)?;
let billing_variants = enums::FieldType::get_billing_variants();
let required_billing_contact_fields = if is_dynamic_fields_required(
&state.conf.required_fields,
enums::PaymentMethod::Wallet,
enums::PaymentMethodType::ApplePay,
&connector.connector_name,
billing_variants,
) {
Some(vec!["postalAddress".to_string()])
} else {
None
};
// Get apple pay payment request
let applepay_payment_request = get_apple_pay_payment_request(
amount_info,
@ -254,6 +305,7 @@ async fn create_applepay_session_token(
router_data.request.to_owned(),
apple_pay_session_request.merchant_identifier.as_str(),
merchant_business_country,
required_billing_contact_fields,
)?;
let applepay_session_request = build_apple_pay_session_request(
@ -354,6 +406,7 @@ fn get_apple_pay_payment_request(
session_data: types::PaymentsSessionData,
merchant_identifier: &str,
merchant_business_country: Option<api_models::enums::CountryAlpha2>,
required_billing_contact_fields: Option<Vec<String>>,
) -> RouterResult<payment_types::ApplePayPaymentRequest> {
let applepay_payment_request = payment_types::ApplePayPaymentRequest {
country_code: merchant_business_country.or(session_data.country).ok_or(
@ -366,6 +419,7 @@ fn get_apple_pay_payment_request(
merchant_capabilities: Some(payment_request_data.merchant_capabilities),
supported_networks: Some(payment_request_data.supported_networks),
merchant_identifier: Some(merchant_identifier.to_string()),
required_billing_contact_fields,
};
Ok(applepay_payment_request)
}
@ -443,6 +497,38 @@ fn create_gpay_session_token(
expected_format: "gpay_metadata_format".to_string(),
})?;
let billing_variants = enums::FieldType::get_billing_variants();
let is_billing_details_required = is_dynamic_fields_required(
&state.conf.required_fields,
enums::PaymentMethod::Wallet,
enums::PaymentMethodType::GooglePay,
&connector.connector_name,
billing_variants,
);
let billing_address_parameters =
is_billing_details_required.then_some(payment_types::GpayBillingAddressParameters {
phone_number_required: is_billing_details_required,
format: payment_types::GpayBillingAddressFormat::FULL,
});
let gpay_allowed_payment_methods = gpay_data
.data
.allowed_payment_methods
.into_iter()
.map(
|allowed_payment_methods| payment_types::GpayAllowedPaymentMethods {
parameters: payment_types::GpayAllowedMethodsParameters {
billing_address_required: Some(is_billing_details_required),
billing_address_parameters: billing_address_parameters.clone(),
..allowed_payment_methods.parameters
},
..allowed_payment_methods
},
)
.collect();
let session_data = router_data.request.clone();
let transaction_info = payment_types::GpayTransactionInfo {
country_code: session_data.country.unwrap_or_default(),
@ -466,7 +552,7 @@ fn create_gpay_session_token(
payment_types::GpaySessionTokenResponse::GooglePaySession(
payment_types::GooglePaySessionResponse {
merchant_info: gpay_data.data.merchant_info,
allowed_payment_methods: gpay_data.data.allowed_payment_methods,
allowed_payment_methods: gpay_allowed_payment_methods,
transaction_info,
connector: connector.connector_name.to_string(),
sdk_next_action: payment_types::SdkNextAction {