Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions CRM/Core/Payment/OmnipayMultiProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ public function doPayment(&$params, $component = 'contribute'): array {
CRM_Utils_System::redirect($url);
}
$response->redirect();
CRM_Utils_System::civiExit();
}
else {
return $this->handleError('alert', 'failed processor transaction ' . $this->_paymentProcessor['payment_processor_type'], [$response->getCode() => $response->getMessage()]);
Expand Down Expand Up @@ -870,11 +871,44 @@ public function processPaymentNotification($params) {
if ($this->getLock() && $this->contribution['contribution_status_id:name'] !== 'Completed') {
$this->gatewayConfirmContribution($response);
$trxnReference = $response->getTransactionReference();
civicrm_api3('contribution', 'completetransaction', [
'id' => $this->transaction_id,
'trxn_id' => $trxnReference,
'payment_processor_id' => $params['processor_id'],
]);
$contributionStatus = $this->contribution['contribution_status_id:name'] ?? '';
if (in_array($contributionStatus, ['Partially paid', 'Pending'], TRUE)) {
// The contribution already carries an outstanding balance (e.g. it received an
// earlier partial payment, or is a pay-later contribution being settled now).
// completetransaction() would record the FULL original contribution amount as
// paid rather than the amount the processor actually reports for this
// transaction, corrupting the balance (see dev/financial#174). Route through
// Payment::create instead, which records only the actual amount and lets core
// recompute the balance/status.
$balanceAmount = (float) (civicrm_api4('Contribution', 'get', [
'select' => ['balance_amount'],
'where' => [['id', '=', $this->transaction_id]],
])->first()['balance_amount'] ?? 0);
$paymentAmount = (float) $response->getAmount();
// Guard against processors that don't report an amount here, and never
// register more than the outstanding balance.
if ($paymentAmount <= 0 || $paymentAmount > $balanceAmount) {
$paymentAmount = $balanceAmount;
}
if ($paymentAmount > 0) {
civicrm_api4('Payment', 'create', [
'values' => [
'contribution_id' => (int) $this->transaction_id,
'total_amount' => $paymentAmount,
'trxn_id' => $trxnReference,
'payment_processor_id' => (int) ($params['processor_id'] ?? 0),
'trxn_date' => date('Y-m-d H:i:s'),
],
]);
}
}
else {
civicrm_api3('contribution', 'completetransaction', [
'id' => $this->transaction_id,
'trxn_id' => $trxnReference,
'payment_processor_id' => $params['processor_id'],
]);
}
if (!empty($this->contribution['contribution_recur_id']) && $trxnReference) {
$this->updatePaymentTokenWithAnyExtraData($trxnReference);
}
Expand Down