From 65f72a3495f37a9b4017e24ea8969e0e3d86786f Mon Sep 17 00:00:00 2001 From: Kristina Date: Thu, 26 Feb 2026 13:28:06 +0100 Subject: [PATCH 1/8] Fix Dependabot alert ISSUE: UPP-400 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 294f122..0d167e2 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.15", - "phpunit/phpunit": "~6.2.0" + "phpunit/phpunit": "^9.6" }, "support": { "email": "support@unzer.com" From db8557fb3743d8f7ecf5efc1e3e62d9f8c1c5c9f Mon Sep 17 00:00:00 2001 From: Kristina Date: Mon, 2 Mar 2026 12:01:49 +0100 Subject: [PATCH 2/8] Replace array_last() with array_key_last() ISSUE: UPP-395 --- Model/Command/TransactionSynchronizer.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Model/Command/TransactionSynchronizer.php b/Model/Command/TransactionSynchronizer.php index 7c61335..c4a3a18 100644 --- a/Model/Command/TransactionSynchronizer.php +++ b/Model/Command/TransactionSynchronizer.php @@ -42,7 +42,8 @@ public function __construct( public function applyCaptureOnMagento(OrderInterface $order, UnzerPayment $unzer): void { $payment = $this->getOrderPayment($order); - $capture = array_last($unzer->getCharges()); + $charges = $unzer->getCharges(); + $capture = $charges[array_key_last($charges)] ?? null; if (!$payment || !$capture) { return; @@ -85,7 +86,8 @@ public function applyCaptureOnMagento(OrderInterface $order, UnzerPayment $unzer public function applyCancellationOnMagento(OrderInterface $order, UnzerPayment $unzer): void { $payment = $this->getOrderPayment($order); - $cancellation = array_last($unzer->getCancellations()); + $cancellations = $unzer->getCancellations(); + $cancellation = $cancellations[array_key_last($cancellations)] ?? null; if (!$payment || !$cancellation) { return; @@ -152,7 +154,8 @@ public function applyCancellationOnMagento(OrderInterface $order, UnzerPayment $ public function applyChargebackOnMagento(OrderInterface $order, UnzerPayment $unzer): void { $payment = $this->getOrderPayment($order); - $chargeback = array_last($unzer->getChargebacks()); + $chargebacks = $unzer->getChargebacks(); + $chargeback = $chargebacks[array_key_last($chargebacks)] ?? null; if (!$payment || !$chargeback) { return; From 36ddfb63cfd6286f31ee8e9c353f859b87f91896 Mon Sep 17 00:00:00 2001 From: Boljanovic Date: Wed, 4 Mar 2026 12:06:33 +0100 Subject: [PATCH 3/8] Add Payment reference to payment requests ISSUE: UPP-405 --- Model/Command/Authorize.php | 2 ++ Model/Command/Cancel.php | 2 +- Model/Command/CancelAuthorization.php | 3 +++ Model/Command/Capture.php | 2 ++ Model/Command/Refund.php | 10 ++++++++-- Model/Command/RefundCharge.php | 3 +++ 6 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Model/Command/Authorize.php b/Model/Command/Authorize.php index f625a84..6f69a6f 100644 --- a/Model/Command/Authorize.php +++ b/Model/Command/Authorize.php @@ -213,12 +213,14 @@ protected function processSaveToVault( */ protected function createAuthorization(OrderInterface $order, float $amount): Authorization { + /** @var Authorization $authorization */ $authorization = $this->authorizationFactory->create([ 'amount' => $amount, 'currency' => $order->getBaseCurrencyCode(), 'returnUrl' => $this->_getCallbackUrl() ]); $authorization->setOrderId($order->getIncrementId()); + $authorization->setPaymentReference($order->getIncrementId()); return $authorization; } diff --git a/Model/Command/Cancel.php b/Model/Command/Cancel.php index ea2d556..8b2f4df 100644 --- a/Model/Command/Cancel.php +++ b/Model/Command/Cancel.php @@ -41,7 +41,7 @@ public function execute(array $commandSubject): void return; } - $cancellations = $client->cancelPayment($hpPayment, $amount, static::REASON); + $cancellations = $client->cancelPayment($hpPayment, $amount, static::REASON, $order->getIncrementId()); if (count($cancellations) > 0) { $lastCancellation = end($cancellations); diff --git a/Model/Command/CancelAuthorization.php b/Model/Command/CancelAuthorization.php index 41ee34f..ab4a0b4 100644 --- a/Model/Command/CancelAuthorization.php +++ b/Model/Command/CancelAuthorization.php @@ -12,6 +12,7 @@ use Unzer\PAPI\Model\Config; use UnzerSDK\Constants\CancelReasonCodes; use UnzerSDK\Exceptions\UnzerApiException; +use UnzerSDK\Resources\TransactionTypes\Cancellation; use UnzerSDK\Resources\TransactionTypes\CancellationFactory; /** @@ -80,8 +81,10 @@ public function execute(array $commandSubject): void return; } + /** @var Cancellation $cancellation */ $cancellation = $this->cancellationFactory->create(['amount' => $amount]); $cancellation->setReasonCode(self::REASON); + $cancellation->setPaymentReference($order->getIncrementId()); $cancellation = $client->cancelAuthorizedPayment($hpPayment, $cancellation); diff --git a/Model/Command/Capture.php b/Model/Command/Capture.php index 1f1fc61..2ff4c16 100644 --- a/Model/Command/Capture.php +++ b/Model/Command/Capture.php @@ -164,12 +164,14 @@ protected function _chargeNew( ): Charge { $storeId = (string)$order->getStoreId(); + /** @var Charge $charge */ $charge = $this->chargeFactory->create([ 'amount' => $amount, 'currency' => $order->getBaseCurrencyCode(), 'returnUrl' => $this->_getCallbackUrl() ]); $charge->setOrderId($order->getIncrementId()); + $charge->setPaymentReference($order->getIncrementId()); $unzerClient = $this->_getClient( $storeId, diff --git a/Model/Command/Refund.php b/Model/Command/Refund.php index 6ded238..9c81d2e 100644 --- a/Model/Command/Refund.php +++ b/Model/Command/Refund.php @@ -46,7 +46,7 @@ public function execute(array $commandSubject): void // because of the nature of Prepayment, we need to refund the whole payment, // otherwise refund is not possible at all for prepayment. if ($payment->getMethodInstance()->getCode() === self::METHOD_PREPAYMENT) { - $cancellations = $client->cancelPayment($hpPayment, $amount, static::REASON); + $cancellations = $client->cancelPayment($hpPayment, $amount, static::REASON, $order->getIncrementId()); if (count($cancellations) > 0) { $lastCancellation = end($cancellations); @@ -57,7 +57,13 @@ public function execute(array $commandSubject): void $chargeId = $payment->getParentTransactionId(); - $cancellation = $client->cancelChargeById($hpPayment, $chargeId, $amount, self::REASON); + $cancellation = $client->cancelChargeById( + $hpPayment, + $chargeId, + $amount, + self::REASON, + $order->getIncrementId() + ); $payment->setLastTransId($cancellation->getId()); } diff --git a/Model/Command/RefundCharge.php b/Model/Command/RefundCharge.php index 6179cd8..d6e3c09 100644 --- a/Model/Command/RefundCharge.php +++ b/Model/Command/RefundCharge.php @@ -12,6 +12,7 @@ use Unzer\PAPI\Model\Config; use UnzerSDK\Constants\CancelReasonCodes; use UnzerSDK\Exceptions\UnzerApiException; +use UnzerSDK\Resources\TransactionTypes\Cancellation; use UnzerSDK\Resources\TransactionTypes\CancellationFactory; /** @@ -82,8 +83,10 @@ public function execute(array $commandSubject): void return; } + /** @var Cancellation $cancellation */ $cancellation = $this->cancellationFactory->create(['amount' => $amount]); $cancellation->setReasonCode(self::REASON); + $cancellation->setPaymentReference($order->getIncrementId()); $cancellation = $client->cancelChargedPayment($hpPayment, $cancellation); From 7d9a0bc9c96d1f97680c091f88c8597488203891 Mon Sep 17 00:00:00 2001 From: Kristina Date: Fri, 6 Mar 2026 15:30:38 +0100 Subject: [PATCH 4/8] Remove country restriction for Direct Bank Transfer ISSUE: UPP-406 --- etc/config.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/etc/config.xml b/etc/config.xml index 1b4e84b..934fe9e 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -97,7 +97,6 @@ 0 0 0 - DE EUR 0 1 From da0a9703eb555d1a8abcd466d1339abbff4513b5 Mon Sep 17 00:00:00 2001 From: Kristina Date: Mon, 9 Mar 2026 11:20:58 +0100 Subject: [PATCH 5/8] Set company info fields in customer data ISSUE: UPP-325 --- Model/Config/Provider.php | 41 ++++++++++++------- .../js/view/payment/method-renderer/basev2.js | 9 +++- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/Model/Config/Provider.php b/Model/Config/Provider.php index 0167ff7..1a2a103 100644 --- a/Model/Config/Provider.php +++ b/Model/Config/Provider.php @@ -117,27 +117,18 @@ public function getConfig(): array $methodConfig = $model->getFrontendConfig(); - if (!$model->hasMethodValidOverrideKeys()) { - if ($baseCustomer) { - $methodConfig['unzerCustomerId'] = $baseCustomer->getId(); - } + $customer = $model->hasMethodValidOverrideKeys() + ? $this->fetchUnzerCustomer($quote, $model) + : $baseCustomer; - $methodConfigs[$model->getCode()] = $methodConfig; - continue; - } - - $overrideCustomer = $this->fetchUnzerCustomer($quote, $model); - - if ($overrideCustomer) { - $methodConfig['unzerCustomerId'] = $overrideCustomer->getId(); + if ($customer) { + $methodConfig = $this->applyCustomerConfig($methodConfig, $customer); } $methodConfigs[$model->getCode()] = $methodConfig; } - return [ - 'payment' => array_filter($methodConfigs), - ]; + return ['payment' => array_filter($methodConfigs)]; } /** @@ -165,4 +156,24 @@ private function fetchUnzerCustomer(Quote $quote, ?MethodBase $method = null): ? return null; } } + + /** + * @param array $methodConfig + * @param Customer $customer + * + * @return array + */ + private function applyCustomerConfig(array $methodConfig, Customer $customer): array + { + $methodConfig['unzerCustomerId'] = $customer->getId(); + + if ($customer->getCompany()) { + $companyInfo = $customer->getCompanyInfo(); + $methodConfig['companyType'] = $companyInfo->getCompanyType(); + $methodConfig['function'] = $companyInfo->getFunction(); + $methodConfig['commercialSector'] = $companyInfo->getCommercialSector(); + } + + return $methodConfig; + } } diff --git a/view/frontend/web/js/view/payment/method-renderer/basev2.js b/view/frontend/web/js/view/payment/method-renderer/basev2.js index 3193d90..5ad74d1 100644 --- a/view/frontend/web/js/view/payment/method-renderer/basev2.js +++ b/view/frontend/web/js/view/payment/method-renderer/basev2.js @@ -303,7 +303,14 @@ define( country: shipping.countryId } : {}, ...(billing?.company && billing.company.trim() !== '' - ? {company: billing.company.trim()} + ? { + company: billing.company.trim(), + companyInfo: { + companyType: methodConfig.companyType || null, + function: methodConfig.function || null, + commercialSector: methodConfig.commercialSector || null, + } + } : {}), customerSettings: { type: billing?.company && billing.company.trim() !== '' ? 'B2B' : 'B2C' From b254e902631dd8ff00ceae94bddd7710074fa87d Mon Sep 17 00:00:00 2001 From: Kristina Date: Tue, 10 Mar 2026 11:14:30 +0100 Subject: [PATCH 6/8] Ensure Apple Pay v1 backward compatibility ISSUE: UPP-404 --- Model/Config.php | 1 + Model/Method/ApplepayV1.php | 13 +++++++++++++ etc/config.xml | 14 ++++++++++++++ etc/di.xml | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 Model/Method/ApplepayV1.php diff --git a/Model/Config.php b/Model/Config.php index c3c29e1..56e34c4 100644 --- a/Model/Config.php +++ b/Model/Config.php @@ -48,6 +48,7 @@ class Config extends \Magento\Payment\Gateway\Config\Config public const METHOD_BANCONTACT = 'unzer_bancontact'; public const METHOD_PREPAYMENT = 'unzer_prepayment'; public const METHOD_APPLEPAYV2 = 'unzer_applepayv2'; + public const METHOD_APPLEPAY = 'unzer_applepay'; public const METHOD_GOOGLEPAY = 'unzer_googlepay'; public const METHOD_TWINT = 'unzer_twint'; public const METHOD_OPEN_BANKING = 'unzer_open_banking'; diff --git a/Model/Method/ApplepayV1.php b/Model/Method/ApplepayV1.php new file mode 100644 index 0000000..d1b1403 --- /dev/null +++ b/Model/Method/ApplepayV1.php @@ -0,0 +1,13 @@ +0 Unzer\PAPI\Model\Method\ApplepayV2 + + 0 + <![CDATA[Apple Pay v1]]> + order + authorize_capture + 0 + 1 + 1 + 1 + 1 + 0 + 0 + Unzer\PAPI\Model\Method\ApplepayV1 + 0 order diff --git a/etc/di.xml b/etc/di.xml index df3778e..e041a28 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -1426,4 +1426,36 @@ UnzerAuthorizeAndCaptureCommandPool + + + + + Unzer\PAPI\Model\Config::METHOD_APPLEPAY + + + + + UnzerApplepayV1Config + + + + + + UnzerApplepayV1ConfigValueHandler + Unzer\PAPI\Model\Config\CanCancelHandler + Unzer\PAPI\Model\Config\CanRefundHandler + Unzer\PAPI\Model\Config\CanRefundHandler + Unzer\PAPI\Model\Config\CanVoidHandler + + + + + + Unzer\PAPI\Model\Config::METHOD_APPLEPAY + Magento\Payment\Block\Form + Magento\Payment\Block\Info + UnzerApplepayV1ValueHandlerPool + UnzerAuthorizeAndCaptureCommandPool + + From 5452dd4e9b904fad1bfe4851ed12147e6d8f3975 Mon Sep 17 00:00:00 2001 From: Kristina Date: Tue, 10 Mar 2026 14:59:37 +0100 Subject: [PATCH 7/8] Fix charge existing order ISSUE: UPP-405 --- Model/Command/Capture.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Model/Command/Capture.php b/Model/Command/Capture.php index 2ff4c16..09883d8 100644 --- a/Model/Command/Capture.php +++ b/Model/Command/Capture.php @@ -22,7 +22,6 @@ use UnzerSDK\Constants\RecurrenceTypes; use UnzerSDK\Exceptions\UnzerApiException; use UnzerSDK\Resources\AbstractUnzerResource; -use UnzerSDK\Resources\TransactionTypes\Authorization; use UnzerSDK\Resources\TransactionTypes\Charge; use UnzerSDK\Resources\TransactionTypes\ChargeFactory; @@ -134,17 +133,24 @@ public function execute(array $commandSubject): ?ResultInterface */ protected function _chargeExisting(Order $order, string $paymentId, float $amount, ?string $storeId = null): Charge { - $payment = $this->_getClient($storeId, $order->getPayment()->getMethodInstance()) - ->fetchPayment($paymentId); + $unzerClient = $this->_getClient( + $storeId, + $order->getPayment()->getMethodInstance() + ); - /** @var Authorization|null $authorization */ - $authorization = $payment->getAuthorization(); + $payment = $unzerClient->fetchPayment($paymentId); - if ($authorization !== null) { - return $authorization->charge($amount); - } + /** @var Charge $charge */ + $charge = $this->chargeFactory->create([ + 'amount' => $amount, + 'currency' => $order->getBaseCurrencyCode(), + 'returnUrl' => $this->_getCallbackUrl() + ]); + + $charge->setOrderId($order->getIncrementId()); + $charge->setPaymentReference($order->getIncrementId()); - return $payment->charge($amount); + return $unzerClient->performChargeOnPayment($payment, $charge); } /** From b7cbf7a3e561ebdee8daa6659b04340f67694dc6 Mon Sep 17 00:00:00 2001 From: Kristina Date: Mon, 16 Mar 2026 14:07:53 +0100 Subject: [PATCH 8/8] [Release 4.0.3 - 2026-03-16] --- CHANGELOG.md | 9 +++++++++ composer.json | 2 +- etc/module.xml | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6a0a1f..3020a50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [4.0.3](https://github.com/unzerdev/magento2/compare/4.0.2..4.0.3) +### Fixed +* Initialization of the Invoice B2B component on the checkout page +* Apple Pay v1 backward compatibility +* Replace 'array_last()' with 'array_key_last()' in TransactionSynchronizer class +### Changed +* Add payment reference to payment, capture, and refund requests +* Remove the country restriction for Direct Bank Transfer + ## [4.0.2](https://github.com/unzerdev/magento2/compare/4.0.1..4.0.2) ### Fixed * Storing PayPal and SEPA Direct Debit on Magento 2.4.8 diff --git a/composer.json b/composer.json index 0d167e2..7833aa2 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "unzerdev/magento2", "description": "This extension for Magento 2 provides a direct integration of the Unzer payment types to your Magento 2 shop via the Unzer Payment API (PAPI).", "type": "magento2-module", - "version": "4.0.2", + "version": "4.0.3", "license": "Apache-2.0", "require": { "php": "~7.4.0|~8.1.0|~8.2.0|~8.3.0|~8.4.0", diff --git a/etc/module.xml b/etc/module.xml index f8e2cb8..5612f3b 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,7 +1,7 @@ - +