mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 09:38:33 +08:00
refactor(paymentMethods): move all pm migration related changes to payment methods crate (#7786)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: Gnanasundari24 <118818938+Gnanasundari24@users.noreply.github.com>
This commit is contained in:
330
crates/payment_methods/src/helpers.rs
Normal file
330
crates/payment_methods/src/helpers.rs
Normal file
@ -0,0 +1,330 @@
|
||||
use api_models::{enums as api_enums, payment_methods as api};
|
||||
use common_utils::ext_traits::AsyncExt;
|
||||
pub use hyperswitch_domain_models::{errors::api_error_response, payment_methods as domain};
|
||||
use router_env::logger;
|
||||
|
||||
use crate::state;
|
||||
#[cfg(all(
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "payment_methods_v2")
|
||||
))]
|
||||
pub async fn populate_bin_details_for_payment_method_create(
|
||||
card_details: api_models::payment_methods::CardDetail,
|
||||
db: Box<dyn state::PaymentMethodsStorageInterface>,
|
||||
) -> api_models::payment_methods::CardDetail {
|
||||
let card_isin: Option<_> = Some(card_details.card_number.get_card_isin());
|
||||
if card_details.card_issuer.is_some()
|
||||
&& card_details.card_network.is_some()
|
||||
&& card_details.card_type.is_some()
|
||||
&& card_details.card_issuing_country.is_some()
|
||||
{
|
||||
api::CardDetail {
|
||||
card_issuer: card_details.card_issuer.to_owned(),
|
||||
card_network: card_details.card_network.clone(),
|
||||
card_type: card_details.card_type.to_owned(),
|
||||
card_issuing_country: card_details.card_issuing_country.to_owned(),
|
||||
card_exp_month: card_details.card_exp_month.clone(),
|
||||
card_exp_year: card_details.card_exp_year.clone(),
|
||||
card_holder_name: card_details.card_holder_name.clone(),
|
||||
card_number: card_details.card_number.clone(),
|
||||
nick_name: card_details.nick_name.clone(),
|
||||
}
|
||||
} else {
|
||||
let card_info = card_isin
|
||||
.clone()
|
||||
.async_and_then(|card_isin| async move {
|
||||
db.get_card_info(&card_isin)
|
||||
.await
|
||||
.map_err(|error| logger::error!(card_info_error=?error))
|
||||
.ok()
|
||||
})
|
||||
.await
|
||||
.flatten()
|
||||
.map(|card_info| api::CardDetail {
|
||||
card_issuer: card_info.card_issuer,
|
||||
card_network: card_info.card_network.clone(),
|
||||
card_type: card_info.card_type,
|
||||
card_issuing_country: card_info.card_issuing_country,
|
||||
card_exp_month: card_details.card_exp_month.clone(),
|
||||
card_exp_year: card_details.card_exp_year.clone(),
|
||||
card_holder_name: card_details.card_holder_name.clone(),
|
||||
card_number: card_details.card_number.clone(),
|
||||
nick_name: card_details.nick_name.clone(),
|
||||
});
|
||||
card_info.unwrap_or_else(|| api::CardDetail {
|
||||
card_issuer: None,
|
||||
card_network: None,
|
||||
card_type: None,
|
||||
card_issuing_country: None,
|
||||
card_exp_month: card_details.card_exp_month.clone(),
|
||||
card_exp_year: card_details.card_exp_year.clone(),
|
||||
card_holder_name: card_details.card_holder_name.clone(),
|
||||
card_number: card_details.card_number.clone(),
|
||||
nick_name: card_details.nick_name.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
pub async fn populate_bin_details_for_payment_method_create(
|
||||
_card_details: api_models::payment_methods::CardDetail,
|
||||
_db: &dyn state::PaymentMethodsStorageInterface,
|
||||
) -> api_models::payment_methods::CardDetail {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn validate_payment_method_type_against_payment_method(
|
||||
payment_method: api_enums::PaymentMethod,
|
||||
payment_method_type: api_enums::PaymentMethodType,
|
||||
) -> bool {
|
||||
match payment_method {
|
||||
#[cfg(feature = "v1")]
|
||||
api_enums::PaymentMethod::Card => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::Credit | api_enums::PaymentMethodType::Debit
|
||||
),
|
||||
#[cfg(feature = "v2")]
|
||||
api_enums::PaymentMethod::Card => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::Credit
|
||||
| api_enums::PaymentMethodType::Debit
|
||||
| api_enums::PaymentMethodType::Card
|
||||
),
|
||||
api_enums::PaymentMethod::PayLater => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::Affirm
|
||||
| api_enums::PaymentMethodType::Alma
|
||||
| api_enums::PaymentMethodType::AfterpayClearpay
|
||||
| api_enums::PaymentMethodType::Klarna
|
||||
| api_enums::PaymentMethodType::PayBright
|
||||
| api_enums::PaymentMethodType::Atome
|
||||
| api_enums::PaymentMethodType::Walley
|
||||
),
|
||||
api_enums::PaymentMethod::Wallet => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::AmazonPay
|
||||
| api_enums::PaymentMethodType::ApplePay
|
||||
| api_enums::PaymentMethodType::GooglePay
|
||||
| api_enums::PaymentMethodType::Paypal
|
||||
| api_enums::PaymentMethodType::AliPay
|
||||
| api_enums::PaymentMethodType::AliPayHk
|
||||
| api_enums::PaymentMethodType::Dana
|
||||
| api_enums::PaymentMethodType::MbWay
|
||||
| api_enums::PaymentMethodType::MobilePay
|
||||
| api_enums::PaymentMethodType::SamsungPay
|
||||
| api_enums::PaymentMethodType::Twint
|
||||
| api_enums::PaymentMethodType::Vipps
|
||||
| api_enums::PaymentMethodType::TouchNGo
|
||||
| api_enums::PaymentMethodType::Swish
|
||||
| api_enums::PaymentMethodType::WeChatPay
|
||||
| api_enums::PaymentMethodType::GoPay
|
||||
| api_enums::PaymentMethodType::Gcash
|
||||
| api_enums::PaymentMethodType::Momo
|
||||
| api_enums::PaymentMethodType::KakaoPay
|
||||
| api_enums::PaymentMethodType::Cashapp
|
||||
| api_enums::PaymentMethodType::Mifinity
|
||||
| api_enums::PaymentMethodType::Paze
|
||||
),
|
||||
api_enums::PaymentMethod::BankRedirect => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::Giropay
|
||||
| api_enums::PaymentMethodType::Ideal
|
||||
| api_enums::PaymentMethodType::Sofort
|
||||
| api_enums::PaymentMethodType::Eft
|
||||
| api_enums::PaymentMethodType::Eps
|
||||
| api_enums::PaymentMethodType::BancontactCard
|
||||
| api_enums::PaymentMethodType::Blik
|
||||
| api_enums::PaymentMethodType::LocalBankRedirect
|
||||
| api_enums::PaymentMethodType::OnlineBankingThailand
|
||||
| api_enums::PaymentMethodType::OnlineBankingCzechRepublic
|
||||
| api_enums::PaymentMethodType::OnlineBankingFinland
|
||||
| api_enums::PaymentMethodType::OnlineBankingFpx
|
||||
| api_enums::PaymentMethodType::OnlineBankingPoland
|
||||
| api_enums::PaymentMethodType::OnlineBankingSlovakia
|
||||
| api_enums::PaymentMethodType::Przelewy24
|
||||
| api_enums::PaymentMethodType::Trustly
|
||||
| api_enums::PaymentMethodType::Bizum
|
||||
| api_enums::PaymentMethodType::Interac
|
||||
| api_enums::PaymentMethodType::OpenBankingUk
|
||||
| api_enums::PaymentMethodType::OpenBankingPIS
|
||||
),
|
||||
api_enums::PaymentMethod::BankTransfer => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::Ach
|
||||
| api_enums::PaymentMethodType::SepaBankTransfer
|
||||
| api_enums::PaymentMethodType::Bacs
|
||||
| api_enums::PaymentMethodType::Multibanco
|
||||
| api_enums::PaymentMethodType::Pix
|
||||
| api_enums::PaymentMethodType::Pse
|
||||
| api_enums::PaymentMethodType::PermataBankTransfer
|
||||
| api_enums::PaymentMethodType::BcaBankTransfer
|
||||
| api_enums::PaymentMethodType::BniVa
|
||||
| api_enums::PaymentMethodType::BriVa
|
||||
| api_enums::PaymentMethodType::CimbVa
|
||||
| api_enums::PaymentMethodType::DanamonVa
|
||||
| api_enums::PaymentMethodType::MandiriVa
|
||||
| api_enums::PaymentMethodType::LocalBankTransfer
|
||||
| api_enums::PaymentMethodType::InstantBankTransfer
|
||||
),
|
||||
api_enums::PaymentMethod::BankDebit => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::Ach
|
||||
| api_enums::PaymentMethodType::Sepa
|
||||
| api_enums::PaymentMethodType::Bacs
|
||||
| api_enums::PaymentMethodType::Becs
|
||||
),
|
||||
api_enums::PaymentMethod::Crypto => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::CryptoCurrency
|
||||
),
|
||||
api_enums::PaymentMethod::Reward => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::Evoucher | api_enums::PaymentMethodType::ClassicReward
|
||||
),
|
||||
api_enums::PaymentMethod::RealTimePayment => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::Fps
|
||||
| api_enums::PaymentMethodType::DuitNow
|
||||
| api_enums::PaymentMethodType::PromptPay
|
||||
| api_enums::PaymentMethodType::VietQr
|
||||
),
|
||||
api_enums::PaymentMethod::Upi => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::UpiCollect | api_enums::PaymentMethodType::UpiIntent
|
||||
),
|
||||
api_enums::PaymentMethod::Voucher => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::Boleto
|
||||
| api_enums::PaymentMethodType::Efecty
|
||||
| api_enums::PaymentMethodType::PagoEfectivo
|
||||
| api_enums::PaymentMethodType::RedCompra
|
||||
| api_enums::PaymentMethodType::RedPagos
|
||||
| api_enums::PaymentMethodType::Indomaret
|
||||
| api_enums::PaymentMethodType::Alfamart
|
||||
| api_enums::PaymentMethodType::Oxxo
|
||||
| api_enums::PaymentMethodType::SevenEleven
|
||||
| api_enums::PaymentMethodType::Lawson
|
||||
| api_enums::PaymentMethodType::MiniStop
|
||||
| api_enums::PaymentMethodType::FamilyMart
|
||||
| api_enums::PaymentMethodType::Seicomart
|
||||
| api_enums::PaymentMethodType::PayEasy
|
||||
),
|
||||
api_enums::PaymentMethod::GiftCard => {
|
||||
matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::Givex | api_enums::PaymentMethodType::PaySafeCard
|
||||
)
|
||||
}
|
||||
api_enums::PaymentMethod::CardRedirect => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::Knet
|
||||
| api_enums::PaymentMethodType::Benefit
|
||||
| api_enums::PaymentMethodType::MomoAtm
|
||||
| api_enums::PaymentMethodType::CardRedirect
|
||||
),
|
||||
api_enums::PaymentMethod::OpenBanking => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::OpenBankingPIS
|
||||
),
|
||||
api_enums::PaymentMethod::MobilePayment => matches!(
|
||||
payment_method_type,
|
||||
api_enums::PaymentMethodType::DirectCarrierBilling
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ForeignFrom<F> {
|
||||
fn foreign_from(from: F) -> Self;
|
||||
}
|
||||
|
||||
/// Trait for converting from one foreign type to another
|
||||
pub trait ForeignTryFrom<F>: Sized {
|
||||
/// Custom error for conversion failure
|
||||
type Error;
|
||||
/// Convert from a foreign type to the current type and return an error if the conversion fails
|
||||
fn foreign_try_from(from: F) -> Result<Self, Self::Error>;
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "payment_methods_v2")
|
||||
))]
|
||||
impl ForeignFrom<(Option<api::CardDetailFromLocker>, domain::PaymentMethod)>
|
||||
for api::PaymentMethodResponse
|
||||
{
|
||||
fn foreign_from(
|
||||
(card_details, item): (Option<api::CardDetailFromLocker>, domain::PaymentMethod),
|
||||
) -> Self {
|
||||
Self {
|
||||
merchant_id: item.merchant_id.to_owned(),
|
||||
customer_id: Some(item.customer_id.to_owned()),
|
||||
payment_method_id: item.get_id().clone(),
|
||||
payment_method: item.get_payment_method_type(),
|
||||
payment_method_type: item.get_payment_method_subtype(),
|
||||
card: card_details,
|
||||
recurring_enabled: false,
|
||||
installment_payment_enabled: false,
|
||||
payment_experience: None,
|
||||
metadata: item.metadata,
|
||||
created: Some(item.created_at),
|
||||
#[cfg(feature = "payouts")]
|
||||
bank_transfer: None,
|
||||
last_used_at: None,
|
||||
client_secret: item.client_secret,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
impl ForeignFrom<(Option<api::CardDetailFromLocker>, domain::PaymentMethod)>
|
||||
for api::PaymentMethodResponse
|
||||
{
|
||||
fn foreign_from(
|
||||
(card_details, item): (Option<api::CardDetailFromLocker>, domain::PaymentMethod),
|
||||
) -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait StorageErrorExt<T, E> {
|
||||
#[track_caller]
|
||||
fn to_not_found_response(self, not_found_response: E) -> error_stack::Result<T, E>;
|
||||
|
||||
#[track_caller]
|
||||
fn to_duplicate_response(self, duplicate_response: E) -> error_stack::Result<T, E>;
|
||||
}
|
||||
|
||||
impl<T> StorageErrorExt<T, api_error_response::ApiErrorResponse>
|
||||
for error_stack::Result<T, storage_impl::StorageError>
|
||||
{
|
||||
#[track_caller]
|
||||
fn to_not_found_response(
|
||||
self,
|
||||
not_found_response: api_error_response::ApiErrorResponse,
|
||||
) -> error_stack::Result<T, api_error_response::ApiErrorResponse> {
|
||||
self.map_err(|err| {
|
||||
let new_err = match err.current_context() {
|
||||
storage_impl::StorageError::ValueNotFound(_) => not_found_response,
|
||||
storage_impl::StorageError::CustomerRedacted => {
|
||||
api_error_response::ApiErrorResponse::CustomerRedacted
|
||||
}
|
||||
_ => api_error_response::ApiErrorResponse::InternalServerError,
|
||||
};
|
||||
err.change_context(new_err)
|
||||
})
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn to_duplicate_response(
|
||||
self,
|
||||
duplicate_response: api_error_response::ApiErrorResponse,
|
||||
) -> error_stack::Result<T, api_error_response::ApiErrorResponse> {
|
||||
self.map_err(|err| {
|
||||
let new_err = match err.current_context() {
|
||||
storage_impl::StorageError::DuplicateValue { .. } => duplicate_response,
|
||||
_ => api_error_response::ApiErrorResponse::InternalServerError,
|
||||
};
|
||||
err.change_context(new_err)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user