From 097807cbe955efba067d40f98a15bc5117daf29e Mon Sep 17 00:00:00 2001 From: Sangamesh Kulkarni <59434228+Sangamesh26@users.noreply.github.com> Date: Mon, 9 Jan 2023 17:39:47 +0530 Subject: [PATCH] feat: support for paypal in wallet (#304) --- crates/api_models/src/payments.rs | 4 +-- .../src/connector/adyen/transformers.rs | 33 +++++++++---------- .../src/connector/braintree/transformers.rs | 9 ++++- .../src/connector/worldpay/transformers.rs | 14 ++++++-- .../payments/operations/payment_confirm.rs | 8 ++--- .../router/src/core/payments/transformers.rs | 32 ++++-------------- crates/router/tests/connectors/worldpay.rs | 4 +-- 7 files changed, 49 insertions(+), 55 deletions(-) diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 2337e01d04..e7d691b22d 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -253,10 +253,10 @@ pub enum PaymentMethod { Paypal, } -#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize)] pub struct WalletData { pub issuer_name: api_enums::WalletIssuer, - pub token: String, + pub token: Option, } #[derive(Eq, PartialEq, Clone, Debug, serde::Serialize)] diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index 976cc7b6c3..0219159709 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -298,9 +298,8 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for AdyenPaymentRequest { let payment_type = match item.payment_method { storage_enums::PaymentMethodType::Card => "scheme".to_string(), - storage_enums::PaymentMethodType::Paypal => "paypal".to_string(), storage_enums::PaymentMethodType::Wallet => wallet_data - .get_required_value("issuer_name") + .get_required_value("wallet_data") .change_context(errors::ConnectorError::RequestEncodingFailed)? .issuer_name .to_string(), @@ -321,7 +320,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for AdyenPaymentRequest { } storage_enums::PaymentMethodType::Wallet => match wallet_data - .get_required_value("issuer_name") + .get_required_value("wallet_data") .change_context(errors::ConnectorError::RequestEncodingFailed)? .issuer_name { @@ -329,10 +328,13 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for AdyenPaymentRequest { let gpay_data = AdyenGPay { payment_type, google_pay_token: wallet_data - .get_required_value("token") + .get_required_value("wallet_data") .change_context(errors::ConnectorError::RequestEncodingFailed)? .token - .to_string(), + .to_owned() + .get_required_value("token") + .change_context(errors::ConnectorError::RequestEncodingFailed) + .attach_printable("No token passed")?, }; Ok(AdyenPaymentMethod::Gpay(gpay_data)) } @@ -341,24 +343,21 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for AdyenPaymentRequest { let apple_pay_data = AdyenApplePay { payment_type, apple_pay_token: wallet_data - .get_required_value("token") + .get_required_value("wallet_data") .change_context(errors::ConnectorError::RequestEncodingFailed)? .token - .to_string(), + .to_owned() + .get_required_value("token") + .change_context(errors::ConnectorError::RequestEncodingFailed) + .attach_printable("No token passed")?, }; Ok(AdyenPaymentMethod::ApplePay(apple_pay_data)) } - - api_enums::WalletIssuer::Paypal => Err(errors::ConnectorError::NotImplemented( - "Adyen - Paypal".to_string(), - )), + api_enums::WalletIssuer::Paypal => { + let wallet = AdyenPaypal { payment_type }; + Ok(AdyenPaymentMethod::AdyenPaypal(wallet)) + } }, - - storage_enums::PaymentMethodType::Paypal => { - let wallet = AdyenPaypal { payment_type }; - Ok(AdyenPaymentMethod::AdyenPaypal(wallet)) - } - _ => Err(errors::ConnectorError::MissingRequiredField { field_name: "payment_method".to_string(), }), diff --git a/crates/router/src/connector/braintree/transformers.rs b/crates/router/src/connector/braintree/transformers.rs index 3691adb974..28d3ed8a18 100644 --- a/crates/router/src/connector/braintree/transformers.rs +++ b/crates/router/src/connector/braintree/transformers.rs @@ -1,9 +1,11 @@ +use error_stack::ResultExt; use serde::{Deserialize, Serialize}; use crate::{ core::errors, pii::PeekInterface, types::{self, api, storage::enums}, + utils::OptionExt, }; #[derive(Default, Debug, Serialize, Eq, PartialEq)] @@ -106,7 +108,12 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for BraintreePaymentsRequest { })), api::PaymentMethod::Wallet(ref wallet_data) => { Ok(PaymentMethodType::PaymentMethodNonce(Nonce { - payment_method_nonce: wallet_data.token.to_string(), + payment_method_nonce: wallet_data + .token + .to_owned() + .get_required_value("token") + .change_context(errors::ConnectorError::RequestEncodingFailed) + .attach_printable("No token passed")?, })) } _ => Err(errors::ConnectorError::NotImplemented(format!( diff --git a/crates/router/src/connector/worldpay/transformers.rs b/crates/router/src/connector/worldpay/transformers.rs index 0ca5da3c78..493c960b48 100644 --- a/crates/router/src/connector/worldpay/transformers.rs +++ b/crates/router/src/connector/worldpay/transformers.rs @@ -1,6 +1,7 @@ use std::str::FromStr; use common_utils::errors::CustomResult; +use error_stack::ResultExt; use masking::PeekInterface; use storage_models::enums; @@ -8,6 +9,7 @@ use super::{requests::*, response::*}; use crate::{ core::errors, types::{self, api}, + utils::OptionExt, }; fn parse_int( @@ -40,14 +42,22 @@ fn fetch_payment_instrument( api_models::enums::WalletIssuer::ApplePay => { Ok(PaymentInstrument::Applepay(WalletPayment { payment_type: PaymentType::Applepay, - wallet_token: wallet.token, + wallet_token: wallet + .token + .get_required_value("token") + .change_context(errors::ConnectorError::RequestEncodingFailed) + .attach_printable("No token passed")?, ..WalletPayment::default() })) } api_models::enums::WalletIssuer::GooglePay => { Ok(PaymentInstrument::Googlepay(WalletPayment { payment_type: PaymentType::Googlepay, - wallet_token: wallet.token, + wallet_token: wallet + .token + .get_required_value("token") + .change_context(errors::ConnectorError::RequestEncodingFailed) + .attach_printable("No token passed")?, ..WalletPayment::default() })) } diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index 714a368b9e..a69fb8a080 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -233,11 +233,9 @@ impl Domain for PaymentConfirm { let (op, payment_method_data) = helpers::make_pm_data(Box::new(self), state, payment_data).await?; - if payment_data.payment_attempt.payment_method != Some(enums::PaymentMethodType::Paypal) { - utils::when(payment_method_data.is_none(), || { - Err(errors::ApiErrorResponse::PaymentMethodNotFound) - })?; - } + utils::when(payment_method_data.is_none(), || { + Err(errors::ApiErrorResponse::PaymentMethodNotFound) + })?; Ok((op, payment_method_data)) } diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 9e7e8e80ea..55b5fd2b9c 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -411,19 +411,9 @@ impl TryFrom> for types::PaymentsAuthorizeData { let order_details = parsed_metadata.and_then(|data| data.order_details); Ok(Self { - payment_method_data: { - let payment_method_type = payment_data - .payment_attempt - .payment_method - .get_required_value("payment_method_type")?; - - match payment_method_type { - enums::PaymentMethodType::Paypal => api::PaymentMethod::Paypal, - _ => payment_data - .payment_method_data - .get_required_value("payment_method_data")?, - } - }, + payment_method_data: payment_data + .payment_method_data + .get_required_value("payment_method_data")?, setup_future_usage: payment_data.payment_intent.setup_future_usage, mandate_id: payment_data.mandate_id.clone(), off_session: payment_data.mandate_id.as_ref().map(|_| true), @@ -527,19 +517,9 @@ impl TryFrom> for types::VerifyRequestData { fn try_from(payment_data: PaymentData) -> Result { Ok(Self { confirm: true, - payment_method_data: { - let payment_method_type = payment_data - .payment_attempt - .payment_method - .get_required_value("payment_method_type")?; - - match payment_method_type { - enums::PaymentMethodType::Paypal => api::PaymentMethod::Paypal, - _ => payment_data - .payment_method_data - .get_required_value("payment_method_data")?, - } - }, + payment_method_data: payment_data + .payment_method_data + .get_required_value("payment_method_data")?, statement_descriptor_suffix: payment_data.payment_intent.statement_descriptor_suffix, setup_future_usage: payment_data.payment_intent.setup_future_usage, off_session: payment_data.mandate_id.as_ref().map(|_| true), diff --git a/crates/router/tests/connectors/worldpay.rs b/crates/router/tests/connectors/worldpay.rs index 3a123239a1..492a743a97 100644 --- a/crates/router/tests/connectors/worldpay.rs +++ b/crates/router/tests/connectors/worldpay.rs @@ -65,7 +65,7 @@ async fn should_authorize_gpay_payment() { .authorize_payment(Some(types::PaymentsAuthorizeData { payment_method_data: types::api::PaymentMethod::Wallet(api::WalletData { issuer_name: api_enums::WalletIssuer::GooglePay, - token: "someToken".to_string(), + token: Some("someToken".to_string()), }), ..utils::PaymentAuthorizeType::default().0 })) @@ -86,7 +86,7 @@ async fn should_authorize_applepay_payment() { .authorize_payment(Some(types::PaymentsAuthorizeData { payment_method_data: types::api::PaymentMethod::Wallet(api::WalletData { issuer_name: api_enums::WalletIssuer::ApplePay, - token: "someToken".to_string(), + token: Some("someToken".to_string()), }), ..utils::PaymentAuthorizeType::default().0 }))