feat(samsung_pay): collect customer address details form Samsung Pay based on business profile config and connector required fields (#7320)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Shankar Singh C
2025-02-22 13:23:33 +05:30
committed by GitHub
parent 1a7ee233db
commit c14519ebd9
4 changed files with 144 additions and 48 deletions

View File

@ -20288,7 +20288,9 @@
"merchant", "merchant",
"amount", "amount",
"protocol", "protocol",
"allowed_brands" "allowed_brands",
"billing_address_required",
"shipping_address_required"
], ],
"properties": { "properties": {
"version": { "version": {
@ -20318,6 +20320,14 @@
"type": "string" "type": "string"
}, },
"description": "List of supported card brands" "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"
} }
} }
}, },

View File

@ -24860,7 +24860,9 @@
"merchant", "merchant",
"amount", "amount",
"protocol", "protocol",
"allowed_brands" "allowed_brands",
"billing_address_required",
"shipping_address_required"
], ],
"properties": { "properties": {
"version": { "version": {
@ -24890,6 +24892,14 @@
"type": "string" "type": "string"
}, },
"description": "List of supported card brands" "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"
} }
} }
}, },

View File

@ -6861,6 +6861,10 @@ pub struct SamsungPaySessionTokenResponse {
pub protocol: SamsungPayProtocolType, pub protocol: SamsungPayProtocolType,
/// List of supported card brands /// List of supported card brands
pub allowed_brands: Vec<String>, pub allowed_brands: Vec<String>,
/// 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)] #[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, ToSchema)]

View File

@ -610,8 +610,11 @@ fn create_paze_session_token(
} }
fn create_samsung_pay_session_token( fn create_samsung_pay_session_token(
state: &routes::SessionState,
router_data: &types::PaymentsSessionRouterData, router_data: &types::PaymentsSessionRouterData,
header_payload: hyperswitch_domain_models::payments::HeaderPayload, header_payload: hyperswitch_domain_models::payments::HeaderPayload,
connector: &api::ConnectorData,
business_profile: &domain::Profile,
) -> RouterResult<types::PaymentsSessionRouterData> { ) -> RouterResult<types::PaymentsSessionRouterData> {
let samsung_pay_session_token_data = router_data let samsung_pay_session_token_data = router_data
.connector_wallets_details .connector_wallets_details
@ -657,6 +660,20 @@ fn create_samsung_pay_session_token(
let formatted_payment_id = router_data.payment_id.replace("_", "-"); 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 { Ok(types::PaymentsSessionRouterData {
response: Ok(types::PaymentsResponseData::SessionResponse { response: Ok(types::PaymentsResponseData::SessionResponse {
session_token: payment_types::SessionToken::SamsungPay(Box::new( session_token: payment_types::SessionToken::SamsungPay(Box::new(
@ -677,6 +694,8 @@ fn create_samsung_pay_session_token(
}, },
protocol: payment_types::SamsungPayProtocolType::Protocol3ds, protocol: payment_types::SamsungPayProtocolType::Protocol3ds,
allowed_brands: samsung_pay_wallet_details.allowed_brands, 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( fn get_session_request_for_simplified_apple_pay(
apple_pay_merchant_identifier: String, apple_pay_merchant_identifier: String,
session_token_data: payment_types::SessionTokenForSimplifiedApplePay, session_token_data: payment_types::SessionTokenForSimplifiedApplePay,
@ -865,27 +964,12 @@ fn create_gpay_session_token(
..router_data.clone() ..router_data.clone()
}) })
} else { } else {
let always_collect_billing_details_from_wallet_connector = business_profile let is_billing_details_required = is_billing_address_required_to_be_collected_from_wallet(
.always_collect_billing_details_from_wallet_connector state,
.unwrap_or(false); connector,
business_profile,
let is_billing_details_required = if always_collect_billing_details_from_wallet_connector { enums::PaymentMethodType::GooglePay,
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 required_amount_type = StringMajorUnitForConnector; let required_amount_type = StringMajorUnitForConnector;
let google_pay_amount = required_amount_type let google_pay_amount = required_amount_type
@ -904,29 +988,13 @@ fn create_gpay_session_token(
total_price: google_pay_amount, 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 = let required_shipping_contact_fields =
if always_collect_shipping_details_from_wallet_connector { is_shipping_address_required_to_be_collected_form_wallet(
true state,
} else if business_profile connector,
.collect_shipping_details_from_wallet_connector business_profile,
.unwrap_or(false) enums::PaymentMethodType::GooglePay,
{ );
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
};
if connector_wallets_details.google_pay.is_some() { if connector_wallets_details.google_pay.is_some() {
let gpay_data = router_data let gpay_data = router_data
@ -1199,9 +1267,13 @@ impl RouterDataSession for types::PaymentsSessionRouterData {
api::GetToken::GpayMetadata => { api::GetToken::GpayMetadata => {
create_gpay_session_token(state, self, connector, business_profile) create_gpay_session_token(state, self, connector, business_profile)
} }
api::GetToken::SamsungPayMetadata => { api::GetToken::SamsungPayMetadata => create_samsung_pay_session_token(
create_samsung_pay_session_token(self, header_payload) state,
} self,
header_payload,
connector,
business_profile,
),
api::GetToken::ApplePayMetadata => { api::GetToken::ApplePayMetadata => {
create_applepay_session_token( create_applepay_session_token(
state, state,