feat(connector): [CYBERSOURCE] Implement Apple Pay (#3149)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
DEEPANSHU BANSAL
2023-12-17 14:10:50 +05:30
committed by GitHub
parent 107c66fec3
commit 5f53d84a8b
2 changed files with 165 additions and 3 deletions

View File

@ -4707,6 +4707,93 @@ impl Default for super::settings::RequiredFields {
), ),
common: HashMap::new(), common: HashMap::new(),
} }
),
(
enums::Connector::Cybersource,
RequiredFieldFinal {
mandate: HashMap::new(),
non_mandate: HashMap::from(
[
(
"email".to_string(),
RequiredFieldInfo {
required_field: "email".to_string(),
display_name: "email".to_string(),
field_type: enums::FieldType::UserEmailAddress,
value: None,
}
),
(
"billing.address.first_name".to_string(),
RequiredFieldInfo {
required_field: "billing.address.first_name".to_string(),
display_name: "billing_first_name".to_string(),
field_type: enums::FieldType::UserBillingName,
value: None,
}
),
(
"billing.address.last_name".to_string(),
RequiredFieldInfo {
required_field: "billing.address.last_name".to_string(),
display_name: "billing_last_name".to_string(),
field_type: enums::FieldType::UserBillingName,
value: None,
}
),
(
"billing.address.city".to_string(),
RequiredFieldInfo {
required_field: "billing.address.city".to_string(),
display_name: "city".to_string(),
field_type: enums::FieldType::UserAddressCity,
value: None,
}
),
(
"billing.address.state".to_string(),
RequiredFieldInfo {
required_field: "billing.address.state".to_string(),
display_name: "state".to_string(),
field_type: enums::FieldType::UserAddressState,
value: None,
}
),
(
"billing.address.zip".to_string(),
RequiredFieldInfo {
required_field: "billing.address.zip".to_string(),
display_name: "zip".to_string(),
field_type: enums::FieldType::UserAddressPincode,
value: None,
}
),
(
"billing.address.country".to_string(),
RequiredFieldInfo {
required_field: "billing.address.country".to_string(),
display_name: "country".to_string(),
field_type: enums::FieldType::UserAddressCountry{
options: vec![
"ALL".to_string(),
]
},
value: None,
}
),
(
"billing.address.line1".to_string(),
RequiredFieldInfo {
required_field: "billing.address.line1".to_string(),
display_name: "line1".to_string(),
field_type: enums::FieldType::UserAddressLine1,
value: None,
}
),
]
),
common: HashMap::new(),
}
) )
]), ]),
}, },

View File

@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
connector::utils::{ connector::utils::{
self, AddressDetailsData, CardData, PaymentsAuthorizeRequestData, self, AddressDetailsData, ApplePayDecrypt, CardData, PaymentsAuthorizeRequestData,
PaymentsSetupMandateRequestData, PaymentsSyncRequestData, RouterData, PaymentsSetupMandateRequestData, PaymentsSyncRequestData, RouterData,
}, },
consts, consts,
@ -16,6 +16,7 @@ use crate::{
api::{self, enums as api_enums}, api::{self, enums as api_enums},
storage::enums, storage::enums,
transformers::ForeignFrom, transformers::ForeignFrom,
ApplePayPredecryptData,
}, },
}; };
@ -207,6 +208,22 @@ pub struct CardPaymentInformation {
instrument_identifier: Option<CybersoucreInstrumentIdentifier>, instrument_identifier: Option<CybersoucreInstrumentIdentifier>,
} }
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TokenizedCard {
number: Secret<String>,
expiration_month: Secret<String>,
expiration_year: Secret<String>,
cryptogram: Secret<String>,
transaction_type: TransactionType,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ApplePayPaymentInformation {
tokenized_card: TokenizedCard,
}
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct FluidData { pub struct FluidData {
@ -224,6 +241,7 @@ pub struct GooglePayPaymentInformation {
pub enum PaymentInformation { pub enum PaymentInformation {
Cards(CardPaymentInformation), Cards(CardPaymentInformation),
GooglePay(GooglePayPaymentInformation), GooglePay(GooglePayPaymentInformation),
ApplePay(ApplePayPaymentInformation),
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@ -295,6 +313,12 @@ pub enum PaymentSolution {
GooglePay, GooglePay,
} }
#[derive(Debug, Serialize)]
pub enum TransactionType {
#[serde(rename = "1")]
ApplePay,
}
impl From<PaymentSolution> for String { impl From<PaymentSolution> for String {
fn from(solution: PaymentSolution) -> Self { fn from(solution: PaymentSolution) -> Self {
let payment_solution = match solution { let payment_solution = match solution {
@ -478,6 +502,47 @@ impl
} }
} }
impl
TryFrom<(
&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>,
Box<ApplePayPredecryptData>,
)> for CybersourcePaymentsRequest
{
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(
(item, apple_pay_data): (
&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>,
Box<ApplePayPredecryptData>,
),
) -> Result<Self, Self::Error> {
let email = item.router_data.request.get_email()?;
let bill_to = build_bill_to(item.router_data.get_billing()?, email)?;
let order_information = OrderInformationWithBill::from((item, bill_to));
let processing_information =
ProcessingInformation::from((item, Some(PaymentSolution::ApplePay)));
let client_reference_information = ClientReferenceInformation::from(item);
let expiration_month = apple_pay_data.get_expiry_month()?;
let expiration_year = apple_pay_data.get_four_digit_expiry_year()?;
let payment_information = PaymentInformation::ApplePay(ApplePayPaymentInformation {
tokenized_card: TokenizedCard {
number: apple_pay_data.application_primary_account_number,
cryptogram: apple_pay_data.payment_data.online_payment_cryptogram,
transaction_type: TransactionType::ApplePay,
expiration_year,
expiration_month,
},
});
Ok(Self {
processing_information,
payment_information,
order_information,
client_reference_information,
})
}
}
impl impl
TryFrom<( TryFrom<(
&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>, &CybersourceRouterData<&types::PaymentsAuthorizeRouterData>,
@ -526,11 +591,21 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>>
match item.router_data.request.payment_method_data.clone() { match item.router_data.request.payment_method_data.clone() {
payments::PaymentMethodData::Card(ccard) => Self::try_from((item, ccard)), payments::PaymentMethodData::Card(ccard) => Self::try_from((item, ccard)),
payments::PaymentMethodData::Wallet(wallet_data) => match wallet_data { payments::PaymentMethodData::Wallet(wallet_data) => match wallet_data {
payments::WalletData::ApplePay(_) => {
let payment_method_token = item.router_data.get_payment_method_token()?;
match payment_method_token {
types::PaymentMethodToken::ApplePayDecrypt(decrypt_data) => {
Self::try_from((item, decrypt_data))
}
types::PaymentMethodToken::Token(_) => {
Err(errors::ConnectorError::InvalidWalletToken)?
}
}
}
payments::WalletData::GooglePay(google_pay_data) => { payments::WalletData::GooglePay(google_pay_data) => {
Self::try_from((item, google_pay_data)) Self::try_from((item, google_pay_data))
} }
payments::WalletData::ApplePay(_) payments::WalletData::AliPayQr(_)
| payments::WalletData::AliPayQr(_)
| payments::WalletData::AliPayRedirect(_) | payments::WalletData::AliPayRedirect(_)
| payments::WalletData::AliPayHkRedirect(_) | payments::WalletData::AliPayHkRedirect(_)
| payments::WalletData::MomoRedirect(_) | payments::WalletData::MomoRedirect(_)