feat(connector): mask pii information in connector request and response for stripe, bluesnap, checkout, zen (#1435)

This commit is contained in:
Arjun Karthik
2023-06-14 17:43:27 +05:30
committed by GitHub
parent fda3fb4d2b
commit 5535159d5c
6 changed files with 111 additions and 111 deletions

View File

@ -10,7 +10,9 @@ use masking::ExposeInterface;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
connector::utils::{self, AddressDetailsData, PaymentsAuthorizeRequestData, RouterData}, connector::utils::{
self, AddressDetailsData, ApplePay, PaymentsAuthorizeRequestData, RouterData,
},
consts, consts,
core::errors, core::errors,
pii::Secret, pii::Secret,
@ -80,7 +82,7 @@ pub struct Card {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct BluesnapWallet { pub struct BluesnapWallet {
wallet_type: BluesnapWalletTypes, wallet_type: BluesnapWalletTypes,
encoded_payment_token: String, encoded_payment_token: Secret<String>,
} }
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
@ -182,21 +184,22 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for BluesnapPaymentsRequest {
Ok(( Ok((
PaymentMethodDetails::Wallet(BluesnapWallet { PaymentMethodDetails::Wallet(BluesnapWallet {
wallet_type: BluesnapWalletTypes::GooglePay, wallet_type: BluesnapWalletTypes::GooglePay,
encoded_payment_token: consts::BASE64_ENGINE.encode(gpay_object), encoded_payment_token: Secret::new(
consts::BASE64_ENGINE.encode(gpay_object),
),
}), }),
None, None,
)) ))
} }
api_models::payments::WalletData::ApplePay(payment_method_data) => { api_models::payments::WalletData::ApplePay(payment_method_data) => {
let apple_pay_payment_data = consts::BASE64_ENGINE let apple_pay_payment_data = payment_method_data
.decode(payment_method_data.payment_data) .get_applepay_decoded_payment_data()
.into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?;
.change_context(errors::ConnectorError::ParsingFailed)?;
let apple_pay_payment_data: ApplePayEncodedPaymentData = apple_pay_payment_data let apple_pay_payment_data: ApplePayEncodedPaymentData = apple_pay_payment_data
[..] .expose()[..]
.as_bytes()
.parse_struct("ApplePayEncodedPaymentData") .parse_struct("ApplePayEncodedPaymentData")
.change_context(errors::ConnectorError::ParsingFailed)?; .change_context(errors::ConnectorError::RequestEncodingFailed)?;
let billing = item let billing = item
.address .address
@ -249,7 +252,9 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for BluesnapPaymentsRequest {
Ok(( Ok((
PaymentMethodDetails::Wallet(BluesnapWallet { PaymentMethodDetails::Wallet(BluesnapWallet {
wallet_type: BluesnapWalletTypes::ApplePay, wallet_type: BluesnapWalletTypes::ApplePay,
encoded_payment_token: consts::BASE64_ENGINE.encode(apple_pay_object), encoded_payment_token: Secret::new(
consts::BASE64_ENGINE.encode(apple_pay_object),
),
}), }),
None, None,
)) ))
@ -528,7 +533,7 @@ impl TryFrom<&types::ConnectorCustomerRouterData> for BluesnapCustomerRequest {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct BluesnapCustomerResponse { pub struct BluesnapCustomerResponse {
vaulted_shopper_id: u64, vaulted_shopper_id: Secret<u64>,
} }
impl<F, T> impl<F, T>
TryFrom<types::ResponseRouterData<F, BluesnapCustomerResponse, T, types::PaymentsResponseData>> TryFrom<types::ResponseRouterData<F, BluesnapCustomerResponse, T, types::PaymentsResponseData>>
@ -545,7 +550,7 @@ impl<F, T>
) -> Result<Self, Self::Error> { ) -> Result<Self, Self::Error> {
Ok(Self { Ok(Self {
response: Ok(types::PaymentsResponseData::ConnectorCustomerResponse { response: Ok(types::PaymentsResponseData::ConnectorCustomerResponse {
connector_customer_id: item.response.vaulted_shopper_id.to_string(), connector_customer_id: item.response.vaulted_shopper_id.expose().to_string(),
}), }),
..item.data ..item.data
}) })
@ -636,7 +641,7 @@ pub struct Refund {
pub struct ProcessingInfoResponse { pub struct ProcessingInfoResponse {
processing_status: BluesnapProcessingStatus, processing_status: BluesnapProcessingStatus,
authorization_code: Option<String>, authorization_code: Option<String>,
network_transaction_id: Option<String>, network_transaction_id: Option<Secret<String>>,
} }
impl<F, T> impl<F, T>

View File

@ -1,5 +1,6 @@
use common_utils::errors::CustomResult; use common_utils::errors::CustomResult;
use error_stack::{IntoReport, ResultExt}; use error_stack::{IntoReport, ResultExt};
use masking::ExposeInterface;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use time::PrimitiveDateTime; use time::PrimitiveDateTime;
use url::Url; use url::Url;
@ -73,7 +74,7 @@ impl TryFrom<&types::TokenizationRouterData> for TokenRequest {
#[derive(Debug, Eq, PartialEq, Deserialize)] #[derive(Debug, Eq, PartialEq, Deserialize)]
pub struct CheckoutTokenResponse { pub struct CheckoutTokenResponse {
token: String, token: pii::Secret<String>,
} }
impl<F, T> impl<F, T>
@ -86,7 +87,7 @@ impl<F, T>
) -> Result<Self, Self::Error> { ) -> Result<Self, Self::Error> {
Ok(Self { Ok(Self {
response: Ok(types::PaymentsResponseData::TokenizationResponse { response: Ok(types::PaymentsResponseData::TokenizationResponse {
token: item.response.token, token: item.response.token.expose(),
}), }),
..item.data ..item.data
}) })

View File

@ -1,7 +1,6 @@
use std::ops::Deref; use std::ops::Deref;
use api_models::{self, enums as api_enums, payments}; use api_models::{self, enums as api_enums, payments};
use base64::Engine;
use common_utils::{ use common_utils::{
errors::CustomResult, errors::CustomResult,
ext_traits::{ByteSliceExt, BytesExt}, ext_traits::{ByteSliceExt, BytesExt},
@ -15,7 +14,11 @@ use url::Url;
use uuid::Uuid; use uuid::Uuid;
use crate::{ use crate::{
collect_missing_value_keys, connector, consts, collect_missing_value_keys,
connector::{
self,
utils::{ApplePay, RouterData},
},
core::errors, core::errors,
services, services,
types::{self, api, storage::enums, transformers::ForeignFrom}, types::{self, api, storage::enums, transformers::ForeignFrom},
@ -99,9 +102,9 @@ pub struct PaymentIntentRequest {
pub metadata_txn_uuid: String, pub metadata_txn_uuid: String,
pub return_url: String, pub return_url: String,
pub confirm: bool, pub confirm: bool,
pub mandate: Option<String>, pub mandate: Option<Secret<String>>,
pub payment_method: Option<String>, pub payment_method: Option<String>,
pub customer: Option<String>, pub customer: Option<Secret<String>>,
#[serde(flatten)] #[serde(flatten)]
pub setup_mandate_details: Option<StripeMandateRequest>, pub setup_mandate_details: Option<StripeMandateRequest>,
pub description: Option<String>, pub description: Option<String>,
@ -127,7 +130,7 @@ pub struct SetupIntentRequest {
pub metadata_txn_uuid: String, pub metadata_txn_uuid: String,
pub confirm: bool, pub confirm: bool,
pub usage: Option<enums::FutureUsage>, pub usage: Option<enums::FutureUsage>,
pub customer: Option<String>, pub customer: Option<Secret<String>>,
pub off_session: Option<bool>, pub off_session: Option<bool>,
pub return_url: Option<String>, pub return_url: Option<String>,
#[serde(flatten)] #[serde(flatten)]
@ -177,7 +180,7 @@ pub struct CustomerRequest {
pub description: Option<String>, pub description: Option<String>,
pub email: Option<Email>, pub email: Option<Email>,
pub phone: Option<Secret<String>>, pub phone: Option<Secret<String>>,
pub name: Option<String>, pub name: Option<Secret<String>>,
pub source: Option<String>, pub source: Option<String>,
} }
@ -187,15 +190,15 @@ pub struct StripeCustomerResponse {
pub description: Option<String>, pub description: Option<String>,
pub email: Option<Email>, pub email: Option<Email>,
pub phone: Option<Secret<String>>, pub phone: Option<Secret<String>>,
pub name: Option<String>, pub name: Option<Secret<String>>,
} }
#[derive(Debug, Eq, PartialEq, Serialize)] #[derive(Debug, Eq, PartialEq, Serialize)]
pub struct ChargesRequest { pub struct ChargesRequest {
pub amount: String, pub amount: String,
pub currency: String, pub currency: String,
pub customer: String, pub customer: Secret<String>,
pub source: String, pub source: Secret<String>,
} }
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize)] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize)]
@ -407,7 +410,7 @@ pub enum StripeWallet {
#[derive(Debug, Eq, PartialEq, Serialize)] #[derive(Debug, Eq, PartialEq, Serialize)]
pub struct StripeApplePay { pub struct StripeApplePay {
pub pk_token: String, pub pk_token: Secret<String>,
pub pk_token_instrument_name: String, pub pk_token_instrument_name: String,
pub pk_token_payment_network: String, pub pk_token_payment_network: String,
pub pk_token_transaction_id: String, pub pk_token_transaction_id: String,
@ -418,13 +421,13 @@ pub struct GooglePayToken {
#[serde(rename = "payment_method_data[type]")] #[serde(rename = "payment_method_data[type]")]
pub payment_type: StripePaymentMethodType, pub payment_type: StripePaymentMethodType,
#[serde(rename = "payment_method_data[card][token]")] #[serde(rename = "payment_method_data[card][token]")]
pub token: String, pub token: Secret<String>,
} }
#[derive(Debug, Eq, PartialEq, Serialize)] #[derive(Debug, Eq, PartialEq, Serialize)]
pub struct ApplepayPayment { pub struct ApplepayPayment {
#[serde(rename = "payment_method_data[card][token]")] #[serde(rename = "payment_method_data[card][token]")]
pub token: String, pub token: Secret<String>,
#[serde(rename = "payment_method_data[type]")] #[serde(rename = "payment_method_data[type]")]
pub payment_method_types: StripePaymentMethodType, pub payment_method_types: StripePaymentMethodType,
} }
@ -1019,14 +1022,9 @@ fn create_stripe_payment_method(
payments::PaymentMethodData::Wallet(wallet_data) => match wallet_data { payments::PaymentMethodData::Wallet(wallet_data) => match wallet_data {
payments::WalletData::ApplePay(applepay_data) => Ok(( payments::WalletData::ApplePay(applepay_data) => Ok((
StripePaymentMethodData::Wallet(StripeWallet::ApplepayToken(StripeApplePay { StripePaymentMethodData::Wallet(StripeWallet::ApplepayToken(StripeApplePay {
pk_token: String::from_utf8( pk_token: applepay_data
consts::BASE64_ENGINE .get_applepay_decoded_payment_data()
.decode(&applepay_data.payment_data) .change_context(errors::ConnectorError::RequestEncodingFailed)?,
.into_report()
.change_context(errors::ConnectorError::RequestEncodingFailed)?,
)
.into_report()
.change_context(errors::ConnectorError::RequestEncodingFailed)?,
pk_token_instrument_name: applepay_data.payment_method.pm_type.to_owned(), pk_token_instrument_name: applepay_data.payment_method.pm_type.to_owned(),
pk_token_payment_network: applepay_data.payment_method.network.to_owned(), pk_token_payment_network: applepay_data.payment_method.network.to_owned(),
pk_token_transaction_id: applepay_data.transaction_identifier.to_owned(), pk_token_transaction_id: applepay_data.transaction_identifier.to_owned(),
@ -1144,13 +1142,15 @@ impl TryFrom<&payments::GooglePayWalletData> for StripePaymentMethodData {
type Error = error_stack::Report<errors::ConnectorError>; type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(gpay_data: &payments::GooglePayWalletData) -> Result<Self, Self::Error> { fn try_from(gpay_data: &payments::GooglePayWalletData) -> Result<Self, Self::Error> {
Ok(Self::Wallet(StripeWallet::GooglepayToken(GooglePayToken { Ok(Self::Wallet(StripeWallet::GooglepayToken(GooglePayToken {
token: gpay_data token: Secret::new(
.tokenization_data gpay_data
.token .tokenization_data
.as_bytes() .token
.parse_struct::<StripeGpayToken>("StripeGpayToken") .as_bytes()
.change_context(errors::ConnectorError::RequestEncodingFailed)? .parse_struct::<StripeGpayToken>("StripeGpayToken")
.id, .change_context(errors::ConnectorError::RequestEncodingFailed)?
.id,
),
payment_type: StripePaymentMethodType::Card, payment_type: StripePaymentMethodType::Card,
}))) })))
} }
@ -1216,7 +1216,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest {
mandate_options: None, mandate_options: None,
network_transaction_id: None, network_transaction_id: None,
mit_exemption: Some(MitExemption { mit_exemption: Some(MitExemption {
network_transaction_id, network_transaction_id: Secret::new(network_transaction_id),
}), }),
}); });
(None, None, None, StripeBillingAddress::default()) (None, None, None, StripeBillingAddress::default())
@ -1243,11 +1243,12 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest {
payment_data = match item.request.payment_method_data { payment_data = match item.request.payment_method_data {
payments::PaymentMethodData::Wallet(payments::WalletData::ApplePay(_)) => Some( payments::PaymentMethodData::Wallet(payments::WalletData::ApplePay(_)) => Some(
StripePaymentMethodData::Wallet(StripeWallet::ApplepayPayment(ApplepayPayment { StripePaymentMethodData::Wallet(StripeWallet::ApplepayPayment(ApplepayPayment {
token: item token: Secret::new(
.payment_method_token item.payment_method_token
.to_owned() .to_owned()
.get_required_value("payment_token") .get_required_value("payment_token")
.change_context(errors::ConnectorError::RequestEncodingFailed)?, .change_context(errors::ConnectorError::RequestEncodingFailed)?,
),
payment_method_types: StripePaymentMethodType::Card, payment_method_types: StripePaymentMethodType::Card,
})), })),
), ),
@ -1299,10 +1300,10 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest {
billing: billing_address, billing: billing_address,
capture_method: StripeCaptureMethod::from(item.request.capture_method), capture_method: StripeCaptureMethod::from(item.request.capture_method),
payment_data, payment_data,
mandate, mandate: mandate.map(Secret::new),
payment_method_options, payment_method_options,
payment_method, payment_method,
customer: item.connector_customer.to_owned(), customer: item.connector_customer.to_owned().map(Secret::new),
setup_mandate_details, setup_mandate_details,
off_session: item.request.off_session, off_session: item.request.off_session,
setup_future_usage: item.request.setup_future_usage, setup_future_usage: item.request.setup_future_usage,
@ -1335,7 +1336,7 @@ impl TryFrom<&types::VerifyRouterData> for SetupIntentRequest {
off_session: item.request.off_session, off_session: item.request.off_session,
usage: item.request.setup_future_usage, usage: item.request.setup_future_usage,
payment_method_options: None, payment_method_options: None,
customer: item.connector_customer.to_owned(), customer: item.connector_customer.to_owned().map(Secret::new),
}) })
} }
} }
@ -1362,7 +1363,7 @@ impl TryFrom<&types::ConnectorCustomerRouterData> for CustomerRequest {
description: item.request.description.to_owned(), description: item.request.description.to_owned(),
email: item.request.email.to_owned(), email: item.request.email.to_owned(),
phone: item.request.phone.to_owned(), phone: item.request.phone.to_owned(),
name: item.request.name.to_owned(), name: item.request.name.to_owned().map(Secret::new),
source: item.request.preprocessing_id.to_owned(), source: item.request.preprocessing_id.to_owned(),
}) })
} }
@ -1774,7 +1775,7 @@ impl ForeignFrom<Option<LatestAttempt>> for Option<String> {
StripePaymentMethodOptions::Card { StripePaymentMethodOptions::Card {
network_transaction_id, network_transaction_id,
.. ..
} => network_transaction_id, } => network_transaction_id.map(|network_id| network_id.expose()),
_ => None, _ => None,
}), }),
_ => None, _ => None,
@ -2059,7 +2060,7 @@ impl TryFrom<&types::PaymentsCancelRouterData> for CancelRequest {
pub enum StripePaymentMethodOptions { pub enum StripePaymentMethodOptions {
Card { Card {
mandate_options: Option<StripeMandateOptions>, mandate_options: Option<StripeMandateOptions>,
network_transaction_id: Option<String>, network_transaction_id: Option<Secret<String>>,
mit_exemption: Option<MitExemption>, // To be used for MIT mandate txns mit_exemption: Option<MitExemption>, // To be used for MIT mandate txns
}, },
Klarna {}, Klarna {},
@ -2087,7 +2088,7 @@ pub enum StripePaymentMethodOptions {
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
pub struct MitExemption { pub struct MitExemption {
pub network_transaction_id: String, pub network_transaction_id: Secret<String>,
} }
#[derive(Clone, Debug, Eq, PartialEq, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, Deserialize)]
@ -2182,20 +2183,8 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for ChargesRequest {
Ok(Self { Ok(Self {
amount: value.request.amount.to_string(), amount: value.request.amount.to_string(),
currency: value.request.currency.to_string(), currency: value.request.currency.to_string(),
customer: value customer: Secret::new(value.get_connector_customer_id()?),
.connector_customer source: Secret::new(value.get_preprocessing_id()?),
.to_owned()
.get_required_value("customer_id")
.change_context(errors::ConnectorError::MissingRequiredField {
field_name: "customer_id",
})?,
source: value
.preprocessing_id
.to_owned()
.get_required_value("source")
.change_context(errors::ConnectorError::MissingRequiredField {
field_name: "source",
})?,
}) })
} }
} }
@ -2506,14 +2495,9 @@ impl
api::PaymentMethodData::Wallet(wallet_data) => match wallet_data { api::PaymentMethodData::Wallet(wallet_data) => match wallet_data {
payments::WalletData::ApplePay(data) => { payments::WalletData::ApplePay(data) => {
let wallet_info = StripeWallet::ApplepayToken(StripeApplePay { let wallet_info = StripeWallet::ApplepayToken(StripeApplePay {
pk_token: String::from_utf8( pk_token: data
consts::BASE64_ENGINE .get_applepay_decoded_payment_data()
.decode(data.payment_data) .change_context(errors::ConnectorError::RequestEncodingFailed)?,
.into_report()
.change_context(errors::ConnectorError::RequestEncodingFailed)?,
)
.into_report()
.change_context(errors::ConnectorError::RequestEncodingFailed)?,
pk_token_instrument_name: data.payment_method.pm_type, pk_token_instrument_name: data.payment_method.pm_type,
pk_token_payment_network: data.payment_method.network, pk_token_payment_network: data.payment_method.network,
pk_token_transaction_id: data.transaction_identifier, pk_token_transaction_id: data.transaction_identifier,

View File

@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use api_models::payments::BankRedirectData; use api_models::payments::BankRedirectData;
use common_utils::{errors::CustomResult, pii::Email}; use common_utils::{errors::CustomResult, pii};
use error_stack::{IntoReport, ResultExt}; use error_stack::{IntoReport, ResultExt};
use masking::Secret; use masking::Secret;
use reqwest::Url; use reqwest::Url;
@ -131,9 +131,9 @@ pub struct PaymentRequestCards {
#[serde(rename = "billing[postcode]")] #[serde(rename = "billing[postcode]")]
pub billing_postcode: Secret<String>, pub billing_postcode: Secret<String>,
#[serde(rename = "customer[email]")] #[serde(rename = "customer[email]")]
pub customer_email: Email, pub customer_email: pii::Email,
#[serde(rename = "customer[ipAddress]")] #[serde(rename = "customer[ipAddress]")]
pub customer_ip_address: std::net::IpAddr, pub customer_ip_address: Secret<String, pii::IpAddress>,
#[serde(rename = "browser[acceptHeader]")] #[serde(rename = "browser[acceptHeader]")]
pub browser_accept_header: String, pub browser_accept_header: String,
#[serde(rename = "browser[language]")] #[serde(rename = "browser[language]")]

View File

@ -5,7 +5,7 @@ use base64::Engine;
use common_utils::{ use common_utils::{
date_time, date_time,
errors::ReportSwitchExt, errors::ReportSwitchExt,
pii::{self, Email}, pii::{self, Email, IpAddress},
}; };
use error_stack::{report, IntoReport, ResultExt}; use error_stack::{report, IntoReport, ResultExt};
use masking::Secret; use masking::Secret;
@ -64,6 +64,7 @@ pub trait RouterData {
fn get_payment_method_token(&self) -> Result<String, Error>; fn get_payment_method_token(&self) -> Result<String, Error>;
fn get_customer_id(&self) -> Result<String, Error>; fn get_customer_id(&self) -> Result<String, Error>;
fn get_connector_customer_id(&self) -> Result<String, Error>; fn get_connector_customer_id(&self) -> Result<String, Error>;
fn get_preprocessing_id(&self) -> Result<String, Error>;
} }
impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Response> { impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Response> {
@ -157,6 +158,11 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
.to_owned() .to_owned()
.ok_or_else(missing_field_err("connector_customer_id")) .ok_or_else(missing_field_err("connector_customer_id"))
} }
fn get_preprocessing_id(&self) -> Result<String, Error> {
self.preprocessing_id
.to_owned()
.ok_or_else(missing_field_err("preprocessing_id"))
}
} }
pub trait PaymentsPreProcessingData { pub trait PaymentsPreProcessingData {
@ -257,13 +263,15 @@ impl PaymentsAuthorizeRequestData for types::PaymentsAuthorizeData {
} }
pub trait BrowserInformationData { pub trait BrowserInformationData {
fn get_ip_address(&self) -> Result<std::net::IpAddr, Error>; fn get_ip_address(&self) -> Result<Secret<String, IpAddress>, Error>;
} }
impl BrowserInformationData for types::BrowserInformation { impl BrowserInformationData for types::BrowserInformation {
fn get_ip_address(&self) -> Result<std::net::IpAddr, Error> { fn get_ip_address(&self) -> Result<Secret<String, IpAddress>, Error> {
self.ip_address let ip_address = self
.ok_or_else(missing_field_err("browser_info.ip_address")) .ip_address
.ok_or_else(missing_field_err("browser_info.ip_address"))?;
Ok(Secret::new(ip_address.to_string()))
} }
} }
@ -368,7 +376,7 @@ pub struct GooglePayPaymentMethodInfo {
pub struct GpayTokenizationData { pub struct GpayTokenizationData {
#[serde(rename = "type")] #[serde(rename = "type")]
pub token_type: String, pub token_type: String,
pub token: String, pub token: Secret<String>,
} }
impl From<api_models::payments::GooglePayWalletData> for GooglePayWalletData { impl From<api_models::payments::GooglePayWalletData> for GooglePayWalletData {
@ -382,7 +390,7 @@ impl From<api_models::payments::GooglePayWalletData> for GooglePayWalletData {
}, },
tokenization_data: GpayTokenizationData { tokenization_data: GpayTokenizationData {
token_type: data.tokenization_data.token_type, token_type: data.tokenization_data.token_type,
token: data.tokenization_data.token, token: Secret::new(data.tokenization_data.token),
}, },
} }
} }
@ -488,18 +496,18 @@ fn get_card_issuer(card_number: &str) -> Result<CardIssuer, Error> {
)) ))
} }
pub trait WalletData { pub trait WalletData {
fn get_wallet_token(&self) -> Result<String, Error>; fn get_wallet_token(&self) -> Result<Secret<String>, Error>;
fn get_wallet_token_as_json<T>(&self) -> Result<T, Error> fn get_wallet_token_as_json<T>(&self) -> Result<T, Error>
where where
T: serde::de::DeserializeOwned; T: serde::de::DeserializeOwned;
} }
impl WalletData for api::WalletData { impl WalletData for api::WalletData {
fn get_wallet_token(&self) -> Result<String, Error> { fn get_wallet_token(&self) -> Result<Secret<String>, Error> {
match self { match self {
Self::GooglePay(data) => Ok(data.tokenization_data.token.clone()), Self::GooglePay(data) => Ok(Secret::new(data.tokenization_data.token.clone())),
Self::ApplePay(data) => Ok(data.get_applepay_decoded_payment_data()?), Self::ApplePay(data) => Ok(data.get_applepay_decoded_payment_data()?),
Self::PaypalSdk(data) => Ok(data.token.clone()), Self::PaypalSdk(data) => Ok(Secret::new(data.token.clone())),
_ => Err(errors::ConnectorError::InvalidWallet.into()), _ => Err(errors::ConnectorError::InvalidWallet.into()),
} }
} }
@ -507,26 +515,28 @@ impl WalletData for api::WalletData {
where where
T: serde::de::DeserializeOwned, T: serde::de::DeserializeOwned,
{ {
serde_json::from_str::<T>(&self.get_wallet_token()?) serde_json::from_str::<T>(self.get_wallet_token()?.peek())
.into_report() .into_report()
.change_context(errors::ConnectorError::InvalidWalletToken) .change_context(errors::ConnectorError::InvalidWalletToken)
} }
} }
pub trait ApplePay { pub trait ApplePay {
fn get_applepay_decoded_payment_data(&self) -> Result<String, Error>; fn get_applepay_decoded_payment_data(&self) -> Result<Secret<String>, Error>;
} }
impl ApplePay for payments::ApplePayWalletData { impl ApplePay for payments::ApplePayWalletData {
fn get_applepay_decoded_payment_data(&self) -> Result<String, Error> { fn get_applepay_decoded_payment_data(&self) -> Result<Secret<String>, Error> {
let token = String::from_utf8( let token = Secret::new(
consts::BASE64_ENGINE String::from_utf8(
.decode(&self.payment_data) consts::BASE64_ENGINE
.into_report() .decode(&self.payment_data)
.change_context(errors::ConnectorError::InvalidWalletToken)?, .into_report()
) .change_context(errors::ConnectorError::InvalidWalletToken)?,
.into_report() )
.change_context(errors::ConnectorError::InvalidWalletToken)?; .into_report()
.change_context(errors::ConnectorError::InvalidWalletToken)?,
);
Ok(token) Ok(token)
} }
} }

View File

@ -1,8 +1,6 @@
use std::net::IpAddr;
use api_models::payments::{ApplePayRedirectData, Card, GooglePayWalletData}; use api_models::payments::{ApplePayRedirectData, Card, GooglePayWalletData};
use cards::CardNumber; use cards::CardNumber;
use common_utils::{ext_traits::ValueExt, pii::Email}; use common_utils::{ext_traits::ValueExt, pii};
use error_stack::ResultExt; use error_stack::ResultExt;
use masking::{PeekInterface, Secret}; use masking::{PeekInterface, Secret};
use ring::digest; use ring::digest;
@ -82,8 +80,8 @@ pub enum ZenPaymentChannels {
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ZenCustomerDetails { pub struct ZenCustomerDetails {
email: Email, email: pii::Email,
ip: IpAddr, ip: Secret<String, pii::IpAddress>,
} }
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
@ -93,7 +91,7 @@ pub struct ZenPaymentData {
#[serde(rename = "type")] #[serde(rename = "type")]
payment_type: ZenPaymentTypes, payment_type: ZenPaymentTypes,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
token: Option<String>, token: Option<Secret<String>>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
card: Option<ZenCardDetails>, card: Option<ZenCardDetails>,
descriptor: String, descriptor: String,
@ -196,7 +194,9 @@ impl TryFrom<(&types::PaymentsAuthorizeRouterData, &GooglePayWalletData)> for Ze
browser_details, browser_details,
//Connector Specific for wallet //Connector Specific for wallet
payment_type: ZenPaymentTypes::ExternalPaymentToken, payment_type: ZenPaymentTypes::ExternalPaymentToken,
token: Some(gpay_pay_redirect_data.tokenization_data.token.clone()), token: Some(Secret::new(
gpay_pay_redirect_data.tokenization_data.token.clone(),
)),
card: None, card: None,
descriptor: item.get_description()?.chars().take(24).collect(), descriptor: item.get_description()?.chars().take(24).collect(),
return_verify_url: item.request.router_return_url.clone(), return_verify_url: item.request.router_return_url.clone(),
@ -323,7 +323,7 @@ fn get_signature_data(checkout_request: &CheckoutRequest) -> String {
fn get_customer( fn get_customer(
item: &types::PaymentsAuthorizeRouterData, item: &types::PaymentsAuthorizeRouterData,
ip: IpAddr, ip: Secret<String, pii::IpAddress>,
) -> Result<ZenCustomerDetails, error_stack::Report<errors::ConnectorError>> { ) -> Result<ZenCustomerDetails, error_stack::Report<errors::ConnectorError>> {
Ok(ZenCustomerDetails { Ok(ZenCustomerDetails {
email: item.request.get_email()?, email: item.request.get_email()?,