Commit 442726cc authored by mattwire's avatar mattwire

Further fixes to contribution/transaction matching and repeat transactions

parent 7deb0441
......@@ -92,12 +92,11 @@ class CRM_Core_Payment_AuthNetIPN {
switch ($this->eventType) {
case 'net.authorize.payment.authcapture.created':
// Notifies you that an authorization and capture transaction was created.
$contributionID = $this->getContributionIDFromInvoiceID($this->getParamFromResponse($response, 'invoice_id'));
$contribution = civicrm_api3('Contribution', 'getsingle', ['id' => $contributionID]);
$contribution = $this->getContributionFromTrxnInfo($this->getParamFromResponse($response, 'invoice_id'));
$pendingStatusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending');
if ($contribution['contribution_status_id'] == $pendingStatusId) {
if (!empty($contribution['id']) && $contribution['contribution_status_id'] == $pendingStatusId) {
$params = [
'contribution_id' => $contributionID,
'contribution_id' => $contribution['id'],
'trxn_id' => $this->getParamFromResponse($response, 'transaction_id'),
'order_reference' => $this->getParamFromResponse($response, 'invoice_id'),
'trxn_date' => $this->event_date,
......@@ -122,7 +121,7 @@ class CRM_Core_Payment_AuthNetIPN {
case 'net.authorize.payment.refund.created':
// Notifies you that a successfully settled transaction was refunded.
$params = [
'contribution_id' => $this->getContributionIDFromInvoiceID($this->getParamFromResponse($response, 'invoice_id')),
'contribution_id' => $this->getContributionFromTrxnInfo($this->getParamFromResponse($response, 'invoice_id'))['id'],
'total_amount' => $this->getParamFromResponse($response, 'refund_amount'),
];
$this->updateContributionRefund($params);
......@@ -131,7 +130,7 @@ class CRM_Core_Payment_AuthNetIPN {
case 'net.authorize.payment.void.created':
// Notifies you that an unsettled transaction was voided.
$params = [
'contribution_id' => $this->getContributionIDFromInvoiceID($this->getParamFromResponse($response, 'invoice_id')),
'contribution_id' => $this->getContributionFromTrxnInfo($this->getParamFromResponse($response, 'invoice_id'))['id'],
'order_reference' => $this->getParamFromResponse($response, 'invoice_id'),
'trxn_date' => $this->event_date,
];
......@@ -145,7 +144,7 @@ class CRM_Core_Payment_AuthNetIPN {
case 'net.authorize.payment.fraud.approved':
// Notifies you that a previously held transaction was approved.
$params = [
'contribution_id' => $this->getContributionIDFromInvoiceID($this->getParamFromResponse($response, 'invoice_id')),
'contribution_id' => $this->getContributionFromTrxnInfo($this->getParamFromResponse($response, 'invoice_id'))['id'],
'trxn_id' => $this->getParamFromResponse($response, 'transaction_id'),
'order_reference' => $this->getParamFromResponse($response, 'invoice_id'),
'trxn_date' => $this->event_date,
......@@ -156,7 +155,7 @@ class CRM_Core_Payment_AuthNetIPN {
case 'net.authorize.payment.fraud.declined':
// Notifies you that a previously held transaction was declined.
$params = [
'contribution_id' => $this->getContributionIDFromInvoiceID($this->getParamFromResponse($response, 'invoice_id')),
'contribution_id' => $this->getContributionFromTrxnInfo($this->getParamFromResponse($response, 'invoice_id'))['id'],
'order_reference' => $this->getParamFromResponse($response, 'invoice_id'),
'trxn_date' => $this->event_date,
];
......@@ -220,24 +219,28 @@ class CRM_Core_Payment_AuthNetIPN {
}
/**
* Get the contribution ID from the paymentprocessor invoiceID.
* For AuthorizeNet we save the 20character invoice ID into the contribution trxn_id
* Get the contribution ID from the transaction info.
*
* @param string $invoiceID
*
* @return int
* @return array
* @throws \CiviCRM_API3_Exception
*/
protected function getContributionIDFromInvoiceID($invoiceID) {
protected function getContributionFromTrxnInfo($invoiceID) {
// invoiceNumber (refID) should be set on trxn_id of matching contribution
$contributionParams = [
'trxn_id' => $invoiceID,
'trxn_id' => $this->trxnId,
'options' => ['limit' => 1, 'sort' => "id DESC"],
'contribution_test' => $this->_paymentProcessor->getIsTestMode(),
];
$contribution = civicrm_api3('Contribution', 'get', $contributionParams);
// But if it is not we derived from first 20 chars of invoice_id so check there
if (empty($contribution['id'])) {
$contributionParams['trxn_id'] = ['LIKE' => "{$invoiceID}%"];
}
$contribution = civicrm_api3('Contribution', 'get', $contributionParams);
// Or finally try via invoice_id directly (first 20 chars)
if (empty($contribution['id'])) {
unset($contributionParams['trxn_id']);
$contributionParams['invoice_id'] = ['LIKE' => "{$invoiceID}%"];
......@@ -246,10 +249,10 @@ class CRM_Core_Payment_AuthNetIPN {
// We can't do anything without a matching contribution!
if (empty($contribution['id'])) {
$this->exception("Could not find matching contribution for invoice ID: {$invoiceID}");
$this->exception("Could not find matching contribution for trxn_id: {$this->trxnId} or invoice ID: {$invoiceID}");
}
return $contribution['id'];
return $contribution;
}
/**
......
......@@ -196,11 +196,11 @@ abstract class CRM_Core_Payment_AuthorizeNetCommon extends CRM_Core_Payment {
$tresponse = $response->getTransactionResponse();
if ($response->getMessages()->getResultCode() == "Ok") {
$this->setPaymentProcessorOrderID($response->getRefId());
if (!$tresponse) {
$this->handleError(NULL, 'No transaction response returned', $params['error_url']);
}
$this->setPaymentProcessorTrxnID($tresponse->getTransId());
$this->setPaymentProcessorOrderID($tresponse->getTransId());
switch ($tresponse->getResponseCode()) {
case self::RESPONSECODE_APPROVED:
......
Markdown is supported
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