diff --git a/CHANGELOG.md b/CHANGELOG.md
index 11c9a4fb..b9df0c56 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -35,6 +35,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- fix show multiple vouchers separately
- fix: only OK, NOT_FINISHED or CANCEL in oxorder->oxtranstatus allowed
- fix showing correct amount when cancelling in admin
+- Order of credit card data input fields optimized
+- Add Descriptor for PrePayment on ThankYou-Page
+- remove Option "Capture Later"-Option for ApplePay
## [2.1.4] - 2023-11-23
diff --git a/metadata.php b/metadata.php
index 902a5d6d..7cfa9e75 100644
--- a/metadata.php
+++ b/metadata.php
@@ -53,7 +53,7 @@
',
],
'thumbnail' => 'logo.svg',
- 'version' => '2.2.0-rc.12',
+ 'version' => '2.2.0-rc.13',
'author' => 'OXID eSales AG',
'url' => 'https://www.oxid-esales.com',
'email' => 'info@oxid-esales.com',
@@ -226,13 +226,6 @@
'value' => '0',
'constraints' => '0|1'
],
- [
- 'group' => 'unzerapplepay',
- 'name' => 'UnzerOption_oscunzer_applepay',
- 'type' => 'select',
- 'value' => '0',
- 'constraints' => '0|1'
- ],
[
'group' => 'unzerapplepay',
'name' => 'applepay_merchant_capabilities',
diff --git a/src/Controller/Admin/AdminOrderController.php b/src/Controller/Admin/AdminOrderController.php
index 9625d1c8..36e4bb09 100644
--- a/src/Controller/Admin/AdminOrderController.php
+++ b/src/Controller/Admin/AdminOrderController.php
@@ -11,10 +11,8 @@
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
use OxidEsales\Eshop\Core\Registry;
-use OxidSolutionCatalysts\Unzer\Core\UnzerDefinitions;
-use OxidSolutionCatalysts\Unzer\Model\Order;
+use OxidEsales\Eshop\Application\Model\Order;
use OxidSolutionCatalysts\Unzer\Model\Payment;
-use OxidSolutionCatalysts\Unzer\Model\Order as UnzerOrder;
use OxidSolutionCatalysts\Unzer\Model\TransactionList;
use OxidSolutionCatalysts\Unzer\Service\Transaction as TransactionService;
use OxidSolutionCatalysts\Unzer\Service\Translator;
@@ -204,7 +202,7 @@ protected function getUnzerViewData(string $sPaymentId, string $sTypeId): void
$editObject->getFieldData('oxpaid') == '0000-00-00 00:00:00' &&
$fCharged == $unzerPayment->getAmount()->getTotal()
) {
- /** @var UnzerOrder $editObject */
+ /** @var Order $editObject */
$editObject->markUnzerOrderAsPaid();
$this->forceReloadListFrame();
}
diff --git a/src/Controller/Admin/ModuleConfiguration.php b/src/Controller/Admin/ModuleConfiguration.php
index b087083a..915c7f11 100644
--- a/src/Controller/Admin/ModuleConfiguration.php
+++ b/src/Controller/Admin/ModuleConfiguration.php
@@ -12,37 +12,37 @@
use GuzzleHttp\Exception\GuzzleException;
use JsonException;
use OxidEsales\Eshop\Core\Registry;
-use OxidEsales\EshopCommunity\Core\Exception\FileException;
use OxidSolutionCatalysts\Unzer\Exception\UnzerException;
use OxidSolutionCatalysts\Unzer\Module;
use OxidSolutionCatalysts\Unzer\Service\ApiClient;
+use OxidSolutionCatalysts\Unzer\Service\ModuleConfiguration\AppleMerchantCertificate;
+use OxidSolutionCatalysts\Unzer\Service\ModuleConfiguration\ApplePaymentProcessingCertificate;
use OxidSolutionCatalysts\Unzer\Service\ModuleSettings;
use OxidSolutionCatalysts\Unzer\Service\Translator;
use OxidSolutionCatalysts\Unzer\Service\UnzerWebhooks;
+use OxidSolutionCatalysts\Unzer\Traits\Request;
use OxidSolutionCatalysts\Unzer\Traits\ServiceContainer;
use Throwable;
use UnzerSDK\Exceptions\UnzerApiException;
/**
- * Order class wrapper for Unzer module
- *
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ModuleConfiguration extends ModuleConfiguration_parent
{
use ServiceContainer;
+ use Request;
+
+ protected Translator $translator;
+ protected ModuleSettings $moduleSettings;
+ protected UnzerWebhooks $unzerWebhooks;
- /** @var Translator $translator */
- protected $translator = null;
- /** @var ModuleSettings $moduleSettings */
- protected $moduleSettings = null;
- /** @var UnzerWebhooks $unzerWebhooks */
- protected $unzerWebhooks = null;
protected string $_sModuleId; // phpcs:ignore PSR2.Classes.PropertyDeclaration.Underscore
- /**
- * @inheritDoc
- */
+ private string $errorPaymentMissing = 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_PAYMENT_MISSING';
+ private bool $isUpdate;
+
public function __construct()
{
parent::__construct();
@@ -52,8 +52,6 @@ public function __construct()
}
/**
- * @inheritDoc
- *
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function render()
@@ -67,6 +65,11 @@ public function render()
$this->_aViewData['applePayNetworks'] = $this->moduleSettings->getApplePayNetworks();
$this->_aViewData['applePayMerchantCert'] = $this->moduleSettings->getApplePayMerchantCert();
$this->_aViewData['applePayMerchantCertKey'] = $this->moduleSettings->getApplePayMerchantCertKey();
+ $this->_aViewData['applePayPaymentProcessingCert'] = $this->moduleSettings->getApplePayPaymentCert();
+
+ $this->_aViewData['applePayPaymentProcessingCertKey'] =
+ $this->moduleSettings->getApplePayPaymentPrivateKey();
+
$this->_aViewData['systemMode'] = $this->moduleSettings->getSystemMode();
} catch (Throwable $loggerException) {
Registry::getUtilsView()->addErrorToDisplay(
@@ -112,26 +115,27 @@ public function unregisterWebhooks(): void
}
/**
- * @throws GuzzleException
- * @throws JsonException
- *
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
* @SuppressWarnings(PHPMD.ElseExpression)
*/
public function transferApplePayPaymentProcessingData(): void
{
- /** @var string $key */
- $key = Registry::getRequest()->getRequestEscapedParameter('applePayPaymentProcessingCertKey');
- /** @var string $cert */
- $cert = Registry::getRequest()->getRequestEscapedParameter('applePayPaymentProcessingCert');
- $errorMessage = !$key || !$cert ? 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_PAYMENT_SET_CERT' : null;
+ $systemMode = $this->moduleSettings->getSystemMode();
+
+ $key = $this->getUnzerStringRequestParameter($systemMode . '-' . 'applePayPaymentProcessingCertKey');
+ $cert = $this->getUnzerStringRequestParameter($systemMode . '-' . 'applePayPaymentProcessingCert');
+ $errorMessage = $key && $cert ? null : $this->errorPaymentMissing;
+
+ $this->saveMerchantCert($systemMode);
+ $this->saveMerchantKey($systemMode);
+ $this->savePaymentCert($systemMode);
+ $this->savePaymentKey($systemMode);
$apiClient = $this->getServiceFromContainer(ApiClient::class);
$applePayKeyId = null;
$applePayCertId = null;
- // Upload Key
if (is_null($errorMessage)) {
try {
$response = $apiClient->uploadApplePayPaymentKey($key);
@@ -170,8 +174,8 @@ public function transferApplePayPaymentProcessingData(): void
if (!$response || $response->getStatusCode() !== 200) {
$errorMessage = 'OSCUNZER_ERROR_ACTIVATE_APPLEPAY_PAYMENT_CERT';
} else {
- $this->moduleSettings->saveApplePayPaymentKeyId($applePayKeyId);
$this->moduleSettings->saveApplePayPaymentCertificateId($applePayCertId);
+ $this->moduleSettings->saveApplePayPaymentKeyId($applePayKeyId);
}
} catch (Throwable $loggerException) {
$errorMessage = 'OSCUNZER_ERROR_ACTIVATE_APPLEPAY_PAYMENT_CERT';
@@ -192,118 +196,199 @@ public function transferApplePayPaymentProcessingData(): void
public function getApplePayPaymentProcessingKeyExists(): bool
{
- $keyExists = false;
$keyId = $this->moduleSettings->getApplePayPaymentKeyId();
if ($this->moduleSettings->getApplePayMerchantCertKey() && $keyId) {
try {
$response = $this->getServiceFromContainer(ApiClient::class)
- ->requestApplePayPaymentCert($keyId);
+ ->requestApplePayPaymentKey($keyId);
if (!$response) {
- $this->addErrorTransmittingKey();
return false;
}
- $keyExists = $response->getStatusCode() === 200;
- } catch (GuzzleException $guzzleException) {
- $this->addErrorTransmittingKey();
+ return $response->getStatusCode() === 200;
+ } catch (GuzzleException | JsonException $guzzleException) {
+ $this->addErrorToDisplay('OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_PAYMENT_GET_KEY');
}
}
- return $keyExists;
+ return false;
}
- /**
- * @throws GuzzleException
- */
public function getApplePayPaymentProcessingCertExists(): bool
{
- $certExists = false;
$certId = $this->moduleSettings->getApplePayPaymentCertificateId();
if ($this->moduleSettings->getApplePayMerchantCert() && $certId) {
try {
$response = $this->getServiceFromContainer(ApiClient::class)
->requestApplePayPaymentCert($certId);
+
if (!$response) {
- $this->addErrorTransmittingCertificate();
+ $this->addErrorToDisplay('OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_PAYMENT_GET_CERT');
return false;
}
- $certExists = $response->getStatusCode() === 200;
- } catch (GuzzleException $guzzleException) {
- $this->addErrorTransmittingCertificate();
+
+ return $response->getStatusCode() === 200;
+ } catch (GuzzleException | JsonException $guzzleException) {
+ $this->addErrorToDisplay('OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_PAYMENT_GET_CERT');
+ return false;
}
}
- return $certExists;
+ return false;
}
/**
- * @return void
- * @throws FileException
* @SuppressWarnings(PHPMD.StaticAccess)
+ * @throws \OxidEsales\EshopCommunity\Core\Exception\FileException
*/
- public function saveConfVars()
+ public function saveConfVars(): void
{
- $request = Registry::getRequest();
- if (
- $request->getRequestEscapedParameter('oxid') &&
- $request->getRequestEscapedParameter('oxid') === 'osc-unzer'
- ) {
- // the systemMode is very important, so we set it first ...
- /** @var array $confselects */
- $confselects = $request->getRequestEscapedParameter('confselects');
- /** @var string $systemMode */
- $systemMode = $confselects['UnzerSystemMode'];
- $this->moduleSettings->setSystemMode($systemMode);
-
- $this->resetContentCache();
-
- $applePayMC = $request->getRequestEscapedParameter('applePayMC');
- if (is_array($applePayMC)) {
- $this->moduleSettings->saveApplePayMerchantCapabilities($applePayMC);
- }
- $applePayNetworks = $request->getRequestEscapedParameter('applePayNetworks');
- if (is_array($applePayNetworks)) {
- $this->moduleSettings->saveApplePayNetworks($applePayNetworks);
- }
- $certConfigKey = $this->moduleSettings->getSystemMode() . '-' . 'applePayMerchantCert';
- $applePayMerchantCert = $request->getRequestEscapedParameter($certConfigKey);
- file_put_contents(
- $this->moduleSettings->getApplePayMerchantCertFilePath(),
- $applePayMerchantCert
- );
- $keyConfigKey = $this->moduleSettings->getSystemMode() . '-' . 'applePayMerchantCertKey';
- $applePayMerchCertKey = $request->getRequestEscapedParameter($keyConfigKey);
- file_put_contents(
- $this->moduleSettings->getApplePayMerchantCertKeyFilePath(),
- $applePayMerchCertKey
- );
- }
+ $moduleId = $this->getUnzerStringRequestEscapedParameter('oxid');
+ if ($moduleId === Module::MODULE_ID) {
+ $systemMode = $this->moduleSettings->getSystemMode();
+
+ $applePayMC = $this->getUnzerArrayRequestParameter('applePayMC');
+ $this->moduleSettings->saveApplePayMerchantCapabilities($applePayMC);
+ $applePayNetworks = $this->getUnzerArrayRequestParameter('applePayNetworks');
+
+ $this->moduleSettings->saveApplePayNetworks($applePayNetworks);
+
+ $this->saveMerchantCert($systemMode);
+ $this->saveMerchantKey($systemMode);
+ $this->savePaymentCert($systemMode);
+ $this->savePaymentKey($systemMode);
- parent::saveConfVars();
- if ($request->getRequestEscapedParameter('oxid') === 'osc-unzer') {
$this->moduleSettings->saveWebhookConfiguration([]);
$this->registerWebhooks();
}
+ parent::saveConfVars();
}
- private function addErrorTransmittingCertificate(): void
+ private function saveMerchantKey(string $systemMode): void
{
- Registry::getUtilsView()->addErrorToDisplay(
- oxNew(
- UnzerException::class,
- $this->translator->translate(
- 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_PAYMENT_GET_CERT'
- )
- )
+ $errorIds = [
+ 'onEmpty' => 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_MERCHANT_KEY_EMPTY',
+ 'onShort' => 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_MERCHANT_KEY_TOO_SHORT'
+ ];
+
+ $newValue = $this->getUnzerStringRequestEscapedParameter(
+ $systemMode . '-' . 'applePayMerchantCertKey'
);
+
+ $oldValue = $this->moduleSettings->getApplePayMerchantCertKey();
+
+ $this->setIsUpdate($oldValue, $newValue);
+
+ $isValidMerchantKey = $this->validateCredentialsForSaving($newValue, $errorIds);
+
+ if ($isValidMerchantKey) {
+ $service = $this->getServiceFromContainer(AppleMerchantCertificate::class);
+ $service->saveCertificateKey($newValue);
+ }
}
- private function addErrorTransmittingKey(): void
+ private function saveMerchantCert(string $systemMode): void
+ {
+ $errorIds = [
+ 'onEmpty' => 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_MERCHANT_CERT_EMPTY',
+ 'onShort' => 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_MERCHANT_CERT_TOO_SHORT'
+ ];
+
+ $newValue = $this->getUnzerStringRequestEscapedParameter(
+ $systemMode . '-' . 'applePayMerchantCert'
+ );
+
+ $oldValue = $this->moduleSettings->getApplePayMerchantCert();
+
+ $this->setIsUpdate($oldValue, $newValue);
+
+ $isValidMerchantCert = $this->validateCredentialsForSaving($newValue, $errorIds);
+
+ if ($isValidMerchantCert) {
+ $service = $this->getServiceFromContainer(AppleMerchantCertificate::class);
+ $service->saveCertificate($newValue);
+ }
+ }
+
+ private function savePaymentKey(string $systemMode): void
+ {
+ $errorIds = [
+ 'onEmpty' => 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_PAYMENT_KEY_EMPTY',
+ 'onShort' => 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_PAYMENT_KEY_TOO_SHORT'
+ ];
+
+ $newValue = $this->getUnzerStringRequestEscapedParameter(
+ $systemMode . '-' . 'applePayPaymentProcessingCertKey'
+ );
+
+ $oldValue = $this->moduleSettings->getApplePayPaymentPrivateKey();
+
+ $this->setIsUpdate($oldValue, $newValue);
+ $isValidPaymentKey = $this->validateCredentialsForSaving($newValue, $errorIds);
+
+ if ($isValidPaymentKey) {
+ $service = $this->getServiceFromContainer(ApplePaymentProcessingCertificate::class);
+ $service->saveCertificateKey($newValue);
+ }
+ }
+
+ private function savePaymentCert(string $systemMode): void
+ {
+ $errorIds = [
+ 'onEmpty' => 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_PAYMENT_CERT_EMPTY',
+ 'onShort' => 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_PAYMENT_CERT_TOO_SHORT'
+ ];
+
+ $newValue = $this->getUnzerStringRequestEscapedParameter(
+ $systemMode . '-' . 'applePayPaymentProcessingCert'
+ );
+
+ $oldValue = $this->moduleSettings->getApplePayPaymentCert();
+
+ $this->setIsUpdate($oldValue, $newValue);
+
+ $isValidPaymentKey = $this->validateCredentialsForSaving($newValue, $errorIds);
+
+ if ($isValidPaymentKey) {
+ $service = $this->getServiceFromContainer(ApplePaymentProcessingCertificate::class);
+ $service->saveCertificate($newValue);
+ }
+ }
+
+ private function validateCredentialsForSaving(?string $string, array $errors): bool
+ {
+ if ($string === null || strlen($string) === 0) {
+ if ($this->getIsUpdate()) {
+ $this->addErrorToDisplay($errors['onEmpty']);
+ }
+ return true;
+ }
+
+ if (strlen($string) > 1 && strlen($string) < 32) {
+ $this->addErrorToDisplay($errors['onShort']);
+ return false;
+ }
+
+ return true;
+ }
+
+ private function addErrorToDisplay(string $translateId): void
{
Registry::getUtilsView()->addErrorToDisplay(
oxNew(
UnzerException::class,
$this->translator->translate(
- 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_PAYMENT_GET_KEY'
+ $translateId
)
)
);
}
+
+ private function setIsUpdate(?string $oldValue, ?string $newValue): bool
+ {
+ $this->isUpdate = $oldValue !== $newValue;
+ return $this->isUpdate;
+ }
+
+ private function getIsUpdate(): bool
+ {
+ return $this->isUpdate;
+ }
}
diff --git a/src/Controller/Admin/OrderMain.php b/src/Controller/Admin/OrderMain.php
index 00e0fc8e..90ae78f5 100644
--- a/src/Controller/Admin/OrderMain.php
+++ b/src/Controller/Admin/OrderMain.php
@@ -13,7 +13,7 @@
use OxidEsales\Eshop\Core\Registry;
use OxidSolutionCatalysts\Unzer\Model\Payment;
use OxidSolutionCatalysts\Unzer\Service\Payment as PaymentService;
-use OxidSolutionCatalysts\Unzer\Model\Order;
+use OxidEsales\Eshop\Application\Model\Order;
use OxidSolutionCatalysts\Unzer\Traits\ServiceContainer;
use UnzerSDK\Exceptions\UnzerApiException;
@@ -44,10 +44,6 @@ protected function onOrderSend()
}
}
- /**
- * @param Order $oOrder
- * @return void
- */
public function sendShipmentNotification(Order $oOrder): void
{
$paymentService = $this->getServiceFromContainer(PaymentService::class);
diff --git a/src/Controller/ApplePayCallbackController.php b/src/Controller/ApplePayCallbackController.php
index 55afcee0..d23b7713 100644
--- a/src/Controller/ApplePayCallbackController.php
+++ b/src/Controller/ApplePayCallbackController.php
@@ -13,6 +13,7 @@
use OxidEsales\Eshop\Application\Controller\FrontendController;
use OxidEsales\Eshop\Core\Registry;
use OxidSolutionCatalysts\Unzer\Service\ApplePaySessionHandler;
+use OxidSolutionCatalysts\Unzer\Service\DebugHandler;
use OxidSolutionCatalysts\Unzer\Service\ResponseHandler;
use OxidSolutionCatalysts\Unzer\Traits\ServiceContainer;
@@ -20,9 +21,6 @@ class ApplePayCallbackController extends FrontendController
{
use ServiceContainer;
- /**
- * @throws JsonException
- */
public function validateMerchant(): void
{
/** @var string $merchValidUrlRaw */
@@ -30,9 +28,11 @@ public function validateMerchant(): void
$merchValidUrl = urldecode($merchValidUrlRaw);
$responseHandler = $this->getServiceFromContainer(ResponseHandler::class);
+
$validationResponse = $this
->getServiceFromContainer(ApplePaySessionHandler::class)
->validateMerchant($merchValidUrl);
+
if (is_array($validationResponse)) {
$responseHandler
->response()
diff --git a/src/Controller/DispatcherController.php b/src/Controller/DispatcherController.php
index 982df6e5..f1177b8f 100644
--- a/src/Controller/DispatcherController.php
+++ b/src/Controller/DispatcherController.php
@@ -14,6 +14,7 @@
use OxidEsales\Eshop\Application\Model\Order;
use OxidEsales\Eshop\Core\Registry;
use OxidSolutionCatalysts\Unzer\Model\TmpOrder;
+use OxidSolutionCatalysts\Unzer\Service\FlexibleSerializer;
use OxidSolutionCatalysts\Unzer\Service\Transaction;
use OxidSolutionCatalysts\Unzer\Service\Translator;
use OxidSolutionCatalysts\Unzer\Service\UnzerSDKLoader;
@@ -35,12 +36,16 @@ class DispatcherController extends FrontendController
public function __construct()
{
parent::__construct();
- $this->transaction = $this->getServiceFromContainer(Transaction::class);
- $this->unzerWebhooks = $this->getServiceFromContainer(UnzerWebhooks::class);
- $this->unzerSDKLoader = $this->getServiceFromContainer(UnzerSDKLoader::class);
- $this->translator = $this->getServiceFromContainer(Translator::class);
+ $this->transaction = $this->getTransactionService();
+ $this->unzerWebhooks = $this->getUnzerWebhooks();
+ $this->unzerSDKLoader = $this->getUnzerSdkLoader();
+ $this->translator = $this->getTranslator();
}
+ /**
+ * @throws \UnzerSDK\Exceptions\UnzerApiException
+ * @throws \OxidSolutionCatalysts\Unzer\Exception\UnzerException
+ */
public function updatePaymentTransStatus(): void
{
$jsonRequest = file_get_contents('php://input');
@@ -78,7 +83,7 @@ public function updatePaymentTransStatus(): void
}
$unzer = $this->unzerSDKLoader->getUnzerSDKbyKey($unzerKey);
- $resource = $unzer->fetchResourceFromEvent((string)$jsonRequest);
+ $resource = $unzer->fetchResourceFromEvent($jsonRequest);
$paymentId = $resource->getId();
if ($paymentId) {
@@ -103,12 +108,12 @@ private function processPayment(Unzer $unzer, string $paymentId): string
$order = oxNew(Order::class);
$data = $this->transaction->getTransactionDataByPaymentId($paymentId);
- if (!is_array($data) || !isset($data[0]['OXORDERID'])) {
+ if (!is_array($data) || !isset($data[0]['oxorderid'])) {
return "Invalid Order Data";
}
$unzerPayment = $unzer->fetchPayment($paymentId);
- if ($order->load($data[0]['OXORDERID'])) {
+ if ($order->load($data[0]['oxorderid'])) {
return $this->updateOrder($order, $unzerPayment, $paymentId);
}
@@ -172,6 +177,79 @@ private function updateOrder(Order $order, Payment $unzerPayment, string $paymen
return $this->translator->translate('oscunzer_TRANSACTION_NOTHINGTODO') . $paymentId;
}
+ /**
+ * @throws \Exception
+ */
+ public function finalizeTmpOrder(
+ Payment $unzerPayment,
+ TmpOrder $tmpOrder,
+ array $tmpData,
+ bool $bError
+ ): string {
+ $return = $this->returnError();
+ if ($tmpOrder->load($tmpData['oxid'])) {
+ $flexibleSerializer = $this->getFlexibleSerializer();
+
+ /** @var Order $oOrder */
+ $oOrder = $flexibleSerializer->safeUnserialize(
+ $tmpData['tmporder'],
+ [
+ Order::class
+ ]
+ );
+
+ if ($oOrder instanceof \stdClass || $oOrder === false) {
+ $oOrder = $flexibleSerializer->restoreOrderFromStrClass($tmpData['tmporder']);
+ }
+
+ if (!is_null($oOrder) && method_exists($oOrder, 'finalizeTmpOrder')) {
+ /** @var \OxidSolutionCatalysts\Unzer\Model\Order $oOrder */
+ $oOrder->finalizeTmpOrder($unzerPayment, $bError);
+ $tmpOrder->assign(['status' => 'FINISHED']);
+ $tmpOrder->save();
+
+ $return = $this->returnSuccess();
+ }
+ }
+
+ return $return;
+ }
+
+ protected function getFlexibleSerializer(): FlexibleSerializer
+ {
+ return $this->getServiceFromContainer(FlexibleSerializer::class);
+ }
+
+ protected function getUnzerSdkLoader(): UnzerSDKLoader
+ {
+ return $this->getServiceFromContainer(UnzerSDKLoader::class);
+ }
+
+ protected function getTranslator(): Translator
+ {
+ return $this->getServiceFromContainer(Translator::class);
+ }
+
+ protected function getUnzerWebhooks(): UnzerWebhooks
+ {
+ return $this->getServiceFromContainer(UnzerWebhooks::class);
+ }
+
+ protected function getTransactionService(): Transaction
+ {
+ return $this->getServiceFromContainer(Transaction::class);
+ }
+
+ protected function returnError(): string
+ {
+ return $this->translator->translate('oscunzer_ERROR_HANDLE_TMP_ORDER');
+ }
+
+ protected function returnSuccess(): string
+ {
+ return $this->translator->translate('oscunzer_SUCCESS_HANDLE_TMP_ORDER');
+ }
+
private function handleTmpOrder(Payment $unzerPayment): string
{
$tmpOrder = oxNew(TmpOrder::class);
@@ -179,8 +257,8 @@ private function handleTmpOrder(Payment $unzerPayment): string
$tmpData = $tmpOrder->getTmpOrderByUnzerId($orderId);
if (
- isset($tmpData['OXID']) &&
- $tmpOrder->load($tmpData['OXID']) &&
+ isset($tmpData['oxid']) &&
+ $tmpOrder->load($tmpData['oxid']) &&
$this->hasExceededTimeLimit($tmpOrder)
) {
$bError = !(
@@ -195,27 +273,6 @@ private function handleTmpOrder(Payment $unzerPayment): string
return $this->translator->translate('oscunzer_ERROR_HANDLE_TMP_ORDER');
}
- private function finalizeTmpOrder(
- Payment $unzerPayment,
- TmpOrder $tmpOrder,
- array $tmpData,
- bool $bError
- ): string {
- if ($tmpOrder->load($tmpData['OXID'])) {
- $aOrderData = unserialize(base64_decode($tmpData['TMPORDER']), ['allowed_classes' => [Order::class]]);
- $oOrder = is_array($aOrderData) && isset($aOrderData['order']) ? $aOrderData['order'] : null;
-
- if ($oOrder) {
- $oOrder->finalizeTmpOrder($unzerPayment, $bError);
- $tmpOrder->assign(['status' => 'FINISHED']);
- $tmpOrder->save();
- return $this->translator->translate('oscunzer_SUCCESS_HANDLE_TMP_ORDER');
- }
- }
-
- return $this->translator->translate('oscunzer_ERROR_HANDLE_TMP_ORDER');
- }
-
private function hasExceededTimeLimit(TmpOrder $tmpOrder): bool
{
$defTimeDiffMin = Registry::getConfig()->getConfigParam('defTimeDiffMin', 5);
diff --git a/src/Core/ViewConfig.php b/src/Core/ViewConfig.php
index 310d5201..d3dc4b41 100644
--- a/src/Core/ViewConfig.php
+++ b/src/Core/ViewConfig.php
@@ -251,6 +251,13 @@ public function getPrePaymentHolder(string $unzerOrderNumber): ?string
return $prePaymentBankAccountService->getHolder($unzerOrderNumber);
}
+ public function getPrePaymentDescriptor(string $unzerOrderNumber): ?string
+ {
+ $prePaymentBankAccountService = $this->getPrePaymentBankAccountService();
+
+ return $prePaymentBankAccountService->getDescriptor($unzerOrderNumber);
+ }
+
private function getPrePaymentBankAccountService(): PrePaymentBankAccountService
{
return $this->getServiceFromContainer(PrePaymentBankAccountService::class);
diff --git a/src/Model/Order.php b/src/Model/Order.php
index 813e5363..c6ee4dd8 100644
--- a/src/Model/Order.php
+++ b/src/Model/Order.php
@@ -272,30 +272,26 @@ public function setUnzerTransId(string $sTransId): void
}
/**
- * @param \UnzerSDK\Resources\Payment|null $unzerPayment
- * @return bool
* @throws UnzerApiException
* @throws Exception
*/
- public function initWriteTransactionToDB($unzerPayment = null): bool
+ public function initWriteTransactionToDB(\UnzerSDK\Resources\Payment|null $unzerPayment = null): void
{
/** @var string $oxpaymenttype */
$oxpaymenttype = $this->getFieldData('oxpaymenttype');
- if (strpos($oxpaymenttype, "oscunzer") !== false) {
+ if ($oxpaymenttype !== null && str_contains($oxpaymenttype, "oscunzer")) {
$transactionService = $this->getServiceFromContainer(TransactionService::class);
$unzerPayment = $unzerPayment instanceof \UnzerSDK\Resources\Payment ?
$unzerPayment :
$this->getServiceFromContainer(PaymentService::class)->getSessionUnzerPayment(true);
- return $transactionService->writeTransactionToDB(
+ $transactionService->writeTransactionToDB(
$this->getId(),
$this->getOrderUser()->getId() ?: '',
$unzerPayment
);
}
-
- return false;
}
/**
@@ -304,9 +300,9 @@ public function initWriteTransactionToDB($unzerPayment = null): bool
public function getUnzerInvoiceNr()
{
/** @var int $number */
- $number = $this->getFieldData('OXINVOICENR') !== 0 ?
- $this->getFieldData('OXINVOICENR') :
- $this->getFieldData('OXORDERNR');
+ $number = $this->getFieldData('oxinvoicenr') !== 0 ?
+ $this->getFieldData('oxinvoicenr') :
+ $this->getFieldData('oxordernr');
return $number;
}
@@ -334,22 +330,17 @@ public function delete($sOxId = null)
return parent::delete($sOxId);
}
- /**
- * @param string $fieldName
- * @param string $value
- * @param int $dataType
- * @return false|void
- */
- public function setFieldData($fieldName, $value, $dataType = Field::T_TEXT)
+
+ public function setFieldData($fieldName, $value, $dataType = Field::T_TEXT): void
{
- return parent::setFieldData($fieldName, $value, $dataType);
+ parent::setFieldData($fieldName, $value, $dataType);
}
private function setTmpOrderStatus(string $unzerOrderId, string $status): void
{
$tmpOrder = oxNew(TmpOrder::class);
$tmpData = $tmpOrder->getTmpOrderByUnzerId($unzerOrderId);
- if ($tmpOrder->load($tmpData['OXID'])) {
+ if ($tmpOrder->load($tmpData['oxid'])) {
$tmpOrder->assign(['status' => $status]);
$tmpOrder->save();
}
diff --git a/src/Model/TmpOrder.php b/src/Model/TmpOrder.php
index b7082f70..364ab3bf 100644
--- a/src/Model/TmpOrder.php
+++ b/src/Model/TmpOrder.php
@@ -139,8 +139,8 @@ public function getTmpOrderByOxOrderId(string $oxSessionOrderId): ?CoreOrderMode
$rawRes = $queryBuilder->execute();
$result = $rawRes->fetchAssociative();
- if (is_array($result) && isset($result['TMPORDER']) && is_string($result['TMPORDER'])) {
- $tmpOrder = $result['TMPORDER'];
+ if (is_array($result) && isset($result['tmporder']) && is_string($result['tmporder'])) {
+ $tmpOrder = $result['tmporder'];
$result = unserialize(base64_decode($tmpOrder));
if (is_array($result) && isset($result['order']) && is_object($result['order'])) {
/** @var CoreOrderModel $order */
diff --git a/src/PaymentExtensions/UnzerPayment.php b/src/PaymentExtensions/UnzerPayment.php
index c70602e0..c180f246 100644
--- a/src/PaymentExtensions/UnzerPayment.php
+++ b/src/PaymentExtensions/UnzerPayment.php
@@ -17,19 +17,16 @@
use OxidSolutionCatalysts\Unzer\Service\PrePaymentBankAccountService;
use OxidSolutionCatalysts\Unzer\Core\UnzerDefinitions;
use OxidSolutionCatalysts\Unzer\Service\DebugHandler;
-use OxidSolutionCatalysts\Unzer\Service\SavedPayment\SavedPaymentSessionService;
use OxidSolutionCatalysts\Unzer\Service\Transaction as TransactionService;
use OxidSolutionCatalysts\Unzer\Service\Payment as PaymentService;
use OxidSolutionCatalysts\Unzer\Service\Translator;
use OxidSolutionCatalysts\Unzer\Service\Unzer as UnzerService;
use OxidSolutionCatalysts\Unzer\Service\UnzerSDKLoader;
use OxidSolutionCatalysts\Unzer\Traits\ServiceContainer;
-use UnzerSDK\Constants\RecurrenceTypes;
use UnzerSDK\Exceptions\UnzerApiException;
use UnzerSDK\Interfaces\UnzerParentInterface;
use UnzerSDK\Resources\Basket as UnzerResourceBasket;
use UnzerSDK\Resources\Customer;
-use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\PaymentTypes\PaylaterInstallment;
use UnzerSDK\Resources\PaymentTypes\Card as UnzerSDKPaymentTypeCard;
use UnzerSDK\Resources\PaymentTypes\Paypal as UnzerSDKPaymentTypePaypal;
@@ -77,25 +74,17 @@ public function getUnzerOrderId(): string
{
return $this->unzerOrderId;
}
- /**
- * @return array
- */
+
public function getPaymentCurrencies(): array
{
return $this->allowedCurrencies;
}
- /**
- * @return bool
- */
public function redirectUrlNeedPending(): bool
{
return $this->needPending;
}
- /**
- * @return BasePaymentType
- */
abstract public function getUnzerPaymentTypeObject(): UnzerParentInterface;
/**
@@ -177,7 +166,7 @@ protected function doTransactions(
Basket $basketModel,
Customer $customer,
User $userModel,
- BasePaymentType $paymentType
+ UnzerParentInterface $paymentType
): AbstractTransactionType {
$this->throwExceptionIfPaymentDataError();
$paymentProcedure = $this->unzerService->getPaymentProcedure($this->paymentMethod);
@@ -369,7 +358,7 @@ private function isSavedPayment(): bool
}
private function performDefaultTransaction(
- BasePaymentType $paymentType,
+ UnzerParentInterface $paymentType,
string $paymentProcedure,
float $price,
Basket $basketModel,
@@ -388,7 +377,7 @@ private function performDefaultTransaction(
}
private function performTransactionForSavedPayment(
- BasePaymentType $paymentType,
+ UnzerParentInterface $paymentType,
string $paymentProcedure,
float $price,
Basket $basketModel,
diff --git a/src/Service/ApiClient.php b/src/Service/ApiClient.php
index a1bef843..80503409 100644
--- a/src/Service/ApiClient.php
+++ b/src/Service/ApiClient.php
@@ -69,10 +69,6 @@ public function requestApplePayPaymentKey(string $keyId): ?ResponseInterface
return $this->request('keypair/applepay/privatekeys/' . $keyId);
}
- /**
- * @throws GuzzleException
- * @throws JsonException
- */
public function uploadApplePayPaymentKey(string $key): ?ResponseInterface
{
return $this->request('keypair/applepay/privatekeys', 'POST', [
diff --git a/src/Service/ApplePaySessionHandler.php b/src/Service/ApplePaySessionHandler.php
index 86f117a0..0cac796d 100644
--- a/src/Service/ApplePaySessionHandler.php
+++ b/src/Service/ApplePaySessionHandler.php
@@ -25,7 +25,7 @@ class ApplePaySessionHandler
private DebugHandler $logger;
/**
- * @param ModuleSettings $moduleSettings
+ * @throws \OxidEsales\EshopCommunity\Core\Exception\FileException
*/
public function __construct(ModuleSettings $moduleSettings, DebugHandler $logger)
{
@@ -35,7 +35,7 @@ public function __construct(ModuleSettings $moduleSettings, DebugHandler $logger
}
/**
- * @return void
+ * @throws \OxidEsales\EshopCommunity\Core\Exception\FileException
*/
private function initialize(): void
{
@@ -64,10 +64,6 @@ private function initialize(): void
}
}
- /**
- * @param string $validationUrl
- * @return array|null
- */
public function validateMerchant(string $validationUrl): ?array
{
// if we have no credentials we could not validate Merchant
diff --git a/src/Service/FlexibleSerializer.php b/src/Service/FlexibleSerializer.php
new file mode 100644
index 00000000..190d639d
--- /dev/null
+++ b/src/Service/FlexibleSerializer.php
@@ -0,0 +1,193 @@
+makeSerializable($object);
+ return serialize($serializable);
+ }
+
+ /**
+ * Safely unserialize data, restoring objects of allowed classes.
+ *
+ * @param string $serialized The serialized data string.
+ * @param array $allowedClasses An array of fully qualified class names that are allowed to be unserialized.
+ * @return mixed The unserialized data.
+ */
+ public function safeUnserialize(string $serialized, array $allowedClasses = [])
+ {
+ $unserializedData = unserialize(
+ $serialized,
+ [
+ 'allowed_classes' => array_merge(
+ $allowedClasses,
+ [stdClass::class]
+ )
+ ]
+ );
+ return $this->restoreUnserializable($unserializedData, $allowedClasses);
+ }
+
+ public function restoreOrderFromStrClass(string $serialized): ?Order
+ {
+ /** @var object $unserializedData */
+ $unserializedData = unserialize(
+ $serialized,
+ [
+ 'allowed_classes' => [stdClass::class, Order ::class]
+ ]
+ );
+
+ /** @var \OxidSolutionCatalysts\Unzer\Model\Order $order */
+ $order = $this->getOrderModel();
+
+ /**
+ * @var string $value
+ */
+ foreach (get_object_vars($unserializedData) as $property => $value) {
+ if (
+ property_exists($order, $property)
+ || method_exists($order, 'setFieldData')
+ ) {
+ $property = str_replace("\0", '', $property);
+ if (method_exists($order, 'setFieldData')) {
+ $reflectionMethod = new ReflectionMethod($order, 'setFieldData');
+ if ($reflectionMethod->isPublic()) {
+ $order->setFieldData($property, $value);
+ }
+ }
+ $order->$property = $value;
+ }
+ }
+
+ return $order;
+ }
+
+ protected function getOrderModel(): Order
+ {
+ return \oxNew(Order::class);
+ }
+
+ /**
+ * Convert data into a serializable format, handling objects and resources.
+ *
+ * @param mixed $data The data to be made serializable.
+ * @return mixed The data in a serializable format.
+ */
+ private function makeSerializable($data)
+ {
+ if (is_object($data)) {
+ $serializable = new stdClass();
+ $serializable->__class = get_class($data);
+ foreach (get_object_vars($data) as $key => $value) {
+ $serializable->$key = $this->makeSerializable($value);
+ }
+ return $serializable;
+ }
+
+ if (is_array($data)) {
+ return array_map([$this, 'makeSerializable'], $data);
+ }
+
+ if (is_resource($data)) {
+ return null;
+ }
+
+ return $data;
+ }
+
+ /**
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+ * @SuppressWarnings(PHPMD.ElseExpression)
+ */
+ private function restoreUnserializable(mixed $data, array $allowedClasses): mixed
+ {
+ if (is_array($data)) {
+ return array_map(function ($item) use ($allowedClasses) {
+ return $this->restoreUnserializable($item, $allowedClasses);
+ }, $data);
+ }
+
+ if (is_object($data) && isset($data->__class)) {
+ $className = $data->__class;
+ if ($this->isAllowedClass($className, $allowedClasses)) {
+ $restored = new $className();
+ foreach (get_object_vars($data) as $key => $value) {
+ if ($key !== '__class') {
+ $key = str_replace("\0", '', $key);
+ $restored->$key = $this->restoreUnserializable($value, $allowedClasses);
+ }
+ }
+ return $restored;
+ }
+ }
+
+ if (is_object($data)) {
+ $restored = new stdClass();
+ foreach (get_object_vars($data) as $key => $value) {
+ if ($key !== '__class') {
+ $key = str_replace("\0", '', $key);
+ $restored->$key = $this->restoreUnserializable($value, $allowedClasses);
+ }
+ }
+ return $restored;
+ }
+
+ return $data;
+ }
+
+ /**
+ * Check if a given class is allowed based on the list of allowed classes.
+ *
+ * @param string $className The name of the class to check.
+ * @param array $allowedClasses An array of allowed class names.
+ * @return bool True if the class is allowed, false otherwise.
+ */
+ private function isAllowedClass(string $className, array $allowedClasses): bool
+ {
+ foreach ($allowedClasses as $allowedClass) {
+ if (
+ $className === $allowedClass ||
+ is_subclass_of($className, $allowedClass) ||
+ $this->isClassAlias($className, $allowedClass)
+ ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if two class names refer to the same class (are aliases).
+ *
+ * @param string $className The name of the class to check.
+ * @param string $aliasName The name of the potential alias to check against.
+ * @return bool True if the classes are aliases, false otherwise.
+ */
+ private function isClassAlias(string $className, string $aliasName): bool
+ {
+ if (class_exists($className) && class_exists($aliasName)) {
+ return (new ReflectionClass($className))->getName() === (new ReflectionClass($aliasName))->getName();
+ }
+ return false;
+ }
+}
diff --git a/src/Service/ModuleConfiguration/AppleMerchantCertificate.php b/src/Service/ModuleConfiguration/AppleMerchantCertificate.php
new file mode 100644
index 00000000..01248473
--- /dev/null
+++ b/src/Service/ModuleConfiguration/AppleMerchantCertificate.php
@@ -0,0 +1,39 @@
+moduleSettings = $moduleSettings;
+ }
+ public function saveCertificate(?string $certificate): bool
+ {
+ if (is_null($certificate)) {
+ return false;
+ }
+
+ return (bool) file_put_contents(
+ $this->moduleSettings->getApplePayMerchantCertFilePath(),
+ $certificate
+ );
+ }
+ public function saveCertificateKey(?string $certificateKey): bool
+ {
+ if (is_null($certificateKey)) {
+ return false;
+ }
+
+ return (bool) file_put_contents(
+ $this->moduleSettings->getApplePayMerchantCertKeyFilePath(),
+ $certificateKey
+ );
+ }
+}
diff --git a/src/Service/ModuleConfiguration/ApplePaymentProcessingCertificate.php b/src/Service/ModuleConfiguration/ApplePaymentProcessingCertificate.php
new file mode 100644
index 00000000..a942ecfe
--- /dev/null
+++ b/src/Service/ModuleConfiguration/ApplePaymentProcessingCertificate.php
@@ -0,0 +1,39 @@
+moduleSettings = $moduleSettings;
+ }
+ public function saveCertificate(?string $certificate): bool
+ {
+ if (is_null($certificate)) {
+ return false;
+ }
+
+ return (bool) file_put_contents(
+ $this->moduleSettings->getApplePayPaymentCertFilePath(),
+ $certificate
+ );
+ }
+ public function saveCertificateKey(?string $certificateKey): bool
+ {
+ if (is_null($certificateKey)) {
+ return false;
+ }
+
+ return (bool) file_put_contents(
+ $this->moduleSettings->getApplePayPaymentPrivateKeyFilePath(),
+ $certificateKey
+ );
+ }
+}
diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php
index 9804e0de..3e091f33 100644
--- a/src/Service/ModuleSettings.php
+++ b/src/Service/ModuleSettings.php
@@ -42,24 +42,11 @@ class ModuleSettings
'visa' => '1'
];
- /** @var ModuleSettingBridgeInterface $moduleSettingBridge */
- private $moduleSettingBridge;
+ private ModuleSettingBridgeInterface $moduleSettingBridge;
+ private ModuleConfigurationDaoBridgeInterface $moduleInfoBridge;
+ private Session $session;
+ private Config $config;
- /** @var ModuleConfigurationDaoBridgeInterface */
- private $moduleInfoBridge;
-
- /** @var Session $session */
- private $session;
-
- /** @var Config $config */
- private $config;
-
- /**
- * @param ModuleSettingBridgeInterface $moduleSettingBridge
- * @param ModuleConfigurationDaoBridgeInterface $moduleInfoBridge
- * @param \OxidEsales\Eshop\Core\Session $session
- * @param \OxidEsales\Eshop\Core\Config $config
- */
public function __construct(
ModuleSettingBridgeInterface $moduleSettingBridge,
ModuleConfigurationDaoBridgeInterface $moduleInfoBridge,
@@ -72,25 +59,16 @@ public function __construct(
$this->config = $config;
}
- /**
- * @return bool
- */
public function isDebugMode(): bool
{
return $this->getSettingValue('UnzerDebug') === true;
}
- /**
- * @return bool
- */
public function isSandboxMode(): bool
{
return $this->getSystemMode() === self::SYSTEM_MODE_SANDBOX;
}
- /**
- * @return string
- */
public function getSystemMode(): string
{
if ($this->getSettingValue('UnzerSystemMode')) {
@@ -99,33 +77,11 @@ public function getSystemMode(): string
return self::SYSTEM_MODE_SANDBOX;
}
- /**
- * @param string $systemMode
- * @return void
- */
public function setSystemMode(string $systemMode): void
{
$this->saveSetting('UnzerSystemMode', $systemMode);
}
-// /**
-// * @return string
-// */
-// public function getShopPublicKey(): string
-// {
-// /** @var string $unzerPublicKey */
-// $unzerPublicKey = $this->getSettingValue($this->getSystemMode() . '-UnzerPublicKey');
-// return $unzerPublicKey;
-// }
-// public function getShopPublicKeyPaylater(): string
-// {
-// /** @var string $unzerPublicKey */
-// $unzerPublicKey = $this->getSettingValue($this->getSystemMode() . '-UnzerPublicKey');
-// return $unzerPublicKey;
-// }
- /**
- * @return float
- */
public function getInstallmentRate(): float
{
/** @var float $unzerOption */
@@ -140,7 +96,6 @@ public function getStandardPrivateKey(): string
return $unzerPrivateKey;
}
-
public function getStandardPublicKey(): string
{
/** @var string $unzerPublicKey */
@@ -148,9 +103,6 @@ public function getStandardPublicKey(): string
return $unzerPublicKey;
}
- /**
- * @return bool
- */
public function useModuleJQueryInFrontend(): bool
{
/** @var bool $unzerJQuery */
@@ -158,10 +110,6 @@ public function useModuleJQueryInFrontend(): bool
return $unzerJQuery;
}
- /**
- * @param string $paymentMethod
- * @return string
- */
public function getPaymentProcedureSetting(string $paymentMethod): string
{
if (
@@ -173,25 +121,16 @@ public function getPaymentProcedureSetting(string $paymentMethod): string
return self::PAYMENT_CHARGE;
}
- /**
- * @return string
- */
public function getModuleVersion(): string
{
return $this->moduleInfoBridge->get(Module::MODULE_ID)->getVersion();
}
- /**
- * @return string
- */
public function getGitHubName(): string
{
return Module::GITHUB_NAME;
}
- /**
- * @return bool
- */
public function isApplePayEligibility(): bool
{
return (
@@ -201,18 +140,12 @@ public function isApplePayEligibility(): bool
);
}
- /**
- * @return mixed
- */
- public function getApplePayLabel()
+ public function getApplePayLabel(): mixed
{
return $this->getSettingValue('applepay_label') ?:
$this->config->getActiveShop()->getFieldData('oxcompany') ?: 'default_label';
}
- /**
- * @return array associative array including capability key and active status
- */
public function getApplePayMerchantCapabilities(): array
{
/** @var array $applepayMerchCaps */
@@ -223,9 +156,6 @@ public function getApplePayMerchantCapabilities(): array
);
}
- /**
- * @return array array of active capability keys
- */
public function getActiveApplePayMerchantCapabilities(): array
{
return array_keys(array_filter(
@@ -234,9 +164,6 @@ public function getActiveApplePayMerchantCapabilities(): array
));
}
- /**
- * @return array associative array including network key and active status
- */
public function getApplePayNetworks(): array
{
/** @var array $applepayNetworks */
@@ -247,9 +174,6 @@ public function getApplePayNetworks(): array
);
}
- /**
- * @return array array of active network keys
- */
public function getActiveApplePayNetworks(): array
{
return array_keys(array_filter(
@@ -258,9 +182,6 @@ public function getActiveApplePayNetworks(): array
));
}
- /**
- * @return string
- */
public function getApplePayMerchantIdentifier(): string
{
/** @var string $applepayMerchId */
@@ -269,10 +190,6 @@ public function getApplePayMerchantIdentifier(): string
return $applepayMerchId;
}
- /**
- * @return string
- * @throws FileException
- */
public function getApplePayMerchantCert(): string
{
$path = $this->getApplePayMerchantCertFilePath();
@@ -285,10 +202,6 @@ public function getApplePayMerchantCert(): string
return '';
}
- /**
- * @return string
- * @throws FileException
- */
public function getApplePayMerchantCertKey(): string
{
$path = $this->getApplePayMerchantCertKeyFilePath();
@@ -302,16 +215,35 @@ public function getApplePayMerchantCertKey(): string
}
/**
- * @param array $capabilities
- * @return void
+ * @throws \OxidEsales\EshopCommunity\Core\Exception\FileException
*/
+ public function getApplePayPaymentPrivateKey(): string
+ {
+ $path = $this->getApplePayPaymentPrivateKeyFilePath();
+ if (file_exists($path)) {
+ /** @var string $fileContest */
+ $fileContest = file_get_contents($path);
+ return $fileContest;
+ }
+
+ return '';
+ }
+
+ public function getApplePayPaymentCertFilePath(): string
+ {
+ return $this->getFilesPath()
+ . '/.applepay_payment_cert.'
+ . $this->getSystemMode()
+ . '.'
+ . $this->config->getShopId();
+ }
+
public function saveApplePayMerchantCapabilities(array $capabilities): void
{
$this->saveSetting('applepay_merchant_capabilities', $capabilities);
}
/**
- * @return string
* @throws FileException
*/
public function getApplePayMerchantCertFilePath(): string
@@ -323,10 +255,6 @@ public function getApplePayMerchantCertFilePath(): string
. $this->config->getShopId();
}
- /**
- * @return string
- * @throws FileException
- */
public function getApplePayMerchantCertKeyFilePath(): string
{
return $this->getFilesPath()
@@ -337,9 +265,17 @@ public function getApplePayMerchantCertKeyFilePath(): string
}
/**
- * @return string
* @throws FileException
*/
+ public function getApplePayPaymentPrivateKeyFilePath(): string
+ {
+ return $this->getFilesPath()
+ . '/.applepay_payment_key.'
+ . $this->getSystemMode()
+ . '.'
+ . $this->config->getShopId();
+ }
+
public function getFilesPath(): string
{
$facts = new Facts();
@@ -356,27 +292,16 @@ public function getFilesPath(): string
return $path;
}
- /**
- * @param string $paymentKeyId
- * @return void
- */
public function saveApplePayPaymentKeyId(string $paymentKeyId): void
{
$this->saveSetting($this->getSystemMode() . 'ApplePayPaymentKeyId', $paymentKeyId);
}
- /**
- * @param string $certificateId
- * @return void
- */
public function saveApplePayPaymentCertificateId(string $certificateId): void
{
$this->saveSetting($this->getSystemMode() . 'ApplePayPaymentCertificateId', $certificateId);
}
- /**
- * @return string
- */
public function getApplePayPaymentKeyId(): string
{
/** @var string $paymentKeyId */
@@ -384,9 +309,6 @@ public function getApplePayPaymentKeyId(): string
return $paymentKeyId;
}
- /**
- * @return string
- */
public function getApplePayPaymentCertificateId(): string
{
/** @var string $certificateId */
@@ -394,27 +316,28 @@ public function getApplePayPaymentCertificateId(): string
return $certificateId;
}
- /**
- * @param array $networks
- * @return void
- */
+ public function getApplePayPaymentCert(): string
+ {
+ $path = $this->getApplePayPaymentCertFilePath();
+ if (file_exists($path)) {
+ /** @var string $fileContest */
+ $fileContest = file_get_contents($path);
+ return $fileContest;
+ }
+
+ return '';
+ }
+
public function saveApplePayNetworks(array $networks): void
{
$this->saveSetting('applepay_networks', $networks);
}
- /**
- * @param array $webhookConfig
- * @return void
- */
public function saveWebhookConfiguration(array $webhookConfig): void
{
$this->moduleSettingBridge->save('webhookConfiguration', $webhookConfig, Module::MODULE_ID);
}
- /**
- * @return array
- */
public function getWebhookConfiguration(): array
{
/** @var array $webhookConfig */
@@ -422,9 +345,6 @@ public function getWebhookConfiguration(): array
return $webhookConfig;
}
- /**
- * @return array
- */
public function getPrivateKeysWithContext(): array
{
$privateKeys = [];
@@ -453,12 +373,7 @@ public function getPrivateKeysWithContext(): array
return $privateKeys;
}
- /**
- * @param string $name
- * @param bool|int|string|array $setting
- * @return void
- */
- private function saveSetting(string $name, $setting): void
+ private function saveSetting(string $name, bool|int|string|array $setting): void
{
$this->moduleSettingBridge->save($name, $setting, Module::MODULE_ID);
}
@@ -475,21 +390,13 @@ private function getSettingValue(string $key): mixed
}
/**
- * Intended to be used as callback function
- *
- * @param bool|int|string $active
- * @return bool
- *
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
*/
- private function isActiveSetting($active): bool
+ private function isActiveSetting(string $active): bool
{
return $active === '1';
}
- /**
- * @return bool
- */
public function isStandardEligibility(): bool
{
return (
@@ -517,9 +424,6 @@ public function isB2BEligibility(): bool
return !empty($userCompany);
}
- /**
- * @return bool
- */
public function isInvoiceEligibility(): bool
{
return (
@@ -533,9 +437,6 @@ public function isInvoiceEligibility(): bool
);
}
- /**
- * @return bool
- */
public function isB2CInvoiceEligibility(): bool
{
return (
@@ -564,9 +465,6 @@ public function isB2CInstallmentEligibility(): bool
);
}
- /**
- * @return bool
- */
public function isB2BInvoiceEligibility(): bool
{
return (
diff --git a/src/Service/Payment.php b/src/Service/Payment.php
index 1ca406da..9611f0ad 100644
--- a/src/Service/Payment.php
+++ b/src/Service/Payment.php
@@ -442,14 +442,11 @@ public function doUnzerCollect(
return true;
}
- /**
- * @param UnzerOrderModel|null $oOrder
- * @param string $unzerid
- * @param float $amount
- * @return UnzerApiException|bool
- */
- public function doUnzerAuthorizationCancel($oOrder, $unzerid, $amount)
- {
+ public function doUnzerAuthorizationCancel(
+ UnzerOrderModel|null $oOrder,
+ string $unzerid,
+ float $amount
+ ): UnzerApiException|bool {
if (!($oOrder instanceof Order)) {
return false;
}
@@ -475,14 +472,12 @@ public function doUnzerAuthorizationCancel($oOrder, $unzerid, $amount)
}
/**
- * @param UnzerOrderModel|null $oOrder
- * @param string $sPaymentId
- * @return UnzerApiException|bool
- *
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
- public function sendShipmentNotification($oOrder, $sPaymentId = null)
- {
+ public function sendShipmentNotification(
+ ?Order $oOrder,
+ string $sPaymentId = null
+ ): Exception|bool|UnzerApiException {
if (!($oOrder instanceof Order)) {
return false;
}
@@ -545,11 +540,7 @@ public function sendShipmentNotification($oOrder, $sPaymentId = null)
return $blSuccess;
}
- /**
- * @param \UnzerSDK\Resources\Payment $unzerPayment
- * @return BasePaymentType|AbstractUnzerResource The updated PaymentType object.
- */
- public function setInstallmentDueDate($unzerPayment)
+ public function setInstallmentDueDate(UnzerPayment $unzerPayment): BasePaymentType|AbstractUnzerResource
{
/** @var InstallmentSecured $installment */
$installment = $unzerPayment->getPaymentType();
@@ -573,9 +564,6 @@ public function getTomorrowsTimestamp(): string
return date('Y-m-d', strtotime("+1 days"));
}
- /**
- * @return bool
- */
public function isPdfSession(): bool
{
return (bool)Registry::getRequest()->getRequestParameter('pdfConfirm', '0');
diff --git a/src/Service/PrePaymentBankAccountService.php b/src/Service/PrePaymentBankAccountService.php
index 7b384bba..fd75f655 100644
--- a/src/Service/PrePaymentBankAccountService.php
+++ b/src/Service/PrePaymentBankAccountService.php
@@ -39,6 +39,13 @@ public function persistBankAccountInfo(Charge $charge): void
$charge->getHolder()
);
}
+
+ if ($charge->getDescriptor()) {
+ $this->session->setVariable(
+ $this->getSessionVariableName($orderId, 'descriptor'),
+ $charge->getHolder()
+ );
+ }
}
public function getIban(string $unzerOrderNumber): ?string
@@ -53,7 +60,22 @@ public function getBic(string $unzerOrderNumber): ?string
public function getHolder(string $unzerOrderNumber): ?string
{
- return $this->getSessionVariableStringValue($unzerOrderNumber, 'holder');
+ return $this->getStringVarFromSession(
+ $this->getSessionVariableName($unzerOrderNumber, 'holder')
+ );
+ }
+
+ public function getDescriptor(string $unzerOrderNumber): ?string
+ {
+ return $this->getStringVarFromSession(
+ $this->getSessionVariableName($unzerOrderNumber, 'descriptor')
+ );
+ }
+
+ private function getStringVarFromSession(string $varName): string
+ {
+ $result = $this->session->getVariable($varName);
+ return is_string($result) ? $result : '';
}
private function getSessionVariableName(string $unzerOrderNumber, string $variableName): string
diff --git a/src/Service/Transaction.php b/src/Service/Transaction.php
index 298d2874..11c46e83 100644
--- a/src/Service/Transaction.php
+++ b/src/Service/Transaction.php
@@ -15,7 +15,7 @@
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface;
use OxidSolutionCatalysts\Unzer\Exception\UnzerException;
-use OxidSolutionCatalysts\Unzer\Model\Order;
+use OxidEsales\Eshop\Application\Model\Order;
use OxidSolutionCatalysts\Unzer\Traits\ServiceContainer;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Registry;
diff --git a/src/Traits/Request.php b/src/Traits/Request.php
new file mode 100644
index 00000000..9e735e7b
--- /dev/null
+++ b/src/Traits/Request.php
@@ -0,0 +1,71 @@
+getRequestEscapedParameter($varName, $defaultValue);
+ return is_string($value) ? $value : '';
+ }
+
+ protected function getUnzerStringRequestParameter(string $varName, string $defaultValue = ''): string
+ {
+ /** @phpstan-ignore argument.type */
+ $value = Registry::getRequest()->getRequestParameter($varName, $defaultValue);
+ return is_string($value) ? $value : '';
+ }
+
+ protected function getUnzerArrayRequestParameter(string $varName, array $defaultValue = []): array
+ {
+ /** @phpstan-ignore argument.type */
+ $value = Registry::getRequest()->getRequestParameter($varName, $defaultValue);
+ return is_array($value) ? $value : [];
+ }
+
+ protected function getUnzerFloatRequestParameter(string $varName, float $defaultValue = 0.0): float
+ {
+ /** @phpstan-ignore argument.type */
+ $value = Registry::getRequest()->getRequestParameter($varName, $defaultValue);
+ $value = is_string($value) ? $this->normalizeNumber($value) : $value;
+ return is_numeric($value) ? (float) $value : 0.0;
+ }
+
+ /**
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
+ */
+ protected function getUnzerBoolRequestParameter(string $varName, bool $defaultValue = false): bool
+ {
+ /** @phpstan-ignore argument.type */
+ $value = Registry::getRequest()->getRequestParameter($varName, $defaultValue);
+ return (bool)$value;
+ }
+
+ private function normalizeNumber(string $input): float
+ {
+ $input = str_replace(' ', '', $input);
+ $lastCommaPos = strrpos($input, ',');
+ $number = $input;
+ if ($lastCommaPos !== false) {
+ if (strpos($number, '.', $lastCommaPos) === false) {
+ $number = substr_replace($input, '.', $lastCommaPos, 1);
+ }
+ $number = str_replace(',', '', $number);
+ }
+
+ return (float)$number;
+ }
+}
diff --git a/tests/Integration/Core/ShopControlTest.php b/tests/Integration/Core/ShopControlTest.php
deleted file mode 100644
index 21dde87b..00000000
--- a/tests/Integration/Core/ShopControlTest.php
+++ /dev/null
@@ -1,98 +0,0 @@
-createPartialMock(ShopControl::class, ['isAdmin', 'logException']);
- $mock->method('isAdmin')->willThrowException($someException);
-
- $this->addToAssertionCount(1);
- $mock->expects($this->once())->method('logException')->with($someException);
-
- $mock->start();
- }
-
- public function customStandardExceptionTestDataProvider(): array
- {
- return [
- [UnzerException::class],
- [StandardException::class]
- ];
- }
-
- public function testHandleRedirectException(): void
- {
- $redirectDestination = 'someDestination';
-
- class_alias(
- \OxidEsales\Eshop\Core\ShopControl::class,
- 'OxidSolutionCatalysts\Unzer\Core\ShopControl_parent'
- );
- $mock = $this->createPartialMock(ShopControl::class, ['isAdmin']);
- $mock->method('isAdmin')->willThrowException(new Redirect($redirectDestination));
-
- $utilsMock = $this->createPartialMock(Utils::class, ['redirect']);
- $utilsMock->expects($this->once())
- ->method('redirect')
- ->with($redirectDestination)
- ->willReturn('ok');
- Registry::set(Utils::class, $utilsMock);
-
- $mock->start();
- }
-
- public function testHandleMessageRedirectException(): void
- {
- $redirectDestination = 'someDestination';
-
- class_alias(
- \OxidEsales\Eshop\Core\ShopControl::class,
- 'OxidSolutionCatalysts\Unzer\Core\ShopControl_parent'
- );
- $mock = $this->createPartialMock(ShopControl::class, ['isAdmin']);
- $mock->method('isAdmin')->willThrowException(
- new RedirectWithMessage($redirectDestination, 'MESSAGE', ['param1'])
- );
-
- $utilsMock = $this->createPartialMock(Utils::class, ['redirect']);
- $utilsMock->expects($this->once())
- ->method('redirect')
- ->with($redirectDestination)
- ->willReturn('ok');
- Registry::set(Utils::class, $utilsMock);
-
- $utilsViewMock = $this->createPartialMock(UtilsView::class, ['addErrorToDisplay']);
- $utilsViewMock->expects($this->once())
- ->method('addErrorToDisplay');
- Registry::set(UtilsView::class, $utilsViewMock);
-
- $mock->start();
- }
-}
diff --git a/tests/PhpMd/standard.xml b/tests/PhpMd/standard.xml
index 78ab9667..92e15880 100644
--- a/tests/PhpMd/standard.xml
+++ b/tests/PhpMd/standard.xml
@@ -35,5 +35,5 @@
-