mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 10:06:32 +08:00 
			
		
		
		
	feat(connector): [Paysafe] implement Skrill wallet Payment Method (#9396)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
		
							
								
								
									
										3
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
| # This file is automatically @generated by Cargo. | # This file is automatically @generated by Cargo. | ||||||
| # It is not intended for manual editing. | # It is not intended for manual editing. | ||||||
| version = 3 | version = 4 | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "actix-codec" | name = "actix-codec" | ||||||
| @ -1970,6 +1970,7 @@ dependencies = [ | |||||||
|  "api_models", |  "api_models", | ||||||
|  "common_utils", |  "common_utils", | ||||||
|  "serde", |  "serde", | ||||||
|  |  "serde_json", | ||||||
|  "serde_with", |  "serde_with", | ||||||
|  "toml 0.8.22", |  "toml 0.8.22", | ||||||
|  "utoipa", |  "utoipa", | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ common_utils = { version = "0.1.0", path = "../common_utils" } | |||||||
|  |  | ||||||
| # Third party crates | # Third party crates | ||||||
| serde = { version = "1.0.219", features = ["derive"] } | serde = { version = "1.0.219", features = ["derive"] } | ||||||
|  | serde_json = "1.0.140" | ||||||
| serde_with = "3.12.0" | serde_with = "3.12.0" | ||||||
| toml = "0.8.22" | toml = "0.8.22" | ||||||
| utoipa = { version = "4.2.3", features = ["preserve_order", "preserve_path_order"] } | utoipa = { version = "4.2.3", features = ["preserve_order", "preserve_path_order"] } | ||||||
|  | |||||||
| @ -110,7 +110,7 @@ pub struct ApiModelMetaData { | |||||||
|     pub merchant_configuration_id: Option<String>, |     pub merchant_configuration_id: Option<String>, | ||||||
|     pub tenant_id: Option<String>, |     pub tenant_id: Option<String>, | ||||||
|     pub platform_url: Option<String>, |     pub platform_url: Option<String>, | ||||||
|     pub account_id: Option<String>, |     pub account_id: Option<serde_json::Value>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[serde_with::skip_serializing_none] | #[serde_with::skip_serializing_none] | ||||||
|  | |||||||
| @ -115,10 +115,19 @@ pub struct AccountIdConfigForCard { | |||||||
|     pub no_three_ds: Option<Vec<InputData>>, |     pub no_three_ds: Option<Vec<InputData>>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[serde_with::skip_serializing_none] | ||||||
|  | #[derive(Debug, Deserialize, Serialize, Clone)] | ||||||
|  | pub struct AccountIdConfigForRedirect { | ||||||
|  |     pub three_ds: Option<Vec<InputData>>, | ||||||
|  | } | ||||||
|  |  | ||||||
| #[serde_with::skip_serializing_none] | #[serde_with::skip_serializing_none] | ||||||
| #[derive(Debug, Deserialize, Serialize, Clone)] | #[derive(Debug, Deserialize, Serialize, Clone)] | ||||||
| pub struct AccountIDSupportedMethods { | pub struct AccountIDSupportedMethods { | ||||||
|     card: HashMap<String, AccountIdConfigForCard>, |     card: HashMap<String, AccountIdConfigForCard>, | ||||||
|  |     skrill: HashMap<String, AccountIdConfigForRedirect>, | ||||||
|  |     interac: HashMap<String, AccountIdConfigForRedirect>, | ||||||
|  |     pay_safe_card: HashMap<String, AccountIdConfigForRedirect>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[serde_with::skip_serializing_none] | #[serde_with::skip_serializing_none] | ||||||
|  | |||||||
| @ -6863,29 +6863,71 @@ key1 = "Password" | |||||||
| [paysafe.connector_webhook_details] | [paysafe.connector_webhook_details] | ||||||
| merchant_secret = "Source verification key" | merchant_secret = "Source verification key" | ||||||
| [[paysafe.metadata.account_id.card.USD.three_ds]] | [[paysafe.metadata.account_id.card.USD.three_ds]] | ||||||
| name="account_id" | name="three_ds" | ||||||
| label="ThreeDS account id" | label="ThreeDS account id" | ||||||
| placeholder="Enter ThreeDS Account ID" | placeholder="Enter ThreeDS Account ID" | ||||||
| required=true | required=true | ||||||
| type="Number" | type="Text" | ||||||
| [[paysafe.metadata.account_id.card.USD.no_three_ds]] | [[paysafe.metadata.account_id.card.USD.no_three_ds]] | ||||||
| name="no_three_ds" | name="no_three_ds" | ||||||
| label="Non ThreeDS account id" | label="Non ThreeDS account id" | ||||||
| placeholder="Enter Non ThreeDS Account ID" | placeholder="Enter Non ThreeDS Account ID" | ||||||
| required=true | required=true | ||||||
| type="Number" | type="Text" | ||||||
| [[paysafe.metadata.account_id.card.EUR.three_ds]] | [[paysafe.metadata.account_id.card.EUR.three_ds]] | ||||||
| name="account_id" | name="three_ds" | ||||||
| label="ThreeDS account id" | label="ThreeDS account id" | ||||||
| placeholder="Enter ThreeDS Account ID" | placeholder="Enter ThreeDS Account ID" | ||||||
| required=true | required=true | ||||||
| type="Number" | type="Text" | ||||||
| [[paysafe.metadata.account_id.card.EUR.no_three_ds]] | [[paysafe.metadata.account_id.card.EUR.no_three_ds]] | ||||||
| name="no_three_ds" | name="no_three_ds" | ||||||
| label="Non ThreeDS account id" | label="Non ThreeDS account id" | ||||||
| placeholder="Enter Non ThreeDS Account ID" | placeholder="Enter Non ThreeDS Account ID" | ||||||
| required=true | required=true | ||||||
| type="Number" | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.interac.CAD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="CAD" | ||||||
|  | placeholder="Enter cad Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.skrill.USD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="USD" | ||||||
|  | placeholder="Enter usd Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.skrill.CAD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="CAD" | ||||||
|  | placeholder="Enter cad Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.skrill.EUR.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="EUR" | ||||||
|  | placeholder="Enter eur Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.pay_safe_card.USD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="USD" | ||||||
|  | placeholder="Enter usd Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.pay_safe_card.CAD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="CAD" | ||||||
|  | placeholder="Enter cad Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.pay_safe_card.EUR.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="EUR" | ||||||
|  | placeholder="Enter eur Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  |  | ||||||
| [peachpayments] | [peachpayments] | ||||||
| [[peachpayments.credit]] | [[peachpayments.credit]] | ||||||
|  | |||||||
| @ -5532,29 +5532,71 @@ key1 = "Password" | |||||||
| [paysafe.connector_webhook_details] | [paysafe.connector_webhook_details] | ||||||
| merchant_secret = "Source verification key" | merchant_secret = "Source verification key" | ||||||
| [[paysafe.metadata.account_id.card.USD.three_ds]] | [[paysafe.metadata.account_id.card.USD.three_ds]] | ||||||
| name="account_id" | name="three_ds" | ||||||
| label="ThreeDS account id" | label="ThreeDS account id" | ||||||
| placeholder="Enter ThreeDS Account ID" | placeholder="Enter ThreeDS Account ID" | ||||||
| required=true | required=true | ||||||
| type="Number" | type="Text" | ||||||
| [[paysafe.metadata.account_id.card.USD.no_three_ds]] | [[paysafe.metadata.account_id.card.USD.no_three_ds]] | ||||||
| name="no_three_ds" | name="no_three_ds" | ||||||
| label="Non ThreeDS account id" | label="Non ThreeDS account id" | ||||||
| placeholder="Enter Non ThreeDS Account ID" | placeholder="Enter Non ThreeDS Account ID" | ||||||
| required=true | required=true | ||||||
| type="Number" | type="Text" | ||||||
| [[paysafe.metadata.account_id.card.EUR.three_ds]] | [[paysafe.metadata.account_id.card.EUR.three_ds]] | ||||||
| name="account_id" | name="three_ds" | ||||||
| label="ThreeDS account id" | label="ThreeDS account id" | ||||||
| placeholder="Enter ThreeDS Account ID" | placeholder="Enter ThreeDS Account ID" | ||||||
| required=true | required=true | ||||||
| type="Number" | type="Text" | ||||||
| [[paysafe.metadata.account_id.card.EUR.no_three_ds]] | [[paysafe.metadata.account_id.card.EUR.no_three_ds]] | ||||||
| name="no_three_ds" | name="no_three_ds" | ||||||
| label="Non ThreeDS account id" | label="Non ThreeDS account id" | ||||||
| placeholder="Enter Non ThreeDS Account ID" | placeholder="Enter Non ThreeDS Account ID" | ||||||
| required=true | required=true | ||||||
| type="Number" | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.interac.CAD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="CAD" | ||||||
|  | placeholder="Enter cad Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.skrill.USD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="USD" | ||||||
|  | placeholder="Enter usd Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.skrill.CAD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="CAD" | ||||||
|  | placeholder="Enter cad Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.skrill.EUR.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="EUR" | ||||||
|  | placeholder="Enter eur Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.pay_safe_card.USD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="USD" | ||||||
|  | placeholder="Enter usd Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.pay_safe_card.CAD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="CAD" | ||||||
|  | placeholder="Enter cad Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.pay_safe_card.EUR.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="EUR" | ||||||
|  | placeholder="Enter eur Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  |  | ||||||
| [peachpayments] | [peachpayments] | ||||||
| [[peachpayments.credit]] | [[peachpayments.credit]] | ||||||
|  | |||||||
| @ -6843,29 +6843,71 @@ key1 = "Password" | |||||||
| [paysafe.connector_webhook_details] | [paysafe.connector_webhook_details] | ||||||
| merchant_secret = "Source verification key" | merchant_secret = "Source verification key" | ||||||
| [[paysafe.metadata.account_id.card.USD.three_ds]] | [[paysafe.metadata.account_id.card.USD.three_ds]] | ||||||
| name="account_id" | name="three_ds" | ||||||
| label="ThreeDS account id" | label="ThreeDS account id" | ||||||
| placeholder="Enter ThreeDS Account ID" | placeholder="Enter ThreeDS Account ID" | ||||||
| required=true | required=true | ||||||
| type="Number" | type="Text" | ||||||
| [[paysafe.metadata.account_id.card.USD.no_three_ds]] | [[paysafe.metadata.account_id.card.USD.no_three_ds]] | ||||||
| name="no_three_ds" | name="no_three_ds" | ||||||
| label="Non ThreeDS account id" | label="Non ThreeDS account id" | ||||||
| placeholder="Enter Non ThreeDS Account ID" | placeholder="Enter Non ThreeDS Account ID" | ||||||
| required=true | required=true | ||||||
| type="Number" | type="Text" | ||||||
| [[paysafe.metadata.account_id.card.EUR.three_ds]] | [[paysafe.metadata.account_id.card.EUR.three_ds]] | ||||||
| name="account_id" | name="three_ds" | ||||||
| label="ThreeDS account id" | label="ThreeDS account id" | ||||||
| placeholder="Enter ThreeDS Account ID" | placeholder="Enter ThreeDS Account ID" | ||||||
| required=true | required=true | ||||||
| type="Number" | type="Text" | ||||||
| [[paysafe.metadata.account_id.card.EUR.no_three_ds]] | [[paysafe.metadata.account_id.card.EUR.no_three_ds]] | ||||||
| name="no_three_ds" | name="no_three_ds" | ||||||
| label="Non ThreeDS account id" | label="Non ThreeDS account id" | ||||||
| placeholder="Enter Non ThreeDS Account ID" | placeholder="Enter Non ThreeDS Account ID" | ||||||
| required=true | required=true | ||||||
| type="Number" | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.interac.CAD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="CAD" | ||||||
|  | placeholder="Enter cad Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.skrill.USD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="USD" | ||||||
|  | placeholder="Enter usd Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.skrill.CAD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="CAD" | ||||||
|  | placeholder="Enter cad Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.skrill.EUR.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="EUR" | ||||||
|  | placeholder="Enter eur Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.pay_safe_card.USD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="USD" | ||||||
|  | placeholder="Enter usd Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.pay_safe_card.CAD.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="CAD" | ||||||
|  | placeholder="Enter cad Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  | [[paysafe.metadata.account_id.pay_safe_card.EUR.three_ds]] | ||||||
|  | name="three_ds" | ||||||
|  | label="EUR" | ||||||
|  | placeholder="Enter eur Account ID" | ||||||
|  | required=true | ||||||
|  | type="Text" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -975,6 +975,7 @@ static PAYSAFE_SUPPORTED_PAYMENT_METHODS: LazyLock<SupportedPaymentMethods> = La | |||||||
|         enums::CaptureMethod::Automatic, |         enums::CaptureMethod::Automatic, | ||||||
|         enums::CaptureMethod::Manual, |         enums::CaptureMethod::Manual, | ||||||
|     ]; |     ]; | ||||||
|  |     let supported_capture_methods2 = vec![enums::CaptureMethod::Automatic]; | ||||||
|  |  | ||||||
|     let supported_card_network = vec![ |     let supported_card_network = vec![ | ||||||
|         common_enums::CardNetwork::Mastercard, |         common_enums::CardNetwork::Mastercard, | ||||||
| @ -1028,6 +1029,39 @@ static PAYSAFE_SUPPORTED_PAYMENT_METHODS: LazyLock<SupportedPaymentMethods> = La | |||||||
|         }, |         }, | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|  |     paysafe_supported_payment_methods.add( | ||||||
|  |         enums::PaymentMethod::Wallet, | ||||||
|  |         enums::PaymentMethodType::Skrill, | ||||||
|  |         PaymentMethodDetails { | ||||||
|  |             mandates: enums::FeatureStatus::NotSupported, | ||||||
|  |             refunds: enums::FeatureStatus::Supported, | ||||||
|  |             supported_capture_methods: supported_capture_methods2.clone(), | ||||||
|  |             specific_features: None, | ||||||
|  |         }, | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     paysafe_supported_payment_methods.add( | ||||||
|  |         enums::PaymentMethod::BankRedirect, | ||||||
|  |         enums::PaymentMethodType::Interac, | ||||||
|  |         PaymentMethodDetails { | ||||||
|  |             mandates: enums::FeatureStatus::NotSupported, | ||||||
|  |             refunds: enums::FeatureStatus::Supported, | ||||||
|  |             supported_capture_methods: supported_capture_methods2.clone(), | ||||||
|  |             specific_features: None, | ||||||
|  |         }, | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     paysafe_supported_payment_methods.add( | ||||||
|  |         enums::PaymentMethod::GiftCard, | ||||||
|  |         enums::PaymentMethodType::PaySafeCard, | ||||||
|  |         PaymentMethodDetails { | ||||||
|  |             mandates: enums::FeatureStatus::NotSupported, | ||||||
|  |             refunds: enums::FeatureStatus::Supported, | ||||||
|  |             supported_capture_methods: supported_capture_methods2.clone(), | ||||||
|  |             specific_features: None, | ||||||
|  |         }, | ||||||
|  |     ); | ||||||
|  |  | ||||||
|     paysafe_supported_payment_methods |     paysafe_supported_payment_methods | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | |||||||
| @ -3,13 +3,14 @@ use std::collections::HashMap; | |||||||
| use cards::CardNumber; | use cards::CardNumber; | ||||||
| use common_enums::{enums, Currency}; | use common_enums::{enums, Currency}; | ||||||
| use common_utils::{ | use common_utils::{ | ||||||
|     pii::{IpAddress, SecretSerdeValue}, |     id_type, | ||||||
|  |     pii::{Email, IpAddress, SecretSerdeValue}, | ||||||
|     request::Method, |     request::Method, | ||||||
|     types::MinorUnit, |     types::MinorUnit, | ||||||
| }; | }; | ||||||
| use error_stack::ResultExt; | use error_stack::ResultExt; | ||||||
| use hyperswitch_domain_models::{ | use hyperswitch_domain_models::{ | ||||||
|     payment_method_data::PaymentMethodData, |     payment_method_data::{BankRedirectData, GiftCardData, PaymentMethodData, WalletData}, | ||||||
|     router_data::{ConnectorAuthType, RouterData}, |     router_data::{ConnectorAuthType, RouterData}, | ||||||
|     router_flow_types::refunds::{Execute, RSync}, |     router_flow_types::refunds::{Execute, RSync}, | ||||||
|     router_request_types::{ |     router_request_types::{ | ||||||
| @ -56,6 +57,9 @@ pub struct PaysafeConnectorMetadataObject { | |||||||
| #[derive(Debug, Default, Serialize, Deserialize)] | #[derive(Debug, Default, Serialize, Deserialize)] | ||||||
| pub struct PaysafePaymentMethodDetails { | pub struct PaysafePaymentMethodDetails { | ||||||
|     pub card: Option<HashMap<Currency, CardAccountId>>, |     pub card: Option<HashMap<Currency, CardAccountId>>, | ||||||
|  |     pub skrill: Option<HashMap<Currency, RedirectAccountId>>, | ||||||
|  |     pub interac: Option<HashMap<Currency, RedirectAccountId>>, | ||||||
|  |     pub pay_safe_card: Option<HashMap<Currency, RedirectAccountId>>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Serialize, Deserialize)] | #[derive(Debug, Default, Serialize, Deserialize)] | ||||||
| @ -64,6 +68,11 @@ pub struct CardAccountId { | |||||||
|     three_ds: Option<Secret<String>>, |     three_ds: Option<Secret<String>>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, Default, Serialize, Deserialize)] | ||||||
|  | pub struct RedirectAccountId { | ||||||
|  |     three_ds: Option<Secret<String>>, | ||||||
|  | } | ||||||
|  |  | ||||||
| impl TryFrom<&Option<SecretSerdeValue>> for PaysafeConnectorMetadataObject { | impl TryFrom<&Option<SecretSerdeValue>> for PaysafeConnectorMetadataObject { | ||||||
|     type Error = error_stack::Report<errors::ConnectorError>; |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|     fn try_from(meta_data: &Option<SecretSerdeValue>) -> Result<Self, Self::Error> { |     fn try_from(meta_data: &Option<SecretSerdeValue>) -> Result<Self, Self::Error> { | ||||||
| @ -127,13 +136,54 @@ pub struct PaysafePaymentHandleRequest { | |||||||
|     pub return_links: Vec<ReturnLink>, |     pub return_links: Vec<ReturnLink>, | ||||||
|     pub account_id: Secret<String>, |     pub account_id: Secret<String>, | ||||||
|     pub three_ds: Option<ThreeDs>, |     pub three_ds: Option<ThreeDs>, | ||||||
|  |     pub profile: Option<PaysafeProfile>, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, Serialize, Clone, PartialEq)] | ||||||
|  | #[serde(rename_all = "camelCase")] | ||||||
|  | pub struct PaysafeProfile { | ||||||
|  |     pub first_name: Secret<String>, | ||||||
|  |     pub last_name: Secret<String>, | ||||||
|  |     pub email: Email, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Serialize)] | #[derive(Debug, Serialize)] | ||||||
| #[serde(rename_all = "camelCase")] | #[serde(rename_all = "camelCase")] | ||||||
| #[serde(untagged)] | #[serde(untagged)] | ||||||
| pub enum PaysafePaymentMethod { | pub enum PaysafePaymentMethod { | ||||||
|     Card { card: PaysafeCard }, |     Card { | ||||||
|  |         card: PaysafeCard, | ||||||
|  |     }, | ||||||
|  |     Skrill { | ||||||
|  |         skrill: SkrillWallet, | ||||||
|  |     }, | ||||||
|  |     Interac { | ||||||
|  |         #[serde(rename = "interacEtransfer")] | ||||||
|  |         interac_etransfer: InteracBankRedirect, | ||||||
|  |     }, | ||||||
|  |     PaysafeCard { | ||||||
|  |         #[serde(rename = "paysafecard")] | ||||||
|  |         pay_safe_card: PaysafeGiftCard, | ||||||
|  |     }, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, Serialize, Clone, PartialEq)] | ||||||
|  | #[serde(rename_all = "camelCase")] | ||||||
|  | pub struct SkrillWallet { | ||||||
|  |     pub consumer_id: Email, | ||||||
|  |     pub country_code: Option<api_models::enums::CountryAlpha2>, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, Serialize, Clone, PartialEq)] | ||||||
|  | #[serde(rename_all = "camelCase")] | ||||||
|  | pub struct InteracBankRedirect { | ||||||
|  |     pub consumer_id: Email, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, Serialize, Clone, PartialEq)] | ||||||
|  | #[serde(rename_all = "camelCase")] | ||||||
|  | pub struct PaysafeGiftCard { | ||||||
|  |     pub consumer_id: id_type::CustomerId, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Serialize)] | #[derive(Debug, Serialize)] | ||||||
| @ -153,9 +203,12 @@ pub enum LinkType { | |||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Serialize)] | #[derive(Debug, Serialize)] | ||||||
|  | #[serde(rename_all = "SCREAMING_SNAKE_CASE")] | ||||||
| pub enum PaysafePaymentType { | pub enum PaysafePaymentType { | ||||||
|     #[serde(rename = "CARD")] |  | ||||||
|     Card, |     Card, | ||||||
|  |     Skrill, | ||||||
|  |     InteracEtransfer, | ||||||
|  |     Paysafecard, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Serialize)] | #[derive(Debug, Serialize)] | ||||||
| @ -173,7 +226,7 @@ impl PaysafePaymentMethodDetails { | |||||||
|             .as_ref() |             .as_ref() | ||||||
|             .and_then(|cards| cards.get(¤cy)) |             .and_then(|cards| cards.get(¤cy)) | ||||||
|             .and_then(|card| card.no_three_ds.clone()) |             .and_then(|card| card.no_three_ds.clone()) | ||||||
|             .ok_or_else(|| errors::ConnectorError::InvalidConnectorConfig { |             .ok_or(errors::ConnectorError::InvalidConnectorConfig { | ||||||
|                 config: "Missing no_3ds account_id", |                 config: "Missing no_3ds account_id", | ||||||
|             }) |             }) | ||||||
|     } |     } | ||||||
| @ -186,10 +239,49 @@ impl PaysafePaymentMethodDetails { | |||||||
|             .as_ref() |             .as_ref() | ||||||
|             .and_then(|cards| cards.get(¤cy)) |             .and_then(|cards| cards.get(¤cy)) | ||||||
|             .and_then(|card| card.three_ds.clone()) |             .and_then(|card| card.three_ds.clone()) | ||||||
|             .ok_or_else(|| errors::ConnectorError::InvalidConnectorConfig { |             .ok_or(errors::ConnectorError::InvalidConnectorConfig { | ||||||
|                 config: "Missing 3ds account_id", |                 config: "Missing 3ds account_id", | ||||||
|             }) |             }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     pub fn get_skrill_account_id( | ||||||
|  |         &self, | ||||||
|  |         currency: Currency, | ||||||
|  |     ) -> Result<Secret<String>, errors::ConnectorError> { | ||||||
|  |         self.skrill | ||||||
|  |             .as_ref() | ||||||
|  |             .and_then(|wallets| wallets.get(¤cy)) | ||||||
|  |             .and_then(|skrill| skrill.three_ds.clone()) | ||||||
|  |             .ok_or(errors::ConnectorError::InvalidConnectorConfig { | ||||||
|  |                 config: "Missing skrill account_id", | ||||||
|  |             }) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     pub fn get_interac_account_id( | ||||||
|  |         &self, | ||||||
|  |         currency: Currency, | ||||||
|  |     ) -> Result<Secret<String>, errors::ConnectorError> { | ||||||
|  |         self.interac | ||||||
|  |             .as_ref() | ||||||
|  |             .and_then(|redirects| redirects.get(¤cy)) | ||||||
|  |             .and_then(|interac| interac.three_ds.clone()) | ||||||
|  |             .ok_or(errors::ConnectorError::InvalidConnectorConfig { | ||||||
|  |                 config: "Missing interac account_id", | ||||||
|  |             }) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     pub fn get_paysafe_gift_card_account_id( | ||||||
|  |         &self, | ||||||
|  |         currency: Currency, | ||||||
|  |     ) -> Result<Secret<String>, errors::ConnectorError> { | ||||||
|  |         self.pay_safe_card | ||||||
|  |             .as_ref() | ||||||
|  |             .and_then(|gift_cards| gift_cards.get(¤cy)) | ||||||
|  |             .and_then(|pay_safe_card| pay_safe_card.three_ds.clone()) | ||||||
|  |             .ok_or(errors::ConnectorError::InvalidConnectorConfig { | ||||||
|  |                 config: "Missing paysafe gift card account_id", | ||||||
|  |             }) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl TryFrom<&PaysafeRouterData<&PaymentsPreProcessingRouterData>> for PaysafePaymentHandleRequest { | impl TryFrom<&PaysafeRouterData<&PaymentsPreProcessingRouterData>> for PaysafePaymentHandleRequest { | ||||||
| @ -268,6 +360,7 @@ impl TryFrom<&PaysafeRouterData<&PaymentsPreProcessingRouterData>> for PaysafePa | |||||||
|                     return_links, |                     return_links, | ||||||
|                     account_id, |                     account_id, | ||||||
|                     three_ds: None, |                     three_ds: None, | ||||||
|  |                     profile: None, | ||||||
|                 }) |                 }) | ||||||
|             } |             } | ||||||
|             _ => Err(errors::ConnectorError::NotImplemented( |             _ => Err(errors::ConnectorError::NotImplemented( | ||||||
| @ -303,6 +396,7 @@ pub enum PaysafePaymentHandleStatus { | |||||||
|     Failed, |     Failed, | ||||||
|     Expired, |     Expired, | ||||||
|     Completed, |     Completed, | ||||||
|  |     Error, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl TryFrom<PaysafePaymentHandleStatus> for common_enums::AttemptStatus { | impl TryFrom<PaysafePaymentHandleStatus> for common_enums::AttemptStatus { | ||||||
| @ -310,9 +404,9 @@ impl TryFrom<PaysafePaymentHandleStatus> for common_enums::AttemptStatus { | |||||||
|     fn try_from(item: PaysafePaymentHandleStatus) -> Result<Self, Self::Error> { |     fn try_from(item: PaysafePaymentHandleStatus) -> Result<Self, Self::Error> { | ||||||
|         match item { |         match item { | ||||||
|             PaysafePaymentHandleStatus::Completed => Ok(Self::Authorized), |             PaysafePaymentHandleStatus::Completed => Ok(Self::Authorized), | ||||||
|             PaysafePaymentHandleStatus::Failed | PaysafePaymentHandleStatus::Expired => { |             PaysafePaymentHandleStatus::Failed | ||||||
|                 Ok(Self::Failure) |             | PaysafePaymentHandleStatus::Expired | ||||||
|             } |             | PaysafePaymentHandleStatus::Error => Ok(Self::Failure), | ||||||
|             // We get an `Initiated` status, with a redirection link from the connector, which indicates that further action is required by the customer, |             // We get an `Initiated` status, with a redirection link from the connector, which indicates that further action is required by the customer, | ||||||
|             PaysafePaymentHandleStatus::Initiated => Ok(Self::AuthenticationPending), |             PaysafePaymentHandleStatus::Initiated => Ok(Self::AuthenticationPending), | ||||||
|             PaysafePaymentHandleStatus::Payable | PaysafePaymentHandleStatus::Processing => { |             PaysafePaymentHandleStatus::Payable | PaysafePaymentHandleStatus::Processing => { | ||||||
| @ -544,60 +638,118 @@ impl TryFrom<&PaysafeRouterData<&PaymentsAuthorizeRouterData>> for PaysafePaymen | |||||||
|             Some(enums::CaptureMethod::Automatic) | None |             Some(enums::CaptureMethod::Automatic) | None | ||||||
|         ); |         ); | ||||||
|         let transaction_type = TransactionType::Payment; |         let transaction_type = TransactionType::Payment; | ||||||
|         match item.router_data.request.payment_method_data.clone() { |         let (payment_method, payment_type, account_id, three_ds, profile) = | ||||||
|             PaymentMethodData::Card(req_card) => { |             match item.router_data.request.payment_method_data.clone() { | ||||||
|                 let card = PaysafeCard { |                 PaymentMethodData::Card(req_card) => { | ||||||
|                     card_num: req_card.card_number.clone(), |                     let card = PaysafeCard { | ||||||
|                     card_expiry: PaysafeCardExpiry { |                         card_num: req_card.card_number.clone(), | ||||||
|                         month: req_card.card_exp_month.clone(), |                         card_expiry: PaysafeCardExpiry { | ||||||
|                         year: req_card.get_expiry_year_4_digit(), |                             month: req_card.card_exp_month.clone(), | ||||||
|                     }, |                             year: req_card.get_expiry_year_4_digit(), | ||||||
|                     cvv: if req_card.card_cvc.clone().expose().is_empty() { |                         }, | ||||||
|                         None |                         cvv: if req_card.card_cvc.clone().expose().is_empty() { | ||||||
|                     } else { |                             None | ||||||
|                         Some(req_card.card_cvc.clone()) |                         } else { | ||||||
|                     }, |                             Some(req_card.card_cvc.clone()) | ||||||
|                     holder_name: item.router_data.get_optional_billing_full_name(), |                         }, | ||||||
|                 }; |                         holder_name: item.router_data.get_optional_billing_full_name(), | ||||||
|                 let payment_method = PaysafePaymentMethod::Card { card: card.clone() }; |                     }; | ||||||
|                 let payment_type = PaysafePaymentType::Card; |                     let payment_method = PaysafePaymentMethod::Card { card: card.clone() }; | ||||||
|                 let headers = item.router_data.header_payload.clone(); |                     let payment_type = PaysafePaymentType::Card; | ||||||
|                 let platform = headers |  | ||||||
|                     .as_ref() |  | ||||||
|                     .and_then(|headers| headers.x_client_platform.clone()); |  | ||||||
|                 let device_channel = match platform { |  | ||||||
|                     Some(common_enums::ClientPlatform::Web) |  | ||||||
|                     | Some(common_enums::ClientPlatform::Unknown) |  | ||||||
|                     | None => DeviceChannel::Browser, |  | ||||||
|                     Some(common_enums::ClientPlatform::Ios) |  | ||||||
|                     | Some(common_enums::ClientPlatform::Android) => DeviceChannel::Sdk, |  | ||||||
|                 }; |  | ||||||
|                 let account_id = metadata.account_id.get_three_ds_account_id(currency_code)?; |  | ||||||
|                 let three_ds = Some(ThreeDs { |  | ||||||
|                     merchant_url: item.router_data.request.get_router_return_url()?, |  | ||||||
|                     device_channel, |  | ||||||
|                     message_category: ThreeDsMessageCategory::Payment, |  | ||||||
|                     authentication_purpose: ThreeDsAuthenticationPurpose::PaymentTransaction, |  | ||||||
|                     requestor_challenge_preference: ThreeDsChallengePreference::ChallengeMandated, |  | ||||||
|                 }); |  | ||||||
|  |  | ||||||
|                 Ok(Self { |                     let headers = item.router_data.header_payload.clone(); | ||||||
|                     merchant_ref_num: item.router_data.connector_request_reference_id.clone(), |                     let platform = headers.as_ref().and_then(|h| h.x_client_platform.clone()); | ||||||
|                     amount, |                     let device_channel = match platform { | ||||||
|                     settle_with_auth, |                         Some(common_enums::ClientPlatform::Web) | ||||||
|                     payment_method, |                         | Some(common_enums::ClientPlatform::Unknown) | ||||||
|                     currency_code, |                         | None => DeviceChannel::Browser, | ||||||
|                     payment_type, |                         Some(common_enums::ClientPlatform::Ios) | ||||||
|                     transaction_type, |                         | Some(common_enums::ClientPlatform::Android) => DeviceChannel::Sdk, | ||||||
|                     return_links, |                     }; | ||||||
|                     account_id, |  | ||||||
|                     three_ds, |                     let account_id = metadata.account_id.get_three_ds_account_id(currency_code)?; | ||||||
|                 }) |                     let three_ds = Some(ThreeDs { | ||||||
|             } |                         merchant_url: item.router_data.request.get_router_return_url()?, | ||||||
|             _ => Err(errors::ConnectorError::NotImplemented( |                         device_channel, | ||||||
|                 "Payment Method".to_string(), |                         message_category: ThreeDsMessageCategory::Payment, | ||||||
|             ))?, |                         authentication_purpose: ThreeDsAuthenticationPurpose::PaymentTransaction, | ||||||
|         } |                         requestor_challenge_preference: | ||||||
|  |                             ThreeDsChallengePreference::ChallengeMandated, | ||||||
|  |                     }); | ||||||
|  |  | ||||||
|  |                     (payment_method, payment_type, account_id, three_ds, None) | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 PaymentMethodData::Wallet(WalletData::Skrill(_)) => { | ||||||
|  |                     let payment_method = PaysafePaymentMethod::Skrill { | ||||||
|  |                         skrill: SkrillWallet { | ||||||
|  |                             consumer_id: item.router_data.get_billing_email()?, | ||||||
|  |                             country_code: item.router_data.get_optional_billing_country(), | ||||||
|  |                         }, | ||||||
|  |                     }; | ||||||
|  |                     let payment_type = PaysafePaymentType::Skrill; | ||||||
|  |                     let account_id = metadata.account_id.get_skrill_account_id(currency_code)?; | ||||||
|  |                     (payment_method, payment_type, account_id, None, None) | ||||||
|  |                 } | ||||||
|  |                 PaymentMethodData::Wallet(_) => Err(errors::ConnectorError::NotImplemented( | ||||||
|  |                     "Payment Method".to_string(), | ||||||
|  |                 ))?, | ||||||
|  |  | ||||||
|  |                 PaymentMethodData::BankRedirect(BankRedirectData::Interac { .. }) => { | ||||||
|  |                     let payment_method = PaysafePaymentMethod::Interac { | ||||||
|  |                         interac_etransfer: InteracBankRedirect { | ||||||
|  |                             consumer_id: item.router_data.get_billing_email()?, | ||||||
|  |                         }, | ||||||
|  |                     }; | ||||||
|  |                     let payment_type = PaysafePaymentType::InteracEtransfer; | ||||||
|  |                     let account_id = metadata.account_id.get_interac_account_id(currency_code)?; | ||||||
|  |                     let profile = Some(PaysafeProfile { | ||||||
|  |                         first_name: item.router_data.get_billing_first_name()?, | ||||||
|  |                         last_name: item.router_data.get_billing_last_name()?, | ||||||
|  |                         email: item.router_data.get_billing_email()?, | ||||||
|  |                     }); | ||||||
|  |                     (payment_method, payment_type, account_id, None, profile) | ||||||
|  |                 } | ||||||
|  |                 PaymentMethodData::BankRedirect(_) => Err(errors::ConnectorError::NotImplemented( | ||||||
|  |                     "Payment Method".to_string(), | ||||||
|  |                 ))?, | ||||||
|  |  | ||||||
|  |                 PaymentMethodData::GiftCard(gift_card_data) => match gift_card_data.as_ref() { | ||||||
|  |                     GiftCardData::PaySafeCard {} => { | ||||||
|  |                         let payment_method = PaysafePaymentMethod::PaysafeCard { | ||||||
|  |                             pay_safe_card: PaysafeGiftCard { | ||||||
|  |                                 consumer_id: item.router_data.get_customer_id()?, | ||||||
|  |                             }, | ||||||
|  |                         }; | ||||||
|  |                         let payment_type = PaysafePaymentType::Paysafecard; | ||||||
|  |                         let account_id = metadata | ||||||
|  |                             .account_id | ||||||
|  |                             .get_paysafe_gift_card_account_id(currency_code)?; | ||||||
|  |                         (payment_method, payment_type, account_id, None, None) | ||||||
|  |                     } | ||||||
|  |                     _ => Err(errors::ConnectorError::NotImplemented( | ||||||
|  |                         "Payment Method".to_string(), | ||||||
|  |                     ))?, | ||||||
|  |                 }, | ||||||
|  |  | ||||||
|  |                 _ => Err(errors::ConnectorError::NotImplemented( | ||||||
|  |                     "Payment Method".to_string(), | ||||||
|  |                 ))?, | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |         Ok(Self { | ||||||
|  |             merchant_ref_num: item.router_data.connector_request_reference_id.clone(), | ||||||
|  |             amount, | ||||||
|  |             settle_with_auth, | ||||||
|  |             payment_method, | ||||||
|  |             currency_code, | ||||||
|  |             payment_type, | ||||||
|  |             transaction_type, | ||||||
|  |             return_links, | ||||||
|  |             account_id, | ||||||
|  |             three_ds, | ||||||
|  |             profile, | ||||||
|  |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -750,7 +902,6 @@ pub struct PaysafePaymentsResponse { | |||||||
|     pub id: String, |     pub id: String, | ||||||
|     pub merchant_ref_num: Option<String>, |     pub merchant_ref_num: Option<String>, | ||||||
|     pub status: PaysafePaymentStatus, |     pub status: PaysafePaymentStatus, | ||||||
|     pub settlements: Option<Vec<PaysafeSettlementResponse>>, |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||||
|  | |||||||
| @ -2292,6 +2292,13 @@ fn get_bank_redirect_required_fields( | |||||||
|                 ), |                 ), | ||||||
|             ]), |             ]), | ||||||
|         ), |         ), | ||||||
|  |         ( | ||||||
|  |             enums::PaymentMethodType::Interac, | ||||||
|  |             connectors(vec![( | ||||||
|  |                 Connector::Paysafe, | ||||||
|  |                 fields(vec![], vec![RequiredField::BillingEmail], vec![]), | ||||||
|  |             )]), | ||||||
|  |         ), | ||||||
|     ]) |     ]) | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -2734,19 +2741,32 @@ fn get_wallet_required_fields() -> HashMap<enums::PaymentMethodType, ConnectorFi | |||||||
|         ), |         ), | ||||||
|         ( |         ( | ||||||
|             enums::PaymentMethodType::Skrill, |             enums::PaymentMethodType::Skrill, | ||||||
|             connectors(vec![( |             connectors(vec![ | ||||||
|                 Connector::Airwallex, |                 ( | ||||||
|                 RequiredFieldFinal { |                     Connector::Airwallex, | ||||||
|                     mandate: HashMap::new(), |                     RequiredFieldFinal { | ||||||
|                     non_mandate: HashMap::from([ |                         mandate: HashMap::new(), | ||||||
|                         RequiredField::BillingUserFirstName.to_tuple(), |                         non_mandate: HashMap::from([ | ||||||
|                         RequiredField::BillingUserLastName.to_tuple(), |                             RequiredField::BillingUserFirstName.to_tuple(), | ||||||
|                         RequiredField::BillingAddressCountries(vec!["ALL"]).to_tuple(), |                             RequiredField::BillingUserLastName.to_tuple(), | ||||||
|                         RequiredField::BillingEmail.to_tuple(), |                             RequiredField::BillingAddressCountries(vec!["ALL"]).to_tuple(), | ||||||
|                     ]), |                             RequiredField::BillingEmail.to_tuple(), | ||||||
|                     common: HashMap::new(), |                         ]), | ||||||
|                 }, |                         common: HashMap::new(), | ||||||
|             )]), |                     }, | ||||||
|  |                 ), | ||||||
|  |                 ( | ||||||
|  |                     Connector::Paysafe, | ||||||
|  |                     RequiredFieldFinal { | ||||||
|  |                         mandate: HashMap::new(), | ||||||
|  |                         non_mandate: HashMap::from([ | ||||||
|  |                             RequiredField::BillingAddressCountries(vec!["ALL"]).to_tuple(), | ||||||
|  |                             RequiredField::BillingEmail.to_tuple(), | ||||||
|  |                         ]), | ||||||
|  |                         common: HashMap::new(), | ||||||
|  |                     }, | ||||||
|  |                 ), | ||||||
|  |             ]), | ||||||
|         ), |         ), | ||||||
|     ]) |     ]) | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Swangi Kumari
					Swangi Kumari