Skip to content

Commit 35d3e27

Browse files
feat(core): added multiple payment_attempt support for payment_intent (#439)
Co-authored-by: Nishant Joshi <[email protected]>
1 parent 4d1013c commit 35d3e27

File tree

29 files changed

+370
-505
lines changed

29 files changed

+370
-505
lines changed

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/drainer/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ async fn drainer(
193193
}
194194
kv::Updateable::PaymentAttemptUpdate(a) => {
195195
macro_util::handle_resp!(
196-
a.orig.update(&conn, a.update_data).await,
196+
a.orig.update_with_attempt_id(&conn, a.update_data).await,
197197
update_op,
198198
payment_attempt
199199
)

crates/router/src/connector/nuvei/transformers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ impl<F, T>
880880
.transaction_id
881881
.map_or(response.order_id, Some) // For paypal there will be no transaction_id, only order_id will be present
882882
.map(types::ResponseId::ConnectorTransactionId)
883-
.ok_or_else(|| errors::ConnectorError::MissingConnectorTransactionID)?,
883+
.ok_or(errors::ConnectorError::MissingConnectorTransactionID)?,
884884
redirection_data,
885885
mandate_reference: None,
886886
// we don't need to save session token for capture, void flow so ignoring if it is not present

crates/router/src/core/payment_methods/cards.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,9 +817,10 @@ pub async fn list_payment_methods(
817817
let payment_attempt = payment_intent
818818
.as_ref()
819819
.async_map(|pi| async {
820-
db.find_payment_attempt_by_payment_id_merchant_id(
820+
db.find_payment_attempt_by_payment_id_merchant_id_attempt_id(
821821
&pi.payment_id,
822822
&pi.merchant_id,
823+
&pi.active_attempt_id,
823824
merchant_account.storage_scheme,
824825
)
825826
.await

crates/router/src/core/payments.rs

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ pub mod transformers;
66

77
use std::{fmt::Debug, marker::PhantomData, time::Instant};
88

9-
use common_utils::ext_traits::AsyncExt;
109
use error_stack::{IntoReport, ResultExt};
1110
use futures::future::join_all;
1211
use router_env::{instrument, tracing};
@@ -127,17 +126,29 @@ where
127126

128127
payment_data = match connector_details {
129128
api::ConnectorCallType::Single(connector) => {
130-
call_connector_service(
129+
let router_data = call_connector_service(
131130
state,
132131
&merchant_account,
133-
&validate_result.payment_id,
134132
connector,
135133
&operation,
136-
payment_data,
134+
&payment_data,
137135
&customer,
138136
call_connector_action,
139137
)
140-
.await?
138+
.await?;
139+
140+
let operation = Box::new(PaymentResponse);
141+
let db = &*state.store;
142+
operation
143+
.to_post_update_tracker()?
144+
.update_tracker(
145+
db,
146+
&validate_result.payment_id,
147+
payment_data,
148+
router_data,
149+
merchant_account.storage_scheme,
150+
)
151+
.await?
141152
}
142153

143154
api::ConnectorCallType::Multiple(connectors) => {
@@ -367,13 +378,12 @@ impl PaymentRedirectFlow for PaymentRedirectSync {
367378
pub async fn call_connector_service<F, Op, Req>(
368379
state: &AppState,
369380
merchant_account: &storage::MerchantAccount,
370-
payment_id: &api::PaymentIdType,
371381
connector: api::ConnectorData,
372382
_operation: &Op,
373-
payment_data: PaymentData<F>,
383+
payment_data: &PaymentData<F>,
374384
customer: &Option<storage::Customer>,
375385
call_connector_action: CallConnectorAction,
376-
) -> RouterResult<PaymentData<F>>
386+
) -> RouterResult<types::RouterData<F, Req, types::PaymentsResponseData>>
377387
where
378388
Op: Debug + Sync,
379389
F: Send + Clone,
@@ -388,8 +398,6 @@ where
388398
// To perform router related operation for PaymentResponse
389399
PaymentResponse: Operation<F, Req>,
390400
{
391-
let db = &*state.store;
392-
393401
let stime_connector = Instant::now();
394402

395403
let mut router_data = payment_data
@@ -420,28 +428,11 @@ where
420428
Ok(router_data)
421429
};
422430

423-
let response = router_data_res
424-
.async_and_then(|response| async {
425-
let operation = helpers::response_operation::<F, Req>();
426-
let payment_data = operation
427-
.to_post_update_tracker()?
428-
.update_tracker(
429-
db,
430-
payment_id,
431-
payment_data,
432-
response,
433-
merchant_account.storage_scheme,
434-
)
435-
.await?;
436-
Ok(payment_data)
437-
})
438-
.await?;
439-
440431
let etime_connector = Instant::now();
441432
let duration_connector = etime_connector.saturating_duration_since(stime_connector);
442433
tracing::info!(duration = format!("Duration taken: {}", duration_connector.as_millis()));
443434

444-
Ok(response)
435+
router_data_res
445436
}
446437

447438
pub async fn call_multiple_connectors_service<F, Op, Req>(
@@ -668,9 +659,10 @@ pub async fn list_payments(
668659
let pi = futures::stream::iter(payment_intents)
669660
.filter_map(|pi| async {
670661
let pa = db
671-
.find_payment_attempt_by_payment_id_merchant_id(
662+
.find_payment_attempt_by_payment_id_merchant_id_attempt_id(
672663
&pi.payment_id,
673664
merchant_id,
665+
&pi.active_attempt_id,
674666
// since OLAP doesn't have KV. Force to get the data from PSQL.
675667
storage_enums::MerchantStorageScheme::PostgresOnly,
676668
)

crates/router/src/core/payments/operations/payment_cancel.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,10 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
5656
})?;
5757

5858
let mut payment_attempt = db
59-
.find_payment_attempt_by_payment_id_merchant_id(
60-
&payment_id,
59+
.find_payment_attempt_by_payment_id_merchant_id_attempt_id(
60+
payment_intent.payment_id.as_str(),
6161
merchant_id,
62+
payment_intent.active_attempt_id.as_str(),
6263
storage_scheme,
6364
)
6465
.await
@@ -175,7 +176,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCancelRequest> for
175176
{
176177
let cancellation_reason = payment_data.payment_attempt.cancellation_reason.clone();
177178
payment_data.payment_attempt = db
178-
.update_payment_attempt(
179+
.update_payment_attempt_with_attempt_id(
179180
payment_data.payment_attempt,
180181
storage::PaymentAttemptUpdate::VoidUpdate {
181182
status: enums::AttemptStatus::VoidInitiated,

crates/router/src/core/payments/operations/payment_capture.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,10 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
6363
helpers::validate_amount_to_capture(payment_intent.amount, request.amount_to_capture)?;
6464

6565
payment_attempt = db
66-
.find_payment_attempt_by_payment_id_merchant_id(
67-
&payment_id,
66+
.find_payment_attempt_by_payment_id_merchant_id_attempt_id(
67+
payment_intent.payment_id.as_str(),
6868
merchant_id,
69+
payment_intent.active_attempt_id.as_str(),
6970
storage_scheme,
7071
)
7172
.await

crates/router/src/core/payments/operations/payment_complete_authorize.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,10 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Co
9494
})?;
9595

9696
payment_attempt = db
97-
.find_payment_attempt_by_payment_id_merchant_id(
98-
&payment_id,
97+
.find_payment_attempt_by_payment_id_merchant_id_attempt_id(
98+
&payment_intent.payment_id,
9999
merchant_id,
100+
&payment_intent.active_attempt_id,
100101
storage_scheme,
101102
)
102103
.await

crates/router/src/core/payments/operations/payment_confirm.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,10 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
9696
})?;
9797

9898
payment_attempt = db
99-
.find_payment_attempt_by_payment_id_merchant_id(
100-
&payment_id,
99+
.find_payment_attempt_by_payment_id_merchant_id_attempt_id(
100+
payment_intent.payment_id.as_str(),
101101
merchant_id,
102+
payment_intent.active_attempt_id.as_str(),
102103
storage_scheme,
103104
)
104105
.await
@@ -338,7 +339,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
338339
.attach_printable("Failed to encode additional pm data")?;
339340

340341
payment_data.payment_attempt = db
341-
.update_payment_attempt(
342+
.update_payment_attempt_with_attempt_id(
342343
payment_data.payment_attempt,
343344
storage::PaymentAttemptUpdate::ConfirmUpdate {
344345
amount: payment_data.amount.into(),

crates/router/src/core/payments/operations/payment_create.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
127127
request,
128128
shipping_address.clone().map(|x| x.address_id),
129129
billing_address.clone().map(|x| x.address_id),
130+
payment_attempt.attempt_id.to_owned(),
130131
)?,
131132
storage_scheme,
132133
)
@@ -316,7 +317,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
316317
let connector = payment_data.payment_attempt.connector.clone();
317318

318319
payment_data.payment_attempt = db
319-
.update_payment_attempt(
320+
.update_payment_attempt_with_attempt_id(
320321
payment_data.payment_attempt,
321322
storage::PaymentAttemptUpdate::UpdateTrackers {
322323
payment_token,
@@ -479,6 +480,7 @@ impl PaymentCreate {
479480
request: &api::PaymentsRequest,
480481
shipping_address_id: Option<String>,
481482
billing_address_id: Option<String>,
483+
active_attempt_id: String,
482484
) -> RouterResult<storage::PaymentIntentNew> {
483485
let created_at @ modified_at @ last_synced = Some(common_utils::date_time::now());
484486
let status =
@@ -512,6 +514,7 @@ impl PaymentCreate {
512514
statement_descriptor_name: request.statement_descriptor_name.clone(),
513515
statement_descriptor_suffix: request.statement_descriptor_suffix.clone(),
514516
metadata: metadata.map(masking::Secret::new),
517+
active_attempt_id,
515518
..storage::PaymentIntentNew::default()
516519
})
517520
}

0 commit comments

Comments
 (0)