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/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..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); } /** @@ -164,12 +170,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); 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; 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/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/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 0 0 - DE EUR 0 1 @@ -153,6 +152,20 @@ 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 + + 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 @@ - + 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'