Skip to content

Commit 33983c7

Browse files
Richard van Oosterhoutclaude
andcommitted
doRefund: send required description, fire alterPaymentProcessorParams, use APIv4 for currency lookup
- Mollie's create-refund API marks 'description' as required; without one the refund is rejected. Send the caller's description when provided, otherwise a sensible default. The description may be shown to the customer (e.g. on their bank statement) depending on the payment method. - Fire the existing alterPaymentProcessorParams hook before sending, with an 'action' => 'Refund' marker (removed again after the hook), so extensions can customise the refund parameters/description the same way they already can for purchases. - Resolve the fallback currency via APIv4 FinancialTrxn::get instead of raw SQL, per the CiviCRM coding standards preference for API access. Verified live against Mollie (iDeal): refund accepted and re_... id returned as refund_trxn_id. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 276790e commit 33983c7

1 file changed

Lines changed: 19 additions & 9 deletions

File tree

CRM/Core/Payment/OmnipayMultiProcessor.php

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -318,21 +318,31 @@ public function doRefund(&$params) {
318318
if (empty($currency)) {
319319
// Look up the currency of the original transaction so the refund is
320320
// issued in the same currency; fall back to the default currency.
321-
$currency = CRM_Core_DAO::singleValueQuery(
322-
'SELECT currency FROM civicrm_financial_trxn WHERE trxn_id = %1',
323-
[1 => [$params['trxn_id'], 'String']]
324-
) ?: $this->getCurrency($params);
321+
$originalTrxn = \Civi\Api4\FinancialTrxn::get(FALSE)
322+
->addSelect('currency')
323+
->addWhere('trxn_id', '=', $params['trxn_id'])
324+
->execute()
325+
->first();
326+
$currency = $originalTrxn['currency'] ?? $this->getCurrency($params);
325327
}
326328
$this->ensurePaymentProcessorTypeIsSet();
327329
$this->createGatewayObject();
328330
$this->setProcessorFields();
329331

332+
$refundOptions = [
333+
'action' => 'Refund',
334+
'transactionReference' => $params['trxn_id'],
335+
'amount' => \Civi::format()->machineMoney($params['amount'], $currency),
336+
'currency' => $currency,
337+
// Mollie requires a description; it may be shown to the customer
338+
// (e.g. on their bank statement) depending on the payment method.
339+
'description' => $params['description'] ?? ts('Refund of payment %1', [1 => $params['trxn_id']]),
340+
];
341+
CRM_Utils_Hook::alterPaymentProcessorParams($this, $params, $refundOptions);
342+
unset($refundOptions['action']);
343+
330344
try {
331-
$response = $this->gateway->refund([
332-
'transactionReference' => $params['trxn_id'],
333-
'amount' => \Civi::format()->machineMoney($params['amount'], $currency),
334-
'currency' => $currency,
335-
])->send();
345+
$response = $this->gateway->refund($refundOptions)->send();
336346
}
337347
catch (\Exception $e) {
338348
throw new \Civi\Payment\Exception\PaymentProcessorException('Refund failed: ' . $e->getMessage());

0 commit comments

Comments
 (0)