From 9bc8fd4d8c4be1b54050398dfb3b574e924e4b5f Mon Sep 17 00:00:00 2001 From: Shankar Singh C <83439957+ShankarSinghC@users.noreply.github.com> Date: Sat, 22 Feb 2025 13:25:37 +0530 Subject: [PATCH] feat(connector): add Samsung pay mandate support for Cybersource (#7298) --- crates/connector_configs/toml/sandbox.toml | 2 + .../src/connectors/cybersource.rs | 1 + .../connectors/cybersource/transformers.rs | 53 +++++++----- .../payment_connector_required_fields.rs | 81 ++++++++++++++++++- 4 files changed, 116 insertions(+), 21 deletions(-) diff --git a/crates/connector_configs/toml/sandbox.toml b/crates/connector_configs/toml/sandbox.toml index 265f06ee74..db440656fb 100644 --- a/crates/connector_configs/toml/sandbox.toml +++ b/crates/connector_configs/toml/sandbox.toml @@ -1215,6 +1215,8 @@ merchant_secret="Source verification key" payment_method_type = "google_pay" [[cybersource.wallet]] payment_method_type = "paze" +[[cybersource.wallet]] + payment_method_type = "samsung_pay" [cybersource.connector_auth.SignatureKey] api_key="Key" key1="Merchant ID" diff --git a/crates/hyperswitch_connectors/src/connectors/cybersource.rs b/crates/hyperswitch_connectors/src/connectors/cybersource.rs index 5a60f6d705..812d0391de 100644 --- a/crates/hyperswitch_connectors/src/connectors/cybersource.rs +++ b/crates/hyperswitch_connectors/src/connectors/cybersource.rs @@ -312,6 +312,7 @@ impl ConnectorValidation for Cybersource { PaymentMethodDataType::Card, PaymentMethodDataType::ApplePay, PaymentMethodDataType::GooglePay, + PaymentMethodDataType::SamsungPay, ]); utils::is_mandate_supported(pm_data, pm_type, mandate_supported_pmd, self.id()) } diff --git a/crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs b/crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs index 20db1648e9..4c65218c5a 100644 --- a/crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs @@ -251,6 +251,11 @@ impl TryFrom<&SetupMandateRouterData> for CybersourceZeroMandateRequest { )), Some(PaymentSolution::GooglePay), ), + WalletData::SamsungPay(samsung_pay_data) => ( + (get_samsung_pay_payment_information(&samsung_pay_data) + .attach_printable("Failed to get samsung pay payment information")?), + Some(PaymentSolution::SamsungPay), + ), WalletData::AliPayQr(_) | WalletData::AliPayRedirect(_) | WalletData::AliPayHkRedirect(_) @@ -269,7 +274,6 @@ impl TryFrom<&SetupMandateRouterData> for CybersourceZeroMandateRequest { | WalletData::PaypalRedirect(_) | WalletData::PaypalSdk(_) | WalletData::Paze(_) - | WalletData::SamsungPay(_) | WalletData::TwintRedirect {} | WalletData::VippsRedirect {} | WalletData::TouchNGoRedirect(_) @@ -1859,25 +1863,8 @@ impl let bill_to = build_bill_to(item.router_data.get_optional_billing(), email)?; let order_information = OrderInformationWithBill::from((item, Some(bill_to))); - let samsung_pay_fluid_data_value = - get_samsung_pay_fluid_data_value(&samsung_pay_data.payment_credential.token_data)?; - - let samsung_pay_fluid_data_str = serde_json::to_string(&samsung_pay_fluid_data_value) - .change_context(errors::ConnectorError::RequestEncodingFailed) - .attach_printable("Failed to serialize samsung pay fluid data")?; - - let payment_information = - PaymentInformation::SamsungPay(Box::new(SamsungPayPaymentInformation { - fluid_data: FluidData { - value: Secret::new(consts::BASE64_ENGINE.encode(samsung_pay_fluid_data_str)), - descriptor: Some( - consts::BASE64_ENGINE.encode(FLUID_DATA_DESCRIPTOR_FOR_SAMSUNG_PAY), - ), - }, - tokenized_card: SamsungPayTokenizedCard { - transaction_type: TransactionType::SamsungPay, - }, - })); + let payment_information = get_samsung_pay_payment_information(&samsung_pay_data) + .attach_printable("Failed to get samsung pay payment information")?; let processing_information = ProcessingInformation::try_from(( item, @@ -1903,6 +1890,32 @@ impl } } +fn get_samsung_pay_payment_information( + samsung_pay_data: &SamsungPayWalletData, +) -> Result> { + let samsung_pay_fluid_data_value = + get_samsung_pay_fluid_data_value(&samsung_pay_data.payment_credential.token_data)?; + + let samsung_pay_fluid_data_str = serde_json::to_string(&samsung_pay_fluid_data_value) + .change_context(errors::ConnectorError::RequestEncodingFailed) + .attach_printable("Failed to serialize samsung pay fluid data")?; + + let payment_information = + PaymentInformation::SamsungPay(Box::new(SamsungPayPaymentInformation { + fluid_data: FluidData { + value: Secret::new(consts::BASE64_ENGINE.encode(samsung_pay_fluid_data_str)), + descriptor: Some( + consts::BASE64_ENGINE.encode(FLUID_DATA_DESCRIPTOR_FOR_SAMSUNG_PAY), + ), + }, + tokenized_card: SamsungPayTokenizedCard { + transaction_type: TransactionType::SamsungPay, + }, + })); + + Ok(payment_information) +} + fn get_samsung_pay_fluid_data_value( samsung_pay_token_data: &hyperswitch_domain_models::payment_method_data::SamsungPayTokenData, ) -> Result> { diff --git a/crates/router/src/configs/defaults/payment_connector_required_fields.rs b/crates/router/src/configs/defaults/payment_connector_required_fields.rs index 27cc485188..3849054045 100644 --- a/crates/router/src/configs/defaults/payment_connector_required_fields.rs +++ b/crates/router/src/configs/defaults/payment_connector_required_fields.rs @@ -9128,7 +9128,86 @@ impl Default for settings::RequiredFields { RequiredFieldFinal { mandate: HashMap::new(), non_mandate: HashMap::new(), - common: HashMap::new(), + common: HashMap::from( + [ + ( + "billing.email".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.email".to_string(), + display_name: "email".to_string(), + field_type: enums::FieldType::UserEmailAddress, + value: None, + } + ), + ( + "billing.address.first_name".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.first_name".to_string(), + display_name: "billing_first_name".to_string(), + field_type: enums::FieldType::UserBillingName, + value: None, + } + ), + ( + "billing.address.last_name".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.last_name".to_string(), + display_name: "billing_last_name".to_string(), + field_type: enums::FieldType::UserBillingName, + value: None, + } + ), + ( + "billing.address.city".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.city".to_string(), + display_name: "city".to_string(), + field_type: enums::FieldType::UserAddressCity, + value: None, + } + ), + ( + "billing.address.state".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.state".to_string(), + display_name: "state".to_string(), + field_type: enums::FieldType::UserAddressState, + value: None, + } + ), + ( + "billing.address.zip".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.zip".to_string(), + display_name: "zip".to_string(), + field_type: enums::FieldType::UserAddressPincode, + value: None, + } + ), + ( + "billing.address.country".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.country".to_string(), + display_name: "country".to_string(), + field_type: enums::FieldType::UserAddressCountry{ + options: vec![ + "ALL".to_string(), + ] + }, + value: None, + } + ), + ( + "billing.address.line1".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.line1".to_string(), + display_name: "line1".to_string(), + field_type: enums::FieldType::UserAddressLine1, + value: None, + } + ) + ] + ), } ), ]),