mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
refactor(payment_methods_v2): refactor network tokenization flow for v2 (#7309)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: Bernard Eugine <114725419+bernard-eugine@users.noreply.github.com>
This commit is contained in:
@ -446,6 +446,12 @@ pub enum NetworkTokenizationError {
|
||||
NetworkTokenizationServiceNotConfigured,
|
||||
#[error("Failed while calling Network Token Service API")]
|
||||
ApiError,
|
||||
#[error("Network Tokenization is not enabled for profile")]
|
||||
NetworkTokenizationNotEnabledForProfile,
|
||||
#[error("Network Tokenization is not supported for {message}")]
|
||||
NotSupported { message: String },
|
||||
#[error("Failed to encrypt the NetworkToken payment method details")]
|
||||
NetworkTokenDetailsEncryptionFailed,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
|
||||
@ -933,11 +933,9 @@ pub async fn create_payment_method_core(
|
||||
.await
|
||||
.attach_printable("Failed to add Payment method to DB")?;
|
||||
|
||||
let payment_method_data =
|
||||
pm_types::PaymentMethodVaultingData::from(req.payment_method_data.clone());
|
||||
|
||||
let payment_method_data =
|
||||
populate_bin_details_for_payment_method(state, &payment_method_data).await;
|
||||
let payment_method_data = domain::PaymentMethodVaultingData::from(req.payment_method_data)
|
||||
.populate_bin_details_for_payment_method(state)
|
||||
.await;
|
||||
|
||||
let vaulting_result = vault_payment_method(
|
||||
state,
|
||||
@ -958,15 +956,7 @@ pub async fn create_payment_method_core(
|
||||
profile.is_network_tokenization_enabled,
|
||||
&customer_id,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
services::logger::error!(
|
||||
"Failed to network tokenize the payment method for customer: {}. Error: {} ",
|
||||
customer_id.get_string_repr(),
|
||||
e
|
||||
);
|
||||
})
|
||||
.ok();
|
||||
.await;
|
||||
|
||||
let (response, payment_method) = match vaulting_result {
|
||||
Ok((vaulting_resp, fingerprint_id)) => {
|
||||
@ -1035,86 +1025,83 @@ pub struct NetworkTokenPaymentMethodDetails {
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
pub async fn network_tokenize_and_vault_the_pmd(
|
||||
state: &SessionState,
|
||||
payment_method_data: &pm_types::PaymentMethodVaultingData,
|
||||
payment_method_data: &domain::PaymentMethodVaultingData,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
network_tokenization: Option<common_types::payment_methods::NetworkTokenization>,
|
||||
network_tokenization_enabled_for_profile: bool,
|
||||
customer_id: &id_type::GlobalCustomerId,
|
||||
) -> RouterResult<NetworkTokenPaymentMethodDetails> {
|
||||
when(!network_tokenization_enabled_for_profile, || {
|
||||
Err(report!(errors::ApiErrorResponse::NotSupported {
|
||||
message: "Network Tokenization is not enabled for this payment method".to_string()
|
||||
}))
|
||||
})?;
|
||||
) -> Option<NetworkTokenPaymentMethodDetails> {
|
||||
let network_token_pm_details_result: errors::CustomResult<
|
||||
NetworkTokenPaymentMethodDetails,
|
||||
errors::NetworkTokenizationError,
|
||||
> = async {
|
||||
when(!network_tokenization_enabled_for_profile, || {
|
||||
Err(report!(
|
||||
errors::NetworkTokenizationError::NetworkTokenizationNotEnabledForProfile
|
||||
))
|
||||
})?;
|
||||
|
||||
let is_network_tokenization_enabled_for_pm = network_tokenization
|
||||
.as_ref()
|
||||
.map(|nt| matches!(nt.enable, common_enums::NetworkTokenizationToggle::Enable))
|
||||
.unwrap_or(false);
|
||||
let is_network_tokenization_enabled_for_pm = network_tokenization
|
||||
.as_ref()
|
||||
.map(|nt| matches!(nt.enable, common_enums::NetworkTokenizationToggle::Enable))
|
||||
.unwrap_or(false);
|
||||
|
||||
let card_data = match payment_method_data {
|
||||
pm_types::PaymentMethodVaultingData::Card(data)
|
||||
if is_network_tokenization_enabled_for_pm =>
|
||||
{
|
||||
Ok(data)
|
||||
}
|
||||
_ => Err(report!(errors::ApiErrorResponse::NotSupported {
|
||||
message: "Network Tokenization is not supported for this payment method".to_string()
|
||||
})),
|
||||
}?;
|
||||
let card_data = payment_method_data
|
||||
.get_card()
|
||||
.and_then(|card| is_network_tokenization_enabled_for_pm.then_some(card))
|
||||
.ok_or_else(|| {
|
||||
report!(errors::NetworkTokenizationError::NotSupported {
|
||||
message: "Payment method".to_string(),
|
||||
})
|
||||
})?;
|
||||
|
||||
let (resp, network_token_req_ref_id) =
|
||||
network_tokenization::make_card_network_tokenization_request(state, card_data, customer_id)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to generate network token")?;
|
||||
|
||||
let network_token_vaulting_data = pm_types::PaymentMethodVaultingData::NetworkToken(resp);
|
||||
let vaulting_resp = vault::add_payment_method_to_vault(
|
||||
state,
|
||||
merchant_account,
|
||||
&network_token_vaulting_data,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to vault the network token data")?;
|
||||
|
||||
let key_manager_state = &(state).into();
|
||||
let network_token = match network_token_vaulting_data {
|
||||
pm_types::PaymentMethodVaultingData::Card(card) => {
|
||||
payment_method_data::PaymentMethodsData::Card(
|
||||
payment_method_data::CardDetailsPaymentMethod::from(card.clone()),
|
||||
let (resp, network_token_req_ref_id) =
|
||||
network_tokenization::make_card_network_tokenization_request(
|
||||
state,
|
||||
card_data,
|
||||
customer_id,
|
||||
)
|
||||
}
|
||||
pm_types::PaymentMethodVaultingData::NetworkToken(network_token) => {
|
||||
payment_method_data::PaymentMethodsData::NetworkToken(
|
||||
payment_method_data::NetworkTokenDetailsPaymentMethod::from(network_token.clone()),
|
||||
)
|
||||
}
|
||||
};
|
||||
.await?;
|
||||
|
||||
let network_token_pmd =
|
||||
cards::create_encrypted_data(key_manager_state, key_store, network_token)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Unable to encrypt Payment method data")?;
|
||||
let network_token_vaulting_data = domain::PaymentMethodVaultingData::NetworkToken(resp);
|
||||
let vaulting_resp = vault::add_payment_method_to_vault(
|
||||
state,
|
||||
merchant_account,
|
||||
&network_token_vaulting_data,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::NetworkTokenizationError::SaveNetworkTokenFailed)
|
||||
.attach_printable("Failed to vault network token")?;
|
||||
|
||||
Ok(NetworkTokenPaymentMethodDetails {
|
||||
network_token_requestor_reference_id: network_token_req_ref_id,
|
||||
network_token_locker_id: vaulting_resp.vault_id.get_string_repr().clone(),
|
||||
network_token_pmd,
|
||||
})
|
||||
let key_manager_state = &(state).into();
|
||||
let network_token_pmd = cards::create_encrypted_data(
|
||||
key_manager_state,
|
||||
key_store,
|
||||
network_token_vaulting_data.get_payment_methods_data(),
|
||||
)
|
||||
.await
|
||||
.change_context(errors::NetworkTokenizationError::NetworkTokenDetailsEncryptionFailed)
|
||||
.attach_printable("Failed to encrypt PaymentMethodsData")?;
|
||||
|
||||
Ok(NetworkTokenPaymentMethodDetails {
|
||||
network_token_requestor_reference_id: network_token_req_ref_id,
|
||||
network_token_locker_id: vaulting_resp.vault_id.get_string_repr().clone(),
|
||||
network_token_pmd,
|
||||
})
|
||||
}
|
||||
.await;
|
||||
network_token_pm_details_result.ok()
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
pub async fn populate_bin_details_for_payment_method(
|
||||
state: &SessionState,
|
||||
payment_method_data: &pm_types::PaymentMethodVaultingData,
|
||||
) -> pm_types::PaymentMethodVaultingData {
|
||||
payment_method_data: &domain::PaymentMethodVaultingData,
|
||||
) -> domain::PaymentMethodVaultingData {
|
||||
match payment_method_data {
|
||||
pm_types::PaymentMethodVaultingData::Card(card) => {
|
||||
domain::PaymentMethodVaultingData::Card(card) => {
|
||||
let card_isin = card.card_number.get_card_isin();
|
||||
|
||||
if card.card_issuer.is_some()
|
||||
@ -1122,7 +1109,7 @@ pub async fn populate_bin_details_for_payment_method(
|
||||
&& card.card_type.is_some()
|
||||
&& card.card_issuing_country.is_some()
|
||||
{
|
||||
pm_types::PaymentMethodVaultingData::Card(card.clone())
|
||||
domain::PaymentMethodVaultingData::Card(card.clone())
|
||||
} else {
|
||||
let card_info = state
|
||||
.store
|
||||
@ -1132,7 +1119,7 @@ pub async fn populate_bin_details_for_payment_method(
|
||||
.ok()
|
||||
.flatten();
|
||||
|
||||
pm_types::PaymentMethodVaultingData::Card(payment_methods::CardDetail {
|
||||
domain::PaymentMethodVaultingData::Card(payment_methods::CardDetail {
|
||||
card_number: card.card_number.clone(),
|
||||
card_exp_month: card.card_exp_month.clone(),
|
||||
card_exp_year: card.card_exp_year.clone(),
|
||||
@ -1163,6 +1150,67 @@ pub async fn populate_bin_details_for_payment_method(
|
||||
_ => payment_method_data.clone(),
|
||||
}
|
||||
}
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[async_trait::async_trait]
|
||||
pub trait PaymentMethodExt {
|
||||
async fn populate_bin_details_for_payment_method(&self, state: &SessionState) -> Self;
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[async_trait::async_trait]
|
||||
impl PaymentMethodExt for domain::PaymentMethodVaultingData {
|
||||
async fn populate_bin_details_for_payment_method(&self, state: &SessionState) -> Self {
|
||||
match self {
|
||||
Self::Card(card) => {
|
||||
let card_isin = card.card_number.get_card_isin();
|
||||
|
||||
if card.card_issuer.is_some()
|
||||
&& card.card_network.is_some()
|
||||
&& card.card_type.is_some()
|
||||
&& card.card_issuing_country.is_some()
|
||||
{
|
||||
Self::Card(card.clone())
|
||||
} else {
|
||||
let card_info = state
|
||||
.store
|
||||
.get_card_info(&card_isin)
|
||||
.await
|
||||
.map_err(|error| services::logger::error!(card_info_error=?error))
|
||||
.ok()
|
||||
.flatten();
|
||||
|
||||
Self::Card(payment_methods::CardDetail {
|
||||
card_number: card.card_number.clone(),
|
||||
card_exp_month: card.card_exp_month.clone(),
|
||||
card_exp_year: card.card_exp_year.clone(),
|
||||
card_holder_name: card.card_holder_name.clone(),
|
||||
nick_name: card.nick_name.clone(),
|
||||
card_issuing_country: card_info.as_ref().and_then(|val| {
|
||||
val.card_issuing_country
|
||||
.as_ref()
|
||||
.map(|c| api_enums::CountryAlpha2::from_str(c))
|
||||
.transpose()
|
||||
.ok()
|
||||
.flatten()
|
||||
}),
|
||||
card_network: card_info.as_ref().and_then(|val| val.card_network.clone()),
|
||||
card_issuer: card_info.as_ref().and_then(|val| val.card_issuer.clone()),
|
||||
card_type: card_info.as_ref().and_then(|val| {
|
||||
val.card_type
|
||||
.as_ref()
|
||||
.map(|c| payment_methods::CardType::from_str(c))
|
||||
.transpose()
|
||||
.ok()
|
||||
.flatten()
|
||||
}),
|
||||
card_cvc: card.card_cvc.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
_ => self.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[instrument(skip_all)]
|
||||
@ -1557,7 +1605,7 @@ fn create_connector_token_details_update(
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn create_pm_additional_data_update(
|
||||
payment_method_vaulting_data: Option<&pm_types::PaymentMethodVaultingData>,
|
||||
pmd: Option<&domain::PaymentMethodVaultingData>,
|
||||
state: &SessionState,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
vault_id: Option<String>,
|
||||
@ -1568,15 +1616,15 @@ pub async fn create_pm_additional_data_update(
|
||||
payment_method_type: Option<common_enums::PaymentMethod>,
|
||||
payment_method_subtype: Option<common_enums::PaymentMethodType>,
|
||||
) -> RouterResult<storage::PaymentMethodUpdate> {
|
||||
let encrypted_payment_method_data = payment_method_vaulting_data
|
||||
let encrypted_payment_method_data = pmd
|
||||
.map(
|
||||
|payment_method_vaulting_data| match payment_method_vaulting_data {
|
||||
pm_types::PaymentMethodVaultingData::Card(card) => {
|
||||
domain::PaymentMethodVaultingData::Card(card) => {
|
||||
payment_method_data::PaymentMethodsData::Card(
|
||||
payment_method_data::CardDetailsPaymentMethod::from(card.clone()),
|
||||
)
|
||||
}
|
||||
pm_types::PaymentMethodVaultingData::NetworkToken(network_token) => {
|
||||
domain::PaymentMethodVaultingData::NetworkToken(network_token) => {
|
||||
payment_method_data::PaymentMethodsData::NetworkToken(
|
||||
payment_method_data::NetworkTokenDetailsPaymentMethod::from(
|
||||
network_token.clone(),
|
||||
@ -1625,7 +1673,7 @@ pub async fn create_pm_additional_data_update(
|
||||
#[instrument(skip_all)]
|
||||
pub async fn vault_payment_method(
|
||||
state: &SessionState,
|
||||
pmd: &pm_types::PaymentMethodVaultingData,
|
||||
pmd: &domain::PaymentMethodVaultingData,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
existing_vault_id: Option<domain::VaultId>,
|
||||
@ -1893,11 +1941,12 @@ pub async fn update_payment_method_core(
|
||||
},
|
||||
)?;
|
||||
|
||||
let pmd = vault::retrieve_payment_method_from_vault(state, merchant_account, &payment_method)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to retrieve payment method from vault")?
|
||||
.data;
|
||||
let pmd: domain::PaymentMethodVaultingData =
|
||||
vault::retrieve_payment_method_from_vault(state, merchant_account, &payment_method)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to retrieve payment method from vault")?
|
||||
.data;
|
||||
|
||||
let vault_request_data = request.payment_method_data.map(|payment_method_data| {
|
||||
pm_transforms::generate_pm_vaulting_req_from_update_request(pmd, payment_method_data)
|
||||
|
||||
@ -30,7 +30,7 @@ use crate::{
|
||||
routes::{self, metrics},
|
||||
services::{self, encryption},
|
||||
settings,
|
||||
types::{api, domain},
|
||||
types::{api, domain, payment_methods as pm_types},
|
||||
};
|
||||
|
||||
pub const NETWORK_TOKEN_SERVICE: &str = "NETWORK_TOKEN";
|
||||
@ -45,7 +45,7 @@ pub async fn mk_tokenization_req(
|
||||
customer_id: id_type::CustomerId,
|
||||
tokenization_service: &settings::NetworkTokenizationService,
|
||||
) -> CustomResult<
|
||||
(domain::CardNetworkTokenResponsePayload, Option<String>),
|
||||
(pm_types::CardNetworkTokenResponsePayload, Option<String>),
|
||||
errors::NetworkTokenizationError,
|
||||
> {
|
||||
let enc_key = tokenization_service.public_key.peek().clone();
|
||||
@ -62,12 +62,12 @@ pub async fn mk_tokenization_req(
|
||||
.change_context(errors::NetworkTokenizationError::SaveNetworkTokenFailed)
|
||||
.attach_printable("Error on jwe encrypt")?;
|
||||
|
||||
let order_data = domain::OrderData {
|
||||
let order_data = pm_types::OrderData {
|
||||
consent_id: uuid::Uuid::new_v4().to_string(),
|
||||
customer_id,
|
||||
};
|
||||
|
||||
let api_payload = domain::ApiPayload {
|
||||
let api_payload = pm_types::ApiPayload {
|
||||
service: NETWORK_TOKEN_SERVICE.to_string(),
|
||||
card_data: Secret::new(jwt),
|
||||
order_data,
|
||||
@ -103,7 +103,7 @@ pub async fn mk_tokenization_req(
|
||||
.attach_printable("Error while receiving response")
|
||||
.and_then(|inner| match inner {
|
||||
Err(err_res) => {
|
||||
let parsed_error: domain::NetworkTokenErrorResponse = err_res
|
||||
let parsed_error: pm_types::NetworkTokenErrorResponse = err_res
|
||||
.response
|
||||
.parse_struct("Card Network Tokenization Response")
|
||||
.change_context(
|
||||
@ -124,7 +124,7 @@ pub async fn mk_tokenization_req(
|
||||
logger::error!("Error while deserializing response: {:?}", err);
|
||||
})?;
|
||||
|
||||
let network_response: domain::CardNetworkTokenResponse = res
|
||||
let network_response: pm_types::CardNetworkTokenResponse = res
|
||||
.response
|
||||
.parse_struct("Card Network Tokenization Response")
|
||||
.change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
|
||||
@ -143,7 +143,7 @@ pub async fn mk_tokenization_req(
|
||||
"Failed to decrypt the tokenization response from the tokenization service",
|
||||
)?;
|
||||
|
||||
let cn_response: domain::CardNetworkTokenResponsePayload =
|
||||
let cn_response: pm_types::CardNetworkTokenResponsePayload =
|
||||
serde_json::from_str(&card_network_token_response)
|
||||
.change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
|
||||
Ok((cn_response.clone(), Some(cn_response.card_reference)))
|
||||
@ -156,7 +156,7 @@ pub async fn generate_network_token(
|
||||
customer_id: id_type::GlobalCustomerId,
|
||||
tokenization_service: &settings::NetworkTokenizationService,
|
||||
) -> CustomResult<
|
||||
(domain::GenerateNetworkTokenResponsePayload, String),
|
||||
(pm_types::GenerateNetworkTokenResponsePayload, String),
|
||||
errors::NetworkTokenizationError,
|
||||
> {
|
||||
let enc_key = tokenization_service.public_key.peek().clone();
|
||||
@ -173,12 +173,12 @@ pub async fn generate_network_token(
|
||||
.change_context(errors::NetworkTokenizationError::SaveNetworkTokenFailed)
|
||||
.attach_printable("Error on jwe encrypt")?;
|
||||
|
||||
let order_data = domain::OrderData {
|
||||
let order_data = pm_types::OrderData {
|
||||
consent_id: uuid::Uuid::new_v4().to_string(),
|
||||
customer_id,
|
||||
};
|
||||
|
||||
let api_payload = domain::ApiPayload {
|
||||
let api_payload = pm_types::ApiPayload {
|
||||
service: NETWORK_TOKEN_SERVICE.to_string(),
|
||||
card_data: Secret::new(jwt),
|
||||
order_data,
|
||||
@ -214,7 +214,7 @@ pub async fn generate_network_token(
|
||||
.attach_printable("Error while receiving response")
|
||||
.and_then(|inner| match inner {
|
||||
Err(err_res) => {
|
||||
let parsed_error: domain::NetworkTokenErrorResponse = err_res
|
||||
let parsed_error: pm_types::NetworkTokenErrorResponse = err_res
|
||||
.response
|
||||
.parse_struct("Card Network Tokenization Response")
|
||||
.change_context(
|
||||
@ -235,7 +235,7 @@ pub async fn generate_network_token(
|
||||
logger::error!("Error while deserializing response: {:?}", err);
|
||||
})?;
|
||||
|
||||
let network_response: domain::CardNetworkTokenResponse = res
|
||||
let network_response: pm_types::CardNetworkTokenResponse = res
|
||||
.response
|
||||
.parse_struct("Card Network Tokenization Response")
|
||||
.change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
|
||||
@ -255,7 +255,7 @@ pub async fn generate_network_token(
|
||||
"Failed to decrypt the tokenization response from the tokenization service",
|
||||
)?;
|
||||
|
||||
let cn_response: domain::GenerateNetworkTokenResponsePayload =
|
||||
let cn_response: pm_types::GenerateNetworkTokenResponsePayload =
|
||||
serde_json::from_str(&card_network_token_response)
|
||||
.change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
|
||||
Ok((cn_response.clone(), cn_response.card_reference))
|
||||
@ -271,10 +271,10 @@ pub async fn make_card_network_tokenization_request(
|
||||
optional_cvc: Option<Secret<String>>,
|
||||
customer_id: &id_type::CustomerId,
|
||||
) -> CustomResult<
|
||||
(domain::CardNetworkTokenResponsePayload, Option<String>),
|
||||
(pm_types::CardNetworkTokenResponsePayload, Option<String>),
|
||||
errors::NetworkTokenizationError,
|
||||
> {
|
||||
let card_data = domain::CardData {
|
||||
let card_data = pm_types::CardData {
|
||||
card_number: card.card_number.clone(),
|
||||
exp_month: card.card_exp_month.clone(),
|
||||
exp_year: card.card_exp_year.clone(),
|
||||
@ -320,7 +320,7 @@ pub async fn make_card_network_tokenization_request(
|
||||
card: &api_payment_methods::CardDetail,
|
||||
customer_id: &id_type::GlobalCustomerId,
|
||||
) -> CustomResult<(NetworkTokenDetails, String), errors::NetworkTokenizationError> {
|
||||
let card_data = domain::CardData {
|
||||
let card_data = pm_types::CardData {
|
||||
card_number: card.card_number.clone(),
|
||||
exp_month: card.card_exp_month.clone(),
|
||||
exp_year: card.card_exp_year.clone(),
|
||||
@ -376,12 +376,12 @@ pub async fn get_network_token(
|
||||
customer_id: id_type::CustomerId,
|
||||
network_token_requestor_ref_id: String,
|
||||
tokenization_service: &settings::NetworkTokenizationService,
|
||||
) -> CustomResult<domain::TokenResponse, errors::NetworkTokenizationError> {
|
||||
) -> CustomResult<pm_types::TokenResponse, errors::NetworkTokenizationError> {
|
||||
let mut request = services::Request::new(
|
||||
services::Method::Post,
|
||||
tokenization_service.fetch_token_url.as_str(),
|
||||
);
|
||||
let payload = domain::GetCardToken {
|
||||
let payload = pm_types::GetCardToken {
|
||||
card_reference: network_token_requestor_ref_id,
|
||||
customer_id,
|
||||
};
|
||||
@ -411,7 +411,7 @@ pub async fn get_network_token(
|
||||
.attach_printable("Error while receiving response")
|
||||
.and_then(|inner| match inner {
|
||||
Err(err_res) => {
|
||||
let parsed_error: domain::NetworkTokenErrorResponse = err_res
|
||||
let parsed_error: pm_types::NetworkTokenErrorResponse = err_res
|
||||
.response
|
||||
.parse_struct("Card Network Tokenization Response")
|
||||
.change_context(
|
||||
@ -429,7 +429,7 @@ pub async fn get_network_token(
|
||||
Ok(res) => Ok(res),
|
||||
})?;
|
||||
|
||||
let token_response: domain::TokenResponse = res
|
||||
let token_response: pm_types::TokenResponse = res
|
||||
.response
|
||||
.parse_struct("Get Network Token Response")
|
||||
.change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
|
||||
@ -444,12 +444,12 @@ pub async fn get_network_token(
|
||||
customer_id: &id_type::GlobalCustomerId,
|
||||
network_token_requestor_ref_id: String,
|
||||
tokenization_service: &settings::NetworkTokenizationService,
|
||||
) -> CustomResult<domain::TokenResponse, errors::NetworkTokenizationError> {
|
||||
) -> CustomResult<pm_types::TokenResponse, errors::NetworkTokenizationError> {
|
||||
let mut request = services::Request::new(
|
||||
services::Method::Post,
|
||||
tokenization_service.fetch_token_url.as_str(),
|
||||
);
|
||||
let payload = domain::GetCardToken {
|
||||
let payload = pm_types::GetCardToken {
|
||||
card_reference: network_token_requestor_ref_id,
|
||||
customer_id: customer_id.clone(),
|
||||
};
|
||||
@ -479,7 +479,7 @@ pub async fn get_network_token(
|
||||
.attach_printable("Error while receiving response")
|
||||
.and_then(|inner| match inner {
|
||||
Err(err_res) => {
|
||||
let parsed_error: domain::NetworkTokenErrorResponse = err_res
|
||||
let parsed_error: pm_types::NetworkTokenErrorResponse = err_res
|
||||
.response
|
||||
.parse_struct("Card Network Tokenization Response")
|
||||
.change_context(
|
||||
@ -497,7 +497,7 @@ pub async fn get_network_token(
|
||||
Ok(res) => Ok(res),
|
||||
})?;
|
||||
|
||||
let token_response: domain::TokenResponse = res
|
||||
let token_response: pm_types::TokenResponse = res
|
||||
.response
|
||||
.parse_struct("Get Network Token Response")
|
||||
.change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
|
||||
@ -656,7 +656,7 @@ pub async fn check_token_status_with_tokenization_service(
|
||||
services::Method::Post,
|
||||
tokenization_service.check_token_status_url.as_str(),
|
||||
);
|
||||
let payload = domain::CheckTokenStatus {
|
||||
let payload = pm_types::CheckTokenStatus {
|
||||
card_reference: network_token_requestor_reference_id,
|
||||
customer_id: customer_id.clone(),
|
||||
};
|
||||
@ -683,7 +683,7 @@ pub async fn check_token_status_with_tokenization_service(
|
||||
.attach_printable("Error while receiving response")
|
||||
.and_then(|inner| match inner {
|
||||
Err(err_res) => {
|
||||
let parsed_error: domain::NetworkTokenErrorResponse = err_res
|
||||
let parsed_error: pm_types::NetworkTokenErrorResponse = err_res
|
||||
.response
|
||||
.parse_struct("Delete Network Tokenization Response")
|
||||
.change_context(
|
||||
@ -704,17 +704,17 @@ pub async fn check_token_status_with_tokenization_service(
|
||||
logger::error!("Error while deserializing response: {:?}", err);
|
||||
})?;
|
||||
|
||||
let check_token_status_response: domain::CheckTokenStatusResponse = res
|
||||
let check_token_status_response: pm_types::CheckTokenStatusResponse = res
|
||||
.response
|
||||
.parse_struct("Delete Network Tokenization Response")
|
||||
.change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
|
||||
|
||||
match check_token_status_response.payload.token_status {
|
||||
domain::TokenStatus::Active => Ok((
|
||||
pm_types::TokenStatus::Active => Ok((
|
||||
Some(check_token_status_response.payload.token_expiry_month),
|
||||
Some(check_token_status_response.payload.token_expiry_year),
|
||||
)),
|
||||
domain::TokenStatus::Inactive => Ok((None, None)),
|
||||
pm_types::TokenStatus::Inactive => Ok((None, None)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -791,7 +791,7 @@ pub async fn delete_network_token_from_tokenization_service(
|
||||
services::Method::Post,
|
||||
tokenization_service.delete_token_url.as_str(),
|
||||
);
|
||||
let payload = domain::DeleteCardToken {
|
||||
let payload = pm_types::DeleteCardToken {
|
||||
card_reference: network_token_requestor_reference_id,
|
||||
customer_id: customer_id.clone(),
|
||||
};
|
||||
@ -820,7 +820,7 @@ pub async fn delete_network_token_from_tokenization_service(
|
||||
.attach_printable("Error while receiving response")
|
||||
.and_then(|inner| match inner {
|
||||
Err(err_res) => {
|
||||
let parsed_error: domain::NetworkTokenErrorResponse = err_res
|
||||
let parsed_error: pm_types::NetworkTokenErrorResponse = err_res
|
||||
.response
|
||||
.parse_struct("Delete Network Tokenization Response")
|
||||
.change_context(
|
||||
@ -841,14 +841,14 @@ pub async fn delete_network_token_from_tokenization_service(
|
||||
logger::error!("Error while deserializing response: {:?}", err);
|
||||
})?;
|
||||
|
||||
let delete_token_response: domain::DeleteNetworkTokenResponse = res
|
||||
let delete_token_response: pm_types::DeleteNetworkTokenResponse = res
|
||||
.response
|
||||
.parse_struct("Delete Network Tokenization Response")
|
||||
.change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
|
||||
|
||||
logger::info!("Delete Network Token Response: {:?}", delete_token_response);
|
||||
|
||||
if delete_token_response.status == domain::DeleteNetworkTokenStatus::Success {
|
||||
if delete_token_response.status == pm_types::DeleteNetworkTokenStatus::Success {
|
||||
Ok(true)
|
||||
} else {
|
||||
Err(errors::NetworkTokenizationError::DeleteNetworkTokenFailed)
|
||||
|
||||
@ -7,9 +7,7 @@ use common_utils::{
|
||||
transformers::{ForeignFrom, ForeignTryFrom},
|
||||
};
|
||||
use error_stack::{report, ResultExt};
|
||||
use hyperswitch_domain_models::{
|
||||
network_tokenization as nt_domain_types, router_request_types as domain_request_types,
|
||||
};
|
||||
use hyperswitch_domain_models::router_request_types as domain_request_types;
|
||||
use masking::{ExposeInterface, Secret};
|
||||
use router_env::logger;
|
||||
|
||||
@ -21,7 +19,7 @@ use crate::{
|
||||
},
|
||||
errors::{self, RouterResult},
|
||||
services,
|
||||
types::{api, domain},
|
||||
types::{api, domain, payment_methods as pm_types},
|
||||
SessionState,
|
||||
};
|
||||
|
||||
@ -137,10 +135,7 @@ pub async fn tokenize_cards(
|
||||
}
|
||||
|
||||
// Data types
|
||||
type NetworkTokenizationResponse = (
|
||||
nt_domain_types::CardNetworkTokenResponsePayload,
|
||||
Option<String>,
|
||||
);
|
||||
type NetworkTokenizationResponse = (pm_types::CardNetworkTokenResponsePayload, Option<String>);
|
||||
|
||||
pub struct StoreLockerResponse {
|
||||
pub store_card_resp: pm_transformers::StoreCardRespPayload,
|
||||
@ -162,7 +157,7 @@ pub struct NetworkTokenizationBuilder<'a, S: State> {
|
||||
pub card_cvc: Option<Secret<String>>,
|
||||
|
||||
/// Network token details
|
||||
pub network_token: Option<&'a nt_domain_types::CardNetworkTokenResponsePayload>,
|
||||
pub network_token: Option<&'a pm_types::CardNetworkTokenResponsePayload>,
|
||||
|
||||
/// Stored card details
|
||||
pub stored_card: Option<&'a pm_transformers::StoreCardRespPayload>,
|
||||
|
||||
@ -522,14 +522,14 @@ pub fn mk_add_card_response_hs(
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
pub fn generate_pm_vaulting_req_from_update_request(
|
||||
pm_create: pm_types::PaymentMethodVaultingData,
|
||||
pm_create: domain::PaymentMethodVaultingData,
|
||||
pm_update: api::PaymentMethodUpdateData,
|
||||
) -> pm_types::PaymentMethodVaultingData {
|
||||
) -> domain::PaymentMethodVaultingData {
|
||||
match (pm_create, pm_update) {
|
||||
(
|
||||
pm_types::PaymentMethodVaultingData::Card(card_create),
|
||||
domain::PaymentMethodVaultingData::Card(card_create),
|
||||
api::PaymentMethodUpdateData::Card(update_card),
|
||||
) => pm_types::PaymentMethodVaultingData::Card(api::CardDetail {
|
||||
) => domain::PaymentMethodVaultingData::Card(api::CardDetail {
|
||||
card_number: card_create.card_number,
|
||||
card_exp_month: card_create.card_exp_month,
|
||||
card_exp_year: card_create.card_exp_year,
|
||||
@ -571,6 +571,20 @@ pub fn generate_payment_method_response(
|
||||
.map(transformers::ForeignFrom::foreign_from)
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
let network_token_pmd = payment_method
|
||||
.network_token_payment_method_data
|
||||
.clone()
|
||||
.map(|data| data.into_inner())
|
||||
.and_then(|data| match data {
|
||||
domain::PaymentMethodsData::NetworkToken(token) => {
|
||||
Some(api::NetworkTokenDetailsPaymentMethod::from(token))
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
|
||||
let network_token = network_token_pmd.map(|pmd| api::NetworkTokenResponse {
|
||||
payment_method_data: pmd,
|
||||
});
|
||||
|
||||
let resp = api::PaymentMethodResponse {
|
||||
merchant_id: payment_method.merchant_id.to_owned(),
|
||||
@ -583,6 +597,7 @@ pub fn generate_payment_method_response(
|
||||
last_used_at: Some(payment_method.last_used_at),
|
||||
payment_method_data: pmd,
|
||||
connector_tokens,
|
||||
network_token,
|
||||
};
|
||||
|
||||
Ok(resp)
|
||||
@ -839,15 +854,6 @@ pub fn get_card_detail(
|
||||
Ok(card_detail)
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
impl From<api::PaymentMethodCreateData> for pm_types::PaymentMethodVaultingData {
|
||||
fn from(item: api::PaymentMethodCreateData) -> Self {
|
||||
match item {
|
||||
api::PaymentMethodCreateData::Card(card) => Self::Card(card),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------TokenizeService------------------------------------------------
|
||||
pub fn mk_crud_locker_request(
|
||||
locker: &settings::Locker,
|
||||
@ -961,6 +967,21 @@ impl transformers::ForeignTryFrom<domain::PaymentMethod> for api::CustomerPaymen
|
||||
.map(|billing| billing.into_inner())
|
||||
.map(From::from);
|
||||
|
||||
let network_token_pmd = item
|
||||
.network_token_payment_method_data
|
||||
.clone()
|
||||
.map(|data| data.into_inner())
|
||||
.and_then(|data| match data {
|
||||
domain::PaymentMethodsData::NetworkToken(token) => {
|
||||
Some(api::NetworkTokenDetailsPaymentMethod::from(token))
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
|
||||
let network_token_resp = network_token_pmd.map(|pmd| api::NetworkTokenResponse {
|
||||
payment_method_data: pmd,
|
||||
});
|
||||
|
||||
// TODO: check how we can get this field
|
||||
let recurring_enabled = true;
|
||||
|
||||
@ -977,6 +998,7 @@ impl transformers::ForeignTryFrom<domain::PaymentMethod> for api::CustomerPaymen
|
||||
requires_cvv: true,
|
||||
is_default: false,
|
||||
billing: payment_method_billing,
|
||||
network_tokenization: network_token_resp,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1033,7 +1055,7 @@ impl transformers::ForeignFrom<api_models::payment_methods::ConnectorTokenDetail
|
||||
} = item;
|
||||
|
||||
Self {
|
||||
connector_token: token,
|
||||
connector_token: token.expose().clone(),
|
||||
// TODO: check why do we need this field
|
||||
payment_method_subtype: None,
|
||||
original_payment_authorized_amount,
|
||||
@ -1075,7 +1097,7 @@ impl
|
||||
original_payment_authorized_amount,
|
||||
original_payment_authorized_currency,
|
||||
metadata,
|
||||
token: connector_token,
|
||||
token: Secret::new(connector_token),
|
||||
// Token that is derived from payments mandate reference will always be multi use token
|
||||
token_type: common_enums::TokenizationType::MultiUse,
|
||||
}
|
||||
|
||||
@ -1252,9 +1252,7 @@ pub async fn call_to_vault<V: pm_types::VaultingInterface>(
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_fingerprint_id_from_vault<
|
||||
D: pm_types::VaultingDataInterface + serde::Serialize,
|
||||
>(
|
||||
pub async fn get_fingerprint_id_from_vault<D: domain::VaultingDataInterface + serde::Serialize>(
|
||||
state: &routes::SessionState,
|
||||
data: &D,
|
||||
key: String,
|
||||
@ -1286,7 +1284,7 @@ pub async fn get_fingerprint_id_from_vault<
|
||||
pub async fn add_payment_method_to_vault(
|
||||
state: &routes::SessionState,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
pmd: &pm_types::PaymentMethodVaultingData,
|
||||
pmd: &domain::PaymentMethodVaultingData,
|
||||
existing_vault_id: Option<domain::VaultId>,
|
||||
) -> CustomResult<pm_types::AddVaultResponse, errors::VaultError> {
|
||||
let payload = pm_types::AddVaultRequest {
|
||||
|
||||
@ -2613,7 +2613,7 @@ impl<F: Clone> PostUpdateTracker<F, PaymentConfirmData<F>, types::SetupMandateRe
|
||||
original_payment_authorized_amount: Some(net_amount),
|
||||
original_payment_authorized_currency: Some(currency),
|
||||
metadata: None,
|
||||
token,
|
||||
token: masking::Secret::new(token),
|
||||
token_type: common_enums::TokenizationType::MultiUse,
|
||||
};
|
||||
|
||||
|
||||
@ -4,14 +4,15 @@ pub use api_models::payment_methods::{
|
||||
CardNetworkTokenizeResponse, CardType, CustomerPaymentMethod,
|
||||
CustomerPaymentMethodsListResponse, DeleteTokenizeByTokenRequest, GetTokenizePayloadRequest,
|
||||
GetTokenizePayloadResponse, ListCountriesCurrenciesRequest, MigrateCardDetail,
|
||||
PaymentMethodCollectLinkRenderRequest, PaymentMethodCollectLinkRequest, PaymentMethodCreate,
|
||||
PaymentMethodCreateData, PaymentMethodDeleteResponse, PaymentMethodId,
|
||||
PaymentMethodIntentConfirm, PaymentMethodIntentCreate, PaymentMethodListData,
|
||||
PaymentMethodListRequest, PaymentMethodListResponse, PaymentMethodMigrate,
|
||||
PaymentMethodMigrateResponse, PaymentMethodResponse, PaymentMethodResponseData,
|
||||
PaymentMethodUpdate, PaymentMethodUpdateData, PaymentMethodsData, TokenizePayloadEncrypted,
|
||||
TokenizePayloadRequest, TokenizedCardValue1, TokenizedCardValue2, TokenizedWalletValue1,
|
||||
TokenizedWalletValue2, TotalPaymentMethodCountResponse,
|
||||
NetworkTokenDetailsPaymentMethod, NetworkTokenResponse, PaymentMethodCollectLinkRenderRequest,
|
||||
PaymentMethodCollectLinkRequest, PaymentMethodCreate, PaymentMethodCreateData,
|
||||
PaymentMethodDeleteResponse, PaymentMethodId, PaymentMethodIntentConfirm,
|
||||
PaymentMethodIntentCreate, PaymentMethodListData, PaymentMethodListRequest,
|
||||
PaymentMethodListResponse, PaymentMethodMigrate, PaymentMethodMigrateResponse,
|
||||
PaymentMethodResponse, PaymentMethodResponseData, PaymentMethodUpdate, PaymentMethodUpdateData,
|
||||
PaymentMethodsData, TokenizePayloadEncrypted, TokenizePayloadRequest, TokenizedCardValue1,
|
||||
TokenizedCardValue2, TokenizedWalletValue1, TokenizedWalletValue2,
|
||||
TotalPaymentMethodCountResponse,
|
||||
};
|
||||
#[cfg(all(
|
||||
any(feature = "v2", feature = "v1"),
|
||||
|
||||
@ -40,6 +40,15 @@ pub mod payment_methods {
|
||||
pub mod consts {
|
||||
pub use hyperswitch_domain_models::consts::*;
|
||||
}
|
||||
pub mod payment_method_data {
|
||||
pub use hyperswitch_domain_models::payment_method_data::*;
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
pub mod vault {
|
||||
pub use hyperswitch_domain_models::vault::*;
|
||||
}
|
||||
|
||||
pub mod payments;
|
||||
pub mod types;
|
||||
#[cfg(feature = "olap")]
|
||||
@ -54,8 +63,10 @@ pub use event::*;
|
||||
pub use merchant_connector_account::*;
|
||||
pub use merchant_key_store::*;
|
||||
pub use network_tokenization::*;
|
||||
pub use payment_method_data::*;
|
||||
pub use payment_methods::*;
|
||||
pub use payments::*;
|
||||
#[cfg(feature = "olap")]
|
||||
pub use user::*;
|
||||
pub use user_key_store::*;
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
pub use vault::*;
|
||||
|
||||
@ -1,9 +1,20 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use api_models::enums as api_enums;
|
||||
#[cfg(all(
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "payment_methods_v2")
|
||||
))]
|
||||
use cards::CardNumber;
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
use cards::{CardNumber, NetworkToken};
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
use common_utils::generate_id;
|
||||
use common_utils::id_type;
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
use hyperswitch_domain_models::payment_method_data::NetworkTokenDetails;
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
use masking::Secret;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
use crate::{
|
||||
@ -18,11 +29,6 @@ pub trait VaultingInterface {
|
||||
fn get_vaulting_flow_name() -> &'static str;
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
pub trait VaultingDataInterface {
|
||||
fn get_vaulting_data_key(&self) -> String;
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct VaultFingerprintRequest {
|
||||
@ -39,7 +45,7 @@ pub struct VaultFingerprintResponse {
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct AddVaultRequest<D> {
|
||||
pub entity_id: common_utils::id_type::MerchantId,
|
||||
pub entity_id: id_type::MerchantId,
|
||||
pub vault_id: domain::VaultId,
|
||||
pub data: D,
|
||||
pub ttl: i64,
|
||||
@ -48,7 +54,7 @@ pub struct AddVaultRequest<D> {
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct AddVaultResponse {
|
||||
pub entity_id: common_utils::id_type::MerchantId,
|
||||
pub entity_id: id_type::MerchantId,
|
||||
pub vault_id: domain::VaultId,
|
||||
pub fingerprint_id: Option<String>,
|
||||
}
|
||||
@ -113,23 +119,6 @@ impl VaultingInterface for VaultDelete {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub enum PaymentMethodVaultingData {
|
||||
Card(api::CardDetail),
|
||||
NetworkToken(NetworkTokenDetails),
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
impl VaultingDataInterface for PaymentMethodVaultingData {
|
||||
fn get_vaulting_data_key(&self) -> String {
|
||||
match &self {
|
||||
Self::Card(card) => card.card_number.to_string(),
|
||||
Self::NetworkToken(network_token) => network_token.network_token.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
pub struct SavedPMLPaymentsInfo {
|
||||
pub payment_intent: storage::PaymentIntent,
|
||||
@ -142,26 +131,235 @@ pub struct SavedPMLPaymentsInfo {
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct VaultRetrieveRequest {
|
||||
pub entity_id: common_utils::id_type::MerchantId,
|
||||
pub entity_id: id_type::MerchantId,
|
||||
pub vault_id: domain::VaultId,
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct VaultRetrieveResponse {
|
||||
pub data: PaymentMethodVaultingData,
|
||||
pub data: domain::PaymentMethodVaultingData,
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct VaultDeleteRequest {
|
||||
pub entity_id: common_utils::id_type::MerchantId,
|
||||
pub entity_id: id_type::MerchantId,
|
||||
pub vault_id: domain::VaultId,
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct VaultDeleteResponse {
|
||||
pub entity_id: common_utils::id_type::MerchantId,
|
||||
pub entity_id: id_type::MerchantId,
|
||||
pub vault_id: domain::VaultId,
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "payment_methods_v2")
|
||||
))]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CardData {
|
||||
pub card_number: CardNumber,
|
||||
pub exp_month: Secret<String>,
|
||||
pub exp_year: Secret<String>,
|
||||
pub card_security_code: Option<Secret<String>>,
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CardData {
|
||||
pub card_number: CardNumber,
|
||||
pub exp_month: Secret<String>,
|
||||
pub exp_year: Secret<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub card_security_code: Option<Secret<String>>,
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "payment_methods_v2")
|
||||
))]
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct OrderData {
|
||||
pub consent_id: String,
|
||||
pub customer_id: id_type::CustomerId,
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct OrderData {
|
||||
pub consent_id: String,
|
||||
pub customer_id: id_type::GlobalCustomerId,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApiPayload {
|
||||
pub service: String,
|
||||
pub card_data: Secret<String>, //encrypted card data
|
||||
pub order_data: OrderData,
|
||||
pub key_id: String,
|
||||
pub should_send_token: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Eq, PartialEq)]
|
||||
pub struct CardNetworkTokenResponse {
|
||||
pub payload: Secret<String>, //encrypted payload
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "payment_methods_v2")
|
||||
))]
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CardNetworkTokenResponsePayload {
|
||||
pub card_brand: api_enums::CardNetwork,
|
||||
pub card_fingerprint: Option<Secret<String>>,
|
||||
pub card_reference: String,
|
||||
pub correlation_id: String,
|
||||
pub customer_id: String,
|
||||
pub par: String,
|
||||
pub token: CardNumber,
|
||||
pub token_expiry_month: Secret<String>,
|
||||
pub token_expiry_year: Secret<String>,
|
||||
pub token_isin: String,
|
||||
pub token_last_four: String,
|
||||
pub token_status: String,
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GenerateNetworkTokenResponsePayload {
|
||||
pub card_brand: api_enums::CardNetwork,
|
||||
pub card_fingerprint: Option<Secret<String>>,
|
||||
pub card_reference: String,
|
||||
pub correlation_id: String,
|
||||
pub customer_id: String,
|
||||
pub par: String,
|
||||
pub token: NetworkToken,
|
||||
pub token_expiry_month: Secret<String>,
|
||||
pub token_expiry_year: Secret<String>,
|
||||
pub token_isin: String,
|
||||
pub token_last_four: String,
|
||||
pub token_status: String,
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "payment_methods_v2")
|
||||
))]
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct GetCardToken {
|
||||
pub card_reference: String,
|
||||
pub customer_id: id_type::CustomerId,
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct GetCardToken {
|
||||
pub card_reference: String,
|
||||
pub customer_id: id_type::GlobalCustomerId,
|
||||
}
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct AuthenticationDetails {
|
||||
pub cryptogram: Secret<String>,
|
||||
pub token: CardNumber, //network token
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct TokenDetails {
|
||||
pub exp_month: Secret<String>,
|
||||
pub exp_year: Secret<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct TokenResponse {
|
||||
pub authentication_details: AuthenticationDetails,
|
||||
pub network: api_enums::CardNetwork,
|
||||
pub token_details: TokenDetails,
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "payment_methods_v2")
|
||||
))]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct DeleteCardToken {
|
||||
pub card_reference: String, //network token requestor ref id
|
||||
pub customer_id: id_type::CustomerId,
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct DeleteCardToken {
|
||||
pub card_reference: String, //network token requestor ref id
|
||||
pub customer_id: id_type::GlobalCustomerId,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Eq, PartialEq)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
pub enum DeleteNetworkTokenStatus {
|
||||
Success,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Eq, PartialEq)]
|
||||
pub struct NetworkTokenErrorInfo {
|
||||
pub code: String,
|
||||
pub developer_message: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Eq, PartialEq)]
|
||||
pub struct NetworkTokenErrorResponse {
|
||||
pub error_message: String,
|
||||
pub error_info: NetworkTokenErrorInfo,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Eq, PartialEq)]
|
||||
pub struct DeleteNetworkTokenResponse {
|
||||
pub status: DeleteNetworkTokenStatus,
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "payment_methods_v2")
|
||||
))]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct CheckTokenStatus {
|
||||
pub card_reference: String,
|
||||
pub customer_id: id_type::CustomerId,
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct CheckTokenStatus {
|
||||
pub card_reference: String,
|
||||
pub customer_id: id_type::GlobalCustomerId,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
pub enum TokenStatus {
|
||||
Active,
|
||||
Inactive,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CheckTokenStatusResponsePayload {
|
||||
pub token_expiry_month: Secret<String>,
|
||||
pub token_expiry_year: Secret<String>,
|
||||
pub token_status: TokenStatus,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct CheckTokenStatusResponse {
|
||||
pub payload: CheckTokenStatusResponsePayload,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user