mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 17:19:15 +08:00
feat: Session flow for Apple Pay trustpay (#1155)
This commit is contained in:
committed by
GitHub
parent
d21fcc7bfc
commit
a6e91a828b
@ -8,10 +8,10 @@ pub mod transformers;
|
||||
|
||||
use std::{fmt::Debug, marker::PhantomData, ops::Deref, time::Instant};
|
||||
|
||||
use actix_web::ResponseError;
|
||||
use api_models::payments::Metadata;
|
||||
use common_utils::pii::Email;
|
||||
use error_stack::{IntoReport, ResultExt};
|
||||
use futures::future::join_all;
|
||||
use masking::Secret;
|
||||
use router_env::{instrument, tracing};
|
||||
use storage_models::ephemeral_key;
|
||||
@ -29,11 +29,10 @@ use self::{
|
||||
use crate::{
|
||||
configs::settings::PaymentMethodTypeTokenFilter,
|
||||
core::{
|
||||
errors::{self, CustomResult, RouterResponse, RouterResult},
|
||||
errors::{self, CustomResult, RouterResponse, RouterResult, StorageErrorExt},
|
||||
payment_methods::vault,
|
||||
},
|
||||
db::StorageInterface,
|
||||
logger,
|
||||
routes::{metrics, AppState},
|
||||
scheduler::utils as pt_utils,
|
||||
services::{self, api::Authenticate},
|
||||
@ -177,7 +176,7 @@ where
|
||||
}
|
||||
|
||||
api::ConnectorCallType::Multiple(connectors) => {
|
||||
call_multiple_connectors_service(
|
||||
get_session_tokens_and_persist_if_required(
|
||||
state,
|
||||
&merchant_account,
|
||||
connectors,
|
||||
@ -564,7 +563,7 @@ where
|
||||
router_data_res
|
||||
}
|
||||
|
||||
pub async fn call_multiple_connectors_service<F, Op, Req>(
|
||||
pub async fn get_session_tokens_and_persist_if_required<F, Op, Req>(
|
||||
state: &AppState,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
connectors: Vec<api::SessionConnectorData>,
|
||||
@ -596,36 +595,52 @@ where
|
||||
.construct_router_data(state, connector_id, merchant_account, customer)
|
||||
.await?;
|
||||
|
||||
let res = router_data.decide_flows(
|
||||
state,
|
||||
&session_connector_data.connector,
|
||||
customer,
|
||||
CallConnectorAction::Trigger,
|
||||
merchant_account,
|
||||
);
|
||||
let res = router_data
|
||||
.decide_flows(
|
||||
state,
|
||||
&session_connector_data.connector,
|
||||
customer,
|
||||
CallConnectorAction::Trigger,
|
||||
merchant_account,
|
||||
)
|
||||
.await;
|
||||
|
||||
join_handlers.push(res);
|
||||
let router_res = match res {
|
||||
Ok(router_result) => Ok(router_result),
|
||||
Err(error) => {
|
||||
let err = error.current_context();
|
||||
Err(errors::ApiErrorResponse::ExternalConnectorError {
|
||||
code: err.error_code(),
|
||||
message: err.error_message(),
|
||||
connector: connector_id.to_string(),
|
||||
status_code: err.status_code().into(),
|
||||
reason: None,
|
||||
})
|
||||
}
|
||||
}?;
|
||||
|
||||
join_handlers.push(router_res.response.clone());
|
||||
|
||||
if connector_id == "trustpay" && payment_data.delayed_session_token.unwrap_or(false) {
|
||||
//Fix: Add post update tracker for payment_session operation
|
||||
let response_id = router_res.response.ok().and_then(|res| match res {
|
||||
types::PaymentsResponseData::SessionResponse { response_id, .. } => response_id,
|
||||
_ => None,
|
||||
});
|
||||
|
||||
update_connector_txn_id_in_payment_attempt(
|
||||
state,
|
||||
merchant_account,
|
||||
&payment_data,
|
||||
response_id,
|
||||
)
|
||||
.await?;
|
||||
};
|
||||
}
|
||||
|
||||
let result = join_all(join_handlers).await;
|
||||
|
||||
for (connector_res, session_connector) in result.into_iter().zip(connectors) {
|
||||
let connector_name = session_connector.connector.connector_name.to_string();
|
||||
match connector_res {
|
||||
Ok(connector_response) => {
|
||||
if let Ok(types::PaymentsResponseData::SessionResponse { session_token }) =
|
||||
connector_response.response
|
||||
{
|
||||
payment_data.sessions_token.push(session_token);
|
||||
}
|
||||
}
|
||||
Err(connector_error) => {
|
||||
logger::error!(
|
||||
"sessions_connector_error {} {:?}",
|
||||
connector_name,
|
||||
connector_error
|
||||
);
|
||||
}
|
||||
for connector_res in join_handlers.into_iter().flatten() {
|
||||
if let types::PaymentsResponseData::SessionResponse { session_token, .. } = connector_res {
|
||||
payment_data.sessions_token.push(session_token);
|
||||
}
|
||||
}
|
||||
|
||||
@ -637,6 +652,31 @@ where
|
||||
Ok(payment_data)
|
||||
}
|
||||
|
||||
pub async fn update_connector_txn_id_in_payment_attempt<F>(
|
||||
state: &AppState,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
payment_data: &PaymentData<F>,
|
||||
response_id: Option<String>,
|
||||
) -> RouterResult<()>
|
||||
where
|
||||
F: Clone,
|
||||
{
|
||||
let payment_attempt_update = storage::PaymentAttemptUpdate::SessionUpdate {
|
||||
connector_transaction_id: response_id,
|
||||
};
|
||||
|
||||
let db = &*state.store;
|
||||
db.update_payment_attempt_with_attempt_id(
|
||||
payment_data.payment_attempt.to_owned(),
|
||||
payment_attempt_update,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn call_create_connector_customer_if_required<F, Req>(
|
||||
state: &AppState,
|
||||
customer: &Option<domain::Customer>,
|
||||
@ -975,6 +1015,7 @@ where
|
||||
pub connector_customer_id: Option<String>,
|
||||
pub ephemeral_key: Option<ephemeral_key::EphemeralKey>,
|
||||
pub redirect_response: Option<api_models::payments::RedirectResponse>,
|
||||
pub delayed_session_token: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@ -1085,7 +1126,7 @@ pub async fn list_payments(
|
||||
) -> RouterResponse<api::PaymentListResponse> {
|
||||
use futures::stream::StreamExt;
|
||||
|
||||
use crate::{core::errors::utils::StorageErrorExt, types::transformers::ForeignFrom};
|
||||
use crate::types::transformers::ForeignFrom;
|
||||
|
||||
helpers::validate_payment_list_request(&constraints)?;
|
||||
let merchant_id = &merchant.merchant_id;
|
||||
|
||||
Reference in New Issue
Block a user