mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
901 lines
31 KiB
Rust
901 lines
31 KiB
Rust
//! Domain Intermediate Representation
|
|
pub mod enums;
|
|
pub mod lowering;
|
|
pub mod transformers;
|
|
|
|
use strum::IntoEnumIterator;
|
|
|
|
use crate::{enums as euclid_enums, frontend::ast, types};
|
|
|
|
#[macro_export]
|
|
#[cfg(feature = "connector_choice_mca_id")]
|
|
macro_rules! dirval {
|
|
(Connector = $name:ident) => {
|
|
$crate::frontend::dir::DirValue::Connector(Box::new(
|
|
$crate::frontend::ast::ConnectorChoice {
|
|
connector: $crate::enums::RoutableConnectors::$name,
|
|
},
|
|
))
|
|
};
|
|
|
|
($key:ident = $val:ident) => {{
|
|
pub use $crate::frontend::dir::enums::*;
|
|
|
|
$crate::frontend::dir::DirValue::$key($key::$val)
|
|
}};
|
|
|
|
($key:ident = $num:literal) => {{
|
|
$crate::frontend::dir::DirValue::$key($crate::types::NumValue {
|
|
number: $num,
|
|
refinement: None,
|
|
})
|
|
}};
|
|
|
|
($key:ident s= $str:literal) => {{
|
|
$crate::frontend::dir::DirValue::$key($crate::types::StrValue {
|
|
value: $str.to_string(),
|
|
})
|
|
}};
|
|
|
|
($key:literal = $str:literal) => {{
|
|
$crate::frontend::dir::DirValue::MetaData($crate::types::MetadataValue {
|
|
key: $key.to_string(),
|
|
value: $str.to_string(),
|
|
})
|
|
}};
|
|
}
|
|
|
|
#[macro_export]
|
|
#[cfg(not(feature = "connector_choice_mca_id"))]
|
|
macro_rules! dirval {
|
|
(Connector = $name:ident) => {
|
|
$crate::frontend::dir::DirValue::Connector(Box::new(
|
|
$crate::frontend::ast::ConnectorChoice {
|
|
connector: $crate::enums::RoutableConnectors::$name,
|
|
sub_label: None,
|
|
},
|
|
))
|
|
};
|
|
|
|
(Connector = ($name:ident, $sub_label:literal)) => {
|
|
$crate::frontend::dir::DirValue::Connector(Box::new(
|
|
$crate::frontend::ast::ConnectorChoice {
|
|
connector: $crate::enums::RoutableConnectors::$name,
|
|
sub_label: Some($sub_label.to_string()),
|
|
},
|
|
))
|
|
};
|
|
|
|
($key:ident = $val:ident) => {{
|
|
pub use $crate::frontend::dir::enums::*;
|
|
|
|
$crate::frontend::dir::DirValue::$key($key::$val)
|
|
}};
|
|
|
|
($key:ident = $num:literal) => {{
|
|
$crate::frontend::dir::DirValue::$key($crate::types::NumValue {
|
|
number: $num,
|
|
refinement: None,
|
|
})
|
|
}};
|
|
|
|
($key:ident s= $str:literal) => {{
|
|
$crate::frontend::dir::DirValue::$key($crate::types::StrValue {
|
|
value: $str.to_string(),
|
|
})
|
|
}};
|
|
($key:literal = $str:literal) => {{
|
|
$crate::frontend::dir::DirValue::MetaData($crate::types::MetadataValue {
|
|
key: $key.to_string(),
|
|
value: $str.to_string(),
|
|
})
|
|
}};
|
|
}
|
|
|
|
#[derive(Debug, Clone, Hash, PartialEq, Eq, serde::Serialize)]
|
|
pub struct DirKey {
|
|
pub kind: DirKeyKind,
|
|
pub value: Option<String>,
|
|
}
|
|
|
|
impl DirKey {
|
|
pub fn new(kind: DirKeyKind, value: Option<String>) -> Self {
|
|
Self { kind, value }
|
|
}
|
|
}
|
|
|
|
#[derive(
|
|
Debug,
|
|
Clone,
|
|
Hash,
|
|
PartialEq,
|
|
Eq,
|
|
serde::Serialize,
|
|
strum::Display,
|
|
strum::EnumIter,
|
|
strum::VariantNames,
|
|
strum::EnumString,
|
|
strum::EnumMessage,
|
|
strum::EnumProperty,
|
|
)]
|
|
pub enum DirKeyKind {
|
|
#[strum(
|
|
serialize = "payment_method",
|
|
detailed_message = "Different modes of payment - eg. cards, wallets, banks",
|
|
props(Category = "Payment Methods")
|
|
)]
|
|
#[serde(rename = "payment_method")]
|
|
PaymentMethod,
|
|
#[strum(
|
|
serialize = "card_bin",
|
|
detailed_message = "First 4 to 6 digits of a payment card number",
|
|
props(Category = "Payment Methods")
|
|
)]
|
|
#[serde(rename = "card_bin")]
|
|
CardBin,
|
|
#[strum(
|
|
serialize = "card_type",
|
|
detailed_message = "Type of the payment card - eg. credit, debit",
|
|
props(Category = "Payment Methods")
|
|
)]
|
|
#[serde(rename = "card_type")]
|
|
CardType,
|
|
#[strum(
|
|
serialize = "card_network",
|
|
detailed_message = "Network that facilitates payment card transactions",
|
|
props(Category = "Payment Methods")
|
|
)]
|
|
#[serde(rename = "card_network")]
|
|
CardNetwork,
|
|
#[strum(
|
|
serialize = "pay_later",
|
|
detailed_message = "Supported types of Pay Later payment method",
|
|
props(Category = "Payment Method Types")
|
|
)]
|
|
#[serde(rename = "pay_later")]
|
|
PayLaterType,
|
|
#[strum(
|
|
serialize = "gift_card",
|
|
detailed_message = "Supported types of Gift Card payment method",
|
|
props(Category = "Payment Method Types")
|
|
)]
|
|
#[serde(rename = "gift_card")]
|
|
GiftCardType,
|
|
#[strum(
|
|
serialize = "mandate_acceptance_type",
|
|
detailed_message = "Mode of customer acceptance for mandates - online and offline",
|
|
props(Category = "Payments")
|
|
)]
|
|
#[serde(rename = "mandate_acceptance_type")]
|
|
MandateAcceptanceType,
|
|
#[strum(
|
|
serialize = "mandate_type",
|
|
detailed_message = "Type of mandate acceptance - single use and multi use",
|
|
props(Category = "Payments")
|
|
)]
|
|
#[serde(rename = "mandate_type")]
|
|
MandateType,
|
|
#[strum(
|
|
serialize = "payment_type",
|
|
detailed_message = "Indicates if a payment is mandate or non-mandate",
|
|
props(Category = "Payments")
|
|
)]
|
|
#[serde(rename = "payment_type")]
|
|
PaymentType,
|
|
#[strum(
|
|
serialize = "wallet",
|
|
detailed_message = "Supported types of Wallet payment method",
|
|
props(Category = "Payment Method Types")
|
|
)]
|
|
#[serde(rename = "wallet")]
|
|
WalletType,
|
|
#[strum(
|
|
serialize = "upi",
|
|
detailed_message = "Supported types of UPI payment method",
|
|
props(Category = "Payment Method Types")
|
|
)]
|
|
#[serde(rename = "upi")]
|
|
UpiType,
|
|
#[strum(
|
|
serialize = "voucher",
|
|
detailed_message = "Supported types of Voucher payment method",
|
|
props(Category = "Payment Method Types")
|
|
)]
|
|
#[serde(rename = "voucher")]
|
|
VoucherType,
|
|
#[strum(
|
|
serialize = "bank_transfer",
|
|
detailed_message = "Supported types of Bank Transfer payment method",
|
|
props(Category = "Payment Method Types")
|
|
)]
|
|
#[serde(rename = "bank_transfer")]
|
|
BankTransferType,
|
|
#[strum(
|
|
serialize = "bank_redirect",
|
|
detailed_message = "Supported types of Bank Redirect payment methods",
|
|
props(Category = "Payment Method Types")
|
|
)]
|
|
#[serde(rename = "bank_redirect")]
|
|
BankRedirectType,
|
|
#[strum(
|
|
serialize = "bank_debit",
|
|
detailed_message = "Supported types of Bank Debit payment method",
|
|
props(Category = "Payment Method Types")
|
|
)]
|
|
#[serde(rename = "bank_debit")]
|
|
BankDebitType,
|
|
#[strum(
|
|
serialize = "crypto",
|
|
detailed_message = "Supported types of Crypto payment method",
|
|
props(Category = "Payment Method Types")
|
|
)]
|
|
#[serde(rename = "crypto")]
|
|
CryptoType,
|
|
#[strum(
|
|
serialize = "metadata",
|
|
detailed_message = "Aribitrary Key and value pair",
|
|
props(Category = "Metadata")
|
|
)]
|
|
#[serde(rename = "metadata")]
|
|
MetaData,
|
|
#[strum(
|
|
serialize = "reward",
|
|
detailed_message = "Supported types of Reward payment method",
|
|
props(Category = "Payment Method Types")
|
|
)]
|
|
#[serde(rename = "reward")]
|
|
RewardType,
|
|
#[strum(
|
|
serialize = "amount",
|
|
detailed_message = "Value of the transaction",
|
|
props(Category = "Payments")
|
|
)]
|
|
#[serde(rename = "amount")]
|
|
PaymentAmount,
|
|
#[strum(
|
|
serialize = "currency",
|
|
detailed_message = "Currency used for the payment",
|
|
props(Category = "Payments")
|
|
)]
|
|
#[serde(rename = "currency")]
|
|
PaymentCurrency,
|
|
#[strum(
|
|
serialize = "authentication_type",
|
|
detailed_message = "Type of authentication for the payment",
|
|
props(Category = "Payments")
|
|
)]
|
|
#[serde(rename = "authentication_type")]
|
|
AuthenticationType,
|
|
#[strum(
|
|
serialize = "capture_method",
|
|
detailed_message = "Modes of capturing a payment",
|
|
props(Category = "Payments")
|
|
)]
|
|
#[serde(rename = "capture_method")]
|
|
CaptureMethod,
|
|
#[strum(
|
|
serialize = "country",
|
|
serialize = "business_country",
|
|
detailed_message = "Country of the business unit",
|
|
props(Category = "Merchant")
|
|
)]
|
|
#[serde(rename = "business_country", alias = "country")]
|
|
BusinessCountry,
|
|
#[strum(
|
|
serialize = "billing_country",
|
|
detailed_message = "Country of the billing address of the customer",
|
|
props(Category = "Customer")
|
|
)]
|
|
#[serde(rename = "billing_country")]
|
|
BillingCountry,
|
|
#[serde(skip_deserializing, rename = "connector")]
|
|
Connector,
|
|
#[strum(
|
|
serialize = "business_label",
|
|
detailed_message = "Identifier for business unit",
|
|
props(Category = "Merchant")
|
|
)]
|
|
#[serde(rename = "business_label")]
|
|
BusinessLabel,
|
|
#[strum(
|
|
serialize = "setup_future_usage",
|
|
detailed_message = "Identifier for recurring payments",
|
|
props(Category = "Payments")
|
|
)]
|
|
#[serde(rename = "setup_future_usage")]
|
|
SetupFutureUsage,
|
|
#[strum(
|
|
serialize = "card_redirect",
|
|
detailed_message = "Supported types of Card Redirect payment method",
|
|
props(Category = "Payment Method Types")
|
|
)]
|
|
#[serde(rename = "card_redirect")]
|
|
CardRedirectType,
|
|
}
|
|
|
|
pub trait EuclidDirFilter: Sized
|
|
where
|
|
Self: 'static,
|
|
{
|
|
const ALLOWED: &'static [DirKeyKind];
|
|
fn get_allowed_keys() -> &'static [DirKeyKind] {
|
|
Self::ALLOWED
|
|
}
|
|
|
|
fn is_key_allowed(key: &DirKeyKind) -> bool {
|
|
Self::ALLOWED.contains(key)
|
|
}
|
|
}
|
|
|
|
impl DirKeyKind {
|
|
pub fn get_type(&self) -> types::DataType {
|
|
match self {
|
|
Self::PaymentMethod => types::DataType::EnumVariant,
|
|
Self::CardBin => types::DataType::StrValue,
|
|
Self::CardType => types::DataType::EnumVariant,
|
|
Self::CardNetwork => types::DataType::EnumVariant,
|
|
Self::MetaData => types::DataType::MetadataValue,
|
|
Self::MandateType => types::DataType::EnumVariant,
|
|
Self::PaymentType => types::DataType::EnumVariant,
|
|
Self::MandateAcceptanceType => types::DataType::EnumVariant,
|
|
Self::PayLaterType => types::DataType::EnumVariant,
|
|
Self::WalletType => types::DataType::EnumVariant,
|
|
Self::UpiType => types::DataType::EnumVariant,
|
|
Self::VoucherType => types::DataType::EnumVariant,
|
|
Self::BankTransferType => types::DataType::EnumVariant,
|
|
Self::GiftCardType => types::DataType::EnumVariant,
|
|
Self::BankRedirectType => types::DataType::EnumVariant,
|
|
Self::CryptoType => types::DataType::EnumVariant,
|
|
Self::RewardType => types::DataType::EnumVariant,
|
|
Self::PaymentAmount => types::DataType::Number,
|
|
Self::PaymentCurrency => types::DataType::EnumVariant,
|
|
Self::AuthenticationType => types::DataType::EnumVariant,
|
|
Self::CaptureMethod => types::DataType::EnumVariant,
|
|
Self::BusinessCountry => types::DataType::EnumVariant,
|
|
Self::BillingCountry => types::DataType::EnumVariant,
|
|
Self::Connector => types::DataType::EnumVariant,
|
|
Self::BankDebitType => types::DataType::EnumVariant,
|
|
Self::BusinessLabel => types::DataType::StrValue,
|
|
Self::SetupFutureUsage => types::DataType::EnumVariant,
|
|
Self::CardRedirectType => types::DataType::EnumVariant,
|
|
}
|
|
}
|
|
pub fn get_value_set(&self) -> Option<Vec<DirValue>> {
|
|
match self {
|
|
Self::PaymentMethod => Some(
|
|
enums::PaymentMethod::iter()
|
|
.map(DirValue::PaymentMethod)
|
|
.collect(),
|
|
),
|
|
Self::CardBin => None,
|
|
Self::CardType => Some(enums::CardType::iter().map(DirValue::CardType).collect()),
|
|
Self::MandateAcceptanceType => Some(
|
|
euclid_enums::MandateAcceptanceType::iter()
|
|
.map(DirValue::MandateAcceptanceType)
|
|
.collect(),
|
|
),
|
|
Self::PaymentType => Some(
|
|
euclid_enums::PaymentType::iter()
|
|
.map(DirValue::PaymentType)
|
|
.collect(),
|
|
),
|
|
Self::MandateType => Some(
|
|
euclid_enums::MandateType::iter()
|
|
.map(DirValue::MandateType)
|
|
.collect(),
|
|
),
|
|
Self::CardNetwork => Some(
|
|
enums::CardNetwork::iter()
|
|
.map(DirValue::CardNetwork)
|
|
.collect(),
|
|
),
|
|
Self::PayLaterType => Some(
|
|
enums::PayLaterType::iter()
|
|
.map(DirValue::PayLaterType)
|
|
.collect(),
|
|
),
|
|
Self::MetaData => None,
|
|
Self::WalletType => Some(
|
|
enums::WalletType::iter()
|
|
.map(DirValue::WalletType)
|
|
.collect(),
|
|
),
|
|
Self::UpiType => Some(enums::UpiType::iter().map(DirValue::UpiType).collect()),
|
|
Self::VoucherType => Some(
|
|
enums::VoucherType::iter()
|
|
.map(DirValue::VoucherType)
|
|
.collect(),
|
|
),
|
|
Self::BankTransferType => Some(
|
|
enums::BankTransferType::iter()
|
|
.map(DirValue::BankTransferType)
|
|
.collect(),
|
|
),
|
|
Self::GiftCardType => Some(
|
|
enums::GiftCardType::iter()
|
|
.map(DirValue::GiftCardType)
|
|
.collect(),
|
|
),
|
|
Self::BankRedirectType => Some(
|
|
enums::BankRedirectType::iter()
|
|
.map(DirValue::BankRedirectType)
|
|
.collect(),
|
|
),
|
|
Self::CryptoType => Some(
|
|
enums::CryptoType::iter()
|
|
.map(DirValue::CryptoType)
|
|
.collect(),
|
|
),
|
|
Self::RewardType => Some(
|
|
enums::RewardType::iter()
|
|
.map(DirValue::RewardType)
|
|
.collect(),
|
|
),
|
|
Self::PaymentAmount => None,
|
|
Self::PaymentCurrency => Some(
|
|
enums::PaymentCurrency::iter()
|
|
.map(DirValue::PaymentCurrency)
|
|
.collect(),
|
|
),
|
|
Self::AuthenticationType => Some(
|
|
enums::AuthenticationType::iter()
|
|
.map(DirValue::AuthenticationType)
|
|
.collect(),
|
|
),
|
|
Self::CaptureMethod => Some(
|
|
enums::CaptureMethod::iter()
|
|
.map(DirValue::CaptureMethod)
|
|
.collect(),
|
|
),
|
|
Self::BankDebitType => Some(
|
|
enums::BankDebitType::iter()
|
|
.map(DirValue::BankDebitType)
|
|
.collect(),
|
|
),
|
|
Self::BusinessCountry => Some(
|
|
enums::Country::iter()
|
|
.map(DirValue::BusinessCountry)
|
|
.collect(),
|
|
),
|
|
Self::BillingCountry => Some(
|
|
enums::Country::iter()
|
|
.map(DirValue::BillingCountry)
|
|
.collect(),
|
|
),
|
|
Self::Connector => Some(
|
|
common_enums::RoutableConnectors::iter()
|
|
.map(|connector| {
|
|
DirValue::Connector(Box::new(ast::ConnectorChoice {
|
|
connector,
|
|
#[cfg(not(feature = "connector_choice_mca_id"))]
|
|
sub_label: None,
|
|
}))
|
|
})
|
|
.collect(),
|
|
),
|
|
Self::BusinessLabel => None,
|
|
Self::SetupFutureUsage => Some(
|
|
enums::SetupFutureUsage::iter()
|
|
.map(DirValue::SetupFutureUsage)
|
|
.collect(),
|
|
),
|
|
Self::CardRedirectType => Some(
|
|
enums::CardRedirectType::iter()
|
|
.map(DirValue::CardRedirectType)
|
|
.collect(),
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(
|
|
Debug, Clone, Hash, PartialEq, Eq, serde::Serialize, strum::Display, strum::VariantNames,
|
|
)]
|
|
#[serde(tag = "key", content = "value")]
|
|
pub enum DirValue {
|
|
#[serde(rename = "payment_method")]
|
|
PaymentMethod(enums::PaymentMethod),
|
|
#[serde(rename = "card_bin")]
|
|
CardBin(types::StrValue),
|
|
#[serde(rename = "card_type")]
|
|
CardType(enums::CardType),
|
|
#[serde(rename = "card_network")]
|
|
CardNetwork(enums::CardNetwork),
|
|
#[serde(rename = "metadata")]
|
|
MetaData(types::MetadataValue),
|
|
#[serde(rename = "pay_later")]
|
|
PayLaterType(enums::PayLaterType),
|
|
#[serde(rename = "wallet")]
|
|
WalletType(enums::WalletType),
|
|
#[serde(rename = "acceptance_type")]
|
|
MandateAcceptanceType(euclid_enums::MandateAcceptanceType),
|
|
#[serde(rename = "mandate_type")]
|
|
MandateType(euclid_enums::MandateType),
|
|
#[serde(rename = "payment_type")]
|
|
PaymentType(euclid_enums::PaymentType),
|
|
#[serde(rename = "upi")]
|
|
UpiType(enums::UpiType),
|
|
#[serde(rename = "voucher")]
|
|
VoucherType(enums::VoucherType),
|
|
#[serde(rename = "bank_transfer")]
|
|
BankTransferType(enums::BankTransferType),
|
|
#[serde(rename = "bank_redirect")]
|
|
BankRedirectType(enums::BankRedirectType),
|
|
#[serde(rename = "bank_debit")]
|
|
BankDebitType(enums::BankDebitType),
|
|
#[serde(rename = "crypto")]
|
|
CryptoType(enums::CryptoType),
|
|
#[serde(rename = "reward")]
|
|
RewardType(enums::RewardType),
|
|
#[serde(rename = "gift_card")]
|
|
GiftCardType(enums::GiftCardType),
|
|
#[serde(rename = "amount")]
|
|
PaymentAmount(types::NumValue),
|
|
#[serde(rename = "currency")]
|
|
PaymentCurrency(enums::PaymentCurrency),
|
|
#[serde(rename = "authentication_type")]
|
|
AuthenticationType(enums::AuthenticationType),
|
|
#[serde(rename = "capture_method")]
|
|
CaptureMethod(enums::CaptureMethod),
|
|
#[serde(rename = "business_country", alias = "country")]
|
|
BusinessCountry(enums::Country),
|
|
#[serde(rename = "billing_country")]
|
|
BillingCountry(enums::Country),
|
|
#[serde(skip_deserializing, rename = "connector")]
|
|
Connector(Box<ast::ConnectorChoice>),
|
|
#[serde(rename = "business_label")]
|
|
BusinessLabel(types::StrValue),
|
|
#[serde(rename = "setup_future_usage")]
|
|
SetupFutureUsage(enums::SetupFutureUsage),
|
|
#[serde(rename = "card_redirect")]
|
|
CardRedirectType(enums::CardRedirectType),
|
|
}
|
|
|
|
impl DirValue {
|
|
pub fn get_key(&self) -> DirKey {
|
|
let (kind, data) = match self {
|
|
Self::PaymentMethod(_) => (DirKeyKind::PaymentMethod, None),
|
|
Self::CardBin(_) => (DirKeyKind::CardBin, None),
|
|
Self::RewardType(_) => (DirKeyKind::RewardType, None),
|
|
Self::BusinessCountry(_) => (DirKeyKind::BusinessCountry, None),
|
|
Self::BillingCountry(_) => (DirKeyKind::BillingCountry, None),
|
|
Self::BankTransferType(_) => (DirKeyKind::BankTransferType, None),
|
|
Self::UpiType(_) => (DirKeyKind::UpiType, None),
|
|
Self::CardType(_) => (DirKeyKind::CardType, None),
|
|
Self::CardNetwork(_) => (DirKeyKind::CardNetwork, None),
|
|
Self::MetaData(met) => (DirKeyKind::MetaData, Some(met.key.clone())),
|
|
Self::PayLaterType(_) => (DirKeyKind::PayLaterType, None),
|
|
Self::WalletType(_) => (DirKeyKind::WalletType, None),
|
|
Self::BankRedirectType(_) => (DirKeyKind::BankRedirectType, None),
|
|
Self::CryptoType(_) => (DirKeyKind::CryptoType, None),
|
|
Self::AuthenticationType(_) => (DirKeyKind::AuthenticationType, None),
|
|
Self::CaptureMethod(_) => (DirKeyKind::CaptureMethod, None),
|
|
Self::PaymentAmount(_) => (DirKeyKind::PaymentAmount, None),
|
|
Self::PaymentCurrency(_) => (DirKeyKind::PaymentCurrency, None),
|
|
Self::Connector(_) => (DirKeyKind::Connector, None),
|
|
Self::BankDebitType(_) => (DirKeyKind::BankDebitType, None),
|
|
Self::MandateAcceptanceType(_) => (DirKeyKind::MandateAcceptanceType, None),
|
|
Self::MandateType(_) => (DirKeyKind::MandateType, None),
|
|
Self::PaymentType(_) => (DirKeyKind::PaymentType, None),
|
|
Self::BusinessLabel(_) => (DirKeyKind::BusinessLabel, None),
|
|
Self::SetupFutureUsage(_) => (DirKeyKind::SetupFutureUsage, None),
|
|
Self::CardRedirectType(_) => (DirKeyKind::CardRedirectType, None),
|
|
Self::VoucherType(_) => (DirKeyKind::VoucherType, None),
|
|
Self::GiftCardType(_) => (DirKeyKind::GiftCardType, None),
|
|
};
|
|
|
|
DirKey::new(kind, data)
|
|
}
|
|
pub fn get_metadata_val(&self) -> Option<types::MetadataValue> {
|
|
match self {
|
|
Self::MetaData(val) => Some(val.clone()),
|
|
Self::PaymentMethod(_) => None,
|
|
Self::CardBin(_) => None,
|
|
Self::CardType(_) => None,
|
|
Self::CardNetwork(_) => None,
|
|
Self::PayLaterType(_) => None,
|
|
Self::WalletType(_) => None,
|
|
Self::BankRedirectType(_) => None,
|
|
Self::CryptoType(_) => None,
|
|
Self::AuthenticationType(_) => None,
|
|
Self::CaptureMethod(_) => None,
|
|
Self::GiftCardType(_) => None,
|
|
Self::PaymentAmount(_) => None,
|
|
Self::PaymentCurrency(_) => None,
|
|
Self::BusinessCountry(_) => None,
|
|
Self::BillingCountry(_) => None,
|
|
Self::Connector(_) => None,
|
|
Self::BankTransferType(_) => None,
|
|
Self::UpiType(_) => None,
|
|
Self::BankDebitType(_) => None,
|
|
Self::RewardType(_) => None,
|
|
Self::VoucherType(_) => None,
|
|
Self::MandateAcceptanceType(_) => None,
|
|
Self::MandateType(_) => None,
|
|
Self::PaymentType(_) => None,
|
|
Self::BusinessLabel(_) => None,
|
|
Self::SetupFutureUsage(_) => None,
|
|
Self::CardRedirectType(_) => None,
|
|
}
|
|
}
|
|
|
|
pub fn get_str_val(&self) -> Option<types::StrValue> {
|
|
match self {
|
|
Self::CardBin(val) => Some(val.clone()),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
pub fn get_num_value(&self) -> Option<types::NumValue> {
|
|
match self {
|
|
Self::PaymentAmount(val) => Some(val.clone()),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
pub fn check_equality(v1: &Self, v2: &Self) -> bool {
|
|
match (v1, v2) {
|
|
(Self::PaymentMethod(pm1), Self::PaymentMethod(pm2)) => pm1 == pm2,
|
|
(Self::CardType(ct1), Self::CardType(ct2)) => ct1 == ct2,
|
|
(Self::CardNetwork(cn1), Self::CardNetwork(cn2)) => cn1 == cn2,
|
|
(Self::MetaData(md1), Self::MetaData(md2)) => md1 == md2,
|
|
(Self::PayLaterType(plt1), Self::PayLaterType(plt2)) => plt1 == plt2,
|
|
(Self::WalletType(wt1), Self::WalletType(wt2)) => wt1 == wt2,
|
|
(Self::BankDebitType(bdt1), Self::BankDebitType(bdt2)) => bdt1 == bdt2,
|
|
(Self::BankRedirectType(brt1), Self::BankRedirectType(brt2)) => brt1 == brt2,
|
|
(Self::BankTransferType(btt1), Self::BankTransferType(btt2)) => btt1 == btt2,
|
|
(Self::GiftCardType(gct1), Self::GiftCardType(gct2)) => gct1 == gct2,
|
|
(Self::CryptoType(ct1), Self::CryptoType(ct2)) => ct1 == ct2,
|
|
(Self::AuthenticationType(at1), Self::AuthenticationType(at2)) => at1 == at2,
|
|
(Self::CaptureMethod(cm1), Self::CaptureMethod(cm2)) => cm1 == cm2,
|
|
(Self::PaymentCurrency(pc1), Self::PaymentCurrency(pc2)) => pc1 == pc2,
|
|
(Self::BusinessCountry(c1), Self::BusinessCountry(c2)) => c1 == c2,
|
|
(Self::BillingCountry(c1), Self::BillingCountry(c2)) => c1 == c2,
|
|
(Self::PaymentType(pt1), Self::PaymentType(pt2)) => pt1 == pt2,
|
|
(Self::MandateType(mt1), Self::MandateType(mt2)) => mt1 == mt2,
|
|
(Self::MandateAcceptanceType(mat1), Self::MandateAcceptanceType(mat2)) => mat1 == mat2,
|
|
(Self::RewardType(rt1), Self::RewardType(rt2)) => rt1 == rt2,
|
|
(Self::Connector(c1), Self::Connector(c2)) => c1 == c2,
|
|
(Self::BusinessLabel(bl1), Self::BusinessLabel(bl2)) => bl1 == bl2,
|
|
(Self::SetupFutureUsage(sfu1), Self::SetupFutureUsage(sfu2)) => sfu1 == sfu2,
|
|
(Self::UpiType(ut1), Self::UpiType(ut2)) => ut1 == ut2,
|
|
(Self::VoucherType(vt1), Self::VoucherType(vt2)) => vt1 == vt2,
|
|
(Self::CardRedirectType(crt1), Self::CardRedirectType(crt2)) => crt1 == crt2,
|
|
_ => false,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "payouts")]
|
|
#[derive(
|
|
Debug,
|
|
Clone,
|
|
Hash,
|
|
PartialEq,
|
|
Eq,
|
|
serde::Serialize,
|
|
strum::Display,
|
|
strum::EnumIter,
|
|
strum::VariantNames,
|
|
strum::EnumString,
|
|
strum::EnumMessage,
|
|
strum::EnumProperty,
|
|
)]
|
|
pub enum PayoutDirKeyKind {
|
|
#[strum(
|
|
serialize = "country",
|
|
serialize = "business_country",
|
|
detailed_message = "Country of the business unit",
|
|
props(Category = "Merchant")
|
|
)]
|
|
#[serde(rename = "business_country", alias = "country")]
|
|
BusinessCountry,
|
|
|
|
#[strum(
|
|
serialize = "billing_country",
|
|
detailed_message = "Country of the billing address of the customer",
|
|
props(Category = "Customer")
|
|
)]
|
|
#[serde(rename = "billing_country")]
|
|
BillingCountry,
|
|
|
|
#[strum(
|
|
serialize = "business_label",
|
|
detailed_message = "Identifier for business unit",
|
|
props(Category = "Merchant")
|
|
)]
|
|
#[serde(rename = "business_label")]
|
|
BusinessLabel,
|
|
|
|
#[strum(
|
|
serialize = "amount",
|
|
detailed_message = "Value of the transaction",
|
|
props(Category = "Order details")
|
|
)]
|
|
#[serde(rename = "amount")]
|
|
PayoutAmount,
|
|
|
|
#[strum(
|
|
serialize = "payment_method",
|
|
detailed_message = "Different modes of payout - eg. cards, wallets, banks",
|
|
props(Category = "Payout Methods")
|
|
)]
|
|
#[serde(rename = "payment_method")]
|
|
PayoutType,
|
|
|
|
#[strum(
|
|
serialize = "wallet",
|
|
detailed_message = "Supported types of Wallets for payouts",
|
|
props(Category = "Payout Methods Type")
|
|
)]
|
|
#[serde(rename = "wallet")]
|
|
WalletType,
|
|
|
|
#[strum(
|
|
serialize = "bank_transfer",
|
|
detailed_message = "Supported types of Bank transfer types for payouts",
|
|
props(Category = "Payout Methods Type")
|
|
)]
|
|
#[serde(rename = "bank_transfer")]
|
|
BankTransferType,
|
|
}
|
|
|
|
#[cfg(feature = "payouts")]
|
|
#[derive(
|
|
Debug, Clone, Hash, PartialEq, Eq, serde::Serialize, strum::Display, strum::VariantNames,
|
|
)]
|
|
pub enum PayoutDirValue {
|
|
#[serde(rename = "business_country", alias = "country")]
|
|
BusinessCountry(enums::Country),
|
|
#[serde(rename = "billing_country")]
|
|
BillingCountry(enums::Country),
|
|
#[serde(rename = "business_label")]
|
|
BusinessLabel(types::StrValue),
|
|
#[serde(rename = "amount")]
|
|
PayoutAmount(types::NumValue),
|
|
#[serde(rename = "payment_method")]
|
|
PayoutType(common_enums::PayoutType),
|
|
#[serde(rename = "wallet")]
|
|
WalletType(enums::PayoutWalletType),
|
|
#[serde(rename = "bank_transfer")]
|
|
BankTransferType(enums::PayoutBankTransferType),
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum DirComparisonLogic {
|
|
NegativeConjunction,
|
|
PositiveDisjunction,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct DirComparison {
|
|
pub values: Vec<DirValue>,
|
|
pub logic: DirComparisonLogic,
|
|
pub metadata: types::Metadata,
|
|
}
|
|
|
|
pub type DirIfCondition = Vec<DirComparison>;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct DirIfStatement {
|
|
pub condition: DirIfCondition,
|
|
pub nested: Option<Vec<DirIfStatement>>,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct DirRule<O> {
|
|
pub name: String,
|
|
pub connector_selection: O,
|
|
pub statements: Vec<DirIfStatement>,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct DirProgram<O> {
|
|
pub default_selection: O,
|
|
pub rules: Vec<DirRule<O>>,
|
|
pub metadata: types::Metadata,
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
#![allow(clippy::expect_used)]
|
|
use rustc_hash::FxHashMap;
|
|
use strum::IntoEnumIterator;
|
|
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_consistent_dir_key_naming() {
|
|
let mut key_names: FxHashMap<DirKeyKind, String> = FxHashMap::default();
|
|
|
|
for key in DirKeyKind::iter() {
|
|
let json_str = if let DirKeyKind::MetaData = key {
|
|
r#""metadata""#.to_string()
|
|
} else {
|
|
serde_json::to_string(&key).expect("JSON Serialization")
|
|
};
|
|
let display_str = key.to_string();
|
|
|
|
assert_eq!(
|
|
json_str.get(1..json_str.len() - 1).expect("Value metadata"),
|
|
display_str
|
|
);
|
|
key_names.insert(key, display_str);
|
|
}
|
|
|
|
let values = vec![
|
|
dirval!(PaymentMethod = Card),
|
|
dirval!(CardBin s= "123456"),
|
|
dirval!(CardType = Credit),
|
|
dirval!(CardNetwork = Visa),
|
|
dirval!(PayLaterType = Klarna),
|
|
dirval!(WalletType = Paypal),
|
|
dirval!(BankRedirectType = Sofort),
|
|
dirval!(BankDebitType = Bacs),
|
|
dirval!(CryptoType = CryptoCurrency),
|
|
dirval!("" = "metadata"),
|
|
dirval!(PaymentAmount = 100),
|
|
dirval!(PaymentCurrency = USD),
|
|
dirval!(CardRedirectType = Benefit),
|
|
dirval!(AuthenticationType = ThreeDs),
|
|
dirval!(CaptureMethod = Manual),
|
|
dirval!(BillingCountry = UnitedStatesOfAmerica),
|
|
dirval!(BusinessCountry = France),
|
|
];
|
|
|
|
for val in values {
|
|
let json_val = serde_json::to_value(&val).expect("JSON Value Serialization");
|
|
|
|
let json_key = json_val
|
|
.as_object()
|
|
.expect("Serialized Object")
|
|
.get("key")
|
|
.expect("Object Key");
|
|
|
|
let value_str = json_key.as_str().expect("Value string");
|
|
let dir_key = val.get_key();
|
|
|
|
let key_name = key_names.get(&dir_key.kind).expect("Key name");
|
|
|
|
assert_eq!(key_name, value_str);
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "ast_parser")]
|
|
#[test]
|
|
fn test_allowed_dir_keys() {
|
|
use crate::types::DummyOutput;
|
|
|
|
let program_str = r#"
|
|
default: ["stripe", "adyen"]
|
|
|
|
rule_1: ["stripe"]
|
|
{
|
|
payment_method = card
|
|
}
|
|
"#;
|
|
let (_, program) = ast::parser::program::<DummyOutput>(program_str).expect("Program");
|
|
|
|
let out = ast::lowering::lower_program::<DummyOutput>(program);
|
|
assert!(out.is_ok())
|
|
}
|
|
#[cfg(feature = "ast_parser")]
|
|
#[test]
|
|
fn test_not_allowed_dir_keys() {
|
|
use crate::types::DummyOutput;
|
|
|
|
let program_str = r#"
|
|
default: ["stripe", "adyen"]
|
|
|
|
rule_1: ["stripe"]
|
|
{
|
|
bank_debit = ach
|
|
}
|
|
"#;
|
|
let (_, program) = ast::parser::program::<DummyOutput>(program_str).expect("Program");
|
|
|
|
let out = ast::lowering::lower_program::<DummyOutput>(program);
|
|
assert!(out.is_err())
|
|
}
|
|
}
|