diff --git a/Cargo.lock b/Cargo.lock index d9999a69ad..94d137885d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2767,7 +2767,7 @@ dependencies = [ [[package]] name = "opentelemetry" version = "0.18.0" -source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658" +source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658" dependencies = [ "opentelemetry_api", "opentelemetry_sdk", @@ -2776,7 +2776,7 @@ dependencies = [ [[package]] name = "opentelemetry-otlp" version = "0.11.0" -source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658" +source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658" dependencies = [ "async-trait", "futures", @@ -2793,7 +2793,7 @@ dependencies = [ [[package]] name = "opentelemetry-proto" version = "0.1.0" -source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658" +source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658" dependencies = [ "futures", "futures-util", @@ -2805,7 +2805,7 @@ dependencies = [ [[package]] name = "opentelemetry_api" version = "0.18.0" -source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658" +source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658" dependencies = [ "fnv", "futures-channel", @@ -2820,7 +2820,7 @@ dependencies = [ [[package]] name = "opentelemetry_sdk" version = "0.18.0" -source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658" +source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658" dependencies = [ "async-trait", "crossbeam-channel", diff --git a/config/development.toml b/config/development.toml index 1a335764d6..7b5fc0b1f6 100644 --- a/config/development.toml +++ b/config/development.toml @@ -142,6 +142,12 @@ adyen = { banks = "bank_austria,bawag_psk_ag,dolomitenbank,easybank_ag,erste_ban stripe = { banks = "abn_amro,asn_bank,bunq,handelsbanken,ing,knab,moneyou,rabobank,regiobank,revolut,sns_bank,triodos_bank,van_lanschot" } adyen = { banks = "abn_amro,asn_bank,bunq,handelsbanken,ing,knab,moneyou,rabobank,regiobank,revolut,sns_bank,triodos_bank,van_lanschot" } +[bank_config.online_banking_czech_republic] +adyen = { banks = "ceska_sporitelna,komercni_banka,platnosc_online_karta_platnicza"} + +[bank_config.online_banking_slovakia] +adyen = { banks = "e_platby_v_u_b,postova_banka,sporo_pay,tatra_pay,viamo,volksbank_gruppe,volkskredit_bank_ag,vr_bank_braunau"} + [pm_filters.stripe] google_pay = { country = "AL,DZ,AS,AO,AG,AR,AU,AT,AZ,BH,BY,BE,BR,BG,CA,CL,CO,HR,CZ,DK,DO,EG,EE,FI,FR,DE,GR,HK,HU,IN,ID,IE,IL,IT,JP,JO,KZ,KE,KW,LV,LB,LT,LU,MY,MX,NL,NZ,NO,OM,PK,PA,PE,PH,PL,PT,QA,RO,RU,SA,SG,SK,ZA,ES,LK,SE,CH,TW,TH,TR,UA,AE,GB,US,UY,VN" } apple_pay = { country = "AU,CN,HK,JP,MO,MY,NZ,SG,TW,AM,AT,AZ,BY,BE,BG,HR,CY,CZ,DK,EE,FO,FI,FR,GE,DE,GR,GL,GG,HU,IS,IE,IM,IT,KZ,JE,LV,LI,LT,LU,MT,MD,MC,ME,NL,NO,PL,PT,RO,SM,RS,SK,SI,ES,SE,CH,UA,GB,AR,CO,CR,BR,MX,PE,BH,IL,JO,KW,PS,QA,SA,AE,CA,UM,US" } diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs index 2d7cfe276a..0aae07bb04 100644 --- a/crates/api_models/src/enums.rs +++ b/crates/api_models/src/enums.rs @@ -409,19 +409,34 @@ pub enum PaymentExperience { #[serde(rename_all = "snake_case")] #[strum(serialize_all = "snake_case")] pub enum PaymentMethodType { - Credit, - Debit, - Giropay, - Ideal, - Sofort, - Eps, - Klarna, Affirm, AfterpayClearpay, - GooglePay, + AliPay, ApplePay, - Paypal, + BancontactCard, + Blik, + Credit, CryptoCurrency, + Debit, + Eps, + Giropay, + GooglePay, + Ideal, + Klarna, + MbWay, + MobilePay, + OnlineBankingCzechRepublic, + OnlineBankingFinland, + OnlineBankingPoland, + OnlineBankingSlovakia, + PayBright, + Paypal, + Przelewy24, + Sofort, + Swish, + Trustly, + Walley, + WeChatPay, } #[derive( @@ -684,6 +699,8 @@ pub enum BankNames { AmericanExpress, BankOfAmerica, Barclays, + #[serde(rename = "BLIK - PSP")] + BlikPSP, CapitalOne, Chase, Citi, @@ -711,13 +728,21 @@ pub enum BankNames { Bank99Ag, BankhausCarlSpangler, BankhausSchelhammerUndSchatteraAg, + #[serde(rename = "Bank Millennium")] + BankMillennium, + #[serde(rename = "Bank PEKAO S.A.")] + BankPEKAOSA, BawagPskAg, BksBankAg, BrullKallmusBankAg, BtvVierLanderBank, CapitalBankGraweGruppeAg, + #[serde(rename = "Česká spořitelna")] + CeskaSporitelna, Dolomitenbank, EasybankAg, + #[serde(rename = "ePlatby VÚB")] + EPlatbyVUB, ErsteBankUndSparkassen, HypoAlpeadriabankInternationalAg, HypoNoeLbFurNiederosterreichUWien, @@ -725,17 +750,57 @@ pub enum BankNames { HypoTirolBankAg, HypoVorarlbergBankAg, HypoBankBurgenlandAktiengesellschaft, + #[serde(rename = "Komercní banka")] + KomercniBanka, + #[serde(rename = "mBank - mTransfer")] + MBank, MarchfelderBank, OberbankAg, OsterreichischeArzteUndApothekerbank, + #[serde(rename = "Pay with ING")] + PayWithING, + #[serde(rename = "Płacę z iPKO")] + PlaceZIPKO, + #[serde(rename = "Płatność online kartą płatniczą")] + PlatnoscOnlineKartaPlatnicza, PosojilnicaBankEGen, + #[serde(rename = "Poštová banka")] + PostovaBanka, RaiffeisenBankengruppeOsterreich, SchelhammerCapitalBankAg, SchoellerbankAg, SpardaBankWien, + SporoPay, + #[serde(rename = "Santander-Przelew24")] + SantanderPrzelew24, + TatraPay, + Viamo, VolksbankGruppe, VolkskreditbankAg, VrBankBraunau, + #[serde(rename = "Pay with Alior Bank")] + PayWithAliorBank, + #[serde(rename = "Banki Spółdzielcze")] + BankiSpoldzielcze, + #[serde(rename = "Pay with Inteligo")] + PayWithInteligo, + #[serde(rename = "BNP Paribas Poland")] + BNPParibasPoland, + #[serde(rename = "Bank Nowy S.A.")] + BankNowySA, + #[serde(rename = "Credit Agricole")] + CreditAgricole, + #[serde(rename = "Pay with BOŚ")] + PayWithBOS, + #[serde(rename = "Pay with CitiHandlowy")] + PayWithCitiHandlowy, + #[serde(rename = "Pay with Plus Bank")] + PayWithPlusBank, + #[serde(rename = "Toyota Bank")] + ToyotaBank, + VeloBank, + #[serde(rename = "e-transfer Pocztowy24")] + ETransferPocztowy24, } #[derive( diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index eefb27ee61..db2c7bd66a 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -454,6 +454,8 @@ pub enum PayLaterData { #[schema(value_type = String)] billing_name: Secret, }, + PayBright {}, + Walley {}, } #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] @@ -510,6 +512,26 @@ impl From<&PaymentMethodData> for AdditionalPaymentData { #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] #[serde(rename_all = "snake_case")] pub enum BankRedirectData { + BancontactCard { + /// The card number + #[schema(value_type = String, example = "4242424242424242")] + card_number: Secret, + /// The card's expiry month + #[schema(value_type = String, example = "24")] + card_exp_month: Secret, + + /// The card's expiry year + #[schema(value_type = String, example = "24")] + card_exp_year: Secret, + + /// The card holder's name + #[schema(value_type = String, example = "John Test")] + card_holder_name: Secret, + }, + Blik { + // Blik Code + blik_code: String, + }, Eps { /// The billing details for bank redirection billing_details: BankRedirectBilling, @@ -530,6 +552,23 @@ pub enum BankRedirectData { #[schema(value_type = BankNames, example = "abn_amro")] bank_name: api_enums::BankNames, }, + OnlineBankingCzechRepublic { + // Issuer banks + issuer: api_enums::BankNames, + }, + OnlineBankingFinland { + // Shopper Email + email: Option>, + }, + OnlineBankingPoland { + // Issuer banks + issuer: api_enums::BankNames, + }, + OnlineBankingSlovakia { + // Issuer value corresponds to the bank + issuer: api_enums::BankNames, + }, + Przelewy24 {}, Sofort { /// The billing details for bank redirection billing_details: BankRedirectBilling, @@ -542,6 +581,8 @@ pub enum BankRedirectData { #[schema(example = "en")] preferred_language: String, }, + Swish {}, + Trustly {}, } #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] @@ -565,14 +606,21 @@ pub struct BankRedirectBilling { #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] #[serde(rename_all = "snake_case")] pub enum WalletData { - /// The wallet data for Google pay - GooglePay(GooglePayWalletData), + /// The wallet data for Ali Pay redirect + AliPay(AliPayRedirection), /// The wallet data for Apple pay ApplePay(ApplePayWalletData), - /// The wallet data for Paypal - PaypalSdk(PayPalWalletData), + /// The wallet data for Google pay + GooglePay(GooglePayWalletData), + MbWay(Box), + /// The wallet data for MobilePay redirect + MobilePay(Box), /// This is for paypal redirection PaypalRedirect(PaypalRedirection), + /// The wallet data for Paypal + PaypalSdk(PayPalWalletData), + /// The wallet data for WeChat Pay Redirection + WeChatPayRedirect(Box), } #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] @@ -588,9 +636,24 @@ pub struct GooglePayWalletData { pub tokenization_data: GpayTokenizationData, } +#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] +pub struct WeChatPayRedirection {} + #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] pub struct PaypalRedirection {} +#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] +pub struct AliPayRedirection {} + +#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] +pub struct MobilePayRedirection {} + +#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] +pub struct MbWayRedirection { + /// Telephone number of the shopper. Should be Portuguese phone number. + pub telephone_number: Secret, +} + #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] pub struct GooglePayPaymentMethodInfo { /// The name of the card network diff --git a/crates/router/src/connector/adyen.rs b/crates/router/src/connector/adyen.rs index 621819b70a..31d3740bf5 100644 --- a/crates/router/src/connector/adyen.rs +++ b/crates/router/src/connector/adyen.rs @@ -191,6 +191,8 @@ impl } } +/// Payment Sync can be useful only incase of Redirect flow. +/// For payments which doesn't involve redrection we have to rely on webhooks. impl services::ConnectorIntegration for Adyen diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index aa3c74f0b9..de5932fe63 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -17,6 +17,8 @@ use crate::{ }, }; +type Error = error_stack::Report; + // Adyen Types Definition // Payments Request and Response Types #[derive(Default, Debug, Serialize, Deserialize)] @@ -115,19 +117,36 @@ struct AdyenBrowserInfo { #[derive(Debug, Clone, Serialize, Deserialize)] pub enum AdyenStatus { + AuthenticationFinished, + AuthenticationNotRequired, Authorised, - Refused, Cancelled, + ChallengeShopper, + Error, + Pending, + Received, RedirectShopper, + Refused, } -impl From for storage_enums::AttemptStatus { - fn from(item: AdyenStatus) -> Self { - match item { - AdyenStatus::Authorised => Self::Charged, - AdyenStatus::Refused => Self::Failure, +/// This implementation will be used only in Authorize, Automatic capture flow. +/// It is also being used in Psync flow, However Psync will be called only after create payment call that too in redirect flow. +impl ForeignFrom<(bool, AdyenStatus)> for storage_enums::AttemptStatus { + fn foreign_from((is_manual_capture, adyen_status): (bool, AdyenStatus)) -> Self { + match adyen_status { + AdyenStatus::AuthenticationFinished => Self::AuthenticationSuccessful, + AdyenStatus::AuthenticationNotRequired => Self::Pending, + AdyenStatus::Authorised => match is_manual_capture { + true => Self::Authorized, + false => Self::Charged, + }, AdyenStatus::Cancelled => Self::Voided, - AdyenStatus::RedirectShopper => Self::AuthenticationPending, + AdyenStatus::ChallengeShopper | AdyenStatus::RedirectShopper => { + Self::AuthenticationPending + } + AdyenStatus::Error | AdyenStatus::Refused => Self::Failure, + AdyenStatus::Pending => Self::Pending, + AdyenStatus::Received => Self::Started, } } } @@ -195,11 +214,19 @@ pub struct AdyenRedirectionResponse { #[serde(rename_all = "camelCase")] pub struct AdyenRedirectionAction { payment_method_type: String, - url: Url, - method: services::Method, + url: Option, + method: Option, #[serde(rename = "type")] - type_of_response: String, + type_of_response: ActionType, data: Option>, + payment_data: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum ActionType { + Redirect, + Await, } #[derive(Default, Debug, Clone, Serialize, Deserialize)] @@ -211,26 +238,245 @@ pub struct Amount { #[derive(Debug, Clone, Serialize)] #[serde(tag = "type")] pub enum AdyenPaymentMethod<'a> { - AdyenCard(AdyenCard), - AdyenPaypal(AdyenPaypal), - Gpay(AdyenGPay), - ApplePay(AdyenApplePay), - AfterPay(AdyenPayLaterData), - AdyenKlarna(AdyenPayLaterData), - AdyenAffirm(AdyenPayLaterData), - Eps(BankRedirectionWithIssuer<'a>), - Ideal(BankRedirectionWithIssuer<'a>), - Giropay(BankRedirectionPMData), - Sofort(BankRedirectionPMData), + AdyenAffirm(Box), + AdyenCard(Box), + AdyenKlarna(Box), + AdyenPaypal(Box), + AfterPay(Box), + AliPay(Box), + ApplePay(Box), + BancontactCard(Box), + Blik(Box), + Eps(Box>), + Giropay(Box), + Gpay(Box), + Ideal(Box>), + Mbway(Box), + MobilePay(Box), + OnlineBankingCzechRepublic(Box), + OnlineBankingFinland(Box), + OnlineBankingPoland(Box), + OnlineBankingSlovakia(Box), + PayBright(Box), + Sofort(Box), + Trustly(Box), + Walley(Box), + WeChatPayWeb(Box), } #[derive(Debug, Clone, Serialize)] +pub struct WeChatPayWebData { + #[serde(rename = "type")] + payment_type: PaymentType, +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct BancontactCardData { + #[serde(rename = "type")] + payment_type: PaymentType, + brand: String, + number: Secret, + expiry_month: Secret, + expiry_year: Secret, + holder_name: Secret, +} + +#[derive(Debug, Clone, Serialize)] +pub struct MobilePayData { + #[serde(rename = "type")] + payment_type: PaymentType, +} +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct MbwayData { + #[serde(rename = "type")] + payment_type: PaymentType, + telephone_number: Secret, +} + +#[derive(Debug, Clone, Serialize)] +pub struct WalleyData { + #[serde(rename = "type")] + payment_type: PaymentType, +} + +#[derive(Debug, Clone, Serialize)] +pub struct PayBrightData { + #[serde(rename = "type")] + payment_type: PaymentType, +} + +#[derive(Debug, Clone, Serialize)] +pub struct OnlineBankingFinlandData { + #[serde(rename = "type")] + payment_type: PaymentType, +} +#[derive(Debug, Clone, Serialize)] +pub struct OnlineBankingCzechRepublicData { + #[serde(rename = "type")] + payment_type: PaymentType, + issuer: OnlineBankingCzechRepublicBanks, +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "lowercase")] +pub enum OnlineBankingCzechRepublicBanks { + KB, + CS, + C, +} + +impl TryFrom<&api_enums::BankNames> for OnlineBankingCzechRepublicBanks { + type Error = Error; + fn try_from(bank_name: &api_enums::BankNames) -> Result { + match bank_name { + api::enums::BankNames::KomercniBanka => Ok(Self::KB), + api::enums::BankNames::CeskaSporitelna => Ok(Self::CS), + api::enums::BankNames::PlatnoscOnlineKartaPlatnicza => Ok(Self::C), + _ => Err(errors::ConnectorError::NotSupported { + payment_method: String::from("BankRedirect"), + connector: "Adyen", + payment_experience: api_enums::PaymentExperience::RedirectToUrl.to_string(), + })?, + } + } +} + +#[derive(Debug, Clone, Serialize)] +pub struct OnlineBankingPolandData { + #[serde(rename = "type")] + payment_type: PaymentType, + issuer: OnlineBankingPolandBanks, +} + +#[derive(Debug, Clone, Serialize)] +pub enum OnlineBankingPolandBanks { + #[serde(rename = "154")] + BlikPSP, + #[serde(rename = "31")] + PlaceZIPKO, + #[serde(rename = "243")] + MBank, + #[serde(rename = "112")] + PayWithING, + #[serde(rename = "20")] + SantanderPrzelew24, + #[serde(rename = "65")] + BankPEKAOSA, + #[serde(rename = "85")] + BankMillennium, + #[serde(rename = "88")] + PayWithAliorBank, + #[serde(rename = "143")] + BankiSpoldzielcze, + #[serde(rename = "26")] + PayWithInteligo, + #[serde(rename = "33")] + BNPParibasPoland, + #[serde(rename = "144")] + BankNowySA, + #[serde(rename = "45")] + CreditAgricole, + #[serde(rename = "99")] + PayWithBOS, + #[serde(rename = "119")] + PayWithCitiHandlowy, + #[serde(rename = "131")] + PayWithPlusBank, + #[serde(rename = "64")] + ToyotaBank, + #[serde(rename = "153")] + VeloBank, + #[serde(rename = "141")] + ETransferPocztowy24, +} + +impl TryFrom<&api_enums::BankNames> for OnlineBankingPolandBanks { + type Error = Error; + fn try_from(bank_name: &api_enums::BankNames) -> Result { + match bank_name { + api_models::enums::BankNames::BlikPSP => Ok(Self::BlikPSP), + api_models::enums::BankNames::PlaceZIPKO => Ok(Self::PlaceZIPKO), + api_models::enums::BankNames::MBank => Ok(Self::MBank), + api_models::enums::BankNames::PayWithING => Ok(Self::PayWithING), + api_models::enums::BankNames::SantanderPrzelew24 => Ok(Self::SantanderPrzelew24), + api_models::enums::BankNames::BankPEKAOSA => Ok(Self::BankPEKAOSA), + api_models::enums::BankNames::BankMillennium => Ok(Self::BankMillennium), + api_models::enums::BankNames::PayWithAliorBank => Ok(Self::PayWithAliorBank), + api_models::enums::BankNames::BankiSpoldzielcze => Ok(Self::BankiSpoldzielcze), + api_models::enums::BankNames::PayWithInteligo => Ok(Self::PayWithInteligo), + api_models::enums::BankNames::BNPParibasPoland => Ok(Self::BNPParibasPoland), + api_models::enums::BankNames::BankNowySA => Ok(Self::BankNowySA), + api_models::enums::BankNames::CreditAgricole => Ok(Self::CreditAgricole), + api_models::enums::BankNames::PayWithBOS => Ok(Self::PayWithBOS), + api_models::enums::BankNames::PayWithCitiHandlowy => Ok(Self::PayWithCitiHandlowy), + api_models::enums::BankNames::PayWithPlusBank => Ok(Self::PayWithPlusBank), + api_models::enums::BankNames::ToyotaBank => Ok(Self::ToyotaBank), + api_models::enums::BankNames::VeloBank => Ok(Self::VeloBank), + api_models::enums::BankNames::ETransferPocztowy24 => Ok(Self::ETransferPocztowy24), + _ => Err(errors::ConnectorError::NotSupported { + payment_method: String::from("BankRedirect"), + connector: "Adyen", + payment_experience: api_enums::PaymentExperience::RedirectToUrl.to_string(), + })?, + } + } +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct OnlineBankingSlovakiaData { + #[serde(rename = "type")] + payment_type: PaymentType, + issuer: OnlineBankingSlovakiaBanks, +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "lowercase")] +pub enum OnlineBankingSlovakiaBanks { + Vub, + Posto, + Sporo, + Tatra, + Viamo, +} + +impl TryFrom<&api_enums::BankNames> for OnlineBankingSlovakiaBanks { + type Error = Error; + fn try_from(bank_name: &api_enums::BankNames) -> Result { + match bank_name { + api::enums::BankNames::EPlatbyVUB => Ok(Self::Vub), + api::enums::BankNames::PostovaBanka => Ok(Self::Posto), + api::enums::BankNames::SporoPay => Ok(Self::Sporo), + api::enums::BankNames::TatraPay => Ok(Self::Tatra), + api::enums::BankNames::Viamo => Ok(Self::Viamo), + _ => Err(errors::ConnectorError::NotSupported { + payment_method: String::from("BankRedirect"), + connector: "Adyen", + payment_experience: api_enums::PaymentExperience::RedirectToUrl.to_string(), + })?, + } + } +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct BlikRedirectionData { + #[serde(rename = "type")] + payment_type: PaymentType, + blik_code: String, +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] pub struct BankRedirectionPMData { #[serde(rename = "type")] payment_type: PaymentType, } #[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] pub struct BankRedirectionWithIssuer<'a> { #[serde(rename = "type")] payment_type: PaymentType, @@ -270,12 +516,17 @@ pub enum CancelStatus { Processing, } #[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] pub struct AdyenPaypal { #[serde(rename = "type")] payment_type: PaymentType, } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AliPayData { + #[serde(rename = "type")] + payment_type: PaymentType, +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AdyenGPay { #[serde(rename = "type")] @@ -326,24 +577,41 @@ pub struct AdyenAuthType { #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] pub enum PaymentType { - Scheme, - Googlepay, - Applepay, - Paypal, - Klarna, Affirm, Afterpaytouch, + Alipay, + Applepay, + Blik, Eps, - Ideal, Giropay, + Googlepay, + Ideal, + Klarna, + Mbway, + MobilePay, + #[serde(rename = "onlineBanking_CZ")] + OnlineBankingCzechRepublic, + #[serde(rename = "ebanking_FI")] + OnlineBankingFinland, + #[serde(rename = "onlineBanking_PL")] + OnlineBankingPoland, + #[serde(rename = "onlineBanking_SK")] + OnlineBankingSlovakia, + PayBright, + Paypal, + Scheme, #[serde(rename = "directEbanking")] Sofort, + Trustly, + Walley, + #[serde(rename = "wechatpayWeb")] + WeChatPayWeb, } pub struct AdyenTestBankNames<'a>(&'a str); impl<'a> TryFrom<&api_enums::BankNames> for AdyenTestBankNames<'a> { - type Error = error_stack::Report; + type Error = Error; fn try_from(bank: &api_enums::BankNames) -> Result { Ok(match bank { api_models::enums::BankNames::AbnAmro => Self("1121"), @@ -405,7 +673,7 @@ impl<'a> TryFrom<&api_enums::BankNames> for AdyenTestBankNames<'a> { } impl TryFrom<&types::ConnectorAuthType> for AdyenAuthType { - type Error = error_stack::Report; + type Error = Error; fn try_from(auth_type: &types::ConnectorAuthType) -> Result { if let types::ConnectorAuthType::BodyKey { api_key, key1 } = auth_type { Ok(Self { @@ -418,27 +686,27 @@ impl TryFrom<&types::ConnectorAuthType> for AdyenAuthType { } } -// Payment Request Transform impl<'a> TryFrom<&types::PaymentsAuthorizeRouterData> for AdyenPaymentRequest<'a> { - type Error = error_stack::Report; + type Error = Error; fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result { - match item.payment_method { - storage_models::enums::PaymentMethod::Card => get_card_specific_payment_data(item), - storage_models::enums::PaymentMethod::PayLater => { - get_paylater_specific_payment_data(item) + match item.request.payment_method_data { + api_models::payments::PaymentMethodData::Card(ref card) => { + AdyenPaymentRequest::try_from((item, card)) } - storage_models::enums::PaymentMethod::Wallet => get_wallet_specific_payment_data(item), - storage_models::enums::PaymentMethod::BankRedirect => { - get_bank_redirect_specific_payment_data(item) + api_models::payments::PaymentMethodData::Wallet(ref wallet) => { + AdyenPaymentRequest::try_from((item, wallet)) } - storage_models::enums::PaymentMethod::Crypto => { - Err(errors::ConnectorError::NotSupported { - payment_method: format!("{:?}", item.payment_method), - connector: "Adyen", - payment_experience: api_models::enums::PaymentExperience::RedirectToUrl - .to_string(), - })? + api_models::payments::PaymentMethodData::PayLater(ref pay_later) => { + AdyenPaymentRequest::try_from((item, pay_later)) } + api_models::payments::PaymentMethodData::BankRedirect(ref bank_redirect) => { + AdyenPaymentRequest::try_from((item, bank_redirect)) + } + _ => Err(errors::ConnectorError::NotSupported { + payment_method: format!("{:?}", item.request.payment_method_type), + connector: "Adyen", + payment_experience: api_models::enums::PaymentExperience::RedirectToUrl.to_string(), + })?, } } } @@ -464,7 +732,9 @@ fn get_recurring_processing_model( } fn get_browser_info(item: &types::PaymentsAuthorizeRouterData) -> Option { - if matches!(item.auth_type, storage_enums::AuthenticationType::ThreeDs) { + if item.auth_type == storage_enums::AuthenticationType::ThreeDs + || item.payment_method == storage_enums::PaymentMethod::BankRedirect + { item.request .browser_info .as_ref() @@ -517,13 +787,13 @@ fn get_line_items(item: &types::PaymentsAuthorizeRouterData) -> Vec { let order_details = item.request.order_details.as_ref(); let line_item = LineItem { amount_including_tax: Some(item.request.amount), - amount_excluding_tax: None, + amount_excluding_tax: Some(item.request.amount), description: order_details.map(|details| details.product_name.clone()), // We support only one product details in payment request as of now, therefore hard coded the id. // If we begin to support multiple product details in future then this logic should be made to create ID dynamically id: Some(String::from("Items #1")), tax_amount: None, - quantity: order_details.map(|details| details.quantity), + quantity: Some(order_details.map_or(1, |details| details.quantity)), }; vec![line_item] } @@ -563,27 +833,30 @@ fn get_country_code(item: &types::PaymentsAuthorizeRouterData) -> Option( - item: &types::PaymentsAuthorizeRouterData, -) -> Result, error_stack::Report> { - match item.request.payment_method_data { - api::PaymentMethodData::Card(ref card) => { - let adyen_card = AdyenCard { - payment_type: PaymentType::Scheme, - number: card.card_number.clone(), - expiry_month: card.card_exp_month.clone(), - expiry_year: card.card_exp_year.clone(), - cvc: Some(card.card_cvc.clone()), - }; - Ok(AdyenPaymentMethod::AdyenCard(adyen_card)) - } - api::PaymentMethodData::Wallet(ref wallet_data) => match wallet_data { +impl<'a> TryFrom<&api::Card> for AdyenPaymentMethod<'a> { + type Error = Error; + fn try_from(card: &api::Card) -> Result { + let adyen_card = AdyenCard { + payment_type: PaymentType::Scheme, + number: card.card_number.clone(), + expiry_month: card.card_exp_month.clone(), + expiry_year: card.card_exp_year.clone(), + cvc: Some(card.card_cvc.clone()), + }; + Ok(AdyenPaymentMethod::AdyenCard(Box::new(adyen_card))) + } +} + +impl<'a> TryFrom<&api::WalletData> for AdyenPaymentMethod<'a> { + type Error = Error; + fn try_from(wallet_data: &api::WalletData) -> Result { + match wallet_data { api_models::payments::WalletData::GooglePay(data) => { let gpay_data = AdyenGPay { payment_type: PaymentType::Googlepay, google_pay_token: data.tokenization_data.token.to_owned(), }; - Ok(AdyenPaymentMethod::Gpay(gpay_data)) + Ok(AdyenPaymentMethod::Gpay(Box::new(gpay_data))) } api_models::payments::WalletData::ApplePay(data) => { let apple_pay_data = AdyenApplePay { @@ -591,106 +864,244 @@ fn get_payment_method_data<'a>( apple_pay_token: data.payment_data.to_string(), }; - Ok(AdyenPaymentMethod::ApplePay(apple_pay_data)) - } - api_models::payments::WalletData::PaypalSdk(_) => { - Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()) + Ok(AdyenPaymentMethod::ApplePay(Box::new(apple_pay_data))) } api_models::payments::WalletData::PaypalRedirect(_) => { let wallet = AdyenPaypal { payment_type: PaymentType::Paypal, }; - Ok(AdyenPaymentMethod::AdyenPaypal(wallet)) + Ok(AdyenPaymentMethod::AdyenPaypal(Box::new(wallet))) } - }, - api_models::payments::PaymentMethodData::PayLater(ref pay_later_data) => { - match pay_later_data { - api_models::payments::PayLaterData::KlarnaRedirect { .. } => { - let klarna = AdyenPayLaterData { - payment_type: PaymentType::Klarna, - }; - Ok(AdyenPaymentMethod::AdyenKlarna(klarna)) - } - api_models::payments::PayLaterData::AffirmRedirect { .. } => { - Ok(AdyenPaymentMethod::AdyenAffirm(AdyenPayLaterData { - payment_type: PaymentType::Affirm, - })) - } - api_models::payments::PayLaterData::AfterpayClearpayRedirect { .. } => { - Ok(AdyenPaymentMethod::AfterPay(AdyenPayLaterData { - payment_type: PaymentType::Afterpaytouch, - })) - } - _ => Err( - errors::ConnectorError::NotImplemented("Payment methods".to_string()).into(), - ), + api_models::payments::WalletData::AliPay(_) => { + let alipay_data = AliPayData { + payment_type: PaymentType::Alipay, + }; + Ok(AdyenPaymentMethod::AliPay(Box::new(alipay_data))) } + api_models::payments::WalletData::MbWay(data) => { + let mbway_data = MbwayData { + payment_type: PaymentType::Mbway, + telephone_number: data.telephone_number.clone(), + }; + Ok(AdyenPaymentMethod::Mbway(Box::new(mbway_data))) + } + api_models::payments::WalletData::MobilePay(_) => { + let data = MobilePayData { + payment_type: PaymentType::MobilePay, + }; + Ok(AdyenPaymentMethod::MobilePay(Box::new(data))) + } + api_models::payments::WalletData::WeChatPayRedirect(_) => { + let data = WeChatPayWebData { + payment_type: PaymentType::WeChatPayWeb, + }; + Ok(AdyenPaymentMethod::WeChatPayWeb(Box::new(data))) + } + _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()), } - api_models::payments::PaymentMethodData::BankRedirect(ref bank_redirect_data) => { - match bank_redirect_data { - api_models::payments::BankRedirectData::Eps { bank_name, .. } => { - Ok(AdyenPaymentMethod::Eps(BankRedirectionWithIssuer { - payment_type: PaymentType::Eps, - issuer: AdyenTestBankNames::try_from(bank_name)?.0, - })) - } - api_models::payments::BankRedirectData::Ideal { bank_name, .. } => { - Ok(AdyenPaymentMethod::Ideal(BankRedirectionWithIssuer { - payment_type: PaymentType::Ideal, - issuer: AdyenTestBankNames::try_from(bank_name)?.0, - })) - } - - api_models::payments::BankRedirectData::Giropay { .. } => { - Ok(AdyenPaymentMethod::Giropay(BankRedirectionPMData { - payment_type: PaymentType::Giropay, - })) - } - api_models::payments::BankRedirectData::Sofort { .. } => { - Ok(AdyenPaymentMethod::Sofort(BankRedirectionPMData { - payment_type: PaymentType::Sofort, - })) - } - } - } - api::PaymentMethodData::Crypto(_) => Err(errors::ConnectorError::NotSupported { - payment_method: format!("{:?}", item.payment_method), - connector: "Adyen", - payment_experience: api_models::enums::PaymentExperience::RedirectToUrl.to_string(), - })?, } } -fn get_card_specific_payment_data<'a>( - item: &types::PaymentsAuthorizeRouterData, -) -> Result, error_stack::Report> { - let amount = get_amount_data(item); - let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?; - let shopper_interaction = AdyenShopperInteraction::from(item); - let recurring_processing_model = get_recurring_processing_model(item); - let browser_info = get_browser_info(item); - let additional_data = get_additional_data(item); - let return_url = item.request.get_return_url()?; - let payment_method = get_payment_method_data(item)?; - Ok(AdyenPaymentRequest { - amount, - merchant_account: auth_type.merchant_account, - payment_method, - reference: item.payment_id.to_string(), - return_url, - shopper_interaction, - recurring_processing_model, - browser_info, - additional_data, - telephone_number: None, - shopper_name: None, - shopper_email: None, - shopper_locale: None, - billing_address: None, - delivery_address: None, - country_code: None, - line_items: None, - }) +impl<'a> TryFrom<&api::PayLaterData> for AdyenPaymentMethod<'a> { + type Error = Error; + fn try_from(pay_later_data: &api::PayLaterData) -> Result { + match pay_later_data { + api_models::payments::PayLaterData::KlarnaRedirect { .. } => { + let klarna = AdyenPayLaterData { + payment_type: PaymentType::Klarna, + }; + Ok(AdyenPaymentMethod::AdyenKlarna(Box::new(klarna))) + } + api_models::payments::PayLaterData::AffirmRedirect { .. } => Ok( + AdyenPaymentMethod::AdyenAffirm(Box::new(AdyenPayLaterData { + payment_type: PaymentType::Affirm, + })), + ), + api_models::payments::PayLaterData::AfterpayClearpayRedirect { .. } => { + Ok(AdyenPaymentMethod::AfterPay(Box::new(AdyenPayLaterData { + payment_type: PaymentType::Afterpaytouch, + }))) + } + api_models::payments::PayLaterData::PayBright { .. } => { + Ok(AdyenPaymentMethod::PayBright(Box::new(PayBrightData { + payment_type: PaymentType::PayBright, + }))) + } + api_models::payments::PayLaterData::Walley { .. } => { + Ok(AdyenPaymentMethod::Walley(Box::new(WalleyData { + payment_type: PaymentType::Walley, + }))) + } + _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()), + } + } +} + +impl<'a> TryFrom<&api_models::payments::BankRedirectData> for AdyenPaymentMethod<'a> { + type Error = Error; + fn try_from( + bank_redirect_data: &api_models::payments::BankRedirectData, + ) -> Result { + match bank_redirect_data { + api_models::payments::BankRedirectData::BancontactCard { + card_number, + card_exp_month, + card_exp_year, + card_holder_name, + } => Ok(AdyenPaymentMethod::BancontactCard(Box::new( + BancontactCardData { + payment_type: PaymentType::Scheme, + brand: "bcmc".to_string(), + number: card_number.clone(), + expiry_month: card_exp_month.clone(), + expiry_year: card_exp_year.clone(), + holder_name: card_holder_name.clone(), + }, + ))), + api_models::payments::BankRedirectData::Blik { blik_code } => { + Ok(AdyenPaymentMethod::Blik(Box::new(BlikRedirectionData { + payment_type: PaymentType::Blik, + blik_code: blik_code.to_string(), + }))) + } + api_models::payments::BankRedirectData::Eps { bank_name, .. } => Ok( + AdyenPaymentMethod::Eps(Box::new(BankRedirectionWithIssuer { + payment_type: PaymentType::Eps, + issuer: AdyenTestBankNames::try_from(bank_name)?.0, + })), + ), + api_models::payments::BankRedirectData::Giropay { .. } => Ok( + AdyenPaymentMethod::Giropay(Box::new(BankRedirectionPMData { + payment_type: PaymentType::Giropay, + })), + ), + api_models::payments::BankRedirectData::Ideal { bank_name, .. } => Ok( + AdyenPaymentMethod::Ideal(Box::new(BankRedirectionWithIssuer { + payment_type: PaymentType::Ideal, + issuer: AdyenTestBankNames::try_from(bank_name)?.0, + })), + ), + api_models::payments::BankRedirectData::OnlineBankingCzechRepublic { issuer } => { + Ok(AdyenPaymentMethod::OnlineBankingCzechRepublic(Box::new( + OnlineBankingCzechRepublicData { + payment_type: PaymentType::OnlineBankingCzechRepublic, + issuer: OnlineBankingCzechRepublicBanks::try_from(issuer)?, + }, + ))) + } + api_models::payments::BankRedirectData::OnlineBankingFinland { .. } => Ok( + AdyenPaymentMethod::OnlineBankingFinland(Box::new(OnlineBankingFinlandData { + payment_type: PaymentType::OnlineBankingFinland, + })), + ), + api_models::payments::BankRedirectData::OnlineBankingPoland { issuer } => Ok( + AdyenPaymentMethod::OnlineBankingPoland(Box::new(OnlineBankingPolandData { + payment_type: PaymentType::OnlineBankingPoland, + issuer: OnlineBankingPolandBanks::try_from(issuer)?, + })), + ), + api_models::payments::BankRedirectData::OnlineBankingSlovakia { issuer } => Ok( + AdyenPaymentMethod::OnlineBankingSlovakia(Box::new(OnlineBankingSlovakiaData { + payment_type: PaymentType::OnlineBankingSlovakia, + issuer: OnlineBankingSlovakiaBanks::try_from(issuer)?, + })), + ), + api_models::payments::BankRedirectData::Sofort { .. } => Ok( + AdyenPaymentMethod::Sofort(Box::new(BankRedirectionPMData { + payment_type: PaymentType::Sofort, + })), + ), + api_models::payments::BankRedirectData::Trustly {} => Ok(AdyenPaymentMethod::Trustly( + Box::new(BankRedirectionPMData { + payment_type: PaymentType::Trustly, + }), + )), + _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()), + } + } +} + +impl<'a> TryFrom<(&types::PaymentsAuthorizeRouterData, &api::Card)> for AdyenPaymentRequest<'a> { + type Error = Error; + fn try_from( + value: (&types::PaymentsAuthorizeRouterData, &api::Card), + ) -> Result { + let (item, card_data) = value; + let amount = get_amount_data(item); + let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?; + let shopper_interaction = AdyenShopperInteraction::from(item); + let recurring_processing_model = get_recurring_processing_model(item); + let browser_info = get_browser_info(item); + let additional_data = get_additional_data(item); + let return_url = item.request.get_return_url()?; + let payment_method = AdyenPaymentMethod::try_from(card_data)?; + Ok(AdyenPaymentRequest { + amount, + merchant_account: auth_type.merchant_account, + payment_method, + reference: item.payment_id.to_string(), + return_url, + shopper_interaction, + recurring_processing_model, + browser_info, + additional_data, + telephone_number: None, + shopper_name: None, + shopper_email: None, + shopper_locale: None, + billing_address: None, + delivery_address: None, + country_code: None, + line_items: None, + }) + } +} + +impl<'a> + TryFrom<( + &types::PaymentsAuthorizeRouterData, + &api_models::payments::BankRedirectData, + )> for AdyenPaymentRequest<'a> +{ + type Error = Error; + fn try_from( + value: ( + &types::PaymentsAuthorizeRouterData, + &api_models::payments::BankRedirectData, + ), + ) -> Result { + let (item, bank_redirect_data) = value; + let amount = get_amount_data(item); + let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?; + let shopper_interaction = AdyenShopperInteraction::from(item); + let recurring_processing_model = get_recurring_processing_model(item); + let browser_info = get_browser_info(item); + let additional_data = get_additional_data(item); + let return_url = item.request.get_return_url()?; + let payment_method = AdyenPaymentMethod::try_from(bank_redirect_data)?; + let (shopper_locale, country) = get_sofort_extra_details(item); + let line_items = Some(get_line_items(item)); + + Ok(AdyenPaymentRequest { + amount, + merchant_account: auth_type.merchant_account, + payment_method, + reference: item.payment_id.to_string(), + return_url, + shopper_interaction, + recurring_processing_model, + browser_info, + additional_data, + telephone_number: None, + shopper_name: None, + shopper_email: item.request.email.clone(), + shopper_locale, + billing_address: None, + delivery_address: None, + country_code: country, + line_items, + }) + } } fn get_sofort_extra_details( @@ -715,113 +1126,92 @@ fn get_sofort_extra_details( _ => (None, None), } } -fn get_bank_redirect_specific_payment_data<'a>( - item: &types::PaymentsAuthorizeRouterData, -) -> Result, error_stack::Report> { - let amount = get_amount_data(item); - let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?; - let shopper_interaction = AdyenShopperInteraction::from(item); - let recurring_processing_model = get_recurring_processing_model(item); - let browser_info = get_browser_info(item); - let additional_data = get_additional_data(item); - let return_url = item.request.get_return_url()?; - let payment_method = get_payment_method_data(item)?; - let (shopper_locale, country) = get_sofort_extra_details(item); - Ok(AdyenPaymentRequest { - amount, - merchant_account: auth_type.merchant_account, - payment_method, - reference: item.payment_id.to_string(), - return_url, - shopper_interaction, - recurring_processing_model, - browser_info, - additional_data, - telephone_number: None, - shopper_name: None, - shopper_email: None, - shopper_locale, - billing_address: None, - delivery_address: None, - country_code: country, - line_items: None, - }) +impl<'a> TryFrom<(&types::PaymentsAuthorizeRouterData, &api::WalletData)> + for AdyenPaymentRequest<'a> +{ + type Error = Error; + fn try_from( + value: (&types::PaymentsAuthorizeRouterData, &api::WalletData), + ) -> Result { + let (item, wallet_data) = value; + let amount = get_amount_data(item); + let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?; + let browser_info = get_browser_info(item); + let additional_data = get_additional_data(item); + let payment_method = AdyenPaymentMethod::try_from(wallet_data)?; + let shopper_interaction = AdyenShopperInteraction::from(item); + let recurring_processing_model = get_recurring_processing_model(item); + let return_url = item.request.get_return_url()?; + Ok(AdyenPaymentRequest { + amount, + merchant_account: auth_type.merchant_account, + payment_method, + reference: item.payment_id.to_string(), + return_url, + shopper_interaction, + recurring_processing_model, + browser_info, + additional_data, + telephone_number: None, + shopper_name: None, + shopper_email: None, + shopper_locale: None, + billing_address: None, + delivery_address: None, + country_code: None, + line_items: None, + }) + } } -fn get_wallet_specific_payment_data<'a>( - item: &types::PaymentsAuthorizeRouterData, -) -> Result, error_stack::Report> { - let amount = get_amount_data(item); - let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?; - let browser_info = get_browser_info(item); - let additional_data = get_additional_data(item); - let payment_method = get_payment_method_data(item)?; - let shopper_interaction = AdyenShopperInteraction::from(item); - let recurring_processing_model = get_recurring_processing_model(item); - let return_url = item.request.get_return_url()?; - Ok(AdyenPaymentRequest { - amount, - merchant_account: auth_type.merchant_account, - payment_method, - reference: item.payment_id.to_string(), - return_url, - shopper_interaction, - recurring_processing_model, - browser_info, - additional_data, - telephone_number: None, - shopper_name: None, - shopper_email: None, - shopper_locale: None, - billing_address: None, - delivery_address: None, - country_code: None, - line_items: None, - }) -} - -fn get_paylater_specific_payment_data<'a>( - item: &types::PaymentsAuthorizeRouterData, -) -> Result, error_stack::Report> { - let amount = get_amount_data(item); - let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?; - let browser_info = get_browser_info(item); - let additional_data = get_additional_data(item); - let payment_method = get_payment_method_data(item)?; - let shopper_interaction = AdyenShopperInteraction::from(item); - let recurring_processing_model = get_recurring_processing_model(item); - let return_url = item.request.get_return_url()?; - let shopper_name = get_shopper_name(item); - let shopper_email = item.request.email.clone(); - let billing_address = get_address_info(item.address.billing.as_ref()); - let delivery_address = get_address_info(item.address.shipping.as_ref()); - let country_code = get_country_code(item); - let line_items = Some(get_line_items(item)); - let telephone_number = get_telephone_number(item); - Ok(AdyenPaymentRequest { - amount, - merchant_account: auth_type.merchant_account, - payment_method, - reference: item.payment_id.to_string(), - return_url, - shopper_interaction, - recurring_processing_model, - browser_info, - additional_data, - telephone_number, - shopper_name, - shopper_email, - shopper_locale: None, - billing_address, - delivery_address, - country_code, - line_items, - }) +impl<'a> TryFrom<(&types::PaymentsAuthorizeRouterData, &api::PayLaterData)> + for AdyenPaymentRequest<'a> +{ + type Error = Error; + fn try_from( + value: (&types::PaymentsAuthorizeRouterData, &api::PayLaterData), + ) -> Result { + let (item, paylater_data) = value; + let amount = get_amount_data(item); + let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?; + let browser_info = get_browser_info(item); + let additional_data = get_additional_data(item); + let payment_method = AdyenPaymentMethod::try_from(paylater_data)?; + let shopper_interaction = AdyenShopperInteraction::from(item); + let recurring_processing_model = get_recurring_processing_model(item); + let return_url = item.request.get_return_url()?; + let shopper_name = get_shopper_name(item); + let shopper_email = item.request.email.clone(); + let billing_address = get_address_info(item.address.billing.as_ref()); + let delivery_address = get_address_info(item.address.shipping.as_ref()); + let country_code = get_country_code(item); + let line_items = Some(get_line_items(item)); + let telephone_number = get_telephone_number(item); + Ok(AdyenPaymentRequest { + amount, + merchant_account: auth_type.merchant_account, + payment_method, + reference: item.payment_id.to_string(), + return_url, + shopper_interaction, + recurring_processing_model, + browser_info, + additional_data, + telephone_number, + shopper_name, + shopper_email, + shopper_locale: None, + billing_address, + delivery_address, + country_code, + line_items, + }) + } } impl TryFrom<&types::PaymentsCancelRouterData> for AdyenCancelRequest { - type Error = error_stack::Report; + type Error = Error; fn try_from(item: &types::PaymentsCancelRouterData) -> Result { let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?; Ok(Self { @@ -843,7 +1233,7 @@ impl From for storage_enums::AttemptStatus { impl TryFrom> for types::PaymentsCancelRouterData { - type Error = error_stack::Report; + type Error = Error; fn try_from( item: types::PaymentsCancelResponseRouterData, ) -> Result { @@ -872,17 +1262,8 @@ pub fn get_adyen_response( ), errors::ConnectorError, > { - let status = match response.result_code { - AdyenStatus::Authorised => { - if is_capture_manual { - storage_enums::AttemptStatus::Authorized - } else { - storage_enums::AttemptStatus::Charged - } - } - AdyenStatus::Refused | AdyenStatus::Cancelled => storage_enums::AttemptStatus::Failure, - _ => storage_enums::AttemptStatus::Pending, - }; + let status = + storage_enums::AttemptStatus::foreign_from((is_capture_manual, response.result_code)); let error = if response.refusal_reason.is_some() || response.refusal_reason_code.is_some() { Some(types::ErrorResponse { code: response @@ -909,6 +1290,7 @@ pub fn get_adyen_response( pub fn get_redirection_response( response: AdyenRedirectionResponse, + is_manual_capture: bool, status_code: u16, ) -> errors::CustomResult< ( @@ -918,8 +1300,8 @@ pub fn get_redirection_response( ), errors::ConnectorError, > { - let status = response.result_code.into(); - + let status = + storage_enums::AttemptStatus::foreign_from((is_manual_capture, response.result_code)); let error = if response.refusal_reason.is_some() || response.refusal_reason_code.is_some() { Some(types::ErrorResponse { code: response @@ -935,26 +1317,24 @@ pub fn get_redirection_response( None }; - let form_fields = response.action.data.unwrap_or_else(|| { - std::collections::HashMap::from_iter( - response - .action - .url - .query_pairs() - .map(|(key, value)| (key.to_string(), value.to_string())), - ) + let redirection_data = response.action.url.map(|url| { + let form_fields = response.action.data.unwrap_or_else(|| { + std::collections::HashMap::from_iter( + url.query_pairs() + .map(|(key, value)| (key.to_string(), value.to_string())), + ) + }); + services::RedirectForm { + endpoint: url.to_string(), + method: response.action.method.unwrap_or(services::Method::Get), + form_fields, + } }); - let redirection_data = services::RedirectForm { - endpoint: response.action.url.to_string(), - method: response.action.method, - form_fields, - }; - // We don't get connector transaction id for redirections in Adyen. let payments_response_data = types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::NoResponseId, - redirection_data: Some(redirection_data), + redirection_data, mandate_reference: None, connector_metadata: None, }; @@ -967,7 +1347,7 @@ impl bool, )> for types::RouterData { - type Error = error_stack::Report; + type Error = Error; fn try_from( items: ( types::ResponseRouterData, @@ -981,7 +1361,7 @@ impl get_adyen_response(response, is_manual_capture, item.http_code)? } AdyenPaymentResponse::AdyenRedirectResponse(response) => { - get_redirection_response(response, item.http_code)? + get_redirection_response(response, is_manual_capture, item.http_code)? } }; @@ -1001,7 +1381,7 @@ pub struct AdyenCaptureRequest { } impl TryFrom<&types::PaymentsCaptureRouterData> for AdyenCaptureRequest { - type Error = error_stack::Report; + type Error = Error; fn try_from(item: &types::PaymentsCaptureRouterData) -> Result { let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?; Ok(Self { @@ -1029,7 +1409,7 @@ pub struct AdyenCaptureResponse { impl TryFrom> for types::PaymentsCaptureRouterData { - type Error = error_stack::Report; + type Error = Error; fn try_from( item: types::PaymentsCaptureResponseRouterData, ) -> Result { @@ -1089,7 +1469,7 @@ impl From for enums::Status { */ // Refund Request Transform impl TryFrom<&types::RefundsRouterData> for AdyenRefundRequest { - type Error = error_stack::Report; + type Error = Error; fn try_from(item: &types::RefundsRouterData) -> Result { let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?; Ok(Self { @@ -1108,7 +1488,7 @@ impl TryFrom<&types::RefundsRouterData> for AdyenRefundRequest { impl TryFrom> for types::RefundsRouterData { - type Error = error_stack::Report; + type Error = Error; fn try_from( item: types::RefundsResponseRouterData, ) -> Result { diff --git a/crates/router/src/connector/globalpay/transformers.rs b/crates/router/src/connector/globalpay/transformers.rs index a22d17cb37..d76b09b5ce 100644 --- a/crates/router/src/connector/globalpay/transformers.rs +++ b/crates/router/src/connector/globalpay/transformers.rs @@ -19,13 +19,15 @@ use crate::{ types::{self, api, storage::enums, ErrorResponse}, }; +type Error = error_stack::Report; + #[derive(Debug, Serialize, Deserialize)] pub struct GlobalPayMeta { account_name: String, } impl TryFrom<&types::PaymentsAuthorizeRouterData> for GlobalpayPaymentsRequest { - type Error = error_stack::Report; + type Error = Error; fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result { let metadata: GlobalPayMeta = utils::to_connector_meta_from_secret(item.connector_meta_data.clone())?; @@ -84,7 +86,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for GlobalpayPaymentsRequest { } impl TryFrom<&types::PaymentsCaptureRouterData> for requests::GlobalpayCaptureRequest { - type Error = error_stack::Report; + type Error = Error; fn try_from(value: &types::PaymentsCaptureRouterData) -> Result { Ok(Self { amount: Some(value.request.amount_to_capture.to_string()), @@ -93,7 +95,7 @@ impl TryFrom<&types::PaymentsCaptureRouterData> for requests::GlobalpayCaptureRe } impl TryFrom<&types::PaymentsCancelRouterData> for requests::GlobalpayCancelRequest { - type Error = error_stack::Report; + type Error = Error; fn try_from(value: &types::PaymentsCancelRouterData) -> Result { Ok(Self { amount: value.request.amount.map(|amount| amount.to_string()), @@ -107,7 +109,7 @@ pub struct GlobalpayAuthType { } impl TryFrom<&types::ConnectorAuthType> for GlobalpayAuthType { - type Error = error_stack::Report; + type Error = Error; fn try_from(auth_type: &types::ConnectorAuthType) -> Result { match auth_type { types::ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self { @@ -131,7 +133,7 @@ impl TryFrom for types::AccessToken { } impl TryFrom<&types::RefreshTokenRouterData> for GlobalpayRefreshTokenRequest { - type Error = error_stack::Report; + type Error = Error; fn try_from(item: &types::RefreshTokenRouterData) -> Result { let globalpay_auth = GlobalpayAuthType::try_from(&item.connector_auth_type) @@ -220,7 +222,7 @@ impl TryFrom> for types::RouterData { - type Error = error_stack::Report; + type Error = Error; fn try_from( item: types::ResponseRouterData< F, @@ -276,7 +278,7 @@ impl } impl TryFrom<&types::RefundsRouterData> for requests::GlobalpayRefundRequest { - type Error = error_stack::Report; + type Error = Error; fn try_from(item: &types::RefundsRouterData) -> Result { Ok(Self { amount: item.request.refund_amount.to_string(), @@ -287,7 +289,7 @@ impl TryFrom<&types::RefundsRouterData> for requests::GlobalpayRefundReque impl TryFrom> for types::RefundExecuteRouterData { - type Error = error_stack::Report; + type Error = Error; fn try_from( item: types::RefundsResponseRouterData, ) -> Result { @@ -304,7 +306,7 @@ impl TryFrom> for types::RefundsRouterData { - type Error = error_stack::Report; + type Error = Error; fn try_from( item: types::RefundsResponseRouterData, ) -> Result { @@ -328,7 +330,7 @@ pub struct GlobalpayErrorResponse { fn get_payment_method_data( item: &types::PaymentsAuthorizeRouterData, brand_reference: Option, -) -> Result> { +) -> Result { match &item.request.payment_method_data { api::PaymentMethodData::Card(ccard) => Ok(PaymentMethodData::Card(requests::Card { number: ccard.card_number.clone(), @@ -348,7 +350,7 @@ fn get_payment_method_data( })), api::PaymentMethodData::Wallet(wallet_data) => get_wallet_data(wallet_data), api::PaymentMethodData::BankRedirect(bank_redirect) => { - get_bank_redirect_data(bank_redirect) + PaymentMethodData::try_from(bank_redirect) } _ => Err(errors::ConnectorError::NotImplemented( "Payment methods".to_string(), @@ -366,9 +368,7 @@ fn get_return_url(item: &types::PaymentsAuthorizeRouterData) -> Option { } type MandateDetails = (Option, Option, Option); -fn get_mandate_details( - item: &types::PaymentsAuthorizeRouterData, -) -> Result> { +fn get_mandate_details(item: &types::PaymentsAuthorizeRouterData) -> Result { Ok(if item.request.is_mandate_payment() { let connector_mandate_id = item .request @@ -396,7 +396,7 @@ fn get_mandate_details( fn get_wallet_data( wallet_data: &api_models::payments::WalletData, -) -> Result> { +) -> Result { match wallet_data { api_models::payments::WalletData::PaypalRedirect(_) => { Ok(PaymentMethodData::Apm(requests::Apm { @@ -410,34 +410,33 @@ fn get_wallet_data( })) } _ => Err(errors::ConnectorError::NotImplemented( - "Payment methods".to_string(), + "Payment method".to_string(), ))?, } } -fn get_bank_redirect_data( - bank_redirect: &api_models::payments::BankRedirectData, -) -> Result> { - match bank_redirect { - api_models::payments::BankRedirectData::Eps { .. } => { - Ok(PaymentMethodData::Apm(requests::Apm { +impl TryFrom<&api_models::payments::BankRedirectData> for PaymentMethodData { + type Error = Error; + fn try_from(value: &api_models::payments::BankRedirectData) -> Result { + match value { + api_models::payments::BankRedirectData::Eps { .. } => Ok(Self::Apm(requests::Apm { provider: Some(ApmProvider::Eps), - })) - } - api_models::payments::BankRedirectData::Giropay { .. } => { - Ok(PaymentMethodData::Apm(requests::Apm { - provider: Some(ApmProvider::Giropay), - })) - } - api_models::payments::BankRedirectData::Ideal { .. } => { - Ok(PaymentMethodData::Apm(requests::Apm { + })), + api_models::payments::BankRedirectData::Giropay { .. } => { + Ok(Self::Apm(requests::Apm { + provider: Some(ApmProvider::Giropay), + })) + } + api_models::payments::BankRedirectData::Ideal { .. } => Ok(Self::Apm(requests::Apm { provider: Some(ApmProvider::Ideal), - })) - } - api_models::payments::BankRedirectData::Sofort { .. } => { - Ok(PaymentMethodData::Apm(requests::Apm { + })), + api_models::payments::BankRedirectData::Sofort { .. } => Ok(Self::Apm(requests::Apm { provider: Some(ApmProvider::Sofort), - })) + })), + _ => Err(errors::ConnectorError::NotImplemented( + "Payment method".to_string(), + )) + .into_report(), } } } diff --git a/crates/router/src/connector/mollie/transformers.rs b/crates/router/src/connector/mollie/transformers.rs index 464994023a..feafe66109 100644 --- a/crates/router/src/connector/mollie/transformers.rs +++ b/crates/router/src/connector/mollie/transformers.rs @@ -98,7 +98,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for MolliePaymentsRequest { let payment_method_data = match item.request.capture_method.unwrap_or_default() { enums::CaptureMethod::Automatic => match item.request.payment_method_data { api_models::payments::PaymentMethodData::BankRedirect(ref redirect_data) => { - get_payment_method_for_bank_redirect(item, redirect_data) + PaymentMethodData::try_from(redirect_data) } api_models::payments::PaymentMethodData::Wallet(ref wallet_data) => { get_payment_method_for_wallet(item, wallet_data) @@ -135,22 +135,22 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for MolliePaymentsRequest { } } -fn get_payment_method_for_bank_redirect( - _item: &types::PaymentsAuthorizeRouterData, - redirect_data: &api_models::payments::BankRedirectData, -) -> Result { - let payment_method_data = match redirect_data { - api_models::payments::BankRedirectData::Eps { .. } => PaymentMethodData::Eps, - api_models::payments::BankRedirectData::Giropay { .. } => PaymentMethodData::Giropay, - api_models::payments::BankRedirectData::Ideal { .. } => { - PaymentMethodData::Ideal(Box::new(IdealMethodData { - // To do if possible this should be from the payment request - issuer: None, - })) +impl TryFrom<&api_models::payments::BankRedirectData> for PaymentMethodData { + type Error = Error; + fn try_from(value: &api_models::payments::BankRedirectData) -> Result { + match value { + api_models::payments::BankRedirectData::Eps { .. } => Ok(Self::Eps), + api_models::payments::BankRedirectData::Giropay { .. } => Ok(Self::Giropay), + api_models::payments::BankRedirectData::Ideal { .. } => { + Ok(Self::Ideal(Box::new(IdealMethodData { + // To do if possible this should be from the payment request + issuer: None, + }))) + } + api_models::payments::BankRedirectData::Sofort { .. } => Ok(Self::Sofort), + _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()), } - api_models::payments::BankRedirectData::Sofort { .. } => PaymentMethodData::Sofort, - }; - Ok(payment_method_data) + } } fn get_payment_method_for_wallet( diff --git a/crates/router/src/connector/shift4/transformers.rs b/crates/router/src/connector/shift4/transformers.rs index b0955ac3f8..a77ada4bdf 100644 --- a/crates/router/src/connector/shift4/transformers.rs +++ b/crates/router/src/connector/shift4/transformers.rs @@ -198,7 +198,7 @@ fn get_bank_redirect_request( redirect_data: &payments::BankRedirectData, ) -> Result { let submit_for_settlement = item.request.is_auto_capture()?; - let method_type = PaymentMethodType::from(redirect_data); + let method_type = PaymentMethodType::try_from(redirect_data)?; let billing = get_billing(item)?; let payment_method = Some(PaymentMethod { method_type, @@ -218,13 +218,15 @@ fn get_bank_redirect_request( ))) } -impl From<&payments::BankRedirectData> for PaymentMethodType { - fn from(value: &payments::BankRedirectData) -> Self { +impl TryFrom<&payments::BankRedirectData> for PaymentMethodType { + type Error = Error; + fn try_from(value: &payments::BankRedirectData) -> Result { match value { - payments::BankRedirectData::Eps { .. } => Self::Eps, - payments::BankRedirectData::Giropay { .. } => Self::Giropay, - payments::BankRedirectData::Ideal { .. } => Self::Ideal, - payments::BankRedirectData::Sofort { .. } => Self::Sofort, + payments::BankRedirectData::Eps { .. } => Ok(Self::Eps), + payments::BankRedirectData::Giropay { .. } => Ok(Self::Giropay), + payments::BankRedirectData::Ideal { .. } => Ok(Self::Ideal), + payments::BankRedirectData::Sofort { .. } => Ok(Self::Sofort), + _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()), } } } diff --git a/crates/router/src/connector/trustpay/transformers.rs b/crates/router/src/connector/trustpay/transformers.rs index a28c6f2bcc..f039321070 100644 --- a/crates/router/src/connector/trustpay/transformers.rs +++ b/crates/router/src/connector/trustpay/transformers.rs @@ -18,6 +18,8 @@ use crate::{ types::{self, api, storage::enums, BrowserInformation}, }; +type Error = error_stack::Report; + pub struct TrustpayAuthType { pub(super) api_key: String, pub(super) project_id: String, @@ -25,7 +27,7 @@ pub struct TrustpayAuthType { } impl TryFrom<&types::ConnectorAuthType> for TrustpayAuthType { - type Error = error_stack::Report; + type Error = Error; fn try_from(auth_type: &types::ConnectorAuthType) -> Result { if let types::ConnectorAuthType::SignatureKey { api_key, @@ -181,18 +183,22 @@ pub struct TrustpayMandatoryParams { pub billing_postcode: Secret, } -fn get_trustpay_payment_method(bank_redirection_data: &BankRedirectData) -> TrustpayPaymentMethod { - match bank_redirection_data { - api_models::payments::BankRedirectData::Giropay { .. } => TrustpayPaymentMethod::Giropay, - api_models::payments::BankRedirectData::Eps { .. } => TrustpayPaymentMethod::Eps, - api_models::payments::BankRedirectData::Ideal { .. } => TrustpayPaymentMethod::IDeal, - api_models::payments::BankRedirectData::Sofort { .. } => TrustpayPaymentMethod::Sofort, +impl TryFrom<&BankRedirectData> for TrustpayPaymentMethod { + type Error = Error; + fn try_from(value: &BankRedirectData) -> Result { + match value { + api_models::payments::BankRedirectData::Giropay { .. } => Ok(Self::Giropay), + api_models::payments::BankRedirectData::Eps { .. } => Ok(Self::Eps), + api_models::payments::BankRedirectData::Ideal { .. } => Ok(Self::IDeal), + api_models::payments::BankRedirectData::Sofort { .. } => Ok(Self::Sofort), + _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()), + } } } fn get_mandatory_fields( item: &types::PaymentsAuthorizeRouterData, -) -> Result> { +) -> Result { let billing_address = item .get_billing()? .address @@ -248,33 +254,35 @@ fn get_bank_redirection_request_data( item: &types::PaymentsAuthorizeRouterData, bank_redirection_data: &BankRedirectData, amount: String, - return_url: String, auth: TrustpayAuthType, -) -> TrustpayPaymentsRequest { - TrustpayPaymentsRequest::BankRedirectPaymentRequest(Box::new(PaymentRequestBankRedirect { - payment_method: get_trustpay_payment_method(bank_redirection_data), - merchant_identification: MerchantIdentification { - project_id: auth.project_id, - }, - payment_information: BankPaymentInformation { - amount: Amount { - amount, - currency: item.request.currency.to_string(), +) -> Result> { + let return_url = item.request.get_return_url()?; + let payment_request = + TrustpayPaymentsRequest::BankRedirectPaymentRequest(Box::new(PaymentRequestBankRedirect { + payment_method: TrustpayPaymentMethod::try_from(bank_redirection_data)?, + merchant_identification: MerchantIdentification { + project_id: auth.project_id, }, - references: References { - merchant_reference: item.attempt_id.clone(), + payment_information: BankPaymentInformation { + amount: Amount { + amount, + currency: item.request.currency.to_string(), + }, + references: References { + merchant_reference: item.attempt_id.clone(), + }, }, - }, - callback_urls: CallbackURLs { - success: format!("{return_url}?status=SuccessOk"), - cancel: return_url.clone(), - error: return_url, - }, - })) + callback_urls: CallbackURLs { + success: format!("{return_url}?status=SuccessOk"), + cancel: return_url.clone(), + error: return_url, + }, + })); + Ok(payment_request) } impl TryFrom<&types::PaymentsAuthorizeRouterData> for TrustpayPaymentsRequest { - type Error = error_stack::Report; + type Error = Error; fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result { let default_browser_info = BrowserInformation { color_depth: 24, @@ -303,7 +311,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for TrustpayPaymentsRequest { ); let auth = TrustpayAuthType::try_from(&item.connector_auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; - Ok(match item.request.payment_method_data { + match item.request.payment_method_data { api::PaymentMethodData::Card(ref ccard) => Ok(get_card_request_data( item, browser_info, @@ -313,19 +321,10 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for TrustpayPaymentsRequest { item.request.get_return_url()?, )), api::PaymentMethodData::BankRedirect(ref bank_redirection_data) => { - Ok(get_bank_redirection_request_data( - item, - bank_redirection_data, - amount, - item.request.get_return_url()?, - auth, - )) + get_bank_redirection_request_data(item, bank_redirection_data, amount, auth) } - _ => Err(errors::ConnectorError::NotImplemented(format!( - "Current Payment Method - {:?}", - item.request.payment_method_data - ))), - }?) + _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()), + } } } @@ -524,7 +523,7 @@ impl TryFrom> for types::RouterData { - type Error = error_stack::Report; + type Error = Error; fn try_from( item: types::ResponseRouterData< F, @@ -733,7 +732,7 @@ pub struct TrustpayAuthUpdateRequest { } impl TryFrom<&types::RefreshTokenRouterData> for TrustpayAuthUpdateRequest { - type Error = error_stack::Report; + type Error = Error; fn try_from(_item: &types::RefreshTokenRouterData) -> Result { Ok(Self { grant_type: "client_credentials".to_string(), @@ -767,7 +766,7 @@ pub struct TrustpayAccessTokenErrorResponse { impl TryFrom> for types::RouterData { - type Error = error_stack::Report; + type Error = Error; fn try_from( item: types::ResponseRouterData, ) -> Result { @@ -820,7 +819,7 @@ pub enum TrustpayRefundRequest { } impl TryFrom<&types::RefundsRouterData> for TrustpayRefundRequest { - type Error = error_stack::Report; + type Error = Error; fn try_from(item: &types::RefundsRouterData) -> Result { let amount = format!( "{:.2}", @@ -1000,7 +999,7 @@ fn handle_bank_redirects_refund_sync_error_response( impl TryFrom> for types::RefundsRouterData { - type Error = error_stack::Report; + type Error = Error; fn try_from( item: types::RefundsResponseRouterData, ) -> Result { diff --git a/crates/storage_models/src/enums.rs b/crates/storage_models/src/enums.rs index e937728a58..21bb28561e 100644 --- a/crates/storage_models/src/enums.rs +++ b/crates/storage_models/src/enums.rs @@ -612,19 +612,34 @@ pub enum MandateStatus { #[strum(serialize_all = "snake_case")] #[serde(rename_all = "snake_case")] pub enum PaymentMethodType { - Credit, - Debit, - Giropay, - Ideal, - Sofort, - Eps, - Klarna, Affirm, AfterpayClearpay, - GooglePay, + AliPay, ApplePay, - Paypal, + BancontactCard, + Blik, + Credit, CryptoCurrency, + Debit, + Eps, + Giropay, + GooglePay, + Ideal, + Klarna, + MbWay, + MobilePay, + OnlineBankingCzechRepublic, + OnlineBankingFinland, + OnlineBankingPoland, + OnlineBankingSlovakia, + PayBright, + Paypal, + Przelewy24, + Sofort, + Swish, + Trustly, + Walley, + WeChatPay, } #[derive(