mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-29 00:49:42 +08:00 
			
		
		
		
	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:
		| @ -4707,6 +4707,93 @@ impl Default for super::settings::RequiredFields { | ||||
|                                         ), | ||||
|                                         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(), | ||||
|                                     } | ||||
|                                 ) | ||||
|                             ]), | ||||
|                         }, | ||||
|  | ||||
| @ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; | ||||
|  | ||||
| use crate::{ | ||||
|     connector::utils::{ | ||||
|         self, AddressDetailsData, CardData, PaymentsAuthorizeRequestData, | ||||
|         self, AddressDetailsData, ApplePayDecrypt, CardData, PaymentsAuthorizeRequestData, | ||||
|         PaymentsSetupMandateRequestData, PaymentsSyncRequestData, RouterData, | ||||
|     }, | ||||
|     consts, | ||||
| @ -16,6 +16,7 @@ use crate::{ | ||||
|         api::{self, enums as api_enums}, | ||||
|         storage::enums, | ||||
|         transformers::ForeignFrom, | ||||
|         ApplePayPredecryptData, | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| @ -207,6 +208,22 @@ pub struct CardPaymentInformation { | ||||
|     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)] | ||||
| #[serde(rename_all = "camelCase")] | ||||
| pub struct FluidData { | ||||
| @ -224,6 +241,7 @@ pub struct GooglePayPaymentInformation { | ||||
| pub enum PaymentInformation { | ||||
|     Cards(CardPaymentInformation), | ||||
|     GooglePay(GooglePayPaymentInformation), | ||||
|     ApplePay(ApplePayPaymentInformation), | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||||
| @ -295,6 +313,12 @@ pub enum PaymentSolution { | ||||
|     GooglePay, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Serialize)] | ||||
| pub enum TransactionType { | ||||
|     #[serde(rename = "1")] | ||||
|     ApplePay, | ||||
| } | ||||
|  | ||||
| impl From<PaymentSolution> for String { | ||||
|     fn from(solution: PaymentSolution) -> Self { | ||||
|         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 | ||||
|     TryFrom<( | ||||
|         &CybersourceRouterData<&types::PaymentsAuthorizeRouterData>, | ||||
| @ -526,11 +591,21 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>> | ||||
|         match item.router_data.request.payment_method_data.clone() { | ||||
|             payments::PaymentMethodData::Card(ccard) => Self::try_from((item, ccard)), | ||||
|             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) => { | ||||
|                     Self::try_from((item, google_pay_data)) | ||||
|                 } | ||||
|                 payments::WalletData::ApplePay(_) | ||||
|                 | payments::WalletData::AliPayQr(_) | ||||
|                 payments::WalletData::AliPayQr(_) | ||||
|                 | payments::WalletData::AliPayRedirect(_) | ||||
|                 | payments::WalletData::AliPayHkRedirect(_) | ||||
|                 | payments::WalletData::MomoRedirect(_) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 DEEPANSHU BANSAL
					DEEPANSHU BANSAL