feat(connector): [Multisafepay] implement Googlepay for Multisafepay (#1456)

Co-authored-by: Jagan Elavarasan <jaganelavarasan@gmail.com>
This commit is contained in:
AkshayaFoiger
2023-07-01 15:31:21 +05:30
committed by GitHub
parent f091be60cc
commit 2136326166
5 changed files with 88 additions and 21 deletions

View File

@ -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<String>,
pub notification_method: Option<String>,
pub redirect_url: Option<String>,
pub cancel_url: Option<String>,
pub redirect_url: String,
pub cancel_url: String,
pub close_window: Option<bool>,
pub settings: Option<Settings>,
pub template_id: Option<String>,
@ -111,9 +114,8 @@ pub struct Customer {
pub reference: Option<String>,
}
#[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<cards::CardNumber>,
pub card_holder_name: Option<Secret<String>>,
pub card_expiry_date: Option<i32>,
@ -121,9 +123,32 @@ pub struct GatewayInfo {
pub flexible_3d: Option<bool>,
pub moto: Option<bool>,
pub term_url: Option<String>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct GpayInfo {
pub payment_token: Option<String>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct PayLaterInfo {
pub email: Option<Email>,
}
#[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<String>,
@ -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<Self, Self::Error> {
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(),
))?,

View File

@ -34,6 +34,7 @@ mod iatapay;
mod mollie;
mod mollie_ui;
mod multisafepay;
mod multisafepay_ui;
mod nexinets;
mod nmi;
mod noon;

View File

@ -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);
}

View File

@ -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
}
}

View File

@ -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")),
],
)