diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 78d58c6971..778e89ab30 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -5433,7 +5433,8 @@ "automatic", "manual", "manual_multiple", - "scheduled" + "scheduled", + "sequential_automatic" ] }, "CaptureResponse": { diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index b391061c38..3f3ffc17a1 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -8012,7 +8012,8 @@ "automatic", "manual", "manual_multiple", - "scheduled" + "scheduled", + "sequential_automatic" ] }, "CaptureResponse": { diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index d966902af8..701e879378 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -353,6 +353,8 @@ pub enum CaptureMethod { ManualMultiple, /// The capture can be scheduled to automatically get triggered at a specific date & time Scheduled, + /// Handles separate auth and capture sequentially; same as `Automatic` for most connectors. + SequentialAutomatic, } /// Type of the Connector for the financial use case. Could range from Payments to Accounting to Banking. diff --git a/crates/hyperswitch_connectors/src/connectors/airwallex.rs b/crates/hyperswitch_connectors/src/connectors/airwallex.rs index 26bfcd1e07..2b7b301ab9 100644 --- a/crates/hyperswitch_connectors/src/connectors/airwallex.rs +++ b/crates/hyperswitch_connectors/src/connectors/airwallex.rs @@ -134,7 +134,9 @@ impl ConnectorValidation for Airwallex { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs b/crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs index 040a1422e0..97c9ed4d36 100644 --- a/crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs @@ -189,7 +189,9 @@ impl TryFrom<&AirwallexRouterData<&types::PaymentsAuthorizeRouterData>> Some(AirwallexPaymentOptions::Card(AirwallexCardPaymentOptions { auto_capture: matches!( request.capture_method, - Some(enums::CaptureMethod::Automatic) | None + Some(enums::CaptureMethod::Automatic) + | Some(enums::CaptureMethod::SequentialAutomatic) + | None ), })); Ok(AirwallexPaymentMethod::Card(AirwallexCard { diff --git a/crates/hyperswitch_connectors/src/connectors/bambora.rs b/crates/hyperswitch_connectors/src/connectors/bambora.rs index 4731546b3d..4e69a39fed 100644 --- a/crates/hyperswitch_connectors/src/connectors/bambora.rs +++ b/crates/hyperswitch_connectors/src/connectors/bambora.rs @@ -152,7 +152,9 @@ impl ConnectorValidation for Bambora { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/bamboraapac.rs b/crates/hyperswitch_connectors/src/connectors/bamboraapac.rs index 16ecee19ee..9954c56807 100644 --- a/crates/hyperswitch_connectors/src/connectors/bamboraapac.rs +++ b/crates/hyperswitch_connectors/src/connectors/bamboraapac.rs @@ -102,7 +102,9 @@ impl ConnectorValidation for Bamboraapac { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/billwerk.rs b/crates/hyperswitch_connectors/src/connectors/billwerk.rs index 251d2355f2..7a6fefa820 100644 --- a/crates/hyperswitch_connectors/src/connectors/billwerk.rs +++ b/crates/hyperswitch_connectors/src/connectors/billwerk.rs @@ -158,7 +158,9 @@ impl ConnectorValidation for Billwerk { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - common_enums::CaptureMethod::Automatic | common_enums::CaptureMethod::Manual => Ok(()), + common_enums::CaptureMethod::Automatic + | common_enums::CaptureMethod::Manual + | common_enums::CaptureMethod::SequentialAutomatic => Ok(()), common_enums::CaptureMethod::ManualMultiple | common_enums::CaptureMethod::Scheduled => Err( construct_not_implemented_error_report(capture_method, self.id()), diff --git a/crates/hyperswitch_connectors/src/connectors/boku.rs b/crates/hyperswitch_connectors/src/connectors/boku.rs index d23d34e473..e6d47c05a9 100644 --- a/crates/hyperswitch_connectors/src/connectors/boku.rs +++ b/crates/hyperswitch_connectors/src/connectors/boku.rs @@ -175,7 +175,9 @@ impl ConnectorValidation for Boku { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/cashtocode.rs b/crates/hyperswitch_connectors/src/connectors/cashtocode.rs index 1ee6f10c63..b5363cdf5d 100644 --- a/crates/hyperswitch_connectors/src/connectors/cashtocode.rs +++ b/crates/hyperswitch_connectors/src/connectors/cashtocode.rs @@ -155,7 +155,9 @@ impl ConnectorValidation for Cashtocode { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/coinbase.rs b/crates/hyperswitch_connectors/src/connectors/coinbase.rs index 7b149952ca..168cb2132d 100644 --- a/crates/hyperswitch_connectors/src/connectors/coinbase.rs +++ b/crates/hyperswitch_connectors/src/connectors/coinbase.rs @@ -140,7 +140,9 @@ impl ConnectorValidation for Coinbase { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank.rs index a861155afb..28bcd8afca 100644 --- a/crates/hyperswitch_connectors/src/connectors/deutschebank.rs +++ b/crates/hyperswitch_connectors/src/connectors/deutschebank.rs @@ -179,7 +179,9 @@ impl ConnectorValidation for Deutschebank { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/digitalvirgo.rs b/crates/hyperswitch_connectors/src/connectors/digitalvirgo.rs index af6486f008..0f84bfa619 100644 --- a/crates/hyperswitch_connectors/src/connectors/digitalvirgo.rs +++ b/crates/hyperswitch_connectors/src/connectors/digitalvirgo.rs @@ -170,7 +170,7 @@ impl ConnectorValidation for Digitalvirgo { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic => Ok(()), + enums::CaptureMethod::Automatic | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::Manual | enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err(utils::construct_not_supported_error_report( diff --git a/crates/hyperswitch_connectors/src/connectors/dlocal.rs b/crates/hyperswitch_connectors/src/connectors/dlocal.rs index 78d3ad4f63..a61110435e 100644 --- a/crates/hyperswitch_connectors/src/connectors/dlocal.rs +++ b/crates/hyperswitch_connectors/src/connectors/dlocal.rs @@ -161,7 +161,9 @@ impl ConnectorValidation for Dlocal { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs b/crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs index 433308059a..c5b4b940c1 100644 --- a/crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs @@ -106,6 +106,7 @@ impl TryFrom<&DlocalRouterData<&types::PaymentsAuthorizeRouterData>> for DlocalP let should_capture = matches!( item.router_data.request.capture_method, Some(enums::CaptureMethod::Automatic) + | Some(enums::CaptureMethod::SequentialAutomatic) ); let payment_request = Self { amount: item.amount, diff --git a/crates/hyperswitch_connectors/src/connectors/elavon.rs b/crates/hyperswitch_connectors/src/connectors/elavon.rs index b236e3a604..4fcc75296f 100644 --- a/crates/hyperswitch_connectors/src/connectors/elavon.rs +++ b/crates/hyperswitch_connectors/src/connectors/elavon.rs @@ -586,7 +586,9 @@ impl ConnectorValidation for Elavon { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - CaptureMethod::Automatic | CaptureMethod::Manual => Ok(()), + CaptureMethod::Automatic + | CaptureMethod::Manual + | CaptureMethod::SequentialAutomatic => Ok(()), CaptureMethod::ManualMultiple | CaptureMethod::Scheduled => Err( utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/fiserv.rs b/crates/hyperswitch_connectors/src/connectors/fiserv.rs index fc67cd2fde..e241990f8e 100644 --- a/crates/hyperswitch_connectors/src/connectors/fiserv.rs +++ b/crates/hyperswitch_connectors/src/connectors/fiserv.rs @@ -186,7 +186,9 @@ impl ConnectorValidation for Fiserv { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/fiserv/transformers.rs b/crates/hyperswitch_connectors/src/connectors/fiserv/transformers.rs index 07562c3efb..f408452541 100644 --- a/crates/hyperswitch_connectors/src/connectors/fiserv/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/fiserv/transformers.rs @@ -149,7 +149,9 @@ impl TryFrom<&FiservRouterData<&types::PaymentsAuthorizeRouterData>> for FiservP let transaction_details = TransactionDetails { capture_flag: Some(matches!( item.router_data.request.capture_method, - Some(enums::CaptureMethod::Automatic) | None + Some(enums::CaptureMethod::Automatic) + | Some(enums::CaptureMethod::SequentialAutomatic) + | None )), reversal_reason_code: None, merchant_transaction_id: item.router_data.connector_request_reference_id.clone(), diff --git a/crates/hyperswitch_connectors/src/connectors/fiservemea.rs b/crates/hyperswitch_connectors/src/connectors/fiservemea.rs index a7eed07d30..86a626908b 100644 --- a/crates/hyperswitch_connectors/src/connectors/fiservemea.rs +++ b/crates/hyperswitch_connectors/src/connectors/fiservemea.rs @@ -254,7 +254,9 @@ impl ConnectorValidation for Fiservemea { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/fiservemea/transformers.rs b/crates/hyperswitch_connectors/src/connectors/fiservemea/transformers.rs index a5362283e7..24934273a4 100644 --- a/crates/hyperswitch_connectors/src/connectors/fiservemea/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/fiservemea/transformers.rs @@ -103,13 +103,16 @@ impl TryFrom<&FiservemeaRouterData<&PaymentsAuthorizeRouterData>> for Fiservemea }, security_code: req_card.card_cvc, }; - let request_type = if item.router_data.request.capture_method - == Some(enums::CaptureMethod::Automatic) - { + let request_type = if matches!( + item.router_data.request.capture_method, + Some(enums::CaptureMethod::Automatic) + | Some(enums::CaptureMethod::SequentialAutomatic) + ) { FiservemeaRequestType::PaymentCardSaleTransaction } else { FiservemeaRequestType::PaymentCardPreAuthTransaction }; + Ok(Self { request_type, merchant_transaction_id: item diff --git a/crates/hyperswitch_connectors/src/connectors/fiuu.rs b/crates/hyperswitch_connectors/src/connectors/fiuu.rs index 774a0ba758..df2d0f5006 100644 --- a/crates/hyperswitch_connectors/src/connectors/fiuu.rs +++ b/crates/hyperswitch_connectors/src/connectors/fiuu.rs @@ -209,7 +209,9 @@ impl ConnectorValidation for Fiuu { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - CaptureMethod::Automatic | CaptureMethod::Manual => Ok(()), + CaptureMethod::Automatic + | CaptureMethod::Manual + | CaptureMethod::SequentialAutomatic => Ok(()), CaptureMethod::ManualMultiple | CaptureMethod::Scheduled => Err( utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/fiuu/transformers.rs b/crates/hyperswitch_connectors/src/connectors/fiuu/transformers.rs index f3c3685b5c..f8f57887c2 100644 --- a/crates/hyperswitch_connectors/src/connectors/fiuu/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/fiuu/transformers.rs @@ -101,7 +101,9 @@ impl TryFrom> for TxnType { type Error = Report; fn try_from(capture_method: Option) -> Result { match capture_method { - Some(CaptureMethod::Automatic) => Ok(Self::Sals), + Some(CaptureMethod::Automatic) | Some(CaptureMethod::SequentialAutomatic) | None => { + Ok(Self::Sals) + } Some(CaptureMethod::Manual) => Ok(Self::Auts), _ => Err(errors::ConnectorError::CaptureMethodNotSupported.into()), } @@ -1244,7 +1246,9 @@ impl TryFrom for enums::AttemptStatus { fn try_from(webhook_status: FiuuWebhookStatus) -> Result { match webhook_status.status { FiuuPaymentWebhookStatus::Success => match webhook_status.capture_method { - Some(CaptureMethod::Automatic) => Ok(Self::Charged), + Some(CaptureMethod::Automatic) | Some(CaptureMethod::SequentialAutomatic) => { + Ok(Self::Charged) + } Some(CaptureMethod::Manual) => Ok(Self::Authorized), _ => Err(errors::ConnectorError::UnexpectedResponseError( bytes::Bytes::from(webhook_status.status.to_string()), diff --git a/crates/hyperswitch_connectors/src/connectors/forte.rs b/crates/hyperswitch_connectors/src/connectors/forte.rs index fd5c779288..b35efc7c5f 100644 --- a/crates/hyperswitch_connectors/src/connectors/forte.rs +++ b/crates/hyperswitch_connectors/src/connectors/forte.rs @@ -174,7 +174,9 @@ impl ConnectorValidation for Forte { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/globepay.rs b/crates/hyperswitch_connectors/src/connectors/globepay.rs index 8faf4190e9..c9e316707c 100644 --- a/crates/hyperswitch_connectors/src/connectors/globepay.rs +++ b/crates/hyperswitch_connectors/src/connectors/globepay.rs @@ -195,7 +195,11 @@ impl ConnectorIntegration CustomResult { let query_params = get_globlepay_query_params(&req.connector_auth_type)?; - if req.request.capture_method == Some(common_enums::enums::CaptureMethod::Automatic) { + if matches!( + req.request.capture_method, + Some(common_enums::enums::CaptureMethod::Automatic) + | Some(common_enums::enums::CaptureMethod::SequentialAutomatic) + ) { Ok(format!( "{}api/v1.0/gateway/partners/{}/orders/{}{query_params}", self.base_url(connectors), diff --git a/crates/hyperswitch_connectors/src/connectors/gocardless.rs b/crates/hyperswitch_connectors/src/connectors/gocardless.rs index becc8749b5..4e866d6f13 100644 --- a/crates/hyperswitch_connectors/src/connectors/gocardless.rs +++ b/crates/hyperswitch_connectors/src/connectors/gocardless.rs @@ -340,7 +340,7 @@ impl ConnectorValidation for Gocardless { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic => Ok(()), + enums::CaptureMethod::Automatic | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::Manual | enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err(construct_not_implemented_error_report( diff --git a/crates/hyperswitch_connectors/src/connectors/helcim.rs b/crates/hyperswitch_connectors/src/connectors/helcim.rs index fcb9c77e10..a9344beac1 100644 --- a/crates/hyperswitch_connectors/src/connectors/helcim.rs +++ b/crates/hyperswitch_connectors/src/connectors/helcim.rs @@ -177,7 +177,9 @@ impl ConnectorValidation for Helcim { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( crate::utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs b/crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs index bbfa0598cf..5257df672f 100644 --- a/crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs @@ -155,7 +155,7 @@ impl TryFrom<&MollieRouterData<&types::PaymentsAuthorizeRouterData>> for MollieP let redirect_url = item.router_data.request.get_return_url()?; let payment_method_data = match item.router_data.request.capture_method.unwrap_or_default() { - enums::CaptureMethod::Automatic => { + enums::CaptureMethod::Automatic | enums::CaptureMethod::SequentialAutomatic => { match &item.router_data.request.payment_method_data { PaymentMethodData::Card(_) => { let pm_token = item.router_data.get_payment_method_token()?; diff --git a/crates/hyperswitch_connectors/src/connectors/multisafepay.rs b/crates/hyperswitch_connectors/src/connectors/multisafepay.rs index 7d212bd1f9..562f84cbe8 100644 --- a/crates/hyperswitch_connectors/src/connectors/multisafepay.rs +++ b/crates/hyperswitch_connectors/src/connectors/multisafepay.rs @@ -134,7 +134,7 @@ impl ConnectorValidation for Multisafepay { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic => Ok(()), + enums::CaptureMethod::Automatic | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::Manual | enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err(errors::ConnectorError::NotImplemented( diff --git a/crates/hyperswitch_connectors/src/connectors/nexinets.rs b/crates/hyperswitch_connectors/src/connectors/nexinets.rs index 94b24bbe86..35899737c2 100644 --- a/crates/hyperswitch_connectors/src/connectors/nexinets.rs +++ b/crates/hyperswitch_connectors/src/connectors/nexinets.rs @@ -171,7 +171,9 @@ impl ConnectorValidation for Nexinets { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( construct_not_implemented_error_report(capture_method, self.id()), ), @@ -232,7 +234,10 @@ impl ConnectorIntegration CustomResult { - let url = if req.request.capture_method == Some(enums::CaptureMethod::Automatic) { + let url = if matches!( + req.request.capture_method, + Some(enums::CaptureMethod::Automatic) | Some(enums::CaptureMethod::SequentialAutomatic) + ) { format!("{}/orders/debit", self.base_url(connectors)) } else { format!("{}/orders/preauth", self.base_url(connectors)) diff --git a/crates/hyperswitch_connectors/src/connectors/nexixpay.rs b/crates/hyperswitch_connectors/src/connectors/nexixpay.rs index 701a0a54e4..0b09b5ea28 100644 --- a/crates/hyperswitch_connectors/src/connectors/nexixpay.rs +++ b/crates/hyperswitch_connectors/src/connectors/nexixpay.rs @@ -208,7 +208,9 @@ impl ConnectorValidation for Nexixpay { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/nexixpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/nexixpay/transformers.rs index 9c35b913db..1384102faf 100644 --- a/crates/hyperswitch_connectors/src/connectors/nexixpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/nexixpay/transformers.rs @@ -748,7 +748,9 @@ fn get_nexixpay_capture_type( ) -> CustomResult, errors::ConnectorError> { match item { Some(CaptureMethod::Manual) => Ok(Some(NexixpayCaptureType::Explicit)), - Some(CaptureMethod::Automatic) | None => Ok(Some(NexixpayCaptureType::Implicit)), + Some(CaptureMethod::Automatic) | Some(CaptureMethod::SequentialAutomatic) | None => { + Ok(Some(NexixpayCaptureType::Implicit)) + } Some(item) => Err(errors::ConnectorError::FlowNotSupported { flow: item.to_string(), connector: "Nexixpay".to_string(), diff --git a/crates/hyperswitch_connectors/src/connectors/novalnet.rs b/crates/hyperswitch_connectors/src/connectors/novalnet.rs index fd7ff906d0..0f53158187 100644 --- a/crates/hyperswitch_connectors/src/connectors/novalnet.rs +++ b/crates/hyperswitch_connectors/src/connectors/novalnet.rs @@ -165,7 +165,9 @@ impl ConnectorValidation for Novalnet { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/payeezy.rs b/crates/hyperswitch_connectors/src/connectors/payeezy.rs index cb22d0cb7b..d2e21a927d 100644 --- a/crates/hyperswitch_connectors/src/connectors/payeezy.rs +++ b/crates/hyperswitch_connectors/src/connectors/payeezy.rs @@ -158,7 +158,9 @@ impl ConnectorValidation for Payeezy { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - CaptureMethod::Automatic | CaptureMethod::Manual => Ok(()), + CaptureMethod::Automatic + | CaptureMethod::Manual + | CaptureMethod::SequentialAutomatic => Ok(()), CaptureMethod::ManualMultiple | CaptureMethod::Scheduled => Err( construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/payeezy/transformers.rs b/crates/hyperswitch_connectors/src/connectors/payeezy/transformers.rs index cda9c6b195..49188803c4 100644 --- a/crates/hyperswitch_connectors/src/connectors/payeezy/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/payeezy/transformers.rs @@ -214,7 +214,9 @@ fn get_transaction_type_and_stored_creds( } else { match item.request.capture_method { Some(CaptureMethod::Manual) => Ok((PayeezyTransactionType::Authorize, None)), - Some(CaptureMethod::Automatic) => Ok((PayeezyTransactionType::Purchase, None)), + Some(CaptureMethod::SequentialAutomatic) | Some(CaptureMethod::Automatic) => { + Ok((PayeezyTransactionType::Purchase, None)) + } Some(CaptureMethod::ManualMultiple) | Some(CaptureMethod::Scheduled) | None => { Err(ConnectorError::FlowNotSupported { diff --git a/crates/hyperswitch_connectors/src/connectors/payu.rs b/crates/hyperswitch_connectors/src/connectors/payu.rs index ad2479f19e..6007b542e9 100644 --- a/crates/hyperswitch_connectors/src/connectors/payu.rs +++ b/crates/hyperswitch_connectors/src/connectors/payu.rs @@ -146,7 +146,9 @@ impl ConnectorValidation for Payu { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/powertranz.rs b/crates/hyperswitch_connectors/src/connectors/powertranz.rs index a437d419bc..7da88269c7 100644 --- a/crates/hyperswitch_connectors/src/connectors/powertranz.rs +++ b/crates/hyperswitch_connectors/src/connectors/powertranz.rs @@ -152,7 +152,9 @@ impl ConnectorValidation for Powertranz { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/rapyd.rs b/crates/hyperswitch_connectors/src/connectors/rapyd.rs index ef12952ee1..c94cd09e27 100644 --- a/crates/hyperswitch_connectors/src/connectors/rapyd.rs +++ b/crates/hyperswitch_connectors/src/connectors/rapyd.rs @@ -153,7 +153,9 @@ impl ConnectorValidation for Rapyd { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/rapyd/transformers.rs b/crates/hyperswitch_connectors/src/connectors/rapyd/transformers.rs index 4f9f276c19..23f861bfa3 100644 --- a/crates/hyperswitch_connectors/src/connectors/rapyd/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/rapyd/transformers.rs @@ -109,7 +109,9 @@ impl TryFrom<&RapydRouterData<&types::PaymentsAuthorizeRouterData>> for RapydPay ( Some(matches!( item.router_data.request.capture_method, - Some(enums::CaptureMethod::Automatic) | None + Some(enums::CaptureMethod::Automatic) + | Some(enums::CaptureMethod::SequentialAutomatic) + | None )), Some(payment_method_options), ) diff --git a/crates/hyperswitch_connectors/src/connectors/shift4.rs b/crates/hyperswitch_connectors/src/connectors/shift4.rs index 283709798d..89f81cb3dd 100644 --- a/crates/hyperswitch_connectors/src/connectors/shift4.rs +++ b/crates/hyperswitch_connectors/src/connectors/shift4.rs @@ -145,7 +145,9 @@ impl ConnectorValidation for Shift4 { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/square.rs b/crates/hyperswitch_connectors/src/connectors/square.rs index bf2cd4e1ac..d3bfd5201e 100644 --- a/crates/hyperswitch_connectors/src/connectors/square.rs +++ b/crates/hyperswitch_connectors/src/connectors/square.rs @@ -163,7 +163,9 @@ impl ConnectorValidation for Square { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/stax.rs b/crates/hyperswitch_connectors/src/connectors/stax.rs index 8ca847327a..63716a20e8 100644 --- a/crates/hyperswitch_connectors/src/connectors/stax.rs +++ b/crates/hyperswitch_connectors/src/connectors/stax.rs @@ -144,7 +144,9 @@ impl ConnectorValidation for Stax { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/tsys.rs b/crates/hyperswitch_connectors/src/connectors/tsys.rs index 25b47981de..2575006b0d 100644 --- a/crates/hyperswitch_connectors/src/connectors/tsys.rs +++ b/crates/hyperswitch_connectors/src/connectors/tsys.rs @@ -109,7 +109,9 @@ impl ConnectorValidation for Tsys { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/worldline.rs b/crates/hyperswitch_connectors/src/connectors/worldline.rs index e40d481722..0cbd4660da 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldline.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldline.rs @@ -177,7 +177,9 @@ impl ConnectorValidation for Worldline { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs b/crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs index e3ebcf490d..09d8d8aef7 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs @@ -538,12 +538,16 @@ fn get_status(item: (PaymentStatus, CaptureMethod)) -> AttemptStatus { PaymentStatus::Rejected => AttemptStatus::Failure, PaymentStatus::RejectedCapture => AttemptStatus::CaptureFailed, PaymentStatus::CaptureRequested => { - if capture_method == CaptureMethod::Automatic { + if matches!( + capture_method, + CaptureMethod::Automatic | CaptureMethod::SequentialAutomatic + ) { AttemptStatus::Pending } else { AttemptStatus::CaptureInitiated } } + PaymentStatus::PendingApproval => AttemptStatus::Authorized, PaymentStatus::Created => AttemptStatus::Started, PaymentStatus::Redirected => AttemptStatus::AuthenticationPending, diff --git a/crates/hyperswitch_connectors/src/connectors/worldpay.rs b/crates/hyperswitch_connectors/src/connectors/worldpay.rs index 266fcc7d65..d43739f197 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldpay.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldpay.rs @@ -168,7 +168,9 @@ impl ConnectorValidation for Worldpay { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs index 781d364a59..ec23b520a2 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs @@ -366,7 +366,8 @@ impl WorldpayPaymentsRequestData fn get_settlement_info(&self, amount: i64) -> Option { match (self.request.capture_method.unwrap_or_default(), amount) { (_, 0) => None, - (enums::CaptureMethod::Automatic, _) => Some(AutoSettlement { auto: true }), + (enums::CaptureMethod::Automatic, _) + | (enums::CaptureMethod::SequentialAutomatic, _) => Some(AutoSettlement { auto: true }), (enums::CaptureMethod::Manual, _) | (enums::CaptureMethod::ManualMultiple, _) => { Some(AutoSettlement { auto: false }) } diff --git a/crates/hyperswitch_connectors/src/connectors/zsl.rs b/crates/hyperswitch_connectors/src/connectors/zsl.rs index 13007b7260..1eeeeafbb2 100644 --- a/crates/hyperswitch_connectors/src/connectors/zsl.rs +++ b/crates/hyperswitch_connectors/src/connectors/zsl.rs @@ -129,7 +129,7 @@ impl ConnectorValidation for Zsl { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic => Ok(()), + enums::CaptureMethod::Automatic | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::Manual | enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err(construct_not_supported_error_report( diff --git a/crates/hyperswitch_connectors/src/utils.rs b/crates/hyperswitch_connectors/src/utils.rs index c60f8e79a5..408a028254 100644 --- a/crates/hyperswitch_connectors/src/utils.rs +++ b/crates/hyperswitch_connectors/src/utils.rs @@ -1190,7 +1190,9 @@ pub trait PaymentsAuthorizeRequestData { impl PaymentsAuthorizeRequestData for PaymentsAuthorizeData { fn is_auto_capture(&self) -> Result { match self.capture_method { - Some(enums::CaptureMethod::Automatic) | None => Ok(true), + Some(enums::CaptureMethod::Automatic) + | Some(enums::CaptureMethod::SequentialAutomatic) + | None => Ok(true), Some(enums::CaptureMethod::Manual) => Ok(false), Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()), } @@ -1409,7 +1411,9 @@ pub trait PaymentsSyncRequestData { impl PaymentsSyncRequestData for PaymentsSyncData { fn is_auto_capture(&self) -> Result { match self.capture_method { - Some(enums::CaptureMethod::Automatic) | None => Ok(true), + Some(enums::CaptureMethod::Automatic) + | Some(enums::CaptureMethod::SequentialAutomatic) + | None => Ok(true), Some(enums::CaptureMethod::Manual) => Ok(false), Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()), } @@ -1542,7 +1546,9 @@ pub trait PaymentsCompleteAuthorizeRequestData { impl PaymentsCompleteAuthorizeRequestData for CompleteAuthorizeData { fn is_auto_capture(&self) -> Result { match self.capture_method { - Some(enums::CaptureMethod::Automatic) | None => Ok(true), + Some(enums::CaptureMethod::Automatic) + | Some(enums::CaptureMethod::SequentialAutomatic) + | None => Ok(true), Some(enums::CaptureMethod::Manual) => Ok(false), Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()), } @@ -1612,7 +1618,9 @@ pub trait PaymentsPreProcessingRequestData { impl PaymentsPreProcessingRequestData for PaymentsPreProcessingData { fn is_auto_capture(&self) -> Result { match self.capture_method { - Some(enums::CaptureMethod::Automatic) | None => Ok(true), + Some(enums::CaptureMethod::Automatic) + | None + | Some(enums::CaptureMethod::SequentialAutomatic) => Ok(true), Some(enums::CaptureMethod::Manual) => Ok(false), Some(enums::CaptureMethod::ManualMultiple) | Some(enums::CaptureMethod::Scheduled) => { Err(errors::ConnectorError::CaptureMethodNotSupported.into()) diff --git a/crates/hyperswitch_domain_models/src/router_response_types.rs b/crates/hyperswitch_domain_models/src/router_response_types.rs index 4501582d00..89eb7f9b3c 100644 --- a/crates/hyperswitch_domain_models/src/router_response_types.rs +++ b/crates/hyperswitch_domain_models/src/router_response_types.rs @@ -5,7 +5,10 @@ use std::collections::HashMap; use common_utils::{request::Method, types as common_types, types::MinorUnit}; pub use disputes::{AcceptDisputeResponse, DefendDisputeResponse, SubmitEvidenceResponse}; -use crate::router_request_types::{authentication::AuthNFlowType, ResponseId}; +use crate::{ + errors::api_error_response::ApiErrorResponse, + router_request_types::{authentication::AuthNFlowType, ResponseId}, +}; #[derive(Debug, Clone)] pub struct RefundsResponseData { pub connector_refund_id: String, @@ -119,6 +122,91 @@ impl CaptureSyncResponse { } } } +impl PaymentsResponseData { + pub fn get_connector_metadata(&self) -> Option> { + match self { + Self::TransactionResponse { + connector_metadata, .. + } + | Self::PreProcessingResponse { + connector_metadata, .. + } => connector_metadata.clone().map(masking::Secret::new), + _ => None, + } + } + + pub fn get_connector_transaction_id( + &self, + ) -> Result> { + match self { + Self::TransactionResponse { + resource_id: ResponseId::ConnectorTransactionId(txn_id), + .. + } => Ok(txn_id.to_string()), + _ => Err(ApiErrorResponse::MissingRequiredField { + field_name: "ConnectorTransactionId", + } + .into()), + } + } + pub fn merge_transaction_responses( + auth_response: &Self, + capture_response: &Self, + ) -> Result> { + match (auth_response, capture_response) { + ( + Self::TransactionResponse { + resource_id: _, + redirection_data: auth_redirection_data, + mandate_reference: auth_mandate_reference, + connector_metadata: auth_connector_metadata, + network_txn_id: auth_network_txn_id, + connector_response_reference_id: auth_connector_response_reference_id, + incremental_authorization_allowed: auth_incremental_auth_allowed, + charge_id: auth_charge_id, + }, + Self::TransactionResponse { + resource_id: capture_resource_id, + redirection_data: capture_redirection_data, + mandate_reference: capture_mandate_reference, + connector_metadata: capture_connector_metadata, + network_txn_id: capture_network_txn_id, + connector_response_reference_id: capture_connector_response_reference_id, + incremental_authorization_allowed: capture_incremental_auth_allowed, + charge_id: capture_charge_id, + }, + ) => Ok(Self::TransactionResponse { + resource_id: capture_resource_id.clone(), + redirection_data: Box::new( + capture_redirection_data + .clone() + .or_else(|| *auth_redirection_data.clone()), + ), + mandate_reference: Box::new( + auth_mandate_reference + .clone() + .or_else(|| *capture_mandate_reference.clone()), + ), + connector_metadata: capture_connector_metadata + .clone() + .or(auth_connector_metadata.clone()), + network_txn_id: capture_network_txn_id + .clone() + .or(auth_network_txn_id.clone()), + connector_response_reference_id: capture_connector_response_reference_id + .clone() + .or(auth_connector_response_reference_id.clone()), + incremental_authorization_allowed: (*capture_incremental_auth_allowed) + .or(*auth_incremental_auth_allowed), + charge_id: capture_charge_id.clone().or(auth_charge_id.clone()), + }), + _ => Err(ApiErrorResponse::NotSupported { + message: "Invalid Flow ".to_owned(), + } + .into()), + } + } +} #[derive(Debug, Clone)] pub enum PreprocessingResponseId { diff --git a/crates/hyperswitch_interfaces/src/api.rs b/crates/hyperswitch_interfaces/src/api.rs index 0ea8996cb4..1326444bb4 100644 --- a/crates/hyperswitch_interfaces/src/api.rs +++ b/crates/hyperswitch_interfaces/src/api.rs @@ -348,7 +348,7 @@ pub trait ConnectorValidation: ConnectorCommon { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - CaptureMethod::Automatic => Ok(()), + CaptureMethod::Automatic | CaptureMethod::SequentialAutomatic => Ok(()), CaptureMethod::Manual | CaptureMethod::ManualMultiple | CaptureMethod::Scheduled => { Err(errors::ConnectorError::NotSupported { message: capture_method.to_string(), diff --git a/crates/router/src/connector/adyen.rs b/crates/router/src/connector/adyen.rs index 583c0a2a35..112842efc6 100644 --- a/crates/router/src/connector/adyen.rs +++ b/crates/router/src/connector/adyen.rs @@ -120,6 +120,7 @@ impl ConnectorValidation for Adyen { | PaymentMethodType::Venmo | PaymentMethodType::Paypal => match capture_method { enums::CaptureMethod::Automatic + | enums::CaptureMethod::SequentialAutomatic | enums::CaptureMethod::Manual | enums::CaptureMethod::ManualMultiple => Ok(()), enums::CaptureMethod::Scheduled => { @@ -139,7 +140,9 @@ impl ConnectorValidation for Adyen { | PaymentMethodType::Klarna | PaymentMethodType::Twint | PaymentMethodType::Walley => match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => { capture_method_not_supported!( connector, @@ -198,7 +201,9 @@ impl ConnectorValidation for Adyen { | PaymentMethodType::OpenBankingUk | PaymentMethodType::OnlineBankingCzechRepublic | PaymentMethodType::PermataBankTransfer => match capture_method { - enums::CaptureMethod::Automatic => Ok(()), + enums::CaptureMethod::Automatic | enums::CaptureMethod::SequentialAutomatic => { + Ok(()) + } enums::CaptureMethod::Manual | enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => { @@ -239,6 +244,7 @@ impl ConnectorValidation for Adyen { }, None => match capture_method { enums::CaptureMethod::Automatic + | enums::CaptureMethod::SequentialAutomatic | enums::CaptureMethod::Manual | enums::CaptureMethod::ManualMultiple => Ok(()), enums::CaptureMethod::Scheduled => { diff --git a/crates/router/src/connector/authorizedotnet.rs b/crates/router/src/connector/authorizedotnet.rs index b48643e76e..fecfa315ab 100644 --- a/crates/router/src/connector/authorizedotnet.rs +++ b/crates/router/src/connector/authorizedotnet.rs @@ -73,7 +73,9 @@ impl ConnectorValidation for Authorizedotnet { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/authorizedotnet/transformers.rs b/crates/router/src/connector/authorizedotnet/transformers.rs index 42effdb4b4..9698b4ac5d 100644 --- a/crates/router/src/connector/authorizedotnet/transformers.rs +++ b/crates/router/src/connector/authorizedotnet/transformers.rs @@ -468,7 +468,9 @@ impl TryFrom for AuthorizationType { fn try_from(capture_method: enums::CaptureMethod) -> Result { match capture_method { enums::CaptureMethod::Manual => Ok(Self::Pre), - enums::CaptureMethod::Automatic => Ok(Self::Final), + enums::CaptureMethod::SequentialAutomatic | enums::CaptureMethod::Automatic => { + Ok(Self::Final) + } enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_supported_error_report(capture_method, "authorizedotnet"), )?, @@ -1579,7 +1581,9 @@ impl TryFrom> for TransactionType { fn try_from(capture_method: Option) -> Result { match capture_method { Some(enums::CaptureMethod::Manual) => Ok(Self::Authorization), - Some(enums::CaptureMethod::Automatic) | None => Ok(Self::Payment), + Some(enums::CaptureMethod::SequentialAutomatic) + | Some(enums::CaptureMethod::Automatic) + | None => Ok(Self::Payment), Some(enums::CaptureMethod::ManualMultiple) => { Err(utils::construct_not_supported_error_report( enums::CaptureMethod::ManualMultiple, @@ -1834,7 +1838,9 @@ impl TryFrom<&AuthorizedotnetRouterData<&types::PaymentsCompleteAuthorizeRouterD .payer_id; let transaction_type = match item.router_data.request.capture_method { Some(enums::CaptureMethod::Manual) => Ok(TransactionType::ContinueAuthorization), - Some(enums::CaptureMethod::Automatic) | None => Ok(TransactionType::ContinueCapture), + Some(enums::CaptureMethod::SequentialAutomatic) + | Some(enums::CaptureMethod::Automatic) + | None => Ok(TransactionType::ContinueCapture), Some(enums::CaptureMethod::ManualMultiple) => { Err(errors::ConnectorError::NotSupported { message: enums::CaptureMethod::ManualMultiple.to_string(), diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index daec033f6f..fc6594442c 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -285,7 +285,9 @@ impl ConnectorValidation for Bankofamerica { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/bluesnap.rs b/crates/router/src/connector/bluesnap.rs index 181f1dbf3d..dc508a3491 100644 --- a/crates/router/src/connector/bluesnap.rs +++ b/crates/router/src/connector/bluesnap.rs @@ -187,7 +187,9 @@ impl ConnectorValidation for Bluesnap { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/braintree.rs b/crates/router/src/connector/braintree.rs index 40155f7117..a462010eeb 100644 --- a/crates/router/src/connector/braintree.rs +++ b/crates/router/src/connector/braintree.rs @@ -180,7 +180,9 @@ impl ConnectorValidation for Braintree { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/checkout.rs b/crates/router/src/connector/checkout.rs index 3fca0b86ae..f73d5cb14e 100644 --- a/crates/router/src/connector/checkout.rs +++ b/crates/router/src/connector/checkout.rs @@ -162,6 +162,7 @@ impl ConnectorValidation for Checkout { let capture_method = capture_method.unwrap_or_default(); match capture_method { enums::CaptureMethod::Automatic + | enums::CaptureMethod::SequentialAutomatic | enums::CaptureMethod::Manual | enums::CaptureMethod::ManualMultiple => Ok(()), enums::CaptureMethod::Scheduled => Err( diff --git a/crates/router/src/connector/checkout/transformers.rs b/crates/router/src/connector/checkout/transformers.rs index 0d4d820100..cd758fffb6 100644 --- a/crates/router/src/connector/checkout/transformers.rs +++ b/crates/router/src/connector/checkout/transformers.rs @@ -638,9 +638,11 @@ fn get_connector_meta( capture_method: enums::CaptureMethod, ) -> CustomResult { match capture_method { - enums::CaptureMethod::Automatic => Ok(serde_json::json!(CheckoutMeta { - psync_flow: CheckoutPaymentIntent::Capture, - })), + enums::CaptureMethod::Automatic | enums::CaptureMethod::SequentialAutomatic => { + Ok(serde_json::json!(CheckoutMeta { + psync_flow: CheckoutPaymentIntent::Capture, + })) + } enums::CaptureMethod::Manual | enums::CaptureMethod::ManualMultiple => { Ok(serde_json::json!(CheckoutMeta { psync_flow: CheckoutPaymentIntent::Authorize, diff --git a/crates/router/src/connector/cybersource.rs b/crates/router/src/connector/cybersource.rs index 06f448e075..f676d6ca25 100644 --- a/crates/router/src/connector/cybersource.rs +++ b/crates/router/src/connector/cybersource.rs @@ -253,7 +253,9 @@ impl ConnectorValidation for Cybersource { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/datatrans.rs b/crates/router/src/connector/datatrans.rs index e6f0ebd098..24202b2196 100644 --- a/crates/router/src/connector/datatrans.rs +++ b/crates/router/src/connector/datatrans.rs @@ -144,7 +144,9 @@ impl ConnectorValidation for Datatrans { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - CaptureMethod::Automatic | CaptureMethod::Manual => Ok(()), + CaptureMethod::Automatic + | CaptureMethod::Manual + | CaptureMethod::SequentialAutomatic => Ok(()), CaptureMethod::ManualMultiple | CaptureMethod::Scheduled => { Err(errors::ConnectorError::NotSupported { message: capture_method.to_string(), diff --git a/crates/router/src/connector/dummyconnector.rs b/crates/router/src/connector/dummyconnector.rs index 13a0557823..b87b495a93 100644 --- a/crates/router/src/connector/dummyconnector.rs +++ b/crates/router/src/connector/dummyconnector.rs @@ -131,7 +131,9 @@ impl ConnectorValidation for DummyConnector { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/globalpay.rs b/crates/router/src/connector/globalpay.rs index 2707ef4b6f..2c8bfb548e 100644 --- a/crates/router/src/connector/globalpay.rs +++ b/crates/router/src/connector/globalpay.rs @@ -136,7 +136,8 @@ impl ConnectorValidation for Globalpay { match capture_method { enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual - | enums::CaptureMethod::ManualMultiple => Ok(()), + | enums::CaptureMethod::ManualMultiple + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/klarna.rs b/crates/router/src/connector/klarna.rs index 6aa9b62ed6..d2bdaae049 100644 --- a/crates/router/src/connector/klarna.rs +++ b/crates/router/src/connector/klarna.rs @@ -117,7 +117,9 @@ impl ConnectorValidation for Klarna { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/nmi.rs b/crates/router/src/connector/nmi.rs index 76665c2700..42a04e7e7e 100644 --- a/crates/router/src/connector/nmi.rs +++ b/crates/router/src/connector/nmi.rs @@ -115,7 +115,9 @@ impl ConnectorValidation for Nmi { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/noon.rs b/crates/router/src/connector/noon.rs index b2b47e5fd3..76526ca2eb 100644 --- a/crates/router/src/connector/noon.rs +++ b/crates/router/src/connector/noon.rs @@ -183,7 +183,9 @@ impl ConnectorValidation for Noon { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/nuvei.rs b/crates/router/src/connector/nuvei.rs index 8108413b4e..7c50f87fc4 100644 --- a/crates/router/src/connector/nuvei.rs +++ b/crates/router/src/connector/nuvei.rs @@ -80,7 +80,9 @@ impl ConnectorValidation for Nuvei { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/opayo.rs b/crates/router/src/connector/opayo.rs index 3e7edba212..4a093c019a 100644 --- a/crates/router/src/connector/opayo.rs +++ b/crates/router/src/connector/opayo.rs @@ -138,7 +138,9 @@ impl ConnectorValidation for Opayo { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/paybox.rs b/crates/router/src/connector/paybox.rs index dd54e185da..99959ca87e 100644 --- a/crates/router/src/connector/paybox.rs +++ b/crates/router/src/connector/paybox.rs @@ -152,7 +152,9 @@ impl ConnectorValidation for Paybox { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/paybox/transformers.rs b/crates/router/src/connector/paybox/transformers.rs index 27096c2a63..4e237223fa 100644 --- a/crates/router/src/connector/paybox/transformers.rs +++ b/crates/router/src/connector/paybox/transformers.rs @@ -501,17 +501,22 @@ fn get_transaction_type( is_mandate_request: bool, ) -> Result { match (capture_method, is_mandate_request) { - (Some(enums::CaptureMethod::Automatic), false) | (None, false) => { + (Some(enums::CaptureMethod::Automatic), false) + | (None, false) + | (Some(enums::CaptureMethod::SequentialAutomatic), false) => { Ok(AUTH_AND_CAPTURE_REQUEST.to_string()) } (Some(enums::CaptureMethod::Automatic), true) | (None, true) => { Err(errors::ConnectorError::NotSupported { - message: "Capture Not allowed in case of Creating the Subscriber".to_string(), + message: "Automatic Capture in CIT payments".to_string(), connector: "Paybox", })? } (Some(enums::CaptureMethod::Manual), false) => Ok(AUTH_REQUEST.to_string()), - (Some(enums::CaptureMethod::Manual), true) => Ok(MANDATE_REQUEST.to_string()), + (Some(enums::CaptureMethod::Manual), true) + | (Some(enums::CaptureMethod::SequentialAutomatic), true) => { + Ok(MANDATE_REQUEST.to_string()) + } _ => Err(errors::ConnectorError::CaptureMethodNotSupported)?, } } @@ -731,12 +736,15 @@ impl ) -> Result { match item.response.clone() { PayboxResponse::NonThreeDs(response) => { - let status = get_status_of_request(response.response_code.clone()); + let status: bool = get_status_of_request(response.response_code.clone()); match status { true => Ok(Self { - status: match item.data.request.is_auto_capture()? { - true => enums::AttemptStatus::Charged, - false => enums::AttemptStatus::Authorized, + status: match ( + item.data.request.is_auto_capture()?, + item.data.request.is_cit_mandate_payment(), + ) { + (_, true) | (false, false) => enums::AttemptStatus::Authorized, + (true, false) => enums::AttemptStatus::Charged, }, response: Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId( @@ -1001,9 +1009,12 @@ impl let status = get_status_of_request(response.response_code.clone()); match status { true => Ok(Self { - status: match item.data.request.is_auto_capture()? { - true => enums::AttemptStatus::Charged, - false => enums::AttemptStatus::Authorized, + status: match ( + item.data.request.is_auto_capture()?, + item.data.request.is_cit_mandate_payment(), + ) { + (_, true) | (false, false) => enums::AttemptStatus::Authorized, + (true, false) => enums::AttemptStatus::Charged, }, response: Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId( diff --git a/crates/router/src/connector/payme.rs b/crates/router/src/connector/payme.rs index bc5524e5c8..c00ab061a3 100644 --- a/crates/router/src/connector/payme.rs +++ b/crates/router/src/connector/payme.rs @@ -145,7 +145,9 @@ impl ConnectorValidation for Payme { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/paypal.rs b/crates/router/src/connector/paypal.rs index 04a5ae6f75..375853e27a 100644 --- a/crates/router/src/connector/paypal.rs +++ b/crates/router/src/connector/paypal.rs @@ -327,7 +327,9 @@ impl ConnectorValidation for Paypal { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/placetopay.rs b/crates/router/src/connector/placetopay.rs index 5eb93e6d53..c6cc244024 100644 --- a/crates/router/src/connector/placetopay.rs +++ b/crates/router/src/connector/placetopay.rs @@ -130,7 +130,7 @@ impl ConnectorValidation for Placetopay { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic => Ok(()), + enums::CaptureMethod::Automatic | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::Manual | enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( diff --git a/crates/router/src/connector/stripe.rs b/crates/router/src/connector/stripe.rs index 1125c0af6d..cb2eba4d0e 100644 --- a/crates/router/src/connector/stripe.rs +++ b/crates/router/src/connector/stripe.rs @@ -140,7 +140,9 @@ impl ConnectorValidation for Stripe { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::SequentialAutomatic + | enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_supported_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index 6d9a4f1c45..8114569c0d 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -72,7 +72,9 @@ impl From> for StripeCaptureMethod { Some(p) => match p { enums::CaptureMethod::ManualMultiple => Self::Manual, enums::CaptureMethod::Manual => Self::Manual, - enums::CaptureMethod::Automatic => Self::Automatic, + enums::CaptureMethod::Automatic | enums::CaptureMethod::SequentialAutomatic => { + Self::Automatic + } enums::CaptureMethod::Scheduled => Self::Manual, }, None => Self::Automatic, diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index c3d6806ff0..1ea7565f69 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -682,7 +682,9 @@ impl PaymentsPreProcessingData for types::PaymentsPreProcessingData { fn is_auto_capture(&self) -> Result { match self.capture_method { - Some(enums::CaptureMethod::Automatic) | None => Ok(true), + Some(enums::CaptureMethod::Automatic) + | None + | Some(enums::CaptureMethod::SequentialAutomatic) => Ok(true), Some(enums::CaptureMethod::Manual) => Ok(false), Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()), } @@ -799,6 +801,7 @@ pub trait PaymentsAuthorizeRequestData { fn connector_mandate_id(&self) -> Option; fn get_optional_network_transaction_id(&self) -> Option; fn is_mandate_payment(&self) -> bool; + fn is_cit_mandate_payment(&self) -> bool; fn is_customer_initiated_mandate_payment(&self) -> bool; fn get_webhook_url(&self) -> Result; fn get_router_return_url(&self) -> Result; @@ -832,7 +835,9 @@ impl PaymentMethodTokenizationRequestData for types::PaymentMethodTokenizationDa impl PaymentsAuthorizeRequestData for types::PaymentsAuthorizeData { fn is_auto_capture(&self) -> Result { match self.capture_method { - Some(enums::CaptureMethod::Automatic) | None => Ok(true), + Some(enums::CaptureMethod::Automatic) + | None + | Some(enums::CaptureMethod::SequentialAutomatic) => Ok(true), Some(enums::CaptureMethod::Manual) => Ok(false), Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()), } @@ -909,6 +914,12 @@ impl PaymentsAuthorizeRequestData for types::PaymentsAuthorizeData { .and_then(|mandate_ids| mandate_ids.mandate_reference_id.as_ref()) .is_some() } + fn is_cit_mandate_payment(&self) -> bool { + (self.customer_acceptance.is_some() || self.setup_mandate_details.is_some()) + && self.setup_future_usage.map_or(false, |setup_future_usage| { + setup_future_usage == storage_enums::FutureUsage::OffSession + }) + } fn get_webhook_url(&self) -> Result { self.webhook_url .clone() @@ -1090,12 +1101,15 @@ pub trait PaymentsCompleteAuthorizeRequestData { fn get_complete_authorize_url(&self) -> Result; fn is_mandate_payment(&self) -> bool; fn get_connector_mandate_request_reference_id(&self) -> Result; + fn is_cit_mandate_payment(&self) -> bool; } impl PaymentsCompleteAuthorizeRequestData for types::CompleteAuthorizeData { fn is_auto_capture(&self) -> Result { match self.capture_method { - Some(enums::CaptureMethod::Automatic) | None => Ok(true), + Some(enums::CaptureMethod::Automatic) + | None + | Some(enums::CaptureMethod::SequentialAutomatic) => Ok(true), Some(enums::CaptureMethod::Manual) => Ok(false), Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()), } @@ -1130,6 +1144,12 @@ impl PaymentsCompleteAuthorizeRequestData for types::CompleteAuthorizeData { .and_then(|mandate_ids| mandate_ids.mandate_reference_id.as_ref()) .is_some() } + fn is_cit_mandate_payment(&self) -> bool { + (self.customer_acceptance.is_some() || self.setup_mandate_details.is_some()) + && self.setup_future_usage.map_or(false, |setup_future_usage| { + setup_future_usage == storage_enums::FutureUsage::OffSession + }) + } /// Attempts to retrieve the connector mandate reference ID as a `Result`. fn get_connector_mandate_request_reference_id(&self) -> Result { self.mandate_id @@ -1154,7 +1174,9 @@ pub trait PaymentsSyncRequestData { impl PaymentsSyncRequestData for types::PaymentsSyncData { fn is_auto_capture(&self) -> Result { match self.capture_method { - Some(enums::CaptureMethod::Automatic) | None => Ok(true), + Some(enums::CaptureMethod::Automatic) + | None + | Some(enums::CaptureMethod::SequentialAutomatic) => Ok(true), Some(enums::CaptureMethod::Manual) => Ok(false), Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()), } @@ -1178,7 +1200,9 @@ pub trait PaymentsPostSessionTokensRequestData { impl PaymentsPostSessionTokensRequestData for types::PaymentsPostSessionTokensData { fn is_auto_capture(&self) -> Result { match self.capture_method { - Some(enums::CaptureMethod::Automatic) | None => Ok(true), + Some(enums::CaptureMethod::Automatic) + | None + | Some(enums::CaptureMethod::SequentialAutomatic) => Ok(true), Some(enums::CaptureMethod::Manual) => Ok(false), Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()), } diff --git a/crates/router/src/connector/wellsfargo.rs b/crates/router/src/connector/wellsfargo.rs index a63007f0a2..df0de2c0c5 100644 --- a/crates/router/src/connector/wellsfargo.rs +++ b/crates/router/src/connector/wellsfargo.rs @@ -252,7 +252,9 @@ impl ConnectorValidation for Wellsfargo { ) -> CustomResult<(), errors::ConnectorError> { let capture_method = capture_method.unwrap_or_default(); match capture_method { - enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::Automatic + | enums::CaptureMethod::Manual + | enums::CaptureMethod::SequentialAutomatic => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( connector_utils::construct_not_implemented_error_report(capture_method, self.id()), ), diff --git a/crates/router/src/connector/wellsfargo/transformers.rs b/crates/router/src/connector/wellsfargo/transformers.rs index 42ee4acade..937af33bd7 100644 --- a/crates/router/src/connector/wellsfargo/transformers.rs +++ b/crates/router/src/connector/wellsfargo/transformers.rs @@ -717,7 +717,9 @@ impl Ok(Self { capture: Some(matches!( item.router_data.request.capture_method, - Some(enums::CaptureMethod::Automatic) | None + Some(enums::CaptureMethod::Automatic) + | Some(enums::CaptureMethod::SequentialAutomatic) + | None )), payment_solution: solution.map(String::from), action_list, diff --git a/crates/router/src/core/fraud_check/operation/fraud_check_post.rs b/crates/router/src/core/fraud_check/operation/fraud_check_post.rs index deb4a3621f..308a00ffa1 100644 --- a/crates/router/src/core/fraud_check/operation/fraud_check_post.rs +++ b/crates/router/src/core/fraud_check/operation/fraud_check_post.rs @@ -303,7 +303,7 @@ where } else if matches!(frm_data.fraud_check.frm_status, FraudCheckStatus::Legit) && matches!( frm_data.fraud_check.payment_capture_method, - Some(CaptureMethod::Automatic) + Some(CaptureMethod::Automatic) | Some(CaptureMethod::SequentialAutomatic) ) { let capture_request = api_models::payments::PaymentsCaptureRequest { diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 1dd9400b8b..c088fa3fce 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -405,7 +405,11 @@ where should_continue_capture, payment_data.get_payment_attempt().capture_method, ) { - (false, Some(storage_enums::CaptureMethod::Automatic)) + ( + false, + Some(storage_enums::CaptureMethod::Automatic) + | Some(storage_enums::CaptureMethod::SequentialAutomatic), + ) | (false, Some(storage_enums::CaptureMethod::Scheduled)) => { if let Some(info) = &mut frm_info { if let Some(frm_data) = &mut info.frm_data { diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs index 45fe296e8e..cf349ef6e0 100644 --- a/crates/router/src/core/payments/flows.rs +++ b/crates/router/src/core/payments/flows.rs @@ -12,6 +12,9 @@ pub mod session_update_flow; pub mod setup_mandate_flow; use async_trait::async_trait; +use hyperswitch_domain_models::{ + mandates::CustomerAcceptance, router_request_types::PaymentsCaptureData, +}; use hyperswitch_interfaces::api::payouts::Payouts; #[cfg(feature = "frm")] @@ -19,12 +22,13 @@ use crate::types::fraud_check as frm_types; use crate::{ connector, core::{ - errors::{ConnectorError, CustomResult, RouterResult}, + errors::{ApiErrorResponse, ConnectorError, CustomResult, RouterResult}, payments::{self, helpers}, }, + logger, routes::SessionState, - services, - types::{self, api, domain}, + services, types as router_types, + types::{self, api, api::enums as api_enums, domain}, }; #[async_trait] @@ -2602,3 +2606,113 @@ default_imp_for_post_session_tokens!( connector::Wellsfargopayout, connector::Wise ); + +/// Determines whether a capture API call should be made for a payment attempt +/// This function evaluates whether an authorized payment should proceed with a capture API call +/// based on various payment parameters. It's primarily used in two-step (auth + capture) payment flows for CaptureMethod SequentialAutomatic +/// +pub fn should_initiate_capture_flow( + connector_name: &router_types::Connector, + customer_acceptance: Option, + capture_method: Option, + setup_future_usage: Option, + status: common_enums::AttemptStatus, +) -> bool { + match status { + common_enums::AttemptStatus::Authorized => { + if let Some(api_enums::CaptureMethod::SequentialAutomatic) = capture_method { + match connector_name { + router_types::Connector::Paybox => { + // Check CIT conditions for Paybox + setup_future_usage == Some(api_enums::FutureUsage::OffSession) + && customer_acceptance.is_some() + } + _ => false, + } + } else { + false + } + } + _ => false, + } +} + +/// Executes a capture request by building a connector-specific request and deciding +/// the appropriate flow to send it to the payment connector. +pub async fn call_capture_request( + mut capture_router_data: types::RouterData< + api::Capture, + PaymentsCaptureData, + types::PaymentsResponseData, + >, + state: &SessionState, + connector: &api::ConnectorData, + call_connector_action: payments::CallConnectorAction, + business_profile: &domain::Profile, + header_payload: hyperswitch_domain_models::payments::HeaderPayload, +) -> RouterResult> +{ + // Build capture-specific connector request + let (connector_request, _should_continue_further) = capture_router_data + .build_flow_specific_connector_request(state, connector, call_connector_action.clone()) + .await?; + + // Execute capture flow + capture_router_data + .decide_flows( + state, + connector, + call_connector_action, + connector_request, + business_profile, + header_payload.clone(), + ) + .await +} + +/// Processes the response from the capture flow and determines the final status and the response. +fn handle_post_capture_response( + authorize_router_data_response: types::PaymentsResponseData, + post_capture_router_data: Result< + types::RouterData, + error_stack::Report, + >, +) -> RouterResult<(common_enums::AttemptStatus, types::PaymentsResponseData)> { + match post_capture_router_data { + Err(err) => { + logger::error!( + "Capture flow encountered an error: {:?}. Proceeding without updating.", + err + ); + Ok(( + common_enums::AttemptStatus::Authorized, + authorize_router_data_response, + )) + } + Ok(post_capture_router_data) => { + match ( + &post_capture_router_data.response, + post_capture_router_data.status, + ) { + (Ok(post_capture_resp), common_enums::AttemptStatus::Charged) => Ok(( + common_enums::AttemptStatus::Charged, + types::PaymentsResponseData::merge_transaction_responses( + &authorize_router_data_response, + post_capture_resp, + )?, + )), + _ => { + logger::error!( + "Error in post capture_router_data response: {:?}, Current Status: {:?}. Proceeding without updating.", + post_capture_router_data.response, + post_capture_router_data.status, + ); + Ok(( + common_enums::AttemptStatus::Authorized, + authorize_router_data_response, + )) + } + } + } + } +} diff --git a/crates/router/src/core/payments/flows/authorize_flow.rs b/crates/router/src/core/payments/flows/authorize_flow.rs index bc62408205..7ee407fa9e 100644 --- a/crates/router/src/core/payments/flows/authorize_flow.rs +++ b/crates/router/src/core/payments/flows/authorize_flow.rs @@ -1,7 +1,9 @@ use async_trait::async_trait; use common_enums as enums; +use hyperswitch_domain_models::errors::api_error_response::ApiErrorResponse; #[cfg(feature = "v2")] use hyperswitch_domain_models::payments::PaymentConfirmData; +use masking::ExposeInterface; use router_env::metrics::add_attributes; // use router_env::tracing::Instrument; @@ -16,9 +18,11 @@ use crate::{ }, logger, routes::{metrics, SessionState}, - services, - services::api::ConnectorValidation, - types::{self, api, domain, transformers::ForeignFrom}, + services::{self, api::ConnectorValidation}, + types::{ + self, api, domain, + transformers::{ForeignFrom, ForeignTryFrom}, + }, utils::OptionExt, }; @@ -173,8 +177,8 @@ impl Feature for types::PaymentsAu connector: &api::ConnectorData, call_connector_action: payments::CallConnectorAction, connector_request: Option, - _business_profile: &domain::Profile, - _header_payload: hyperswitch_domain_models::payments::HeaderPayload, + business_profile: &domain::Profile, + header_payload: hyperswitch_domain_models::payments::HeaderPayload, ) -> RouterResult { let connector_integration: services::BoxedPaymentConnectorIntegrationInterface< api::Authorize, @@ -185,11 +189,11 @@ impl Feature for types::PaymentsAu if self.should_proceed_with_authorize() { self.decide_authentication_type(); logger::debug!(auth_type=?self.auth_type); - let mut new_router_data = services::execute_connector_processing_step( + let mut auth_router_data = services::execute_connector_processing_step( state, connector_integration, &self, - call_connector_action, + call_connector_action.clone(), connector_request, ) .await @@ -197,14 +201,37 @@ impl Feature for types::PaymentsAu // Initiating Integrity check let integrity_result = helpers::check_integrity_based_on_flow( - &new_router_data.request, - &new_router_data.response, + &auth_router_data.request, + &auth_router_data.response, ); + auth_router_data.integrity_check = integrity_result; + metrics::PAYMENT_COUNT.add(&metrics::CONTEXT, 1, &[]); // Move outside of the if block - new_router_data.integrity_check = integrity_result; - - metrics::PAYMENT_COUNT.add(&metrics::CONTEXT, 1, &[]); // Metrics - Ok(new_router_data) + match auth_router_data.response.clone() { + Err(_) => Ok(auth_router_data), + Ok(authorize_response) => { + // Check if the Capture API should be called based on the connector and other parameters + if super::should_initiate_capture_flow( + &connector.connector_name, + self.request.customer_acceptance, + self.request.capture_method, + self.request.setup_future_usage, + auth_router_data.status, + ) { + auth_router_data = Box::pin(process_capture_flow( + auth_router_data, + authorize_response, + state, + connector, + call_connector_action.clone(), + business_profile, + header_payload, + )) + .await?; + } + Ok(auth_router_data) + } + } } else { Ok(self.clone()) } @@ -566,3 +593,83 @@ pub async fn authorize_postprocessing_steps( Ok(router_data.clone()) } } + +impl + ForeignTryFrom> + for types::PaymentsCaptureData +{ + type Error = error_stack::Report; + + fn foreign_try_from( + item: types::RouterData, + ) -> Result { + let response = item + .response + .map_err(|err| ApiErrorResponse::ExternalConnectorError { + code: err.code, + message: err.message, + connector: item.connector.clone(), + status_code: err.status_code, + reason: err.reason, + })?; + + Ok(Self { + amount_to_capture: item.request.amount, + currency: item.request.currency, + connector_transaction_id: types::PaymentsResponseData::get_connector_transaction_id( + &response, + )?, + payment_amount: item.request.amount, + multiple_capture_data: None, + connector_meta: types::PaymentsResponseData::get_connector_metadata(&response) + .map(|secret| secret.expose()), + browser_info: None, + metadata: None, + capture_method: item.request.capture_method, + minor_payment_amount: item.request.minor_amount, + minor_amount_to_capture: item.request.minor_amount, + integrity_object: None, + }) + } +} + +async fn process_capture_flow( + mut router_data: types::RouterData< + api::Authorize, + types::PaymentsAuthorizeData, + types::PaymentsResponseData, + >, + authorize_response: types::PaymentsResponseData, + state: &SessionState, + connector: &api::ConnectorData, + call_connector_action: payments::CallConnectorAction, + business_profile: &domain::Profile, + header_payload: hyperswitch_domain_models::payments::HeaderPayload, +) -> RouterResult< + types::RouterData, +> { + // Convert RouterData into Capture RouterData + let capture_router_data = helpers::router_data_type_conversion( + router_data.clone(), + types::PaymentsCaptureData::foreign_try_from(router_data.clone())?, + Err(types::ErrorResponse::default()), + ); + + // Call capture request + let post_capture_router_data = super::call_capture_request( + capture_router_data, + state, + connector, + call_connector_action, + business_profile, + header_payload, + ) + .await; + + // Process capture response + let (updated_status, updated_response) = + super::handle_post_capture_response(authorize_response, post_capture_router_data)?; + router_data.status = updated_status; + router_data.response = Ok(updated_response); + Ok(router_data) +} diff --git a/crates/router/src/core/payments/flows/complete_authorize_flow.rs b/crates/router/src/core/payments/flows/complete_authorize_flow.rs index f3cfb45f18..e347cd3c3d 100644 --- a/crates/router/src/core/payments/flows/complete_authorize_flow.rs +++ b/crates/router/src/core/payments/flows/complete_authorize_flow.rs @@ -1,15 +1,16 @@ use async_trait::async_trait; +use masking::ExposeInterface; use router_env::metrics::add_attributes; use super::{ConstructFlowSpecificData, Feature}; use crate::{ core::{ - errors::{ConnectorErrorExt, RouterResult}, + errors::{ApiErrorResponse, ConnectorErrorExt, RouterResult}, payments::{self, access_token, helpers, transformers, PaymentData}, }, routes::{metrics, SessionState}, services, - types::{self, api, domain}, + types::{self, api, domain, transformers::ForeignTryFrom}, }; #[async_trait] @@ -102,8 +103,8 @@ impl Feature connector: &api::ConnectorData, call_connector_action: payments::CallConnectorAction, connector_request: Option, - _business_profile: &domain::Profile, - _header_payload: hyperswitch_domain_models::payments::HeaderPayload, + business_profile: &domain::Profile, + header_payload: hyperswitch_domain_models::payments::HeaderPayload, ) -> RouterResult { let connector_integration: services::BoxedPaymentConnectorIntegrationInterface< api::CompleteAuthorize, @@ -111,17 +112,40 @@ impl Feature types::PaymentsResponseData, > = connector.connector.get_connector_integration(); - let resp = services::execute_connector_processing_step( + let mut complete_authorize_router_data = services::execute_connector_processing_step( state, connector_integration, &self, - call_connector_action, + call_connector_action.clone(), connector_request, ) .await .to_payment_failed_response()?; - - Ok(resp) + match complete_authorize_router_data.response.clone() { + Err(_) => Ok(complete_authorize_router_data), + Ok(complete_authorize_response) => { + // Check if the Capture API should be called based on the connector and other parameters + if super::should_initiate_capture_flow( + &connector.connector_name, + self.request.customer_acceptance, + self.request.capture_method, + self.request.setup_future_usage, + complete_authorize_router_data.status, + ) { + complete_authorize_router_data = Box::pin(process_capture_flow( + complete_authorize_router_data, + complete_authorize_response, + state, + connector, + call_connector_action.clone(), + business_profile, + header_payload, + )) + .await?; + } + Ok(complete_authorize_router_data) + } + } } async fn add_access_token<'a>( @@ -260,3 +284,88 @@ pub async fn complete_authorize_preprocessing_steps( Ok(router_data.clone()) } } + +impl + ForeignTryFrom> + for types::PaymentsCaptureData +{ + type Error = error_stack::Report; + + fn foreign_try_from( + item: types::RouterData, + ) -> Result { + let response = item + .response + .map_err(|err| ApiErrorResponse::ExternalConnectorError { + code: err.code, + message: err.message, + connector: item.connector.clone().to_string(), + status_code: err.status_code, + reason: err.reason, + })?; + + Ok(Self { + amount_to_capture: item.request.amount, + currency: item.request.currency, + connector_transaction_id: types::PaymentsResponseData::get_connector_transaction_id( + &response, + )?, + payment_amount: item.request.amount, + multiple_capture_data: None, + connector_meta: types::PaymentsResponseData::get_connector_metadata(&response) + .map(|secret| secret.expose()), + browser_info: None, + metadata: None, + capture_method: item.request.capture_method, + minor_payment_amount: item.request.minor_amount, + minor_amount_to_capture: item.request.minor_amount, + integrity_object: None, + }) + } +} + +async fn process_capture_flow( + mut router_data: types::RouterData< + api::CompleteAuthorize, + types::CompleteAuthorizeData, + types::PaymentsResponseData, + >, + complete_authorize_response: types::PaymentsResponseData, + state: &SessionState, + connector: &api::ConnectorData, + call_connector_action: payments::CallConnectorAction, + business_profile: &domain::Profile, + header_payload: hyperswitch_domain_models::payments::HeaderPayload, +) -> RouterResult< + types::RouterData< + api::CompleteAuthorize, + types::CompleteAuthorizeData, + types::PaymentsResponseData, + >, +> { + // Convert RouterData into Capture RouterData + let capture_router_data = helpers::router_data_type_conversion( + router_data.clone(), + types::PaymentsCaptureData::foreign_try_from(router_data.clone())?, + Err(types::ErrorResponse::default()), + ); + + // Call capture request + let post_capture_router_data = super::call_capture_request( + capture_router_data, + state, + connector, + call_connector_action, + business_profile, + header_payload, + ) + .await; + + // Process capture response + let (updated_status, updated_response) = + super::handle_post_capture_response(complete_authorize_response, post_capture_router_data)?; + + router_data.status = updated_status; + router_data.response = Ok(updated_response); + Ok(router_data) +} diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index e7de03804d..1be4f4eb7c 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -948,7 +948,10 @@ pub fn validate_amount_to_capture_and_capture_method( .or(payment_attempt .map(|payment_attempt| payment_attempt.capture_method.unwrap_or_default())) .unwrap_or_default(); - if capture_method == api_enums::CaptureMethod::Automatic { + if matches!( + capture_method, + api_enums::CaptureMethod::Automatic | api_enums::CaptureMethod::SequentialAutomatic + ) { let total_capturable_amount = option_net_amount.map(|net_amount| net_amount.get_total_amount()); diff --git a/crates/router/src/core/payments/routing/transformers.rs b/crates/router/src/core/payments/routing/transformers.rs index abe3fbd01b..026807f397 100644 --- a/crates/router/src/core/payments/routing/transformers.rs +++ b/crates/router/src/core/payments/routing/transformers.rs @@ -22,6 +22,9 @@ impl ForeignFrom for Option Self { match value { storage_enums::CaptureMethod::Automatic => Some(dsl_enums::CaptureMethod::Automatic), + storage_enums::CaptureMethod::SequentialAutomatic => { + Some(dsl_enums::CaptureMethod::SequentialAutomatic) + } storage_enums::CaptureMethod::Manual => Some(dsl_enums::CaptureMethod::Manual), _ => None, } diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs index 99f93f685d..cfd3662913 100644 --- a/crates/router/src/core/utils.rs +++ b/crates/router/src/core/utils.rs @@ -1504,7 +1504,10 @@ pub fn get_request_incremental_authorization_value( Some(request_incremental_authorization .map(|request_incremental_authorization| { if request_incremental_authorization { - if capture_method == Some(common_enums::CaptureMethod::Automatic) { + if matches!( + capture_method, + Some(common_enums::CaptureMethod::Automatic) | Some(common_enums::CaptureMethod::SequentialAutomatic) + ) { Err(errors::ApiErrorResponse::NotSupported { message: "incremental authorization is not supported when capture_method is automatic".to_owned() })? } Ok(RequestIncrementalAuthorization::True) diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index 95728bd04b..9e7fc4e204 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -282,7 +282,7 @@ impl Capturable for PaymentsAuthorizeData { { match payment_data.get_capture_method().unwrap_or_default() { - common_enums::CaptureMethod::Automatic => { + common_enums::CaptureMethod::Automatic|common_enums::CaptureMethod::SequentialAutomatic => { let intent_status = common_enums::IntentStatus::foreign_from(attempt_status); match intent_status { common_enums::IntentStatus::Succeeded @@ -365,7 +365,7 @@ impl Capturable for CompleteAuthorizeData { .get_capture_method() .unwrap_or_default() { - common_enums::CaptureMethod::Automatic => { + common_enums::CaptureMethod::Automatic | common_enums::CaptureMethod::SequentialAutomatic => { let intent_status = common_enums::IntentStatus::foreign_from(attempt_status); match intent_status { common_enums::IntentStatus::Succeeded| diff --git a/migrations/2024-11-15-171347_add_capture_method_sequential_automatic/down.sql b/migrations/2024-11-15-171347_add_capture_method_sequential_automatic/down.sql new file mode 100644 index 0000000000..c7c9cbeb40 --- /dev/null +++ b/migrations/2024-11-15-171347_add_capture_method_sequential_automatic/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +SELECT 1; \ No newline at end of file diff --git a/migrations/2024-11-15-171347_add_capture_method_sequential_automatic/up.sql b/migrations/2024-11-15-171347_add_capture_method_sequential_automatic/up.sql new file mode 100644 index 0000000000..7a6be5e265 --- /dev/null +++ b/migrations/2024-11-15-171347_add_capture_method_sequential_automatic/up.sql @@ -0,0 +1,11 @@ +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_enum + WHERE enumlabel = 'sequential_automatic' + AND enumtypid = (SELECT oid FROM pg_type WHERE typname = 'CaptureMethod') + ) THEN + ALTER TYPE "CaptureMethod" ADD VALUE 'sequential_automatic' AFTER 'manual'; + END IF; +END $$;