use std::collections::HashSet; use common_utils::pii; use serde::de; use utoipa::ToSchema; use crate::enums as api_enums; #[derive(Debug, serde::Deserialize, serde::Serialize, Clone)] #[serde(deny_unknown_fields)] pub struct CreatePaymentMethod { pub payment_method: api_enums::PaymentMethodType, pub payment_method_type: Option, pub payment_method_issuer: Option, pub payment_method_issuer_code: Option, pub card: Option, pub metadata: Option, pub customer_id: Option, } #[derive(Debug, serde::Deserialize, serde::Serialize, Clone)] #[serde(deny_unknown_fields)] pub struct UpdatePaymentMethod { pub card: Option, // Add more payment method update field in future pub metadata: Option, } #[derive(Debug, serde::Deserialize, serde::Serialize, Clone)] #[serde(deny_unknown_fields)] pub struct CardDetail { pub card_number: masking::Secret, pub card_exp_month: masking::Secret, pub card_exp_year: masking::Secret, pub card_holder_name: Option>, } #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct PaymentMethodResponse { pub merchant_id: String, pub customer_id: Option, pub payment_method_id: String, pub payment_method: api_enums::PaymentMethodType, pub payment_method_type: Option, pub payment_method_issuer: Option, pub payment_method_issuer_code: Option, pub card: Option, pub recurring_enabled: bool, pub installment_payment_enabled: bool, pub payment_experience: Option>, pub metadata: Option, #[serde(default, with = "common_utils::custom_serde::iso8601::option")] pub created: Option, } #[derive(Debug, serde::Deserialize, serde::Serialize, Clone)] pub struct CardDetailFromLocker { pub scheme: Option, pub issuer_country: Option, pub last4_digits: Option, #[serde(skip)] pub card_number: Option>, pub expiry_month: Option>, pub expiry_year: Option>, pub card_token: Option>, pub card_holder_name: Option>, pub card_fingerprint: Option>, } //List Payment Method #[derive(Debug, serde::Serialize, Default)] #[serde(deny_unknown_fields)] pub struct ListPaymentMethodRequest { pub client_secret: Option, pub accepted_countries: Option>, pub accepted_currencies: Option>, pub amount: Option, pub recurring_enabled: Option, pub installment_payment_enabled: Option, } impl<'de> serde::Deserialize<'de> for ListPaymentMethodRequest { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct FieldVisitor; impl<'de> de::Visitor<'de> for FieldVisitor { type Value = ListPaymentMethodRequest; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { formatter.write_str("Failed while deserializing as map") } fn visit_map(self, mut map: A) -> Result where A: de::MapAccess<'de>, { let mut output = ListPaymentMethodRequest::default(); while let Some(key) = map.next_key()? { match key { "client_secret" => { set_or_reject_duplicate( &mut output.client_secret, "client_secret", map.next_value()?, )?; } "accepted_countries" => match output.accepted_countries.as_mut() { Some(inner) => inner.push(map.next_value()?), None => { output.accepted_countries = Some(vec![map.next_value()?]); } }, "accepted_currencies" => match output.accepted_currencies.as_mut() { Some(inner) => inner.push(map.next_value()?), None => { output.accepted_currencies = Some(vec![map.next_value()?]); } }, "amount" => { set_or_reject_duplicate( &mut output.amount, "amount", map.next_value()?, )?; } "recurring_enabled" => { set_or_reject_duplicate( &mut output.recurring_enabled, "recurring_enabled", map.next_value()?, )?; } "installment_payment_enabled" => { set_or_reject_duplicate( &mut output.installment_payment_enabled, "installment_payment_enabled", map.next_value()?, )?; } _ => {} } } Ok(output) } } deserializer.deserialize_identifier(FieldVisitor) } } // Try to set the provided value to the data otherwise throw an error fn set_or_reject_duplicate( data: &mut Option, name: &'static str, value: T, ) -> Result<(), E> { match data { Some(_inner) => Err(de::Error::duplicate_field(name)), None => { *data = Some(value); Ok(()) } } } #[derive(Debug, serde::Serialize)] pub struct ListPaymentMethodResponse { pub redirect_url: Option, pub payment_methods: HashSet, } #[derive(Eq, PartialEq, Hash, Debug, serde::Deserialize)] pub struct ListPaymentMethod { pub payment_method: api_enums::PaymentMethodType, pub payment_method_types: Option>, pub payment_method_issuers: Option>, pub payment_method_issuer_code: Option>, pub payment_schemes: Option>, pub accepted_countries: Option>, pub accepted_currencies: Option>, pub minimum_amount: Option, pub maximum_amount: Option, pub recurring_enabled: bool, pub installment_payment_enabled: bool, pub payment_experience: Option>, } /// We need a custom serializer to only send relevant fields in ListPaymentMethodResponse /// Currently if the payment method is Wallet or Paylater the relevant fields are `payment_method` /// and `payment_method_issuers`. Otherwise only consider /// `payment_method`,`payment_method_issuers`,`payment_method_types`,`payment_schemes` fields. impl serde::Serialize for ListPaymentMethod { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { use serde::ser::SerializeStruct; let mut state = serializer.serialize_struct("ListPaymentMethod", 4)?; state.serialize_field("payment_method", &self.payment_method)?; state.serialize_field("payment_experience", &self.payment_experience)?; match self.payment_method { api_enums::PaymentMethodType::Wallet | api_enums::PaymentMethodType::PayLater => { state.serialize_field("payment_method_issuers", &self.payment_method_issuers)?; } _ => { state.serialize_field("payment_method_issuers", &self.payment_method_issuers)?; state.serialize_field("payment_method_types", &self.payment_method_types)?; state.serialize_field("payment_schemes", &self.payment_schemes)?; } } state.end() } } #[derive(Debug, serde::Serialize)] pub struct ListCustomerPaymentMethodsResponse { pub enabled_payment_methods: HashSet, pub customer_payment_methods: Vec, } #[derive(Debug, serde::Serialize)] pub struct DeletePaymentMethodResponse { pub payment_method_id: String, pub deleted: bool, } #[derive(Debug, serde::Serialize)] pub struct CustomerPaymentMethod { pub payment_token: String, pub customer_id: String, pub payment_method: api_enums::PaymentMethodType, pub payment_method_type: Option, pub payment_method_issuer: Option, pub payment_method_issuer_code: Option, pub recurring_enabled: bool, pub installment_payment_enabled: bool, pub payment_experience: Option>, pub card: Option, pub metadata: Option, #[serde(default, with = "common_utils::custom_serde::iso8601::option")] pub created: Option, } #[derive(Eq, PartialEq, Hash, Clone, Debug, serde::Serialize, serde::Deserialize, ToSchema)] #[serde(rename_all = "snake_case")] #[non_exhaustive] pub enum PaymentExperience { /// The URL to which the customer needs to be redirected for completing the payment.The URL to /// which the customer needs to be redirected for completing the payment. RedirectToUrl, /// Contains the data for invoking the sdk client for completing the payment. InvokeSdkClient, /// The QR code data to be displayed to the customer. DisplayQrCode, /// Contains data to finish one click payment. OneClick, /// Redirect customer to link wallet LinkWallet, /// Contains the data for invoking the sdk client for completing the payment. InvokePaymentApp, } #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct PaymentMethodId { pub payment_method_id: String, } //------------------------------------------------TokenizeService------------------------------------------------ #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct TokenizePayloadEncrypted { pub payload: String, pub key_id: String, pub version: Option, } #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct TokenizePayloadRequest { pub value1: String, pub value2: String, pub lookup_key: String, pub service_name: String, } #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct GetTokenizePayloadRequest { pub lookup_key: String, pub get_value2: bool, } #[derive(Debug, serde::Serialize)] pub struct DeleteTokenizeByTokenRequest { pub lookup_key: String, } #[derive(Debug, serde::Serialize)] // Blocked: Yet to be implemented by `basilisk` pub struct DeleteTokenizeByDateRequest { pub buffer_minutes: i32, pub service_name: String, pub max_rows: i32, } #[derive(Debug, serde::Deserialize)] pub struct GetTokenizePayloadResponse { pub lookup_key: String, pub get_value2: Option, } #[derive(Debug, serde::Serialize, serde::Deserialize)] #[serde(rename_all = "camelCase")] pub struct TokenizedCardValue1 { pub card_number: String, pub exp_year: String, pub exp_month: String, pub name_on_card: Option, pub nickname: Option, pub card_last_four: Option, pub card_token: Option, } #[derive(Debug, serde::Serialize, serde::Deserialize)] #[serde(rename_all = "camelCase")] pub struct TokenizedCardValue2 { pub card_security_code: Option, pub card_fingerprint: Option, pub external_id: Option, pub customer_id: Option, pub payment_method_id: Option, } #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct TokenizedWalletValue1 { pub issuer: String, pub token: Option, } #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct TokenizedWalletValue2 { pub customer_id: Option, }