Skip to content

Commit

Permalink
post payment processing
Browse files Browse the repository at this point in the history
  • Loading branch information
ImSagnik007 committed Dec 25, 2024
1 parent 3f9c0ba commit dcc8625
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 35 deletions.
15 changes: 7 additions & 8 deletions crates/router/src/core/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,12 +497,12 @@ where
};
match pm_data {
Some(domain::PaymentMethodData::Card(card_data)) => {
let vault_data = VaultData {
let card_and_network_token_data = CardAndNetworkTokenData {
card_data: card_data.clone(),
network_token_data: token_data.clone(),
};
payment_data.set_vault_operation(
PaymentMethodDataAction::VaultData(vault_data.clone()),
PaymentMethodDataAction::SaveCardAndNetworkTokenData(card_and_network_token_data.clone()),
)
}
_ => (),
Expand Down Expand Up @@ -641,12 +641,12 @@ where
};
match pm_data {
Some(domain::PaymentMethodData::Card(card_data)) => {
let vault_data = VaultData {
let card_and_network_token_data = CardAndNetworkTokenData {
card_data: card_data.clone(),
network_token_data: token_data.clone(),
};
payment_data.set_vault_operation(
PaymentMethodDataAction::VaultData(vault_data.clone()),
PaymentMethodDataAction::SaveCardAndNetworkTokenData(card_and_network_token_data.clone()),
)
}
_ => (),
Expand Down Expand Up @@ -4526,12 +4526,11 @@ where
#[derive(Clone, serde::Serialize, Debug)]
pub enum PaymentMethodDataAction {
SaveCardData(hyperswitch_domain_models::payment_method_data::Card),
SaveNetworkTokenData(hyperswitch_domain_models::payment_method_data::NetworkTokenData),
VaultData(VaultData),
SaveCardAndNetworkTokenData(CardAndNetworkTokenData)
}

#[derive(Clone, serde::Serialize, Debug)]
pub struct VaultData {
#[derive(Default, Clone, serde::Serialize, Debug)]
pub struct CardAndNetworkTokenData {
pub card_data: hyperswitch_domain_models::payment_method_data::Card,
pub network_token_data: hyperswitch_domain_models::payment_method_data::NetworkTokenData,
}
Expand Down
11 changes: 10 additions & 1 deletion crates/router/src/core/payments/operations/payment_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ impl<F: Send + Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthor
.and_then(|billing_details| billing_details.address.as_ref())
.and_then(|address| address.get_optional_full_name());
let mut should_avoid_saving = false;
let vault_operation = payment_data.vault_operation.clone();
let payment_method_info = payment_data.payment_method_info.clone();

if let Some(payment_method_info) = &payment_data.payment_method_info {
if payment_data.payment_intent.off_session.is_none() && resp.response.is_ok() {
Expand Down Expand Up @@ -200,6 +202,8 @@ impl<F: Send + Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthor
payment_method_billing_address,
business_profile,
connector_mandate_reference_id.clone(),
vault_operation.clone(),
payment_method_info.clone(),
));

let is_connector_mandate = resp.request.customer_acceptance.is_some()
Expand Down Expand Up @@ -315,6 +319,8 @@ impl<F: Send + Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthor
payment_method_billing_address.as_ref(),
&business_profile,
connector_mandate_reference_id,
vault_operation.clone(),
payment_method_info.clone(),
))
.await;

Expand Down Expand Up @@ -1081,7 +1087,8 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::SetupMandateRequestDa
.connector_mandate_detail
.as_ref()
.map(|detail| ConnectorMandateReferenceId::foreign_from(detail.clone()));

let vault_operation = payment_data.vault_operation.clone();
let payment_method_info = payment_data.payment_method_info.clone();
let merchant_connector_id = payment_data.payment_attempt.merchant_connector_id.clone();
let tokenization::SavePaymentMethodDataResponse {
payment_method_id,
Expand All @@ -1099,6 +1106,8 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::SetupMandateRequestDa
payment_method_billing_address,
business_profile,
connector_mandate_reference_id,
vault_operation,
payment_method_info,
))
.await?;

Expand Down
159 changes: 133 additions & 26 deletions crates/router/src/core/payments/tokenization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ pub async fn save_payment_method<FData>(
payment_method_billing_address: Option<&hyperswitch_domain_models::address::Address>,
business_profile: &domain::Profile,
mut original_connector_mandate_reference_id: Option<ConnectorMandateReferenceId>,
vault_operation: Option<payments::PaymentMethodDataAction>,
payment_method_info: Option<domain::PaymentMethod>,
) -> RouterResult<SavePaymentMethodDataResponse>
where
FData: mandate::MandateBehaviour + Clone,
Expand Down Expand Up @@ -204,41 +206,146 @@ where
.await?;
((res, dc, None), None)
} else {
pm_status = Some(common_enums::PaymentMethodStatus::from(
let payment_method_status = common_enums::PaymentMethodStatus::from(
save_payment_method_data.attempt_status,
));
let (res, dc) = Box::pin(save_in_locker(
state,
merchant_account,
payment_method_create_request.to_owned(),
))
.await?;
);
pm_status = Some(payment_method_status);

if let Some(payment_method_data_action) = vault_operation {
let network_token_requestor_reference_id = payment_method_info.and_then(|pm_info| pm_info.network_token_requestor_reference_id.clone());
match payment_method_data_action {
payments::PaymentMethodDataAction::SaveCardData(card)=>{
if payment_method_status == common_enums::PaymentMethodStatus::Inactive {
if let (Some(nt_ref_id), Some(tokenization_service)) = (network_token_requestor_reference_id.clone(), &state.conf.network_tokenization_service) {
let _ = record_operation_time(
async {
network_tokenization::delete_network_token_from_tokenization_service(
state,
nt_ref_id.clone(),
&customer_id,
tokenization_service.get_inner(),
)
.await
},
&metrics::DELETE_NETWORK_TOKEN_TIME,
&[],
)
.await;
}
}
let card_data = api::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: None,
nick_name: None,
card_issuing_country: None,
card_network: card.card_network.clone(),
card_issuer: None,
card_type: None,
};
let (res, dc) = Box::pin(payment_methods::cards::add_card_to_locker(
state,
payment_method_create_request.to_owned(),
&card_data,
&customer_id,
merchant_account,
None,
))
.await
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Add Card In Locker Failed")?;

if is_network_tokenization_enabled {
let pm_data = &save_payment_method_data.request.get_payment_method_data();
match pm_data {
domain::PaymentMethodData::Card(card) => {
let (
network_token_resp,
_network_token_duplication_check, //the duplication check is discarded, since each card has only one token, handling card duplication check will be suffice
network_token_requestor_ref_id,
) = Box::pin(save_network_token_in_locker(
((res,dc,None),None)
}
payments::PaymentMethodDataAction::SaveCardAndNetworkTokenData(save_card_and_network_token_data)=>{
let card_data = api::CardDetail {
card_number: save_card_and_network_token_data.card_data.card_number.clone(),
card_exp_month: save_card_and_network_token_data.card_data.card_exp_month.clone(),
card_exp_year: save_card_and_network_token_data.card_data.card_exp_year.clone(),
card_holder_name: None,
nick_name: None,
card_issuing_country: None,
card_network: save_card_and_network_token_data.card_data.card_network.clone(),
card_issuer: None,
card_type: None,
};
let (res, dc) = Box::pin(payment_methods::cards::add_card_to_locker(
state,
payment_method_create_request.to_owned(),
&card_data,
&customer_id,
merchant_account,
card,
payment_method_create_request.clone(),
None,
))
.await?;
.await
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Add Card In Locker Failed")?;

let network_token_data = api::CardDetail {
card_number: save_card_and_network_token_data.network_token_data.token_number.clone(),
card_exp_month: save_card_and_network_token_data.network_token_data.token_exp_month.clone(),
card_exp_year: save_card_and_network_token_data.network_token_data.token_exp_year.clone(),
card_holder_name: None,
nick_name: None,
card_issuing_country: None,
card_network: save_card_and_network_token_data.network_token_data.card_network.clone(),
card_issuer: None,
card_type: None,
};

(
(res, dc, network_token_requestor_ref_id),
network_token_resp,
)
let card_reference = network_token_requestor_reference_id.as_ref().map(|x| x.as_str());

let (network_token_resp, _dc) = Box::pin(payment_methods::cards::add_card_to_locker(
state,
payment_method_create_request.to_owned(),
&network_token_data,
&customer_id,
merchant_account,
card_reference,
))
.await
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Add Network Token In Locker Failed")?;

((res, dc, network_token_requestor_reference_id), Some(network_token_resp))
}
_ => ((res, dc, None), None), //network_token_resp is None in case of other payment methods
}
} else {
((res, dc, None), None)
let (res, dc) = Box::pin(save_in_locker(
state,
merchant_account,
payment_method_create_request.to_owned(),
))
.await?;

if is_network_tokenization_enabled {
let pm_data = &save_payment_method_data.request.get_payment_method_data();
match pm_data {
domain::PaymentMethodData::Card(card) => {
let (
network_token_resp,
_network_token_duplication_check, //the duplication check is discarded, since each card has only one token, handling card duplication check will be suffice
network_token_requestor_ref_id,
) = Box::pin(save_network_token_in_locker(
state,
merchant_account,
card,
payment_method_create_request.clone(),
))
.await?;

(
(res, dc, network_token_requestor_ref_id),
network_token_resp,
)
}
_ => ((res, dc, None), None), //network_token_resp is None in case of other payment methods
}
} else {
((res, dc, None), None)
}

}
};
let network_token_locker_id = match network_token_resp {
Expand Down

0 comments on commit dcc8625

Please sign in to comment.