Skip to content

Commit 433cdfa

Browse files
fix(refunds): fetch refund if insert fails due to duplicate response (#2682)
1 parent e6272c6 commit 433cdfa

File tree

1 file changed

+36
-20
lines changed

1 file changed

+36
-20
lines changed

crates/router/src/core/refunds.rs

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -519,14 +519,13 @@ pub async fn validate_and_create_refund(
519519
creds_identifier: Option<String>,
520520
) -> RouterResult<refunds::RefundResponse> {
521521
let db = &*state.store;
522-
let (refund_id, all_refunds, currency, refund_create_req, refund);
523522

524523
// Only for initial dev and testing
525524
let refund_type = req.refund_type.unwrap_or_default();
526525

527526
// If Refund Id not passed in request Generate one.
528527

529-
refund_id = core_utils::get_or_generate_id("refund_id", &req.refund_id, "ref")?;
528+
let refund_id = core_utils::get_or_generate_id("refund_id", &req.refund_id, "ref")?;
530529

531530
let predicate = req
532531
.merchant_id
@@ -546,7 +545,7 @@ pub async fn validate_and_create_refund(
546545
.attach_printable("Transaction in invalid. Missing field \"connector_transaction_id\" in payment_attempt.")
547546
})?;
548547

549-
all_refunds = db
548+
let all_refunds = db
550549
.find_refund_by_merchant_id_connector_transaction_id(
551550
&merchant_account.merchant_id,
552551
&connecter_transaction_id,
@@ -555,7 +554,7 @@ pub async fn validate_and_create_refund(
555554
.await
556555
.to_not_found_response(errors::ApiErrorResponse::RefundNotFound)?;
557556

558-
currency = payment_attempt.currency.get_required_value("currency")?;
557+
let currency = payment_attempt.currency.get_required_value("currency")?;
559558

560559
//[#249]: Add Connector Based Validation here.
561560
validator::validate_payment_order_age(&payment_intent.created_at, state.conf.refund.max_age)
@@ -583,10 +582,10 @@ pub async fn validate_and_create_refund(
583582
.into_report()
584583
.attach_printable("No connector populated in payment attempt")?;
585584

586-
refund_create_req = storage::RefundNew::default()
585+
let refund_create_req = storage::RefundNew::default()
587586
.set_refund_id(refund_id.to_string())
588587
.set_internal_reference_id(utils::generate_id(consts::ID_LENGTH, "refid"))
589-
.set_external_reference_id(Some(refund_id))
588+
.set_external_reference_id(Some(refund_id.clone()))
590589
.set_payment_id(req.payment_id)
591590
.set_merchant_id(merchant_account.merchant_id.clone())
592591
.set_connector_transaction_id(connecter_transaction_id.to_string())
@@ -605,22 +604,39 @@ pub async fn validate_and_create_refund(
605604
.set_profile_id(payment_intent.profile_id.clone())
606605
.to_owned();
607606

608-
refund = db
607+
let refund = match db
609608
.insert_refund(refund_create_req, merchant_account.storage_scheme)
610609
.await
611-
.to_duplicate_response(errors::ApiErrorResponse::DuplicateRefundRequest)?;
612-
613-
schedule_refund_execution(
614-
state,
615-
refund.clone(),
616-
refund_type,
617-
merchant_account,
618-
key_store,
619-
payment_attempt,
620-
payment_intent,
621-
creds_identifier,
622-
)
623-
.await?;
610+
{
611+
Ok(refund) => {
612+
schedule_refund_execution(
613+
state,
614+
refund.clone(),
615+
refund_type,
616+
merchant_account,
617+
key_store,
618+
payment_attempt,
619+
payment_intent,
620+
creds_identifier,
621+
)
622+
.await?
623+
}
624+
Err(err) => {
625+
if err.current_context().is_db_unique_violation() {
626+
db.find_refund_by_merchant_id_refund_id(
627+
merchant_account.merchant_id.as_str(),
628+
refund_id.as_str(),
629+
merchant_account.storage_scheme,
630+
)
631+
.await
632+
.to_not_found_response(errors::ApiErrorResponse::RefundNotFound)?
633+
} else {
634+
return Err(err)
635+
.change_context(errors::ApiErrorResponse::RefundNotFound)
636+
.attach_printable("Inserting Refund failed");
637+
}
638+
}
639+
};
624640

625641
Ok(refund.foreign_into())
626642
}

0 commit comments

Comments
 (0)