diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 2ea34e8469..06796b4486 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -20288,7 +20288,9 @@ "merchant", "amount", "protocol", - "allowed_brands" + "allowed_brands", + "billing_address_required", + "shipping_address_required" ], "properties": { "version": { @@ -20318,6 +20320,14 @@ "type": "string" }, "description": "List of supported card brands" + }, + "billing_address_required": { + "type": "boolean", + "description": "Is billing address required to be collected from wallet" + }, + "shipping_address_required": { + "type": "boolean", + "description": "Is shipping address required to be collected from wallet" } } }, diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 78760af592..632d800f47 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -24860,7 +24860,9 @@ "merchant", "amount", "protocol", - "allowed_brands" + "allowed_brands", + "billing_address_required", + "shipping_address_required" ], "properties": { "version": { @@ -24890,6 +24892,14 @@ "type": "string" }, "description": "List of supported card brands" + }, + "billing_address_required": { + "type": "boolean", + "description": "Is billing address required to be collected from wallet" + }, + "shipping_address_required": { + "type": "boolean", + "description": "Is shipping address required to be collected from wallet" } } }, diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index b567bc5228..faee2e3887 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -6861,6 +6861,10 @@ pub struct SamsungPaySessionTokenResponse { pub protocol: SamsungPayProtocolType, /// List of supported card brands pub allowed_brands: Vec, + /// Is billing address required to be collected from wallet + pub billing_address_required: bool, + /// Is shipping address required to be collected from wallet + pub shipping_address_required: bool, } #[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, ToSchema)] diff --git a/crates/router/src/core/payments/flows/session_flow.rs b/crates/router/src/core/payments/flows/session_flow.rs index f6e5d1e7f0..662453c4a3 100644 --- a/crates/router/src/core/payments/flows/session_flow.rs +++ b/crates/router/src/core/payments/flows/session_flow.rs @@ -610,8 +610,11 @@ fn create_paze_session_token( } fn create_samsung_pay_session_token( + state: &routes::SessionState, router_data: &types::PaymentsSessionRouterData, header_payload: hyperswitch_domain_models::payments::HeaderPayload, + connector: &api::ConnectorData, + business_profile: &domain::Profile, ) -> RouterResult { let samsung_pay_session_token_data = router_data .connector_wallets_details @@ -657,6 +660,20 @@ fn create_samsung_pay_session_token( let formatted_payment_id = router_data.payment_id.replace("_", "-"); + let billing_address_required = is_billing_address_required_to_be_collected_from_wallet( + state, + connector, + business_profile, + enums::PaymentMethodType::SamsungPay, + ); + + let shipping_address_required = is_shipping_address_required_to_be_collected_form_wallet( + state, + connector, + business_profile, + enums::PaymentMethodType::SamsungPay, + ); + Ok(types::PaymentsSessionRouterData { response: Ok(types::PaymentsResponseData::SessionResponse { session_token: payment_types::SessionToken::SamsungPay(Box::new( @@ -677,6 +694,8 @@ fn create_samsung_pay_session_token( }, protocol: payment_types::SamsungPayProtocolType::Protocol3ds, allowed_brands: samsung_pay_wallet_details.allowed_brands, + billing_address_required, + shipping_address_required, }, )), }), @@ -684,6 +703,86 @@ fn create_samsung_pay_session_token( }) } +/// Function to determine whether the billing address is required to be collected from the wallet, +/// based on business profile settings, the payment method type, and the connector's required fields +/// for the specific payment method. +/// +/// If `always_collect_billing_details_from_wallet_connector` is enabled, it indicates that the +/// billing address is always required to be collected from the wallet. +/// +/// If only `collect_billing_details_from_wallet_connector` is enabled, the billing address will be +/// collected only if the connector required fields for the specific payment method type contain +/// the billing fields. +fn is_billing_address_required_to_be_collected_from_wallet( + state: &routes::SessionState, + connector: &api::ConnectorData, + business_profile: &domain::Profile, + payment_method_type: enums::PaymentMethodType, +) -> bool { + let always_collect_billing_details_from_wallet_connector = business_profile + .always_collect_billing_details_from_wallet_connector + .unwrap_or(false); + + 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, + payment_method_type, + connector.connector_name, + billing_variants, + ) + } else { + false + } +} + +/// Function to determine whether the shipping address is required to be collected from the wallet, +/// based on business profile settings, the payment method type, and the connector required fields +/// for the specific payment method type. +/// +/// If `always_collect_shipping_details_from_wallet_connector` is enabled, it indicates that the +/// shipping address is always required to be collected from the wallet. +/// +/// If only `collect_shipping_details_from_wallet_connector` is enabled, the shipping address will be +/// collected only if the connector required fields for the specific payment method type contain +/// the shipping fields. +fn is_shipping_address_required_to_be_collected_form_wallet( + state: &routes::SessionState, + connector: &api::ConnectorData, + business_profile: &domain::Profile, + payment_method_type: enums::PaymentMethodType, +) -> bool { + let always_collect_shipping_details_from_wallet_connector = business_profile + .always_collect_shipping_details_from_wallet_connector + .unwrap_or(false); + + if always_collect_shipping_details_from_wallet_connector { + always_collect_shipping_details_from_wallet_connector + } 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( + &state.conf.required_fields, + enums::PaymentMethod::Wallet, + payment_method_type, + connector.connector_name, + shipping_variants, + ) + } else { + false + } +} + fn get_session_request_for_simplified_apple_pay( apple_pay_merchant_identifier: String, session_token_data: payment_types::SessionTokenForSimplifiedApplePay, @@ -865,27 +964,12 @@ fn create_gpay_session_token( ..router_data.clone() }) } else { - let always_collect_billing_details_from_wallet_connector = business_profile - .always_collect_billing_details_from_wallet_connector - .unwrap_or(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 is_billing_details_required = is_billing_address_required_to_be_collected_from_wallet( + state, + connector, + business_profile, + enums::PaymentMethodType::GooglePay, + ); let required_amount_type = StringMajorUnitForConnector; let google_pay_amount = required_amount_type @@ -904,29 +988,13 @@ 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 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( - &state.conf.required_fields, - enums::PaymentMethod::Wallet, - enums::PaymentMethodType::GooglePay, - connector.connector_name, - shipping_variants, - ) - } else { - false - }; + is_shipping_address_required_to_be_collected_form_wallet( + state, + connector, + business_profile, + enums::PaymentMethodType::GooglePay, + ); if connector_wallets_details.google_pay.is_some() { let gpay_data = router_data @@ -1199,9 +1267,13 @@ impl RouterDataSession for types::PaymentsSessionRouterData { api::GetToken::GpayMetadata => { create_gpay_session_token(state, self, connector, business_profile) } - api::GetToken::SamsungPayMetadata => { - create_samsung_pay_session_token(self, header_payload) - } + api::GetToken::SamsungPayMetadata => create_samsung_pay_session_token( + state, + self, + header_payload, + connector, + business_profile, + ), api::GetToken::ApplePayMetadata => { create_applepay_session_token( state,