feat(connector): Added a new CaptureMethod SequentialAutomatic to Support CIT Mandates for Paybox (#6587)

This commit is contained in:
awasthi21
2024-12-05 18:50:15 +05:30
committed by GitHub
parent 19f8ee46e5
commit e5dde6acc0
88 changed files with 760 additions and 129 deletions

View File

@ -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<CustomerAcceptance>,
capture_method: Option<api_enums::CaptureMethod>,
setup_future_usage: Option<api_enums::FutureUsage>,
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<types::RouterData<api::Capture, PaymentsCaptureData, types::PaymentsResponseData>>
{
// 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<api::Capture, PaymentsCaptureData, types::PaymentsResponseData>,
error_stack::Report<ApiErrorResponse>,
>,
) -> 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,
))
}
}
}
}
}