From 5405d92c8c77ff31e0a79500657c66b8ec4a0c31 Mon Sep 17 00:00:00 2001 From: "Matthew Wire (MJW Consulting)" <mjw@mjwconsult.co.uk> Date: Thu, 18 Oct 2018 12:59:01 +0100 Subject: [PATCH] Delay IPN processing so we don't conflict with browser --- CRM/Core/Payment/StripeIPN.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CRM/Core/Payment/StripeIPN.php b/CRM/Core/Payment/StripeIPN.php index bbc170ec..24633704 100644 --- a/CRM/Core/Payment/StripeIPN.php +++ b/CRM/Core/Payment/StripeIPN.php @@ -192,6 +192,31 @@ class CRM_Core_Payment_StripeIPN extends CRM_Core_Payment_BaseIPN { return $value; } + /** + * Get a lock so we don't process browser return & ipn return at the same time. + * + * Paralell processing notably results in 2 receipts. + * + * Currently mysql 5.7.5+ will process a cross-session lock. If we can't do that + * then we should be tardy on the processing of the ipn response. + * + * @return bool + */ + protected function getLock() { + $mysqlVersion = CRM_Core_DAO::singleValueQuery('SELECT VERSION()'); + if (stripos($mysqlVersion, 'mariadb') === FALSE + && version_compare($mysqlVersion, '5.7.5', '>=') + ) { + $lock = Civi::lockManager()->acquire('data.contribute.contribution.' . $this->transaction_id); + return $lock->isAcquired(); + } + if (empty(CRM_Core_Session::singleton()->getLoggedInContactID())) { + // So far the best way of telling the difference is the session. + sleep(30); + } + return TRUE; + } + /** * @return bool * @throws \CRM_Core_Exception @@ -449,6 +474,10 @@ class CRM_Core_Payment_StripeIPN extends CRM_Core_Payment_BaseIPN { * @throws \CiviCRM_API3_Exception */ public function setInfo() { + if (!$this->getLock()) { + return; + } + $this->test_mode = $this->retrieve('test_mode', 'Integer'); $abort = FALSE; -- GitLab