Commit dade401d authored by mattwire's avatar mattwire
Browse files

Add a lock around recording refund payment

parent ac9da104
......@@ -9,6 +9,8 @@
+--------------------------------------------------------------------+
*/
use Civi\Payment\Exception\PaymentProcessorException;
/**
* Shared payment IPN functions that should one day be migrated to CiviCRM core
*
......@@ -372,7 +374,7 @@ trait CRM_Core_Payment_MJWIPNTrait {
// We catch, log, throw again so we have debug details in the logs
$message = 'MJWIPNTrait call to repeattransaction failed: ' . $e->getMessage() . '; params: ' . print_r($contributionParams, TRUE);
\Civi::log()->error($message);
throw new \Civi\Payment\Exception\PaymentProcessorException($message);
throw new PaymentProcessorException($message);
}
// Get total amount from contribution returned by repeatTransaction (Which came from the recur template Contribution)
......@@ -529,7 +531,21 @@ trait CRM_Core_Payment_MJWIPNTrait {
protected function updateContributionRefund($params) {
$this->checkRequiredParams('updateContributionRefund', ['contribution_id', 'total_amount'], $params);
$params['payment_processor_id'] = $this->getPaymentProcessor()->getID();
civicrm_api3('Mjwpayment', 'create_payment', $params);
$lock = Civi::lockManager()->acquire('data.contribute.contribution.' . $params['contribution_id']);
if (!$lock->isAcquired()) {
throw new PaymentProcessorException('Could not acquire lock to record refund for contribution: ' . $params['contribution_id']);
}
// Check if it was already recorded (in case two processes are running the same time - eg. Refund UI + IPN processing).
$refundPayment = civicrm_api3('Payment', 'get', [
'contribution_id' => $params['contribution_id'],
'total_amount' => $params['total_amount'],
'trxn_id' => $params['trxn_id'] ?? NULL,
]);
if (empty($refundPayment['count'])) {
civicrm_api3('Mjwpayment', 'create_payment', $params);
}
$lock->release();
}
/**
......@@ -558,7 +574,7 @@ trait CRM_Core_Payment_MJWIPNTrait {
http_response_code(400);
exit(1);
} else {
Throw new \Civi\Payment\Exception\PaymentProcessorException($message);
Throw new PaymentProcessorException($message);
}
}
......
<?php
use Civi\Payment\Exception\PaymentProcessorException;
use CRM_Mjwshared_ExtensionUtil as E;
/**
......@@ -111,13 +112,20 @@ class CRM_Mjwshared_Form_PaymentRefund extends CRM_Core_Form {
'payment_processor_id' => $payment['payment_processor_id'],
];
$lock = Civi::lockManager()->acquire('data.contribute.contribution.' . $refundPaymentParams['contribution_id']);
if (!$lock->isAcquired()) {
throw new PaymentProcessorException('Could not acquire lock to record refund for contribution: ' . $refundPaymentParams['contribution_id']);
}
$refundPayment = civicrm_api3('Payment', 'get', [
'trxn_id' => $refund['refund_trxn_id'],
'contribution_id' => $refundPaymentParams['contribution_id'],
'total_amount' => $refundPaymentParams['total_amount'],
'trxn_id' => $refundPaymentParams['trxn_id'],
]);
if (empty($refundPayment['count'])) {
// Record the refund in CiviCRM
civicrm_api3('Mjwpayment', 'create_payment', $refundPaymentParams);
}
$lock->release();
$message = E::ts('Refund was processed successfully.');
if ($formValues['cancel_participants'] && !empty($participantIDs)) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment