Skip to content

Commit

Permalink
fix: status goes from pending to partially captured in psync (#2915)
Browse files Browse the repository at this point in the history
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
hrithikesh026 and github-actions[bot] authored Nov 21, 2023
1 parent 8f610f4 commit 3f3b797
Show file tree
Hide file tree
Showing 15 changed files with 112 additions and 37 deletions.
7 changes: 5 additions & 2 deletions crates/data_models/src/payments/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,12 +321,15 @@ pub enum PaymentAttemptUpdate {
error_message: Option<Option<String>>,
error_reason: Option<Option<String>>,
amount_capturable: Option<i64>,
surcharge_amount: Option<i64>,
tax_amount: Option<i64>,
updated_by: String,
unified_code: Option<Option<String>>,
unified_message: Option<Option<String>>,
},
MultipleCaptureCountUpdate {
multiple_capture_count: i16,
CaptureUpdate {
amount_to_capture: Option<i64>,
multiple_capture_count: Option<i16>,
updated_by: String,
},
AmountToCaptureUpdate {
Expand Down
17 changes: 13 additions & 4 deletions crates/diesel_models/src/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,15 @@ pub enum PaymentAttemptUpdate {
error_message: Option<Option<String>>,
error_reason: Option<Option<String>>,
amount_capturable: Option<i64>,
surcharge_amount: Option<i64>,
tax_amount: Option<i64>,
updated_by: String,
unified_code: Option<Option<String>>,
unified_message: Option<Option<String>>,
},
MultipleCaptureCountUpdate {
multiple_capture_count: i16,
CaptureUpdate {
amount_to_capture: Option<i64>,
multiple_capture_count: Option<i16>,
updated_by: String,
},
AmountToCaptureUpdate {
Expand Down Expand Up @@ -535,6 +538,8 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
error_message,
error_reason,
amount_capturable,
surcharge_amount,
tax_amount,
updated_by,
unified_code,
unified_message,
Expand All @@ -547,6 +552,8 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
error_reason,
amount_capturable,
updated_by,
surcharge_amount,
tax_amount,
unified_code,
unified_message,
..Default::default()
Expand Down Expand Up @@ -618,12 +625,14 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
updated_by,
..Default::default()
},
PaymentAttemptUpdate::MultipleCaptureCountUpdate {
PaymentAttemptUpdate::CaptureUpdate {
multiple_capture_count,
updated_by,
amount_to_capture,
} => Self {
multiple_capture_count: Some(multiple_capture_count),
multiple_capture_count,
updated_by,
amount_to_capture,
..Default::default()
},
PaymentAttemptUpdate::AmountToCaptureUpdate {
Expand Down
20 changes: 16 additions & 4 deletions crates/router/src/connector/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ use crate::{
payments::PaymentData,
},
pii::PeekInterface,
types::{self, api, transformers::ForeignTryFrom, PaymentsCancelData, ResponseId},
types::{
self, api, storage::payment_attempt::PaymentAttemptExt, transformers::ForeignTryFrom,
PaymentsCancelData, ResponseId,
},
utils::{OptionExt, ValueExt},
};

Expand Down Expand Up @@ -108,11 +111,20 @@ where
}
}
enums::AttemptStatus::Charged => {
let captured_amount = types::Capturable::get_capture_amount(&self.request);
if Some(payment_data.payment_intent.amount) == captured_amount {
enums::AttemptStatus::Charged
let captured_amount = if self.request.is_psync() {
payment_data
.payment_attempt
.amount_to_capture
.or(Some(payment_data.payment_attempt.get_total_amount()))
} else {
types::Capturable::get_capture_amount(&self.request)
};
if Some(payment_data.payment_attempt.get_total_amount()) == captured_amount {
enums::AttemptStatus::Charged
} else if captured_amount.is_some() {
enums::AttemptStatus::PartialCharged
} else {
self.status
}
}
_ => self.status,
Expand Down
23 changes: 23 additions & 0 deletions crates/router/src/core/payments/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,29 @@ pub fn validate_request_amount_and_amount_to_capture(
}
}

/// if confirm = true and capture method = automatic, amount_to_capture(if provided) must be equal to amount
#[instrument(skip_all)]
pub fn validate_amount_to_capture_in_create_call_request(
request: &api_models::payments::PaymentsRequest,
) -> CustomResult<(), errors::ApiErrorResponse> {
if request.capture_method.unwrap_or_default() == api_enums::CaptureMethod::Automatic
&& request.confirm.unwrap_or(false)
{
if let Some((amount_to_capture, amount)) = request.amount_to_capture.zip(request.amount) {
let amount_int: i64 = amount.into();
utils::when(amount_to_capture != amount_int, || {
Err(report!(errors::ApiErrorResponse::PreconditionFailed {
message: "amount_to_capture must be equal to amount when confirm = true and capture_method = automatic".into()
}))
})
} else {
Ok(())
}
} else {
Ok(())
}
}

#[instrument(skip_all)]
pub fn validate_card_data(
payment_method_data: Option<api::PaymentMethodData>,
Expand Down
23 changes: 16 additions & 7 deletions crates/router/src/core/payments/operations/payment_capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,20 +251,29 @@ impl<F: Clone, Ctx: PaymentMethodRetrieve>
where
F: 'b + Send,
{
payment_data.payment_attempt = match &payment_data.multiple_capture_data {
Some(multiple_capture_data) => db
.store
payment_data.payment_attempt = if payment_data.multiple_capture_data.is_some()
|| payment_data.payment_attempt.amount_to_capture.is_some()
{
let multiple_capture_count = payment_data
.multiple_capture_data
.as_ref()
.map(|multiple_capture_data| multiple_capture_data.get_captures_count())
.transpose()?;
let amount_to_capture = payment_data.payment_attempt.amount_to_capture;
db.store
.update_payment_attempt_with_attempt_id(
payment_data.payment_attempt,
storage::PaymentAttemptUpdate::MultipleCaptureCountUpdate {
multiple_capture_count: multiple_capture_data.get_captures_count()?,
storage::PaymentAttemptUpdate::CaptureUpdate {
amount_to_capture,
multiple_capture_count,
updated_by: storage_scheme.to_string(),
},
storage_scheme,
)
.await
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?,
None => payment_data.payment_attempt,
.to_not_found_response(errors::ApiErrorResponse::InternalServerError)?
} else {
payment_data.payment_attempt
};
Ok((Box::new(self), payment_data))
}
Expand Down
14 changes: 4 additions & 10 deletions crates/router/src/core/payments/operations/payment_create.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::marker::PhantomData;

use api_models::{enums::FrmSuggestion, payment_methods};
use api_models::enums::FrmSuggestion;
use async_trait::async_trait;
use common_utils::ext_traits::{AsyncExt, Encode, ValueExt};
use data_models::{mandates::MandateData, payments::payment_attempt::PaymentAttempt};
Expand Down Expand Up @@ -279,15 +279,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
let setup_mandate = setup_mandate.map(MandateData::from);

let surcharge_details = request.surcharge_details.map(|surcharge_details| {
payment_methods::SurchargeDetailsResponse {
surcharge: payment_methods::Surcharge::Fixed(surcharge_details.surcharge_amount),
tax_on_surcharge: None,
surcharge_amount: surcharge_details.surcharge_amount,
tax_on_surcharge_amount: surcharge_details.tax_amount.unwrap_or(0),
final_amount: payment_attempt.amount
+ surcharge_details.surcharge_amount
+ surcharge_details.tax_amount.unwrap_or(0),
}
surcharge_details.get_surcharge_details_object(payment_attempt.amount)
});

let payment_data = PaymentData {
Expand Down Expand Up @@ -546,6 +538,8 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::Paymen
expected_format: "amount_to_capture lesser than amount".to_string(),
})?;

helpers::validate_amount_to_capture_in_create_call_request(request)?;

helpers::validate_card_data(request.payment_method_data.clone())?;

helpers::validate_payment_method_fields_present(request)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,8 @@ async fn payment_response_update_tracker<F: Clone, T: types::Capturable>(
} else {
None
},
surcharge_amount: router_data.request.get_surcharge_amount(),
tax_amount: router_data.request.get_tax_on_surcharge_amount(),
updated_by: storage_scheme.to_string(),
unified_code: option_gsm.clone().map(|gsm| gsm.unified_code),
unified_message: option_gsm.map(|gsm| gsm.unified_message),
Expand Down
2 changes: 2 additions & 0 deletions crates/router/src/core/payments/retry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ where
status: storage_enums::AttemptStatus::Failure,
error_reason: Some(error_response.reason.clone()),
amount_capturable: Some(0),
surcharge_amount: None,
tax_amount: None,
updated_by: storage_scheme.to_string(),
unified_code: option_gsm.clone().map(|gsm| gsm.unified_code),
unified_message: option_gsm.map(|gsm| gsm.unified_message),
Expand Down
11 changes: 9 additions & 2 deletions crates/router/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,14 +545,17 @@ pub struct AccessTokenRequestData {

pub trait Capturable {
fn get_capture_amount(&self) -> Option<i64> {
Some(0)
None
}
fn get_surcharge_amount(&self) -> Option<i64> {
None
}
fn get_tax_on_surcharge_amount(&self) -> Option<i64> {
None
}
fn is_psync(&self) -> bool {
false
}
}

impl Capturable for PaymentsAuthorizeData {
Expand Down Expand Up @@ -591,7 +594,11 @@ impl Capturable for PaymentsCancelData {}
impl Capturable for PaymentsApproveData {}
impl Capturable for PaymentsRejectData {}
impl Capturable for PaymentsSessionData {}
impl Capturable for PaymentsSyncData {}
impl Capturable for PaymentsSyncData {
fn is_psync(&self) -> bool {
true
}
}

pub struct AddAccessTokenResult {
pub access_token_result: Result<Option<AccessToken>, ErrorResponse>,
Expand Down
2 changes: 2 additions & 0 deletions crates/router/src/workflows/payment_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ impl ProcessTrackerWorkflow<AppState> for PaymentsSyncWorkflow {
consts::REQUEST_TIMEOUT_ERROR_MESSAGE_FROM_PSYNC.to_string(),
)),
amount_capturable: Some(0),
surcharge_amount: None,
tax_amount: None,
updated_by: merchant_account.storage_scheme.to_string(),
unified_code: None,
unified_message: None,
Expand Down
20 changes: 16 additions & 4 deletions crates/storage_impl/src/payments/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,8 @@ impl DataModelExt for PaymentAttemptUpdate {
error_message,
error_reason,
amount_capturable,
tax_amount,
surcharge_amount,
updated_by,
unified_code,
unified_message,
Expand All @@ -1330,16 +1332,20 @@ impl DataModelExt for PaymentAttemptUpdate {
error_message,
error_reason,
amount_capturable,
surcharge_amount,
tax_amount,
updated_by,
unified_code,
unified_message,
},
Self::MultipleCaptureCountUpdate {
Self::CaptureUpdate {
multiple_capture_count,
updated_by,
} => DieselPaymentAttemptUpdate::MultipleCaptureCountUpdate {
amount_to_capture,
} => DieselPaymentAttemptUpdate::CaptureUpdate {
multiple_capture_count,
updated_by,
amount_to_capture,
},
Self::PreprocessingUpdate {
status,
Expand Down Expand Up @@ -1577,6 +1583,8 @@ impl DataModelExt for PaymentAttemptUpdate {
error_message,
error_reason,
amount_capturable,
surcharge_amount,
tax_amount,
updated_by,
unified_code,
unified_message,
Expand All @@ -1588,13 +1596,17 @@ impl DataModelExt for PaymentAttemptUpdate {
error_reason,
amount_capturable,
updated_by,
surcharge_amount,
tax_amount,
unified_code,
unified_message,
},
DieselPaymentAttemptUpdate::MultipleCaptureCountUpdate {
DieselPaymentAttemptUpdate::CaptureUpdate {
amount_to_capture,
multiple_capture_count,
updated_by,
} => Self::MultipleCaptureCountUpdate {
} => Self::CaptureUpdate {
amount_to_capture,
multiple_capture_count,
updated_by,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"business_label": "default",
"capture_method": "automatic",
"capture_on": "2022-09-10T10:11:12Z",
"amount_to_capture": 1,
"amount_to_capture": 6540,
"customer_id": "bernard123",
"email": "[email protected]",
"name": "John Doe",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"confirm": true,
"capture_method": "automatic",
"capture_on": "2022-09-10T10:11:12Z",
"amount_to_capture": 6540,
"amount_to_capture": 6570,
"customer_id": "StripeCustomer",
"email": "[email protected]",
"name": "John Doe",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"business_label": "default",
"capture_method": "automatic",
"capture_on": "2022-09-10T10:11:12Z",
"amount_to_capture": 1,
"amount_to_capture": 6540,
"customer_id": "bernard123",
"email": "[email protected]",
"name": "John Doe",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"business_label": "default",
"capture_method": "automatic",
"capture_on": "2022-09-10T10:11:12Z",
"amount_to_capture": 1,
"amount_to_capture": 6540,
"customer_id": "bernard123",
"email": "[email protected]",
"name": "John Doe",
Expand Down

0 comments on commit 3f3b797

Please sign in to comment.