diff --git a/crates/router/src/connector/multisafepay/transformers.rs b/crates/router/src/connector/multisafepay/transformers.rs index 183c5527f7..28231334f5 100644 --- a/crates/router/src/connector/multisafepay/transformers.rs +++ b/crates/router/src/connector/multisafepay/transformers.rs @@ -4,7 +4,9 @@ use serde::{Deserialize, Serialize}; use url::Url; use crate::{ - connector::utils::{self, AddressDetailsData, CardData, RouterData}, + connector::utils::{ + self, AddressDetailsData, CardData, PaymentsAuthorizeRequestData, RouterData, + }, core::errors, pii::Secret, services, @@ -28,6 +30,7 @@ pub enum Gateway { MasterCard, Visa, Klarna, + Googlepay, } #[serde_with::skip_serializing_none] @@ -63,8 +66,8 @@ pub struct Settings { pub struct PaymentOptions { pub notification_url: Option, pub notification_method: Option, - pub redirect_url: Option, - pub cancel_url: Option, + pub redirect_url: String, + pub cancel_url: String, pub close_window: Option, pub settings: Option, pub template_id: Option, @@ -111,9 +114,8 @@ pub struct Customer { pub reference: Option, } -#[serde_with::skip_serializing_none] -#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] -pub struct GatewayInfo { +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub struct CardInfo { pub card_number: Option, pub card_holder_name: Option>, pub card_expiry_date: Option, @@ -121,9 +123,32 @@ pub struct GatewayInfo { pub flexible_3d: Option, pub moto: Option, pub term_url: Option, +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub struct GpayInfo { + pub payment_token: Option, +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub struct PayLaterInfo { pub email: Option, } +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +#[serde(untagged)] +pub enum GatewayInfo { + Card(CardInfo), + Wallet(WalletInfo), + PayLater(PayLaterInfo), +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +#[serde(untagged)] +pub enum WalletInfo { + GooglePay(GpayInfo), +} + #[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] pub struct DeliveryObject { first_name: Secret, @@ -168,7 +193,7 @@ pub struct ShoppingCart { } #[serde_with::skip_serializing_none] -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, PartialEq, Serialize)] pub struct MultisafepayPaymentsRequest { #[serde(rename = "type")] pub payment_type: Type, @@ -218,12 +243,14 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for MultisafepayPaymentsReques fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result { let payment_type = match item.request.payment_method_data { api::PaymentMethodData::Card(ref _ccard) => Type::Direct, + api::PaymentMethodData::Wallet(api::WalletData::GooglePay(_)) => Type::Direct, api::PaymentMethodData::PayLater(ref _paylater) => Type::Redirect, _ => Type::Redirect, }; let gateway = match item.request.payment_method_data { api::PaymentMethodData::Card(ref ccard) => Gateway::try_from(ccard.get_card_issuer()?)?, + api::PaymentMethodData::Wallet(api::WalletData::GooglePay(_)) => Gateway::Googlepay, api::PaymentMethodData::PayLater( api_models::payments::PayLaterData::KlarnaRedirect { billing_email: _, @@ -237,8 +264,8 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for MultisafepayPaymentsReques let description = item.get_description()?; let payment_options = PaymentOptions { notification_url: None, - redirect_url: item.request.router_return_url.clone(), - cancel_url: None, + redirect_url: item.request.get_router_return_url()?, + cancel_url: item.request.get_router_return_url()?, close_window: None, notification_method: None, settings: None, @@ -285,7 +312,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for MultisafepayPaymentsReques }; let gateway_info = match item.request.payment_method_data { - api::PaymentMethodData::Card(ref ccard) => GatewayInfo { + api::PaymentMethodData::Card(ref ccard) => GatewayInfo::Card(CardInfo { card_number: Some(ccard.card_number.clone()), card_expiry_date: Some( (format!( @@ -301,16 +328,15 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for MultisafepayPaymentsReques flexible_3d: None, moto: None, term_url: None, - email: None, - }, - api::PaymentMethodData::PayLater(ref paylater) => GatewayInfo { - card_number: None, - card_expiry_date: None, - card_cvc: None, - card_holder_name: None, - flexible_3d: None, - moto: None, - term_url: None, + }), + api::PaymentMethodData::Wallet(api::WalletData::GooglePay(ref google_pay)) => { + GatewayInfo::Wallet(WalletInfo::GooglePay({ + GpayInfo { + payment_token: Some(google_pay.tokenization_data.token.clone()), + } + })) + } + api::PaymentMethodData::PayLater(ref paylater) => GatewayInfo::PayLater(PayLaterInfo { email: Some(match paylater { api_models::payments::PayLaterData::KlarnaRedirect { billing_email, @@ -320,7 +346,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for MultisafepayPaymentsReques "Only KlarnaRedirect is implemented".to_string(), ))?, }), - }, + }), _ => Err(errors::ConnectorError::NotImplemented( "Payment method".to_string(), ))?, diff --git a/crates/router/tests/connectors/main.rs b/crates/router/tests/connectors/main.rs index 9eef3ceba6..0e5326ba4c 100644 --- a/crates/router/tests/connectors/main.rs +++ b/crates/router/tests/connectors/main.rs @@ -34,6 +34,7 @@ mod iatapay; mod mollie; mod mollie_ui; mod multisafepay; +mod multisafepay_ui; mod nexinets; mod nmi; mod noon; diff --git a/crates/router/tests/connectors/multisafepay_ui.rs b/crates/router/tests/connectors/multisafepay_ui.rs new file mode 100644 index 0000000000..292634cdb1 --- /dev/null +++ b/crates/router/tests/connectors/multisafepay_ui.rs @@ -0,0 +1,33 @@ +use serial_test::serial; +use thirtyfour::{prelude::*, WebDriver}; + +use crate::{selenium::*, tester}; + +struct MultisafepaySeleniumTest; + +impl SeleniumTest for MultisafepaySeleniumTest { + fn get_connector_name(&self) -> String { + "multisafepay".to_string() + } +} + +async fn should_make_gpay_payment(c: WebDriver) -> Result<(), WebDriverError> { + let conn = MultisafepaySeleniumTest {}; + conn.make_redirection_payment( + c, + vec![ + Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/153"))), + Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))), + Event::Trigger(Trigger::Click(By::Css("button[class='btn btn-default']"))), + Event::Assert(Assert::IsPresent("succeeded")), + ], + ) + .await?; + Ok(()) +} + +#[test] +#[serial] +fn should_make_gpay_payment_test() { + tester!(should_make_gpay_payment); +} diff --git a/crates/router/tests/connectors/selenium.rs b/crates/router/tests/connectors/selenium.rs index 6b54dd661b..e509da98de 100644 --- a/crates/router/tests/connectors/selenium.rs +++ b/crates/router/tests/connectors/selenium.rs @@ -213,6 +213,10 @@ pub trait SeleniumTest { .unwrap(); let script = &[ format!("localStorage.configs='{configs_url}'").as_str(), + "localStorage.current_env='local'", + "localStorage.hs_api_key=''", + "localStorage.hs_api_keys=''", + format!("localStorage.base_url='{hs_base_url}'").as_str(), format!("localStorage.hs_api_configs='{conf}'").as_str(), "localStorage.force_sync='true'", format!( @@ -307,6 +311,7 @@ pub trait SeleniumTest { if config.run_minimum_steps.unwrap() { self.complete_actions(&c, actions[..3].to_vec()).await } else { + println!("Run all steps"); self.complete_actions(&c, actions).await } } diff --git a/crates/router/tests/connectors/stripe_ui.rs b/crates/router/tests/connectors/stripe_ui.rs index 9e7d0cd63d..1c55f94ef1 100644 --- a/crates/router/tests/connectors/stripe_ui.rs +++ b/crates/router/tests/connectors/stripe_ui.rs @@ -363,6 +363,7 @@ async fn should_make_stripe_becs_bank_debit_payment(c: WebDriver) -> Result<(), vec![ Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/56"))), Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))), + Event::Assert(Assert::IsPresent("Status")), Event::Assert(Assert::IsPresent("processing")), ], ) @@ -377,6 +378,7 @@ async fn should_make_stripe_sepa_bank_debit_payment(c: WebDriver) -> Result<(), vec![ Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/67"))), Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))), + Event::Assert(Assert::IsPresent("Status")), Event::Assert(Assert::IsPresent("processing")), ], )