diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index b479f4442ba6..8b4a37b90e77 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -1675,6 +1675,20 @@ impl std::fmt::Display for PaymentIdType { } } +impl PaymentIdType { + pub fn and_then(self, f: F) -> Result + where + F: FnOnce(String) -> Result, + { + match self { + Self::PaymentIntentId(s) => f(s).map(Self::PaymentIntentId), + Self::ConnectorTransactionId(s) => f(s).map(Self::ConnectorTransactionId), + Self::PaymentAttemptId(s) => f(s).map(Self::PaymentAttemptId), + Self::PreprocessingId(s) => f(s).map(Self::PreprocessingId), + } + } +} + impl Default for PaymentIdType { fn default() -> Self { Self::PaymentIntentId(Default::default()) diff --git a/crates/router/src/core/payments/operations/payment_approve.rs b/crates/router/src/core/payments/operations/payment_approve.rs index 538e65e4b22e..6fd87faebd4d 100644 --- a/crates/router/src/core/payments/operations/payment_approve.rs +++ b/crates/router/src/core/payments/operations/payment_approve.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use api_models::enums::FrmSuggestion; use async_trait::async_trait; use data_models::mandates::MandateData; -use error_stack::ResultExt; +use error_stack::{report, IntoReport, ResultExt}; use router_derive::PaymentOperation; use router_env::{instrument, tracing}; @@ -381,15 +381,6 @@ impl ValidateRequest, operations::ValidateResult<'a>, )> { - let given_payment_id = match &request.payment_id { - Some(id_type) => Some( - id_type - .get_payment_intent_id() - .change_context(errors::ApiErrorResponse::PaymentNotFound)?, - ), - None => None, - }; - let request_merchant_id = request.merchant_id.as_deref(); helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id) .change_context(errors::ApiErrorResponse::InvalidDataFormat { @@ -401,13 +392,18 @@ impl ValidateRequest ValidateRequest, operations::ValidateResult<'a>, )> { - let given_payment_id = match &request.payment_id { - Some(id_type) => Some( - id_type - .get_payment_intent_id() - .change_context(errors::ApiErrorResponse::PaymentNotFound)?, - ), - None => None, - }; + let payment_id = request + .payment_id + .clone() + .ok_or(report!(errors::ApiErrorResponse::PaymentNotFound))?; let request_merchant_id = request.merchant_id.as_deref(); helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id) @@ -377,13 +373,14 @@ impl ValidateRequest ValidateRequest, )> { helpers::validate_customer_details_in_request(request)?; - let given_payment_id = match &request.payment_id { - Some(id_type) => Some( - id_type - .get_payment_intent_id() - .change_context(errors::ApiErrorResponse::PaymentNotFound)?, - ), - None => None, - }; let request_merchant_id = request.merchant_id.as_deref(); helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id) @@ -794,14 +786,19 @@ impl ValidateRequest ValidateRequest Some( - id_type - .get_payment_intent_id() - .change_context(errors::ApiErrorResponse::PaymentNotFound)?, - ), - None => None, - }; + let payment_id = request.payment_id.clone().ok_or(error_stack::report!( + errors::ApiErrorResponse::PaymentNotFound + ))?; let request_merchant_id = request.merchant_id.as_deref(); helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id) @@ -540,8 +535,6 @@ impl ValidateRequest ValidateRequest ValidateRequest, )> { helpers::validate_customer_details_in_request(request)?; - let given_payment_id = match &request.payment_id { - Some(id_type) => Some( - id_type - .get_payment_intent_id() - .change_context(errors::ApiErrorResponse::PaymentNotFound)?, - ), - None => None, - }; + let payment_id = request + .payment_id + .clone() + .ok_or(report!(errors::ApiErrorResponse::PaymentNotFound))?; let request_merchant_id = request.merchant_id.as_deref(); helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id) @@ -620,13 +616,14 @@ impl ValidateRequest, ) -> impl Responder { let flow = Flow::PaymentsCreate; - let payload = json_payload.into_inner(); + let mut payload = json_payload.into_inner(); if let Some(api_enums::CaptureMethod::Scheduled) = payload.capture_method { return http_not_implemented(); }; + if let Err(err) = get_or_generate_payment_id(&mut payload) { + return api::log_and_return_error_response(err); + } + let locking_action = payload.get_locking_input(flow.clone()); Box::pin(api::server_wrap( @@ -959,6 +967,29 @@ where } } +pub fn get_or_generate_payment_id( + payload: &mut payment_types::PaymentsRequest, +) -> errors::RouterResult<()> { + let given_payment_id = payload + .payment_id + .clone() + .map(|payment_id| { + payment_id + .get_payment_intent_id() + .map_err(|err| err.change_context(errors::ApiErrorResponse::PaymentNotFound)) + }) + .transpose()?; + + let payment_id = + core_utils::get_or_generate_id("payment_id", &given_payment_id, "pay").into_report()?; + + payload.payment_id = Some(api_models::payments::PaymentIdType::PaymentIntentId( + payment_id, + )); + + Ok(()) +} + impl GetLockingInput for payment_types::PaymentsRequest { fn get_locking_input(&self, flow: F) -> api_locking::LockAction where