Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): add bulk tokenization flows #7066

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/api_models/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ mime = "0.3.17"
reqwest = { version = "0.11.27", optional = true }
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.115"
serde_with = "3.7.1"
strum = { version = "0.26", features = ["derive"] }
time = { version = "0.3.35", features = ["serde", "serde-well-known", "std"] }
url = { version = "2.5.0", features = ["serde"] }
Expand Down
129 changes: 128 additions & 1 deletion crates/api_models/src/payment_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,6 @@ pub struct CardDetail {
pub card_type: Option<String>,
}

#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
#[derive(
Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema, strum::EnumString, strum::Display,
)]
Expand Down Expand Up @@ -2396,3 +2395,131 @@ impl From<(PaymentMethodRecord, id_type::MerchantId)> for customers::CustomerReq
// }
// }
// }

#[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct CardNetworkTokenizeRequest {
/// Merchant ID associated with the tokenization request
pub merchant_id: id_type::MerchantId,

#[serde(flatten)]
pub data: TokenizeDataRequest,

/// Card type
pub card_type: Option<CardType>,

/// Customer details
pub customer: Option<payments::CustomerDetails>,

/// The billing details of the payment method
pub billing: Option<payments::Address>,

/// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.
pub metadata: Option<pii::SecretSerdeValue>,

/// The name of the bank/ provider issuing the payment method to the end user
pub payment_method_issuer: Option<String>,
}

impl common_utils::events::ApiEventMetric for CardNetworkTokenizeRequest {}

#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum TokenizeDataRequest {
Card(TokenizeCardRequest),
PaymentMethod(TokenizePaymentMethodRequest),
}

#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, ToSchema)]
#[serde(deny_unknown_fields)]
pub struct TokenizeCardRequest {
/// Card Number
#[schema(value_type = String, example = "4111111145551142")]
pub raw_card_number: masking::Secret<String>,

/// Card Expiry Month
#[schema(value_type = String, example = "10")]
pub card_expiry_month: masking::Secret<String>,

/// Card Expiry Year
#[schema(value_type = String, example = "25")]
pub card_expiry_year: masking::Secret<String>,

/// The CVC number for the card
#[schema(value_type = String, example = "242")]
pub card_cvc: masking::Secret<String>,

/// Card Holder Name
#[schema(value_type = Option<String>, example = "John Doe")]
pub card_holder_name: Option<masking::Secret<String>>,

/// Card Holder's Nick Name
#[schema(value_type = Option<String>, example = "John Doe")]
pub nick_name: Option<masking::Secret<String>>,

/// Card Issuing Country
pub card_issuing_country: Option<String>,

/// Card's Network
#[schema(value_type = Option<CardNetwork>)]
pub card_network: Option<api_enums::CardNetwork>,

/// Issuer Bank for Card
pub card_issuer: Option<String>,

/// Card Type
pub card_type: Option<CardType>,
}

#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct TokenizePaymentMethodRequest {
/// Payment method's ID
pub payment_method_id: String,

/// The CVC number for the card
pub card_cvc: masking::Secret<String>,
}

#[derive(Debug, Default, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct CardNetworkTokenizeResponse {
/// Response for payment method entry in DB
pub payment_method_response: Option<PaymentMethodResponse>,

/// Customer details
pub customer: Option<payments::CustomerDetails>,

/// Card network tokenization status
pub card_tokenized: bool,

/// Error code
#[serde(skip_serializing_if = "Option::is_none")]
pub error_code: Option<String>,

/// Error message
#[serde(skip_serializing_if = "Option::is_none")]
pub error_message: Option<String>,

/// Details that were sent for tokenization
#[serde(skip_serializing_if = "Option::is_none")]
pub req: Option<TokenizeDataRequest>,
}

impl common_utils::events::ApiEventMetric for CardNetworkTokenizeResponse {}

impl From<&Card> for MigrateCardDetail {
fn from(card: &Card) -> Self {
Self {
card_number: masking::Secret::new(card.card_number.get_card_no()),
card_exp_month: card.card_exp_month.clone(),
card_exp_year: card.card_exp_year.clone(),
card_holder_name: card.name_on_card.clone(),
nick_name: card
.nick_name
.as_ref()
.map(|name| masking::Secret::new(name.clone())),
card_issuing_country: None,
card_network: None,
card_issuer: None,
card_type: None,
}
}
}
Loading
Loading