diff --git a/CRM/Core/Payment/StripeIPN.php b/CRM/Core/Payment/StripeIPN.php
index 1fd5fd62cd62c21e942a58674e0363d8c1105537..94174f9c5c65d576fccc03baf211ed6a0729f26b 100644
--- a/CRM/Core/Payment/StripeIPN.php
+++ b/CRM/Core/Payment/StripeIPN.php
@@ -655,7 +655,18 @@ class CRM_Core_Payment_StripeIPN {
       $refundParams['cancelled_payment_id'] = $cancelledPaymentID;
     }
 
-    $this->updateContributionRefund($refundParams);
+    $lock = Civi::lockManager()->acquire('data.contribute.contribution.' . $refundParams['contribution_id']);
+    if (!$lock->isAcquired()) {
+      \Civi::log()->error('Could not acquire lock to record refund for contribution: ' . $refundParams['contribution_id']);
+    }
+    $refundPayment = civicrm_api3('Payment', 'get', [
+      'trxn_id' => $refund['refund_trxn_id'],
+      'total_amount' => $refundParams['total_amount'],
+    ]);
+    if (empty($refundPayment['count'])) {
+      $this->updateContributionRefund($refundParams);
+    }
+    $lock->release();
     return 'OK - refund recorded';
   }