mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 01:27:31 +08:00
feat(router): add card_info in payment_attempt table if not provided in request (#1538)
Co-authored-by: Sahkal Poddar <sahkal.poddar@juspay.in>
This commit is contained in:
@ -551,6 +551,14 @@ pub struct Card {
|
|||||||
#[schema(value_type = Option<CardNetwork>, example = "Visa")]
|
#[schema(value_type = Option<CardNetwork>, example = "Visa")]
|
||||||
pub card_network: Option<api_enums::CardNetwork>,
|
pub card_network: Option<api_enums::CardNetwork>,
|
||||||
|
|
||||||
|
#[schema(example = "CREDIT")]
|
||||||
|
pub card_type: Option<String>,
|
||||||
|
|
||||||
|
#[schema(example = "INDIA")]
|
||||||
|
pub card_issuing_country: Option<String>,
|
||||||
|
|
||||||
|
#[schema(example = "JP_AMEX")]
|
||||||
|
pub bank_code: Option<String>,
|
||||||
/// The card holder's nick name
|
/// The card holder's nick name
|
||||||
#[schema(value_type = Option<String>, example = "John Test")]
|
#[schema(value_type = Option<String>, example = "John Test")]
|
||||||
pub nick_name: Option<Secret<String>>,
|
pub nick_name: Option<Secret<String>>,
|
||||||
@ -663,7 +671,10 @@ pub enum PaymentMethodData {
|
|||||||
pub enum AdditionalPaymentData {
|
pub enum AdditionalPaymentData {
|
||||||
Card {
|
Card {
|
||||||
card_issuer: Option<String>,
|
card_issuer: Option<String>,
|
||||||
card_network: Option<String>,
|
card_network: Option<api_enums::CardNetwork>,
|
||||||
|
card_type: Option<String>,
|
||||||
|
card_issuing_country: Option<String>,
|
||||||
|
bank_code: Option<String>,
|
||||||
},
|
},
|
||||||
BankRedirect {
|
BankRedirect {
|
||||||
bank_name: Option<api_enums::BankNames>,
|
bank_name: Option<api_enums::BankNames>,
|
||||||
@ -678,37 +689,6 @@ pub enum AdditionalPaymentData {
|
|||||||
Upi {},
|
Upi {},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&PaymentMethodData> for AdditionalPaymentData {
|
|
||||||
fn from(pm_data: &PaymentMethodData) -> Self {
|
|
||||||
match pm_data {
|
|
||||||
PaymentMethodData::Card(card_data) => Self::Card {
|
|
||||||
card_issuer: card_data.card_issuer.to_owned(),
|
|
||||||
card_network: card_data
|
|
||||||
.card_network
|
|
||||||
.as_ref()
|
|
||||||
.map(|card_network| card_network.to_string()),
|
|
||||||
},
|
|
||||||
PaymentMethodData::BankRedirect(bank_redirect_data) => match bank_redirect_data {
|
|
||||||
BankRedirectData::Eps { bank_name, .. } => Self::BankRedirect {
|
|
||||||
bank_name: bank_name.to_owned(),
|
|
||||||
},
|
|
||||||
BankRedirectData::Ideal { bank_name, .. } => Self::BankRedirect {
|
|
||||||
bank_name: bank_name.to_owned(),
|
|
||||||
},
|
|
||||||
_ => Self::BankRedirect { bank_name: None },
|
|
||||||
},
|
|
||||||
PaymentMethodData::Wallet(_) => Self::Wallet {},
|
|
||||||
PaymentMethodData::PayLater(_) => Self::PayLater {},
|
|
||||||
PaymentMethodData::BankTransfer(_) => Self::BankTransfer {},
|
|
||||||
PaymentMethodData::Crypto(_) => Self::Crypto {},
|
|
||||||
PaymentMethodData::BankDebit(_) => Self::BankDebit {},
|
|
||||||
PaymentMethodData::MandatePayment => Self::MandatePayment {},
|
|
||||||
PaymentMethodData::Reward(_) => Self::Reward {},
|
|
||||||
PaymentMethodData::Upi(_) => Self::Upi {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)]
|
#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum BankRedirectData {
|
pub enum BankRedirectData {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::{fmt, ops::Deref, str::FromStr};
|
use std::{fmt, ops::Deref, str::FromStr};
|
||||||
|
|
||||||
use masking::{Strategy, StrongSecret, WithType};
|
use masking::{PeekInterface, Strategy, StrongSecret, WithType};
|
||||||
use serde::{Deserialize, Deserializer, Serialize};
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
@ -18,6 +18,12 @@ impl From<core::convert::Infallible> for CCValError {
|
|||||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
|
||||||
pub struct CardNumber(StrongSecret<String, CardNumberStrategy>);
|
pub struct CardNumber(StrongSecret<String, CardNumberStrategy>);
|
||||||
|
|
||||||
|
impl CardNumber {
|
||||||
|
pub fn get_card_isin(self) -> String {
|
||||||
|
self.0.peek().chars().take(6).collect::<String>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for CardNumber {
|
impl FromStr for CardNumber {
|
||||||
type Err = CCValError;
|
type Err = CCValError;
|
||||||
|
|
||||||
|
|||||||
@ -98,6 +98,9 @@ impl From<StripeCard> for payments::Card {
|
|||||||
card_cvc: card.cvc,
|
card_cvc: card.cvc,
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
bank_code: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
card_type: None,
|
||||||
nick_name: None,
|
nick_name: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,6 +89,9 @@ impl From<StripeCard> for payments::Card {
|
|||||||
card_cvc: card.cvc,
|
card_cvc: card.cvc,
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
bank_code: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
card_type: None,
|
||||||
nick_name: None,
|
nick_name: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -106,6 +106,9 @@ impl Vaultable for api::Card {
|
|||||||
card_cvc: value2.card_security_code.unwrap_or_default().into(),
|
card_cvc: value2.card_security_code.unwrap_or_default().into(),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
bank_code: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
card_type: None,
|
||||||
nick_name: value1.nickname.map(masking::Secret::new),
|
nick_name: value1.nickname.map(masking::Secret::new),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -2449,3 +2449,93 @@ mod test {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_additional_payment_data(
|
||||||
|
pm_data: &api_models::payments::PaymentMethodData,
|
||||||
|
db: &dyn StorageInterface,
|
||||||
|
) -> api_models::payments::AdditionalPaymentData {
|
||||||
|
match pm_data {
|
||||||
|
api_models::payments::PaymentMethodData::Card(card_data) => {
|
||||||
|
if card_data.card_issuer.is_some()
|
||||||
|
&& card_data.card_network.is_some()
|
||||||
|
&& card_data.card_type.is_some()
|
||||||
|
&& card_data.card_issuing_country.is_some()
|
||||||
|
&& card_data.bank_code.is_some()
|
||||||
|
{
|
||||||
|
api_models::payments::AdditionalPaymentData::Card {
|
||||||
|
card_issuer: card_data.card_issuer.to_owned(),
|
||||||
|
card_network: card_data.card_network.clone(),
|
||||||
|
card_type: card_data.card_type.to_owned(),
|
||||||
|
card_issuing_country: card_data.card_issuing_country.to_owned(),
|
||||||
|
bank_code: card_data.bank_code.to_owned(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let card_number = card_data.clone().card_number;
|
||||||
|
let card_info = db
|
||||||
|
.get_card_info(&card_number.get_card_isin())
|
||||||
|
.await
|
||||||
|
.map_err(|error| services::logger::warn!(card_info_error=?error))
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
.map(
|
||||||
|
|card_info| api_models::payments::AdditionalPaymentData::Card {
|
||||||
|
card_issuer: card_info.card_issuer,
|
||||||
|
card_network: card_info
|
||||||
|
.card_network
|
||||||
|
.clone()
|
||||||
|
.map(|network| network.foreign_into()),
|
||||||
|
bank_code: card_info.bank_code,
|
||||||
|
card_type: card_info.card_type,
|
||||||
|
card_issuing_country: card_info.card_issuing_country,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
card_info.unwrap_or(api_models::payments::AdditionalPaymentData::Card {
|
||||||
|
card_issuer: None,
|
||||||
|
card_network: None,
|
||||||
|
bank_code: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
api_models::payments::PaymentMethodData::BankRedirect(bank_redirect_data) => {
|
||||||
|
match bank_redirect_data {
|
||||||
|
api_models::payments::BankRedirectData::Eps { bank_name, .. } => {
|
||||||
|
api_models::payments::AdditionalPaymentData::BankRedirect {
|
||||||
|
bank_name: bank_name.to_owned(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
api_models::payments::BankRedirectData::Ideal { bank_name, .. } => {
|
||||||
|
api_models::payments::AdditionalPaymentData::BankRedirect {
|
||||||
|
bank_name: bank_name.to_owned(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => api_models::payments::AdditionalPaymentData::BankRedirect { bank_name: None },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
api_models::payments::PaymentMethodData::Wallet(_) => {
|
||||||
|
api_models::payments::AdditionalPaymentData::Wallet {}
|
||||||
|
}
|
||||||
|
api_models::payments::PaymentMethodData::PayLater(_) => {
|
||||||
|
api_models::payments::AdditionalPaymentData::PayLater {}
|
||||||
|
}
|
||||||
|
api_models::payments::PaymentMethodData::BankTransfer(_) => {
|
||||||
|
api_models::payments::AdditionalPaymentData::BankTransfer {}
|
||||||
|
}
|
||||||
|
api_models::payments::PaymentMethodData::Crypto(_) => {
|
||||||
|
api_models::payments::AdditionalPaymentData::Crypto {}
|
||||||
|
}
|
||||||
|
api_models::payments::PaymentMethodData::BankDebit(_) => {
|
||||||
|
api_models::payments::AdditionalPaymentData::BankDebit {}
|
||||||
|
}
|
||||||
|
api_models::payments::PaymentMethodData::MandatePayment => {
|
||||||
|
api_models::payments::AdditionalPaymentData::MandatePayment {}
|
||||||
|
}
|
||||||
|
api_models::payments::PaymentMethodData::Reward(_) => {
|
||||||
|
api_models::payments::AdditionalPaymentData::Reward {}
|
||||||
|
}
|
||||||
|
api_models::payments::PaymentMethodData::Upi(_) => {
|
||||||
|
api_models::payments::AdditionalPaymentData::Upi {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -397,7 +397,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
|||||||
let additional_pm_data = payment_data
|
let additional_pm_data = payment_data
|
||||||
.payment_method_data
|
.payment_method_data
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(api_models::payments::AdditionalPaymentData::from)
|
.async_map(|payment_method_data| async {
|
||||||
|
helpers::get_additional_payment_data(payment_method_data, db).await
|
||||||
|
})
|
||||||
|
.await
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(Encode::<api_models::payments::AdditionalPaymentData>::encode_to_value)
|
.map(Encode::<api_models::payments::AdditionalPaymentData>::encode_to_value)
|
||||||
.transpose()
|
.transpose()
|
||||||
|
|||||||
@ -55,7 +55,6 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
let ephemeral_key = Self::get_ephemeral_key(request, state, merchant_account).await;
|
let ephemeral_key = Self::get_ephemeral_key(request, state, merchant_account).await;
|
||||||
let merchant_id = &merchant_account.merchant_id;
|
let merchant_id = &merchant_account.merchant_id;
|
||||||
let storage_scheme = merchant_account.storage_scheme;
|
let storage_scheme = merchant_account.storage_scheme;
|
||||||
|
|
||||||
let (payment_intent, payment_attempt, connector_response);
|
let (payment_intent, payment_attempt, connector_response);
|
||||||
|
|
||||||
let money @ (amount, currency) = payments_create_request_validation(request)?;
|
let money @ (amount, currency) = payments_create_request_validation(request)?;
|
||||||
@ -116,7 +115,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
payment_method_type,
|
payment_method_type,
|
||||||
request,
|
request,
|
||||||
browser_info,
|
browser_info,
|
||||||
)?,
|
db,
|
||||||
|
)
|
||||||
|
.await?,
|
||||||
storage_scheme,
|
storage_scheme,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@ -486,7 +487,8 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentCreate
|
|||||||
|
|
||||||
impl PaymentCreate {
|
impl PaymentCreate {
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
fn make_payment_attempt(
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub async fn make_payment_attempt(
|
||||||
payment_id: &str,
|
payment_id: &str,
|
||||||
merchant_id: &str,
|
merchant_id: &str,
|
||||||
money: (api::Amount, enums::Currency),
|
money: (api::Amount, enums::Currency),
|
||||||
@ -494,6 +496,7 @@ impl PaymentCreate {
|
|||||||
payment_method_type: Option<enums::PaymentMethodType>,
|
payment_method_type: Option<enums::PaymentMethodType>,
|
||||||
request: &api::PaymentsRequest,
|
request: &api::PaymentsRequest,
|
||||||
browser_info: Option<serde_json::Value>,
|
browser_info: Option<serde_json::Value>,
|
||||||
|
db: &dyn StorageInterface,
|
||||||
) -> RouterResult<storage::PaymentAttemptNew> {
|
) -> RouterResult<storage::PaymentAttemptNew> {
|
||||||
let created_at @ modified_at @ last_synced = Some(common_utils::date_time::now());
|
let created_at @ modified_at @ last_synced = Some(common_utils::date_time::now());
|
||||||
let status =
|
let status =
|
||||||
@ -503,7 +506,10 @@ impl PaymentCreate {
|
|||||||
let additional_pm_data = request
|
let additional_pm_data = request
|
||||||
.payment_method_data
|
.payment_method_data
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(api_models::payments::AdditionalPaymentData::from)
|
.async_map(|payment_method_data| async {
|
||||||
|
helpers::get_additional_payment_data(payment_method_data, db).await
|
||||||
|
})
|
||||||
|
.await
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(Encode::<api_models::payments::AdditionalPaymentData>::encode_to_value)
|
.map(Encode::<api_models::payments::AdditionalPaymentData>::encode_to_value)
|
||||||
.transpose()
|
.transpose()
|
||||||
|
|||||||
@ -429,7 +429,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
|||||||
let additional_pm_data = payment_data
|
let additional_pm_data = payment_data
|
||||||
.payment_method_data
|
.payment_method_data
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(api_models::payments::AdditionalPaymentData::from)
|
.async_map(|payment_method_data| async {
|
||||||
|
helpers::get_additional_payment_data(payment_method_data, db).await
|
||||||
|
})
|
||||||
|
.await
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(Encode::<api_models::payments::AdditionalPaymentData>::encode_to_value)
|
.map(Encode::<api_models::payments::AdditionalPaymentData>::encode_to_value)
|
||||||
.transpose()
|
.transpose()
|
||||||
|
|||||||
@ -233,6 +233,9 @@ mod payments_test {
|
|||||||
card_cvc: "123".to_string().into(),
|
card_cvc: "123".to_string().into(),
|
||||||
card_issuer: Some("HDFC".to_string()),
|
card_issuer: Some("HDFC".to_string()),
|
||||||
card_network: Some(api_models::enums::CardNetwork::Visa),
|
card_network: Some(api_models::enums::CardNetwork::Visa),
|
||||||
|
bank_code: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
card_type: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -174,6 +174,7 @@ impl ForeignFrom<api_models::payments::MandateType> for storage_enums::MandateDa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ForeignFrom<storage_enums::MandateDataType> for api_models::payments::MandateType {
|
impl ForeignFrom<storage_enums::MandateDataType> for api_models::payments::MandateType {
|
||||||
fn foreign_from(from: storage_enums::MandateDataType) -> Self {
|
fn foreign_from(from: storage_enums::MandateDataType) -> Self {
|
||||||
match from {
|
match from {
|
||||||
@ -572,7 +573,7 @@ impl ForeignFrom<storage_models::cards_info::CardInfo>
|
|||||||
card_iin: item.card_iin,
|
card_iin: item.card_iin,
|
||||||
card_type: item.card_type,
|
card_type: item.card_type,
|
||||||
card_sub_type: item.card_subtype,
|
card_sub_type: item.card_subtype,
|
||||||
card_network: item.card_network,
|
card_network: item.card_network.map(|x| x.to_string()),
|
||||||
card_issuer: item.card_issuer,
|
card_issuer: item.card_issuer,
|
||||||
card_issuing_country: item.card_issuing_country,
|
card_issuing_country: item.card_issuing_country,
|
||||||
}
|
}
|
||||||
@ -619,3 +620,9 @@ impl TryFrom<domain::MerchantConnectorAccount> for api_models::admin::MerchantCo
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ForeignFrom<storage_models::enums::CardNetwork> for api_models::enums::CardNetwork {
|
||||||
|
fn foreign_from(source: storage_models::enums::CardNetwork) -> Self {
|
||||||
|
frunk::labelled_convert_from(source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -42,6 +42,9 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData {
|
|||||||
card_cvc: Secret::new("999".to_string()),
|
card_cvc: Secret::new("999".to_string()),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
bank_code: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
}),
|
}),
|
||||||
confirm: true,
|
confirm: true,
|
||||||
@ -188,6 +191,9 @@ async fn payments_create_failure() {
|
|||||||
card_cvc: Secret::new("99".to_string()),
|
card_cvc: Secret::new("99".to_string()),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
bank_code: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -70,6 +70,9 @@ impl AdyenTest {
|
|||||||
card_cvc: Secret::new(card_cvc.to_string()),
|
card_cvc: Secret::new(card_cvc.to_string()),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
bank_code: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
}),
|
}),
|
||||||
confirm: true,
|
confirm: true,
|
||||||
|
|||||||
@ -62,6 +62,9 @@ fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
|
|||||||
card_cvc: Secret::new("123".to_string()),
|
card_cvc: Secret::new("123".to_string()),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
bank_code: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
}),
|
}),
|
||||||
capture_method: Some(storage_models::enums::CaptureMethod::Manual),
|
capture_method: Some(storage_models::enums::CaptureMethod::Manual),
|
||||||
|
|||||||
@ -48,6 +48,9 @@ fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
|
|||||||
card_cvc: Secret::new("123".to_string()),
|
card_cvc: Secret::new("123".to_string()),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
bank_code: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
}),
|
}),
|
||||||
capture_method: Some(storage_models::enums::CaptureMethod::Manual),
|
capture_method: Some(storage_models::enums::CaptureMethod::Manual),
|
||||||
|
|||||||
@ -48,6 +48,9 @@ async fn should_only_authorize_payment() {
|
|||||||
card_cvc: Secret::new("123".to_string()),
|
card_cvc: Secret::new("123".to_string()),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
bank_code: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
}),
|
}),
|
||||||
capture_method: Some(storage_models::enums::CaptureMethod::Manual),
|
capture_method: Some(storage_models::enums::CaptureMethod::Manual),
|
||||||
@ -73,6 +76,9 @@ async fn should_authorize_and_capture_payment() {
|
|||||||
card_cvc: Secret::new("123".to_string()),
|
card_cvc: Secret::new("123".to_string()),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
bank_code: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
}),
|
}),
|
||||||
..utils::PaymentAuthorizeType::default().0
|
..utils::PaymentAuthorizeType::default().0
|
||||||
|
|||||||
@ -489,6 +489,9 @@ impl Default for CCardType {
|
|||||||
card_cvc: Secret::new("999".to_string()),
|
card_cvc: Secret::new("999".to_string()),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
bank_code: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,6 +73,9 @@ impl WorldlineTest {
|
|||||||
card_cvc: Secret::new(card_cvc.to_string()),
|
card_cvc: Secret::new(card_cvc.to_string()),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
bank_code: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
}),
|
}),
|
||||||
confirm: true,
|
confirm: true,
|
||||||
|
|||||||
@ -318,6 +318,9 @@ async fn payments_create_core() {
|
|||||||
card_cvc: "123".to_string().into(),
|
card_cvc: "123".to_string().into(),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
bank_code: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
})),
|
})),
|
||||||
payment_method: Some(api_enums::PaymentMethod::Card),
|
payment_method: Some(api_enums::PaymentMethod::Card),
|
||||||
@ -476,6 +479,9 @@ async fn payments_create_core_adyen_no_redirect() {
|
|||||||
card_cvc: "737".to_string().into(),
|
card_cvc: "737".to_string().into(),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
bank_code: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
})),
|
})),
|
||||||
payment_method: Some(api_enums::PaymentMethod::Card),
|
payment_method: Some(api_enums::PaymentMethod::Card),
|
||||||
|
|||||||
@ -78,6 +78,9 @@ async fn payments_create_core() {
|
|||||||
card_cvc: "123".to_string().into(),
|
card_cvc: "123".to_string().into(),
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
|
bank_code: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
})),
|
})),
|
||||||
payment_method: Some(api_enums::PaymentMethod::Card),
|
payment_method: Some(api_enums::PaymentMethod::Card),
|
||||||
@ -240,15 +243,14 @@ async fn payments_create_core_adyen_no_redirect() {
|
|||||||
card_exp_year: "2030".to_string().into(),
|
card_exp_year: "2030".to_string().into(),
|
||||||
card_holder_name: "JohnDoe".to_string().into(),
|
card_holder_name: "JohnDoe".to_string().into(),
|
||||||
card_cvc: "737".to_string().into(),
|
card_cvc: "737".to_string().into(),
|
||||||
|
bank_code: None,
|
||||||
card_issuer: None,
|
card_issuer: None,
|
||||||
card_network: None,
|
card_network: None,
|
||||||
|
card_type: None,
|
||||||
|
card_issuing_country: None,
|
||||||
nick_name: Some(masking::Secret::new("nick_name".into())),
|
nick_name: Some(masking::Secret::new("nick_name".into())),
|
||||||
})),
|
})),
|
||||||
payment_method: Some(api_enums::PaymentMethod::Card),
|
payment_method: Some(api_enums::PaymentMethod::Card),
|
||||||
shipping: Some(api::Address {
|
|
||||||
address: None,
|
|
||||||
phone: None,
|
|
||||||
}),
|
|
||||||
billing: Some(api::Address {
|
billing: Some(api::Address {
|
||||||
address: None,
|
address: None,
|
||||||
phone: None,
|
phone: None,
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
use diesel::{Identifiable, Queryable};
|
use diesel::{Identifiable, Queryable};
|
||||||
use time::PrimitiveDateTime;
|
use time::PrimitiveDateTime;
|
||||||
|
|
||||||
use crate::schema::cards_info;
|
use crate::{enums as storage_enums, schema::cards_info};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Queryable, Identifiable, serde::Deserialize, serde::Serialize)]
|
#[derive(Clone, Debug, Queryable, Identifiable, serde::Deserialize, serde::Serialize)]
|
||||||
#[diesel(table_name = cards_info, primary_key(card_iin))]
|
#[diesel(table_name = cards_info, primary_key(card_iin))]
|
||||||
pub struct CardInfo {
|
pub struct CardInfo {
|
||||||
pub card_iin: String,
|
pub card_iin: String,
|
||||||
pub card_issuer: Option<String>,
|
pub card_issuer: Option<String>,
|
||||||
pub card_network: Option<String>,
|
pub card_network: Option<storage_enums::CardNetwork>,
|
||||||
pub card_type: Option<String>,
|
pub card_type: Option<String>,
|
||||||
pub card_subtype: Option<String>,
|
pub card_subtype: Option<String>,
|
||||||
pub card_issuing_country: Option<String>,
|
pub card_issuing_country: Option<String>,
|
||||||
|
|||||||
@ -805,6 +805,33 @@ pub enum BankNames {
|
|||||||
Boz,
|
Boz,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
Eq,
|
||||||
|
Hash,
|
||||||
|
PartialEq,
|
||||||
|
serde::Deserialize,
|
||||||
|
serde::Serialize,
|
||||||
|
strum::Display,
|
||||||
|
strum::EnumString,
|
||||||
|
frunk::LabelledGeneric,
|
||||||
|
)]
|
||||||
|
#[router_derive::diesel_enum(storage_type = "text")]
|
||||||
|
pub enum CardNetwork {
|
||||||
|
Visa,
|
||||||
|
Mastercard,
|
||||||
|
AmericanExpress,
|
||||||
|
JCB,
|
||||||
|
DinersClub,
|
||||||
|
Discover,
|
||||||
|
CartesBancaires,
|
||||||
|
UnionPay,
|
||||||
|
Interac,
|
||||||
|
RuPay,
|
||||||
|
Maestro,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Eq,
|
Eq,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
|
|||||||
@ -2764,6 +2764,21 @@
|
|||||||
],
|
],
|
||||||
"nullable": true
|
"nullable": true
|
||||||
},
|
},
|
||||||
|
"card_type": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "CREDIT",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"card_issuing_country": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "INDIA",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"bank_code": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "JP_AMEX",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
"nick_name": {
|
"nick_name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The card holder's nick name",
|
"description": "The card holder's nick name",
|
||||||
|
|||||||
Reference in New Issue
Block a user