feat(confirm): reduce the database calls to 2 stages in case of non-retry (#2113)

This commit is contained in:
Nishant Joshi
2023-09-11 12:10:48 +05:30
committed by GitHub
parent 76e9159344
commit 28b102de24
2 changed files with 108 additions and 40 deletions

View File

@ -2772,7 +2772,7 @@ impl AttemptType {
}
}
pub async fn get_connector_response(
pub async fn get_or_insert_connector_response(
&self,
payment_attempt: &PaymentAttempt,
db: &dyn StorageInterface,
@ -2799,6 +2799,30 @@ impl AttemptType {
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound),
}
}
pub async fn get_connector_response(
&self,
db: &dyn StorageInterface,
payment_id: &str,
merchant_id: &str,
attempt_id: &str,
storage_scheme: storage_enums::MerchantStorageScheme,
) -> RouterResult<storage::ConnectorResponse> {
match self {
Self::New => Err(errors::ApiErrorResponse::InternalServerError)
.into_report()
.attach_printable("Precondition failed, the attempt type should not be `New`"),
Self::SameOld => db
.find_connector_response_by_payment_id_merchant_id_attempt_id(
payment_id,
merchant_id,
attempt_id,
storage_scheme,
)
.await
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound),
}
}
}
#[inline(always)]

View File

@ -33,7 +33,6 @@ use crate::{
pub struct PaymentConfirm;
#[async_trait]
impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for PaymentConfirm {
#[instrument(skip_all)]
async fn get_trackers<'a>(
&'a self,
state: &'a AppState,
@ -130,11 +129,89 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
key_store,
);
let (mut payment_attempt, shipping_address, billing_address) = futures::try_join!(
payment_attempt_fut,
shipping_address_fut,
billing_address_fut
)?;
let config_update_fut = request
.merchant_connector_details
.to_owned()
.async_map(|mcd| async {
helpers::insert_merchant_connector_creds_to_config(
db,
merchant_account.merchant_id.as_str(),
mcd,
)
.await
})
.map(|x| x.transpose());
let (mut payment_attempt, shipping_address, billing_address, connector_response) =
match payment_intent.status {
api_models::enums::IntentStatus::RequiresCustomerAction
| api_models::enums::IntentStatus::RequiresMerchantAction
| api_models::enums::IntentStatus::RequiresPaymentMethod
| api_models::enums::IntentStatus::RequiresConfirmation => {
let attempt_type = helpers::AttemptType::SameOld;
let connector_response_fut = attempt_type.get_connector_response(
db,
&payment_intent.payment_id,
&payment_intent.merchant_id,
&payment_intent.active_attempt_id,
storage_scheme,
);
let (payment_attempt, shipping_address, billing_address, connector_response, _) =
futures::try_join!(
payment_attempt_fut,
shipping_address_fut,
billing_address_fut,
connector_response_fut,
config_update_fut
)?;
(
payment_attempt,
shipping_address,
billing_address,
connector_response,
)
}
_ => {
let (mut payment_attempt, shipping_address, billing_address, _) = futures::try_join!(
payment_attempt_fut,
shipping_address_fut,
billing_address_fut,
config_update_fut
)?;
let attempt_type = helpers::get_attempt_type(
&payment_intent,
&payment_attempt,
request,
"confirm",
)?;
(payment_intent, payment_attempt) = attempt_type
.modify_payment_intent_and_payment_attempt(
// 3
request,
payment_intent,
payment_attempt,
db,
storage_scheme,
)
.await?;
let connector_response = attempt_type
.get_or_insert_connector_response(&payment_attempt, db, storage_scheme)
.await?;
(
payment_attempt,
shipping_address,
billing_address,
connector_response,
)
}
};
payment_intent.order_details = request
.get_order_details_as_value()
@ -142,20 +219,6 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
.attach_printable("Failed to convert order details to value")?
.or(payment_intent.order_details);
let attempt_type =
helpers::get_attempt_type(&payment_intent, &payment_attempt, request, "confirm")?;
(payment_intent, payment_attempt) = attempt_type
.modify_payment_intent_and_payment_attempt(
// 3
request,
payment_intent,
payment_attempt,
db,
storage_scheme,
)
.await?;
payment_intent.setup_future_usage = request
.setup_future_usage
.or(payment_intent.setup_future_usage);
@ -220,25 +283,6 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
.as_ref()
.map(|mcd| mcd.creds_identifier.to_owned());
let config_update_fut = request
.merchant_connector_details
.to_owned()
.async_map(|mcd| async {
helpers::insert_merchant_connector_creds_to_config(
db,
merchant_account.merchant_id.as_str(),
mcd,
)
.await
})
.map(|x| x.transpose());
let connector_response_fut =
attempt_type.get_connector_response(&payment_attempt, db, storage_scheme);
let (connector_response, _) =
futures::try_join!(connector_response_fut, config_update_fut)?;
payment_intent.shipping_address_id = shipping_address.clone().map(|i| i.address_id);
payment_intent.billing_address_id = billing_address.clone().map(|i| i.address_id);
payment_intent.return_url = request