feat(router): Add support for network token migration (#6300)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Prasunna Soppa
2024-11-20 18:43:12 +05:30
committed by GitHub
parent c04f81e3c4
commit 012e352db0
7 changed files with 487 additions and 47 deletions

View File

@ -18,7 +18,7 @@ use crate::{
ListCountriesCurrenciesResponse, PaymentMethodCollectLinkRenderRequest,
PaymentMethodCollectLinkRequest, PaymentMethodCollectLinkResponse,
PaymentMethodDeleteResponse, PaymentMethodListRequest, PaymentMethodListResponse,
PaymentMethodResponse, PaymentMethodUpdate,
PaymentMethodMigrateResponse, PaymentMethodResponse, PaymentMethodUpdate,
},
payments::{
self, ExtendedCardInfoResponse, PaymentIdType, PaymentListConstraints,
@ -218,6 +218,29 @@ impl ApiEventMetric for PaymentMethodResponse {
}
}
impl ApiEventMetric for PaymentMethodMigrateResponse {
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "payment_methods_v2")
))]
fn get_api_event_type(&self) -> Option<ApiEventsType> {
Some(ApiEventsType::PaymentMethod {
payment_method_id: self.payment_method_response.payment_method_id.clone(),
payment_method: self.payment_method_response.payment_method,
payment_method_type: self.payment_method_response.payment_method_type,
})
}
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
fn get_api_event_type(&self) -> Option<ApiEventsType> {
Some(ApiEventsType::PaymentMethod {
payment_method_id: self.payment_method_response.payment_method_id.clone(),
payment_method: self.payment_method_response.payment_method_type,
payment_method_type: self.payment_method_response.payment_method_subtype,
})
}
}
impl ApiEventMetric for PaymentMethodUpdate {}
impl ApiEventMetric for DefaultPaymentMethod {

View File

@ -245,6 +245,9 @@ pub struct PaymentMethodMigrate {
/// Card Details
pub card: Option<MigrateCardDetail>,
/// Network token details
pub network_token: Option<MigrateNetworkTokenDetail>,
/// 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>,
@ -276,6 +279,24 @@ pub struct PaymentMethodMigrate {
pub network_transaction_id: Option<String>,
}
#[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct PaymentMethodMigrateResponse {
//payment method response when payment method entry is created
pub payment_method_response: PaymentMethodResponse,
//card data migration status
pub card_migrated: Option<bool>,
//network token data migration status
pub network_token_migrated: Option<bool>,
//connector mandate details migration status
pub connector_mandate_details_migrated: Option<bool>,
//network transaction id migration status
pub network_transaction_id_migrated: Option<bool>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PaymentsMandateReference(
pub HashMap<id_type::MerchantConnectorAccountId, PaymentsMandateReferenceRecord>,
@ -540,6 +561,53 @@ pub struct MigrateCardDetail {
pub card_type: Option<String>,
}
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
#[serde(deny_unknown_fields)]
pub struct MigrateNetworkTokenData {
/// Network Token Number
#[schema(value_type = String,example = "4111111145551142")]
pub network_token_number: CardNumber,
/// Network Token Expiry Month
#[schema(value_type = String,example = "10")]
pub network_token_exp_month: masking::Secret<String>,
/// Network Token Expiry Year
#[schema(value_type = String,example = "25")]
pub network_token_exp_year: masking::Secret<String>,
/// Card Holder Name
#[schema(value_type = 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<String>,
}
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
#[serde(deny_unknown_fields)]
pub struct MigrateNetworkTokenDetail {
/// Network token details
pub network_token_data: MigrateNetworkTokenData,
/// Network token requestor reference id
pub network_token_requestor_ref_id: String,
}
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "payment_methods_v2")
@ -2082,6 +2150,10 @@ pub struct PaymentMethodRecord {
pub original_transaction_amount: Option<i64>,
pub original_transaction_currency: Option<common_enums::Currency>,
pub line_number: Option<i64>,
pub network_token_number: Option<CardNumber>,
pub network_token_expiry_month: Option<masking::Secret<String>>,
pub network_token_expiry_year: Option<masking::Secret<String>>,
pub network_token_requestor_ref_id: Option<String>,
}
#[derive(Debug, Default, serde::Serialize)]
@ -2098,6 +2170,10 @@ pub struct PaymentMethodMigrationResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub migration_error: Option<String>,
pub card_number_masked: Option<masking::Secret<String>>,
pub card_migrated: Option<bool>,
pub network_token_migrated: Option<bool>,
pub connector_mandate_details_migrated: Option<bool>,
pub network_transaction_id_migrated: Option<bool>,
}
#[derive(Debug, Default, serde::Serialize)]
@ -2107,8 +2183,10 @@ pub enum MigrationStatus {
Failed,
}
type PaymentMethodMigrationResponseType =
(Result<PaymentMethodResponse, String>, PaymentMethodRecord);
type PaymentMethodMigrationResponseType = (
Result<PaymentMethodMigrateResponse, String>,
PaymentMethodRecord,
);
#[cfg(all(
any(feature = "v2", feature = "v1"),
not(feature = "payment_methods_v2")
@ -2117,14 +2195,18 @@ impl From<PaymentMethodMigrationResponseType> for PaymentMethodMigrationResponse
fn from((response, record): PaymentMethodMigrationResponseType) -> Self {
match response {
Ok(res) => Self {
payment_method_id: Some(res.payment_method_id),
payment_method: res.payment_method,
payment_method_type: res.payment_method_type,
customer_id: res.customer_id,
payment_method_id: Some(res.payment_method_response.payment_method_id),
payment_method: res.payment_method_response.payment_method,
payment_method_type: res.payment_method_response.payment_method_type,
customer_id: res.payment_method_response.customer_id,
migration_status: MigrationStatus::Success,
migration_error: None,
card_number_masked: Some(record.card_number_masked),
line_number: record.line_number,
card_migrated: res.card_migrated,
network_token_migrated: res.network_token_migrated,
connector_mandate_details_migrated: res.connector_mandate_details_migrated,
network_transaction_id_migrated: res.network_transaction_id_migrated,
},
Err(e) => Self {
customer_id: Some(record.customer_id),
@ -2143,14 +2225,18 @@ impl From<PaymentMethodMigrationResponseType> for PaymentMethodMigrationResponse
fn from((response, record): PaymentMethodMigrationResponseType) -> Self {
match response {
Ok(res) => Self {
payment_method_id: Some(res.payment_method_id),
payment_method: res.payment_method_type,
payment_method_type: res.payment_method_subtype,
customer_id: Some(res.customer_id),
payment_method_id: Some(res.payment_method_response.payment_method_id),
payment_method: res.payment_method_response.payment_method_type,
payment_method_type: res.payment_method_response.payment_method_subtype,
customer_id: Some(res.payment_method_response.customer_id),
migration_status: MigrationStatus::Success,
migration_error: None,
card_number_masked: Some(record.card_number_masked),
line_number: record.line_number,
card_migrated: res.card_migrated,
network_token_migrated: res.network_token_migrated,
connector_mandate_details_migrated: res.connector_mandate_details_migrated,
network_transaction_id_migrated: res.network_transaction_id_migrated,
},
Err(e) => Self {
customer_id: Some(record.customer_id),
@ -2213,6 +2299,22 @@ impl
card_issuing_country: None,
nick_name: Some(record.nick_name.clone()),
}),
network_token: Some(MigrateNetworkTokenDetail {
network_token_data: MigrateNetworkTokenData {
network_token_number: record.network_token_number.unwrap_or_default(),
network_token_exp_month: record.network_token_expiry_month.unwrap_or_default(),
network_token_exp_year: record.network_token_expiry_year.unwrap_or_default(),
card_holder_name: record.name,
nick_name: Some(record.nick_name.clone()),
card_issuing_country: None,
card_network: None,
card_issuer: None,
card_type: None,
},
network_token_requestor_ref_id: record
.network_token_requestor_ref_id
.unwrap_or_default(),
}),
payment_method: record.payment_method,
payment_method_type: record.payment_method_type,
payment_method_issuer: None,