mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 04:04:43 +08:00
feat: Allow payment cancels for more statuses (#1027)
Co-authored-by: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com>
This commit is contained in:
@ -53,6 +53,18 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
|
|||||||
.await
|
.await
|
||||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
|
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||||
|
|
||||||
|
helpers::validate_payment_status_against_not_allowed_statuses(
|
||||||
|
&payment_intent.status,
|
||||||
|
&[
|
||||||
|
enums::IntentStatus::Failed,
|
||||||
|
enums::IntentStatus::Succeeded,
|
||||||
|
enums::IntentStatus::Cancelled,
|
||||||
|
enums::IntentStatus::Processing,
|
||||||
|
enums::IntentStatus::RequiresMerchantAction,
|
||||||
|
],
|
||||||
|
"cancelled",
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut payment_attempt = db
|
let mut payment_attempt = db
|
||||||
.find_payment_attempt_by_payment_id_merchant_id_attempt_id(
|
.find_payment_attempt_by_payment_id_merchant_id_attempt_id(
|
||||||
payment_intent.payment_id.as_str(),
|
payment_intent.payment_id.as_str(),
|
||||||
@ -112,44 +124,35 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
|
|||||||
.await
|
.await
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
match payment_intent.status {
|
Ok((
|
||||||
status if status != enums::IntentStatus::RequiresCapture => {
|
Box::new(self),
|
||||||
Err(errors::ApiErrorResponse::InvalidRequestData {
|
PaymentData {
|
||||||
message: "You cannot cancel the payment that has not been authorized"
|
flow: PhantomData,
|
||||||
.to_string(),
|
payment_intent,
|
||||||
}
|
payment_attempt,
|
||||||
.into())
|
currency,
|
||||||
}
|
amount,
|
||||||
_ => Ok((
|
email: None,
|
||||||
Box::new(self),
|
mandate_id: None,
|
||||||
PaymentData {
|
setup_mandate: None,
|
||||||
flow: PhantomData,
|
token: None,
|
||||||
payment_intent,
|
address: PaymentAddress {
|
||||||
payment_attempt,
|
shipping: shipping_address.as_ref().map(|a| a.foreign_into()),
|
||||||
currency,
|
billing: billing_address.as_ref().map(|a| a.foreign_into()),
|
||||||
amount,
|
|
||||||
email: None,
|
|
||||||
mandate_id: None,
|
|
||||||
setup_mandate: None,
|
|
||||||
token: None,
|
|
||||||
address: PaymentAddress {
|
|
||||||
shipping: shipping_address.as_ref().map(|a| a.foreign_into()),
|
|
||||||
billing: billing_address.as_ref().map(|a| a.foreign_into()),
|
|
||||||
},
|
|
||||||
confirm: None,
|
|
||||||
payment_method_data: None,
|
|
||||||
force_sync: None,
|
|
||||||
refunds: vec![],
|
|
||||||
connector_response,
|
|
||||||
sessions_token: vec![],
|
|
||||||
card_cvc: None,
|
|
||||||
creds_identifier,
|
|
||||||
pm_token: None,
|
|
||||||
connector_customer_id: None,
|
|
||||||
},
|
},
|
||||||
None,
|
confirm: None,
|
||||||
)),
|
payment_method_data: None,
|
||||||
}
|
force_sync: None,
|
||||||
|
refunds: vec![],
|
||||||
|
connector_response,
|
||||||
|
sessions_token: vec![],
|
||||||
|
card_cvc: None,
|
||||||
|
creds_identifier,
|
||||||
|
pm_token: None,
|
||||||
|
connector_customer_id: None,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,18 +175,37 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCancelRequest> for
|
|||||||
F: 'b + Send,
|
F: 'b + Send,
|
||||||
{
|
{
|
||||||
let cancellation_reason = payment_data.payment_attempt.cancellation_reason.clone();
|
let cancellation_reason = payment_data.payment_attempt.cancellation_reason.clone();
|
||||||
payment_data.payment_attempt = db
|
let (intent_status_update, attempt_status_update) =
|
||||||
.update_payment_attempt_with_attempt_id(
|
if payment_data.payment_intent.status != enums::IntentStatus::RequiresCapture {
|
||||||
payment_data.payment_attempt,
|
let payment_intent_update = storage::PaymentIntentUpdate::PGStatusUpdate {
|
||||||
storage::PaymentAttemptUpdate::VoidUpdate {
|
status: enums::IntentStatus::Cancelled,
|
||||||
status: enums::AttemptStatus::VoidInitiated,
|
};
|
||||||
cancellation_reason,
|
(Some(payment_intent_update), enums::AttemptStatus::Voided)
|
||||||
},
|
} else {
|
||||||
storage_scheme,
|
(None, enums::AttemptStatus::VoidInitiated)
|
||||||
)
|
};
|
||||||
.await
|
|
||||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
|
|
||||||
|
|
||||||
|
if let Some(payment_intent_update) = intent_status_update {
|
||||||
|
payment_data.payment_intent = db
|
||||||
|
.update_payment_intent(
|
||||||
|
payment_data.payment_intent,
|
||||||
|
payment_intent_update,
|
||||||
|
storage_scheme,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.update_payment_attempt_with_attempt_id(
|
||||||
|
payment_data.payment_attempt.clone(),
|
||||||
|
storage::PaymentAttemptUpdate::VoidUpdate {
|
||||||
|
status: attempt_status_update,
|
||||||
|
cancellation_reason,
|
||||||
|
},
|
||||||
|
storage_scheme,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||||
Ok((Box::new(self), payment_data))
|
Ok((Box::new(self), payment_data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -623,7 +623,6 @@ pub async fn payments_cancel(
|
|||||||
let mut payload = json_payload.into_inner();
|
let mut payload = json_payload.into_inner();
|
||||||
let payment_id = path.into_inner();
|
let payment_id = path.into_inner();
|
||||||
payload.payment_id = payment_id;
|
payload.payment_id = payment_id;
|
||||||
|
|
||||||
api::server_wrap(
|
api::server_wrap(
|
||||||
flow,
|
flow,
|
||||||
state.get_ref(),
|
state.get_ref(),
|
||||||
|
|||||||
Reference in New Issue
Block a user