diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 0c8924f0d2..1a68b649bb 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -1342,12 +1342,12 @@ impl GetAddressFromPaymentMethodData for PaymentMethodData { match self { Self::Card(card_data) => card_data.get_billing_address(), Self::CardRedirect(_) => None, - Self::Wallet(_) => None, + Self::Wallet(wallet_data) => wallet_data.get_billing_address(), Self::PayLater(_) => None, Self::BankRedirect(_) => None, Self::BankDebit(_) => None, Self::BankTransfer(_) => None, - Self::Voucher(_) => None, + Self::Voucher(voucher_data) => voucher_data.get_billing_address(), Self::Crypto(_) | Self::Reward | Self::Upi(_) @@ -1898,43 +1898,43 @@ impl GetAddressFromPaymentMethodData for BankRedirectData { #[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)] pub struct AlfamartVoucherData { /// The billing first name for Alfamart - #[schema(value_type = String, example = "Jane")] - pub first_name: Secret, + #[schema(value_type = Option, example = "Jane")] + pub first_name: Option>, /// The billing second name for Alfamart - #[schema(value_type = String, example = "Doe")] + #[schema(value_type = Option, example = "Doe")] pub last_name: Option>, /// The Email ID for Alfamart - #[schema(value_type = String, example = "example@me.com")] - pub email: Email, + #[schema(value_type = Option, example = "example@me.com")] + pub email: Option, } #[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)] pub struct IndomaretVoucherData { /// The billing first name for Alfamart - #[schema(value_type = String, example = "Jane")] - pub first_name: Secret, + #[schema(value_type = Option, example = "Jane")] + pub first_name: Option>, /// The billing second name for Alfamart - #[schema(value_type = String, example = "Doe")] + #[schema(value_type = Option, example = "Doe")] pub last_name: Option>, /// The Email ID for Alfamart - #[schema(value_type = String, example = "example@me.com")] - pub email: Email, + #[schema(value_type = Option, example = "example@me.com")] + pub email: Option, } #[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)] pub struct JCSVoucherData { /// The billing first name for Japanese convenience stores - #[schema(value_type = String, example = "Jane")] - pub first_name: Secret, + #[schema(value_type = Option, example = "Jane")] + pub first_name: Option>, /// The billing second name Japanese convenience stores - #[schema(value_type = String, example = "Doe")] + #[schema(value_type = Option, example = "Doe")] pub last_name: Option>, /// The Email ID for Japanese convenience stores - #[schema(value_type = String, example = "example@me.com")] - pub email: Email, + #[schema(value_type = Option, example = "example@me.com")] + pub email: Option, /// The telephone number for Japanese convenience stores - #[schema(value_type = String, example = "9999999999")] - pub phone_number: String, + #[schema(value_type = Option, example = "9999999999")] + pub phone_number: Option, } #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] @@ -2468,21 +2468,21 @@ impl GetAddressFromPaymentMethodData for VoucherData { match self { Self::Alfamart(voucher_data) => Some(Address { address: Some(AddressDetails { - first_name: Some(voucher_data.first_name.clone()), + first_name: voucher_data.first_name.clone(), last_name: voucher_data.last_name.clone(), ..AddressDetails::default() }), phone: None, - email: Some(voucher_data.email.clone()), + email: voucher_data.email.clone(), }), Self::Indomaret(voucher_data) => Some(Address { address: Some(AddressDetails { - first_name: Some(voucher_data.first_name.clone()), + first_name: voucher_data.first_name.clone(), last_name: voucher_data.last_name.clone(), ..AddressDetails::default() }), phone: None, - email: Some(voucher_data.email.clone()), + email: voucher_data.email.clone(), }), Self::Lawson(voucher_data) | Self::MiniStop(voucher_data) @@ -2491,15 +2491,15 @@ impl GetAddressFromPaymentMethodData for VoucherData { | Self::PayEasy(voucher_data) | Self::SevenEleven(voucher_data) => Some(Address { address: Some(AddressDetails { - first_name: Some(voucher_data.first_name.clone()), + first_name: voucher_data.first_name.clone(), last_name: voucher_data.last_name.clone(), ..AddressDetails::default() }), phone: Some(PhoneDetails { - number: Some(voucher_data.phone_number.clone().into()), + number: voucher_data.phone_number.clone().map(Secret::new), country_code: None, }), - email: Some(voucher_data.email.clone()), + email: voucher_data.email.clone(), }), Self::Boleto(_) | Self::Efecty diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index 67b61960e8..d02078702e 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -734,14 +734,14 @@ pub enum OnlineBankingCzechRepublicBanks { C, } -impl TryFrom<&Box> for JCSVoucherData { +impl TryFrom<&types::PaymentsAuthorizeRouterData> for JCSVoucherData { type Error = Error; - fn try_from(jcs_data: &Box) -> Result { + fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result { Ok(Self { - first_name: jcs_data.first_name.clone(), - last_name: jcs_data.last_name.clone(), - shopper_email: jcs_data.email.clone(), - telephone_number: Secret::new(jcs_data.phone_number.clone()), + first_name: item.get_billing_first_name()?, + last_name: item.get_optional_billing_last_name(), + shopper_email: item.get_billing_email()?, + telephone_number: item.get_billing_phone_number()?, }) } } @@ -1884,43 +1884,41 @@ impl<'a> TryFrom<&domain::BankDebitData> for AdyenPaymentMethod<'a> { } } -impl<'a> TryFrom<&domain::VoucherData> for AdyenPaymentMethod<'a> { +impl<'a> TryFrom<(&domain::VoucherData, &types::PaymentsAuthorizeRouterData)> + for AdyenPaymentMethod<'a> +{ type Error = Error; - fn try_from(voucher_data: &domain::VoucherData) -> Result { + fn try_from( + (voucher_data, item): (&domain::VoucherData, &types::PaymentsAuthorizeRouterData), + ) -> Result { match voucher_data { domain::VoucherData::Boleto { .. } => Ok(AdyenPaymentMethod::BoletoBancario), - domain::VoucherData::Alfamart(alfarmart_data) => { - Ok(AdyenPaymentMethod::Alfamart(Box::new(DokuBankData { - first_name: alfarmart_data.first_name.clone(), - last_name: alfarmart_data.last_name.clone(), - shopper_email: alfarmart_data.email.clone(), - }))) - } - domain::VoucherData::Indomaret(indomaret_data) => { - Ok(AdyenPaymentMethod::Indomaret(Box::new(DokuBankData { - first_name: indomaret_data.first_name.clone(), - last_name: indomaret_data.last_name.clone(), - shopper_email: indomaret_data.email.clone(), - }))) - } + domain::VoucherData::Alfamart(_) => Ok(AdyenPaymentMethod::Alfamart(Box::new( + DokuBankData::try_from(item)?, + ))), + + domain::VoucherData::Indomaret(_) => Ok(AdyenPaymentMethod::Indomaret(Box::new( + DokuBankData::try_from(item)?, + ))), + domain::VoucherData::Oxxo => Ok(AdyenPaymentMethod::Oxxo), - domain::VoucherData::SevenEleven(jcs_data) => Ok(AdyenPaymentMethod::SevenEleven( - Box::new(JCSVoucherData::try_from(jcs_data)?), - )), - domain::VoucherData::Lawson(jcs_data) => Ok(AdyenPaymentMethod::Lawson(Box::new( - JCSVoucherData::try_from(jcs_data)?, + domain::VoucherData::SevenEleven(_) => Ok(AdyenPaymentMethod::SevenEleven(Box::new( + JCSVoucherData::try_from(item)?, ))), - domain::VoucherData::MiniStop(jcs_data) => Ok(AdyenPaymentMethod::MiniStop(Box::new( - JCSVoucherData::try_from(jcs_data)?, + domain::VoucherData::Lawson(_) => Ok(AdyenPaymentMethod::Lawson(Box::new( + JCSVoucherData::try_from(item)?, ))), - domain::VoucherData::FamilyMart(jcs_data) => Ok(AdyenPaymentMethod::FamilyMart( - Box::new(JCSVoucherData::try_from(jcs_data)?), - )), - domain::VoucherData::Seicomart(jcs_data) => Ok(AdyenPaymentMethod::Seicomart( - Box::new(JCSVoucherData::try_from(jcs_data)?), - )), - domain::VoucherData::PayEasy(jcs_data) => Ok(AdyenPaymentMethod::PayEasy(Box::new( - JCSVoucherData::try_from(jcs_data)?, + domain::VoucherData::MiniStop(_) => Ok(AdyenPaymentMethod::MiniStop(Box::new( + JCSVoucherData::try_from(item)?, + ))), + domain::VoucherData::FamilyMart(_) => Ok(AdyenPaymentMethod::FamilyMart(Box::new( + JCSVoucherData::try_from(item)?, + ))), + domain::VoucherData::Seicomart(_) => Ok(AdyenPaymentMethod::Seicomart(Box::new( + JCSVoucherData::try_from(item)?, + ))), + domain::VoucherData::PayEasy(_) => Ok(AdyenPaymentMethod::PayEasy(Box::new( + JCSVoucherData::try_from(item)?, ))), domain::VoucherData::Efecty | domain::VoucherData::PagoEfectivo @@ -2495,6 +2493,17 @@ impl<'a> TryFrom<&domain::BankTransferData> for AdyenPaymentMethod<'a> { } } +impl TryFrom<&types::PaymentsAuthorizeRouterData> for DokuBankData { + type Error = Error; + fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result { + Ok(Self { + first_name: item.get_billing_first_name()?, + last_name: item.get_optional_billing_last_name(), + shopper_email: item.get_billing_email()?, + }) + } +} + impl<'a> TryFrom<&domain::payments::CardRedirectData> for AdyenPaymentMethod<'a> { type Error = Error; fn try_from( @@ -2759,7 +2768,7 @@ impl<'a> let recurring_processing_model = get_recurring_processing_model(item.router_data)?.0; let browser_info = get_browser_info(item.router_data)?; let additional_data = get_additional_data(item.router_data); - let payment_method = AdyenPaymentMethod::try_from(voucher_data)?; + let payment_method = AdyenPaymentMethod::try_from((voucher_data, item.router_data))?; let return_url = item.router_data.request.get_return_url()?; let social_security_number = get_social_security_number(voucher_data); let request = AdyenPaymentRequest { diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index fac0d91655..6d427c5419 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -72,6 +72,9 @@ pub trait RouterData { fn get_shipping_address_with_phone_number(&self) -> Result<&api::Address, Error>; fn get_connector_meta(&self) -> Result; fn get_session_token(&self) -> Result; + fn get_billing_first_name(&self) -> Result, Error>; + fn get_billing_email(&self) -> Result; + fn get_billing_phone_number(&self) -> Result, Error>; fn to_connector_meta(&self) -> Result where T: serde::de::DeserializeOwned; @@ -214,6 +217,36 @@ impl RouterData for types::RouterData Result, Error> { + self.address + .get_payment_method_billing() + .and_then(|billing_address| { + billing_address + .clone() + .address + .and_then(|billing_address_details| billing_address_details.first_name.clone()) + }) + .ok_or_else(missing_field_err( + "payment_method_data.billing.address.first_name", + )) + } + + fn get_billing_email(&self) -> Result { + self.address + .get_payment_method_billing() + .and_then(|billing_address| billing_address.email.clone()) + .ok_or_else(missing_field_err("payment_method_data.billing.email")) + } + + fn get_billing_phone_number(&self) -> Result, Error> { + self.address + .get_payment_method_billing() + .and_then(|billing_address| billing_address.clone().phone) + .map(|phone_details| phone_details.get_number_with_country_code()) + .transpose()? + .ok_or_else(missing_field_err("payment_method_data.billing.phone")) + } + fn get_optional_billing_line1(&self) -> Option> { self.address .get_payment_method_billing() diff --git a/crates/router/src/types/domain/payments.rs b/crates/router/src/types/domain/payments.rs index 746c100911..fe34f2092b 100644 --- a/crates/router/src/types/domain/payments.rs +++ b/crates/router/src/types/domain/payments.rs @@ -352,36 +352,13 @@ pub struct BoletoVoucherData { } #[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct AlfamartVoucherData { - /// The billing first name for Alfamart - pub first_name: Secret, - /// The billing second name for Alfamart - pub last_name: Option>, - /// The Email ID for Alfamart - pub email: Email, -} +pub struct AlfamartVoucherData {} #[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct IndomaretVoucherData { - /// The billing first name for Alfamart - pub first_name: Secret, - /// The billing second name for Alfamart - pub last_name: Option>, - /// The Email ID for Alfamart - pub email: Email, -} +pub struct IndomaretVoucherData {} #[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct JCSVoucherData { - /// The billing first name for Japanese convenience stores - pub first_name: Secret, - /// The billing second name Japanese convenience stores - pub last_name: Option>, - /// The Email ID for Japanese convenience stores - pub email: Email, - /// The telephone number for Japanese convenience stores - pub phone_number: String, -} +pub struct JCSVoucherData {} #[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Eq, PartialEq)] #[serde(rename_all = "snake_case")] @@ -888,32 +865,19 @@ impl From for VoucherData { social_security_number: boleto_data.social_security_number, })) } - api_models::payments::VoucherData::Alfamart(alfamart_data) => { - Self::Alfamart(Box::new(AlfamartVoucherData { - first_name: alfamart_data.first_name, - last_name: alfamart_data.last_name, - email: alfamart_data.email, - })) + api_models::payments::VoucherData::Alfamart(_) => { + Self::Alfamart(Box::new(AlfamartVoucherData {})) } - api_models::payments::VoucherData::Indomaret(indomaret_data) => { - Self::Indomaret(Box::new(IndomaretVoucherData { - first_name: indomaret_data.first_name, - last_name: indomaret_data.last_name, - email: indomaret_data.email, - })) + api_models::payments::VoucherData::Indomaret(_) => { + Self::Indomaret(Box::new(IndomaretVoucherData {})) } - api_models::payments::VoucherData::SevenEleven(jcs_data) - | api_models::payments::VoucherData::Lawson(jcs_data) - | api_models::payments::VoucherData::MiniStop(jcs_data) - | api_models::payments::VoucherData::FamilyMart(jcs_data) - | api_models::payments::VoucherData::Seicomart(jcs_data) - | api_models::payments::VoucherData::PayEasy(jcs_data) => { - Self::SevenEleven(Box::new(JCSVoucherData { - first_name: jcs_data.first_name, - last_name: jcs_data.last_name, - email: jcs_data.email, - phone_number: jcs_data.phone_number, - })) + api_models::payments::VoucherData::SevenEleven(_) + | api_models::payments::VoucherData::Lawson(_) + | api_models::payments::VoucherData::MiniStop(_) + | api_models::payments::VoucherData::FamilyMart(_) + | api_models::payments::VoucherData::Seicomart(_) + | api_models::payments::VoucherData::PayEasy(_) => { + Self::SevenEleven(Box::new(JCSVoucherData {})) } api_models::payments::VoucherData::Efecty => Self::Efecty, api_models::payments::VoucherData::PagoEfectivo => Self::PagoEfectivo, diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json index b736475858..913782448f 100644 --- a/openapi/openapi_spec.json +++ b/openapi/openapi_spec.json @@ -4882,26 +4882,24 @@ }, "AlfamartVoucherData": { "type": "object", - "required": [ - "first_name", - "last_name", - "email" - ], "properties": { "first_name": { "type": "string", "description": "The billing first name for Alfamart", - "example": "Jane" + "example": "Jane", + "nullable": true }, "last_name": { "type": "string", "description": "The billing second name for Alfamart", - "example": "Doe" + "example": "Doe", + "nullable": true }, "email": { "type": "string", "description": "The Email ID for Alfamart", - "example": "example@me.com" + "example": "example@me.com", + "nullable": true } } }, @@ -9753,26 +9751,24 @@ }, "IndomaretVoucherData": { "type": "object", - "required": [ - "first_name", - "last_name", - "email" - ], "properties": { "first_name": { "type": "string", "description": "The billing first name for Alfamart", - "example": "Jane" + "example": "Jane", + "nullable": true }, "last_name": { "type": "string", "description": "The billing second name for Alfamart", - "example": "Doe" + "example": "Doe", + "nullable": true }, "email": { "type": "string", "description": "The Email ID for Alfamart", - "example": "example@me.com" + "example": "example@me.com", + "nullable": true } } }, @@ -9794,32 +9790,30 @@ }, "JCSVoucherData": { "type": "object", - "required": [ - "first_name", - "last_name", - "email", - "phone_number" - ], "properties": { "first_name": { "type": "string", "description": "The billing first name for Japanese convenience stores", - "example": "Jane" + "example": "Jane", + "nullable": true }, "last_name": { "type": "string", "description": "The billing second name Japanese convenience stores", - "example": "Doe" + "example": "Doe", + "nullable": true }, "email": { "type": "string", "description": "The Email ID for Japanese convenience stores", - "example": "example@me.com" + "example": "example@me.com", + "nullable": true }, "phone_number": { "type": "string", "description": "The telephone number for Japanese convenience stores", - "example": "9999999999" + "example": "9999999999", + "nullable": true } } },