Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
64d4bde
feat(network-tokenization): expose flows for card network tokenization
kashif-m Jan 7, 2025
e2eeeeb
feat(bulk-tokenization): add pm id flow and batch flow
kashif-m Jan 10, 2025
a2e626a
Merge remote-tracking branch 'origin/main' into 6969-feature-expose-t…
kashif-m Jan 20, 2025
0e73f1d
chore: run formatter
hyperswitch-bot[bot] Jan 20, 2025
c278183
chore: address clippy suggestions and remove redundant changes
kashif-m Jan 20, 2025
2fd2787
chore: revert a few changes
kashif-m Jan 20, 2025
d4d0fae
chore: run formatter
hyperswitch-bot[bot] Jan 20, 2025
60b90dd
chore: revert
kashif-m Jan 20, 2025
8fc2a77
Merge remote-tracking branch 'origin/main' into 6969-feature-expose-t…
kashif-m Jan 21, 2025
06e0c4f
chore: update sm
kashif-m Jan 22, 2025
530cd0d
Merge remote-tracking branch 'origin/main' into 6969-feature-expose-t…
kashif-m Jan 22, 2025
e9c4d87
Merge remote-tracking branch 'origin/main' into 6969-feature-expose-t…
kashif-m Jan 23, 2025
80c27d5
chore: add v2 flags
kashif-m Jan 23, 2025
5842421
chore: run formatter
hyperswitch-bot[bot] Jan 23, 2025
aa0676f
refactor: add a common trait for common tokenization steps and resolv…
kashif-m Jan 30, 2025
f1c8122
chore: run formatter
hyperswitch-bot[bot] Jan 30, 2025
e0547f0
refactor: use generic impl and fix clippy
kashif-m Jan 30, 2025
1deeb07
chore: run formatter
hyperswitch-bot[bot] Jan 30, 2025
66f16e7
refactor: make customer a required field
kashif-m Jan 31, 2025
8b86c39
chore: run formatter
hyperswitch-bot[bot] Jan 31, 2025
dac3060
Merge branch 'main' into 6969-feature-expose-tokenize-endpoints
kashif-m Feb 3, 2025
364ec3e
refactor: resolve comments and add more validations
kashif-m Feb 3, 2025
152184d
chore: add CardDetail domain type
kashif-m Feb 5, 2025
5812e79
Merge remote-tracking branch 'origin/main' into 6969-feature-expose-t…
kashif-m Feb 5, 2025
5b8813c
chore: run formatter
hyperswitch-bot[bot] Feb 5, 2025
89e7b3e
chore: use stricter types in the match statement
kashif-m Feb 6, 2025
2a9975d
Merge remote-tracking branch 'origin/main' into 6969-feature-expose-t…
kashif-m Feb 18, 2025
4ebd5d7
chore: resolve comments
kashif-m Feb 19, 2025
2a9f5b3
Merge remote-tracking branch 'origin/main' into 6969-feature-expose-t…
kashif-m Feb 19, 2025
2ddc524
chore: resolve missed merge conflict
kashif-m Feb 19, 2025
98eef21
refactor: expose a separate endpoint for tokenizing with PM ID
kashif-m Feb 20, 2025
35f864a
refactor: fill pm_id from path into request body
kashif-m Feb 20, 2025
9faf424
Merge remote-tracking branch 'origin/main' into 6969-feature-expose-t…
kashif-m Feb 20, 2025
9f9d6d7
Merge remote-tracking branch 'origin/main' into 6969-feature-expose-t…
kashif-m Feb 21, 2025
67e79d5
refactor: network tokenization API path
kashif-m Feb 21, 2025
a02c7da
Merge remote-tracking branch 'origin/main' into 6969-feature-expose-t…
kashif-m Feb 24, 2025
de5cd31
Merge remote-tracking branch 'origin/main' into 6969-feature-expose-t…
kashif-m Feb 28, 2025
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