From bff8b35e2813ae9baddb0f225301dee85a294e2c Mon Sep 17 00:00:00 2001 From: ItsMeShashank Date: Thu, 5 Jan 2023 13:53:24 +0530 Subject: [PATCH] fix(router): make customer id mandatory when address or setup future usage given (#282) --- crates/router/src/core/payments/helpers.rs | 38 +++++++++++++++++++ .../payments/operations/payment_confirm.rs | 38 ++++++++++++------- .../payments/operations/payment_create.rs | 22 ++++++++--- .../payments/operations/payment_update.rs | 21 +++++++++- 4 files changed, 98 insertions(+), 21 deletions(-) diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 37fa06a427..61a33de4ef 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -305,6 +305,44 @@ fn validate_new_mandate_request(req: api::MandateValidationFields) -> RouterResu Ok(()) } +pub fn validate_customer_id_mandatory_cases_api( + shipping: &Option, + billing: &Option, + setup_future_usage: &Option, + customer_id: &Option, +) -> RouterResult<()> { + match (shipping, billing, setup_future_usage, customer_id) { + (Some(_), _, _, None) | (_, Some(_), _, None) | (_, _, Some(_), None) => { + Err(errors::ApiErrorResponse::PreconditionFailed { + message: "customer_id is mandatory when shipping or billing \ + address is given or when setup_future_usage is given" + .to_string(), + }) + .into_report() + } + _ => Ok(()), + } +} + +pub fn validate_customer_id_mandatory_cases_storage( + shipping: &Option, + billing: &Option, + setup_future_usage: &Option, + customer_id: &Option, +) -> RouterResult<()> { + match (shipping, billing, setup_future_usage, customer_id) { + (Some(_), _, _, None) | (_, Some(_), _, None) | (_, _, Some(_), None) => { + Err(errors::ApiErrorResponse::PreconditionFailed { + message: "customer_id is mandatory when shipping or billing \ + address is given or when setup_future_usage is given" + .to_string(), + }) + .into_report() + } + _ => Ok(()), + } +} + pub fn create_startpay_url( server: &Server, payment_attempt: &storage::PaymentAttempt, diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index 3de10cc9ad..5eb74e5095 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -87,24 +87,10 @@ impl GetTracker, api::PaymentsRequest> for Pa error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound) })?; payment_attempt.payment_method = payment_method_type.or(payment_attempt.payment_method); - - payment_attempt.payment_method = payment_method_type.or(payment_attempt.payment_method); payment_attempt.browser_info = browser_info; currency = payment_attempt.currency.get_required_value("currency")?; amount = payment_attempt.amount.into(); - connector_response = db - .find_connector_response_by_payment_id_merchant_id_attempt_id( - &payment_attempt.payment_id, - &payment_attempt.merchant_id, - &payment_attempt.attempt_id, - storage_scheme, - ) - .await - .map_err(|error| { - error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound) - })?; - let shipping_address = helpers::get_address_for_payment_request( db, request.shipping.as_ref(), @@ -122,6 +108,30 @@ impl GetTracker, api::PaymentsRequest> for Pa ) .await?; + helpers::validate_customer_id_mandatory_cases_storage( + &shipping_address, + &billing_address, + &payment_intent + .setup_future_usage + .or_else(|| request.setup_future_usage.map(ForeignInto::foreign_into)), + &payment_intent + .customer_id + .clone() + .or_else(|| request.customer_id.clone()), + )?; + + connector_response = db + .find_connector_response_by_payment_id_merchant_id_attempt_id( + &payment_attempt.payment_id, + &payment_attempt.merchant_id, + &payment_attempt.attempt_id, + storage_scheme, + ) + .await + .map_err(|error| { + error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound) + })?; + payment_intent.shipping_address_id = shipping_address.clone().map(|i| i.address_id); payment_intent.billing_address_id = billing_address.clone().map(|i| i.address_id); diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index 51695466dd..031cf67651 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -407,12 +407,22 @@ impl ValidateRequest for PaymentCreate None => None, }; - if request.confirm == Some(true) - && request.payment_method != Some(api_models::enums::PaymentMethodType::Paypal) - { - helpers::validate_pm_or_token_given( - &request.payment_token, - &request.payment_method_data, + if request.confirm.unwrap_or(false) { + if !matches!( + request.payment_method, + Some(api_models::enums::PaymentMethodType::Paypal) + ) { + helpers::validate_pm_or_token_given( + &request.payment_token, + &request.payment_method_data, + )?; + } + + helpers::validate_customer_id_mandatory_cases_api( + &request.shipping, + &request.billing, + &request.setup_future_usage, + &request.customer_id, )?; } diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index 78ce6ec9c8..a017802ba2 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -108,6 +108,20 @@ impl GetTracker, api::PaymentsRequest> for Pa payment_intent.shipping_address_id = shipping_address.clone().map(|x| x.address_id); payment_intent.billing_address_id = billing_address.clone().map(|x| x.address_id); + if request.confirm.unwrap_or(false) { + helpers::validate_customer_id_mandatory_cases_storage( + &shipping_address, + &billing_address, + &payment_intent + .setup_future_usage + .or_else(|| request.setup_future_usage.map(ForeignInto::foreign_into)), + &payment_intent + .customer_id + .clone() + .or_else(|| request.customer_id.clone()), + )?; + } + let connector_response = db .find_connector_response_by_payment_id_merchant_id_attempt_id( &payment_intent.payment_id, @@ -371,7 +385,12 @@ impl ValidateRequest for PaymentUpdate None => None, }; - if let Some(true) = request.confirm { + if request.confirm.unwrap_or(false) + && !matches!( + request.payment_method, + Some(api_models::enums::PaymentMethodType::Paypal) + ) + { helpers::validate_pm_or_token_given( &request.payment_token, &request.payment_method_data,