mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 09:07:09 +08:00
feat: ACH transfers (#905)
This commit is contained in:
committed by
GitHub
parent
39405bb478
commit
23bca66b81
@ -6,7 +6,7 @@ pub mod operations;
|
||||
pub mod tokenization;
|
||||
pub mod transformers;
|
||||
|
||||
use std::{fmt::Debug, marker::PhantomData, time::Instant};
|
||||
use std::{fmt::Debug, marker::PhantomData, ops::Deref, time::Instant};
|
||||
|
||||
use api_models::payments::Metadata;
|
||||
use common_utils::pii::Email;
|
||||
@ -143,10 +143,12 @@ where
|
||||
.await?;
|
||||
|
||||
if let Some(connector_details) = connector {
|
||||
operation
|
||||
.to_domain()?
|
||||
.add_task_to_process_tracker(state, &payment_data.payment_attempt)
|
||||
.await?;
|
||||
if should_add_task_to_process_tracker(&payment_data)? {
|
||||
operation
|
||||
.to_domain()?
|
||||
.add_task_to_process_tracker(state, &payment_data.payment_attempt)
|
||||
.await?;
|
||||
}
|
||||
|
||||
payment_data = match connector_details {
|
||||
api::ConnectorCallType::Single(connector) => {
|
||||
@ -188,8 +190,7 @@ where
|
||||
.await?
|
||||
}
|
||||
};
|
||||
if payment_data.payment_intent.status != storage_enums::IntentStatus::RequiresCustomerAction
|
||||
{
|
||||
if should_delete_pm_from_locker(payment_data.payment_intent.status) {
|
||||
vault::Vault::delete_locker_payment_method_by_lookup_key(state, &payment_data.token)
|
||||
.await
|
||||
}
|
||||
@ -499,7 +500,7 @@ where
|
||||
.add_access_token(state, &connector, merchant_account)
|
||||
.await?;
|
||||
|
||||
let should_continue_payment = access_token::update_router_data_with_access_token_result(
|
||||
let mut should_continue_payment = access_token::update_router_data_with_access_token_result(
|
||||
&add_access_token_result,
|
||||
&mut router_data,
|
||||
&call_connector_action,
|
||||
@ -513,6 +514,15 @@ where
|
||||
router_data.payment_method_token = Some(payment_method_token);
|
||||
};
|
||||
|
||||
(router_data, should_continue_payment) = complete_preprocessing_steps_if_required(
|
||||
state,
|
||||
&connector,
|
||||
payment_data,
|
||||
router_data,
|
||||
should_continue_payment,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let router_data_res = if should_continue_payment {
|
||||
router_data
|
||||
.decide_flows(
|
||||
@ -665,6 +675,39 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
async fn complete_preprocessing_steps_if_required<F, Req, Res>(
|
||||
state: &AppState,
|
||||
connector: &api::ConnectorData,
|
||||
payment_data: &PaymentData<F>,
|
||||
router_data: types::RouterData<F, Req, Res>,
|
||||
should_continue_payment: bool,
|
||||
) -> RouterResult<(types::RouterData<F, Req, Res>, bool)>
|
||||
where
|
||||
F: Send + Clone + Sync,
|
||||
Req: Send + Sync,
|
||||
types::RouterData<F, Req, Res>: Feature<F, Req> + Send,
|
||||
dyn api::Connector: services::api::ConnectorIntegration<F, Req, types::PaymentsResponseData>,
|
||||
{
|
||||
//TODO: For ACH transfers, if preprocessing_step is not required for connectors encountered in future, add the check
|
||||
let router_data_and_should_continue_payment = match payment_data.payment_method_data.clone() {
|
||||
Some(api_models::payments::PaymentMethodData::BankTransfer(data)) => match data.deref() {
|
||||
api_models::payments::BankTransferData::AchBankTransfer(_) => {
|
||||
if payment_data.payment_attempt.preprocessing_step_id.is_none() {
|
||||
(
|
||||
router_data.preprocessing_steps(state, connector).await?,
|
||||
false,
|
||||
)
|
||||
} else {
|
||||
(router_data, should_continue_payment)
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => (router_data, should_continue_payment),
|
||||
};
|
||||
|
||||
Ok(router_data_and_should_continue_payment)
|
||||
}
|
||||
|
||||
fn is_payment_method_tokenization_enabled_for_connector(
|
||||
state: &AppState,
|
||||
connector_name: &str,
|
||||
@ -979,6 +1022,13 @@ pub fn should_call_connector<Op: Debug, F: Clone>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn should_delete_pm_from_locker(status: storage_enums::IntentStatus) -> bool {
|
||||
!matches!(
|
||||
status,
|
||||
storage_models::enums::IntentStatus::RequiresCustomerAction
|
||||
)
|
||||
}
|
||||
|
||||
pub fn is_operation_confirm<Op: Debug>(operation: &Op) -> bool {
|
||||
matches!(format!("{operation:?}").as_str(), "PaymentConfirm")
|
||||
}
|
||||
@ -1259,3 +1309,23 @@ pub fn decide_connector(
|
||||
|
||||
Ok(api::ConnectorCallType::Single(connector_data))
|
||||
}
|
||||
|
||||
pub fn should_add_task_to_process_tracker<F: Clone>(
|
||||
payment_data: &PaymentData<F>,
|
||||
) -> RouterResult<bool> {
|
||||
let pm = payment_data
|
||||
.payment_attempt
|
||||
.payment_method
|
||||
.get_required_value("payment_method")?;
|
||||
let connector = payment_data
|
||||
.payment_attempt
|
||||
.connector
|
||||
.clone()
|
||||
.get_required_value("connector")?;
|
||||
let add_task_check = if matches!(pm, storage_enums::PaymentMethod::BankTransfer) {
|
||||
!connector.eq("stripe")
|
||||
} else {
|
||||
true
|
||||
};
|
||||
Ok(add_task_check)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user