From 1375d0a66d5970957dbf3c4f23e40f638867aa52 Mon Sep 17 00:00:00 2001 From: Matthew Wire <mjw@mjwconsult.co.uk> Date: Thu, 9 Jan 2020 09:53:48 +0000 Subject: [PATCH] Fix IPN API when working with charge.captured/succeeded --- api/v3/Stripe/Ipn.php | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/api/v3/Stripe/Ipn.php b/api/v3/Stripe/Ipn.php index 6767a923..c067c474 100644 --- a/api/v3/Stripe/Ipn.php +++ b/api/v3/Stripe/Ipn.php @@ -65,14 +65,33 @@ function civicrm_api3_stripe_Ipn($params) { $object = \Stripe\Event::retrieve($params['evtid']); } - // Avoid a SQL error if this one has been processed already. - $sql = "SELECT COUNT(*) AS count FROM civicrm_contribution WHERE trxn_id = %0"; - $sql_params = array(0 => array($object->data->object->charge, 'String')); - $dao = CRM_Core_DAO::executeQuery($sql, $sql_params); - $dao->fetch(); - if ($dao->count > 0) { - return civicrm_api3_create_error("Ipn already processed."); + + // See if we've already processed the IPN (do we have a contribution not in pending state?) + if ($object->data->object->object === 'charge') { + // For a charge event we get the ID here + $trxnID = $object->data->object->id; + } + else { + // I'm not sure if this is still used for any events? + $trxnID = $object->data->object->charge; + } + if (empty($trxnID)) { + throw new API_Exception('Could not get Charge ID from event.'); } + try { + $contribution = civicrm_api3('Contribution', 'getsingle', [ + 'trxn_id' => $trxnID, + ]); + if ($contribution['contribution_status_id'] !== CRM_Core_PseudoConstant::getKey( + 'CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending') + ) { + return civicrm_api3_create_error("Ipn already processed."); + } + } + catch (Exception $e) { + // No existing contribution so we process IPN + } + if (class_exists('CRM_Core_Payment_StripeIPN')) { // The $_GET['processor_id'] value is normally set by // CRM_Core_Payment::handlePaymentMethod -- GitLab