Skip to content

Commit

Permalink
feat(payouts): add payout types in euclid crate (#3862)
Browse files Browse the repository at this point in the history
Co-authored-by: Kashif <[email protected]>
  • Loading branch information
kashif-m and kashif-m authored Mar 21, 2024
1 parent fb5f0e6 commit a151485
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 19 deletions.
5 changes: 4 additions & 1 deletion crates/common_enums/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2057,12 +2057,15 @@ pub enum PayoutStatus {
Debug,
Default,
Eq,
Hash,
PartialEq,
ToSchema,
serde::Deserialize,
serde::Serialize,
strum::Display,
strum::EnumVariantNames,
strum::EnumIter,
strum::EnumString,
ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[serde(rename_all = "snake_case")]
Expand Down
2 changes: 2 additions & 0 deletions crates/euclid/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ common_enums = { version = "0.1.0", path = "../common_enums" }
euclid_macros = { version = "0.1.0", path = "../euclid_macros" }

[features]
default = []
ast_parser = ["dep:nom"]
valued_jit = []
connector_choice_mca_id = []
dummy_connector = []
payouts = []

[dev-dependencies]
criterion = "0.5"
Expand Down
70 changes: 70 additions & 0 deletions crates/euclid/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ collect_variants!(CaptureMethod);
collect_variants!(Currency);
collect_variants!(Country);
collect_variants!(SetupFutureUsage);
#[cfg(feature = "payouts")]
collect_variants!(PayoutType);
#[cfg(feature = "payouts")]
collect_variants!(PayoutBankTransferType);
#[cfg(feature = "payouts")]
collect_variants!(PayoutWalletType);

#[derive(
Clone,
Expand Down Expand Up @@ -94,3 +100,67 @@ pub enum MandateType {
SingleUse,
MultiUse,
}

#[cfg(feature = "payouts")]
#[derive(
Clone,
Debug,
Hash,
PartialEq,
Eq,
strum::Display,
strum::EnumVariantNames,
strum::EnumIter,
strum::EnumString,
serde::Serialize,
serde::Deserialize,
)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum PayoutBankTransferType {
Ach,
Bacs,
Sepa,
}

#[cfg(feature = "payouts")]
#[derive(
Clone,
Debug,
Hash,
PartialEq,
Eq,
strum::Display,
strum::EnumVariantNames,
strum::EnumIter,
strum::EnumString,
serde::Serialize,
serde::Deserialize,
)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum PayoutWalletType {
Paypal,
}

#[cfg(feature = "payouts")]
#[derive(
Clone,
Debug,
Hash,
PartialEq,
Eq,
strum::Display,
strum::EnumVariantNames,
strum::EnumIter,
strum::EnumString,
serde::Serialize,
serde::Deserialize,
)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum PayoutType {
Card,
BankTransfer,
Wallet,
}
95 changes: 95 additions & 0 deletions crates/euclid/src/frontend/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,101 @@ impl DirValue {
}
}

#[cfg(feature = "payouts")]
#[derive(
Debug,
Clone,
Hash,
PartialEq,
Eq,
serde::Serialize,
strum::Display,
strum::EnumIter,
strum::EnumVariantNames,
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::EnumVariantNames,
)]
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,
Expand Down
2 changes: 2 additions & 0 deletions crates/euclid/src/frontend/dir/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ pub use crate::enums::{
Country as BillingCountry, Currency as PaymentCurrency, MandateAcceptanceType, MandateType,
PaymentMethod, PaymentType, RoutableConnectors, SetupFutureUsage,
};
#[cfg(feature = "payouts")]
pub use crate::enums::{PayoutBankTransferType, PayoutType, PayoutWalletType};

#[derive(
Clone,
Expand Down
4 changes: 2 additions & 2 deletions crates/euclid_wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ crate-type = ["cdylib"]

[features]
default = ["connector_choice_bcompat", "payouts", "connector_choice_mca_id"]
release = ["connector_choice_bcompat", "connector_choice_mca_id"]
release = ["connector_choice_bcompat", "connector_choice_mca_id", "payouts"]
connector_choice_bcompat = ["api_models/connector_choice_bcompat"]
connector_choice_mca_id = ["api_models/connector_choice_mca_id", "euclid/connector_choice_mca_id", "kgraph_utils/connector_choice_mca_id"]
dummy_connector = ["kgraph_utils/dummy_connector", "connector_configs/dummy_connector"]
production = ["connector_configs/production"]
development = ["connector_configs/development"]
sandbox = ["connector_configs/sandbox"]
payouts = ["api_models/payouts"]
payouts = ["api_models/payouts", "euclid/payouts"]

[dependencies]
api_models = { version = "0.1.0", path = "../api_models", package = "api_models" }
Expand Down
52 changes: 51 additions & 1 deletion crates/euclid_wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,12 +256,13 @@ pub fn get_variant_values(key: &str) -> Result<JsValue, JsValue> {
dir::DirKeyKind::CardRedirectType => dir_enums::CardRedirectType::VARIANTS,
dir::DirKeyKind::GiftCardType => dir_enums::GiftCardType::VARIANTS,
dir::DirKeyKind::VoucherType => dir_enums::VoucherType::VARIANTS,
dir::DirKeyKind::BankDebitType => dir_enums::BankDebitType::VARIANTS,

dir::DirKeyKind::PaymentAmount
| dir::DirKeyKind::Connector
| dir::DirKeyKind::CardBin
| dir::DirKeyKind::BusinessLabel
| dir::DirKeyKind::MetaData => Err("Key does not have variants".to_string())?,
dir::DirKeyKind::BankDebitType => dir_enums::BankDebitType::VARIANTS,
};

Ok(serde_wasm_bindgen::to_value(variants)?)
Expand Down Expand Up @@ -335,3 +336,52 @@ pub fn get_response_payload(input: JsValue) -> JsResult {
let result = ConnectorApiIntegrationPayload::get_transformed_response_payload(input);
Ok(serde_wasm_bindgen::to_value(&result)?)
}

#[cfg(feature = "payouts")]
#[wasm_bindgen(js_name = getAllPayoutKeys)]
pub fn get_all_payout_keys() -> JsResult {
let keys: Vec<&'static str> = dir::PayoutDirKeyKind::VARIANTS.to_vec();
Ok(serde_wasm_bindgen::to_value(&keys)?)
}

#[cfg(feature = "payouts")]
#[wasm_bindgen(js_name = getPayoutVariantValues)]
pub fn get_payout_variant_values(key: &str) -> Result<JsValue, JsValue> {
let key =
dir::PayoutDirKeyKind::from_str(key).map_err(|_| "Invalid key received".to_string())?;

let variants: &[&str] = match key {
dir::PayoutDirKeyKind::BusinessCountry => dir_enums::BusinessCountry::VARIANTS,
dir::PayoutDirKeyKind::BillingCountry => dir_enums::BillingCountry::VARIANTS,
dir::PayoutDirKeyKind::PayoutType => dir_enums::PayoutType::VARIANTS,
dir::PayoutDirKeyKind::WalletType => dir_enums::PayoutWalletType::VARIANTS,
dir::PayoutDirKeyKind::BankTransferType => dir_enums::PayoutBankTransferType::VARIANTS,

dir::PayoutDirKeyKind::PayoutAmount | dir::PayoutDirKeyKind::BusinessLabel => {
Err("Key does not have variants".to_string())?
}
};

Ok(serde_wasm_bindgen::to_value(variants)?)
}

#[cfg(feature = "payouts")]
#[wasm_bindgen(js_name = getPayoutDescriptionCategory)]
pub fn get_payout_description_category() -> JsResult {
let keys = dir::PayoutDirKeyKind::VARIANTS.to_vec();
let mut category: HashMap<Option<&str>, Vec<types::PayoutDetails<'_>>> = HashMap::new();
for key in keys {
let dir_key =
dir::PayoutDirKeyKind::from_str(key).map_err(|_| "Invalid key received".to_string())?;
let details = types::PayoutDetails {
description: dir_key.get_detailed_message(),
kind: dir_key.clone(),
};
category
.entry(dir_key.get_str("Category"))
.and_modify(|val| val.push(details.clone()))
.or_insert(vec![details]);
}

Ok(serde_wasm_bindgen::to_value(&category)?)
}
9 changes: 9 additions & 0 deletions crates/euclid_wasm/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
use euclid::frontend::dir::DirKeyKind;
#[cfg(feature = "payouts")]
use euclid::frontend::dir::PayoutDirKeyKind;
use serde::Serialize;

#[derive(Serialize, Clone)]
pub struct Details<'a> {
pub description: Option<&'a str>,
pub kind: DirKeyKind,
}

#[cfg(feature = "payouts")]
#[derive(Serialize, Clone)]
pub struct PayoutDetails<'a> {
pub description: Option<&'a str>,
pub kind: PayoutDirKeyKind,
}
22 changes: 12 additions & 10 deletions crates/router/src/core/routing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,7 @@ pub async fn retrieve_linked_routing_config(
state: AppState,
merchant_account: domain::MerchantAccount,
#[cfg(feature = "business_profile_routing")] query_params: RoutingRetrieveLinkQuery,
#[cfg(feature = "business_profile_routing")] transaction_type: &enums::TransactionType,
) -> RouterResponse<routing_types::LinkedRoutingConfigRetrieveResponse> {
metrics::ROUTING_RETRIEVE_LINK_CONFIG.add(&metrics::CONTEXT, 1, &[]);
let db = state.store.as_ref();
Expand All @@ -739,16 +740,17 @@ pub async fn retrieve_linked_routing_config(
let mut active_algorithms = Vec::new();

for business_profile in business_profiles {
let routing_ref: routing_types::RoutingAlgorithmRef = business_profile
.routing_algorithm
.clone()
.map(|val| val.parse_value("RoutingAlgorithmRef"))
.transpose()
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable(
"unable to deserialize routing algorithm ref from merchant account",
)?
.unwrap_or_default();
let routing_ref: routing_types::RoutingAlgorithmRef = match transaction_type {
enums::TransactionType::Payment => business_profile.routing_algorithm,
#[cfg(feature = "payouts")]
enums::TransactionType::Payout => business_profile.payout_routing_algorithm,
}
.clone()
.map(|val| val.parse_value("RoutingAlgorithmRef"))
.transpose()
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("unable to deserialize routing algorithm ref from merchant account")?
.unwrap_or_default();

if let Some(algorithm_id) = routing_ref.algorithm_id {
let record = db
Expand Down
Loading

0 comments on commit a151485

Please sign in to comment.