diff --git a/.github/workflows/coding-standard.yml b/.github/workflows/coding-standard.yml index 0b8bee405..4ae22078a 100644 --- a/.github/workflows/coding-standard.yml +++ b/.github/workflows/coding-standard.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest continue-on-error: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: extdn/github-actions-m2/magento-coding-standard/8.1@master with: phpcs_severity: 10 @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest continue-on-error: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: extdn/github-actions-m2/magento-mess-detector@master phpstan: @@ -26,7 +26,47 @@ jobs: runs-on: ubuntu-latest continue-on-error: true steps: - - uses: actions/checkout@v2 - - uses: extdn/github-actions-m2/magento-phpstan@master + - name: Setup PHP + uses: shivammathur/setup-php@v2 with: - composer_name: buckaroo/magento2 + php-version: 8.1 + tools: composer:v2 + + - uses: actions/checkout@v3 + + - name: Validate composer json + run: composer validate + + - name: Clear Composer cache + run: composer clear-cache + + - name: Setup Magento + run: | + pull_number=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH") + url="https://api.github.com/repos/buckaroo-it/Magento2/pulls/$pull_number/files" + echo $url + curl $url > files_changed + cat files_changed | grep '"filename"' | sed 's/\"filename\"\: \"//' | sed 's/\",//' | xargs ls + echo '{"http-basic": {"repo.magento.com": {"username": "${{ secrets.REPO_USERNAME }}","password": "${{ secrets.REPO_PASS }}"}}}' > auth.json + composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.6-p2 ~/m246 + mkdir -p ~/m246/app/code/Buckaroo/Magento2/ + rsync -r --exclude='m246' ./ ~/m246/app/code/Buckaroo/Magento2/ + cd ~/m246 + bin/magento module:enable --all + bin/magento setup:di:compile + + - name: Install PHPStan + run: | + cd ~/m246 + composer require --dev phpstan/phpstan:^1.10 + ls -la vendor/bin/ + + - name: Install Buckaroo SDK + run: | + cd ~/m246 + composer require buckaroo/sdk + + - name: Run PHPStan + run: | + cd ~/m246 + vendor/bin/phpstan analyse --level 1 app/code/Buckaroo/Magento2/ -c dev/tests/static/testsuite/Magento/Test/Php/_files/phpstan/phpstan.neon \ No newline at end of file diff --git a/.github/workflows/icons.yml b/.github/workflows/icons.yml index 0b3c9df64..ef0aaf7f3 100644 --- a/.github/workflows/icons.yml +++ b/.github/workflows/icons.yml @@ -1,9 +1,9 @@ name: Icon update on: push: - branches: [ develop ] + branches: [develop, feature/payment_provider_gateway] pull_request: - branches: [ develop ] + branches: [develop, feature/payment_provider_gateway] workflow_dispatch: jobs: build: @@ -22,7 +22,7 @@ jobs: - name: Copy payment method icons run: | cd "${{ github.workspace }}/Media/Payment methods/SVG/" - rm -f ideal-qr.svg knaken.svg paylink.svg paybybank.svg pos-nfc.svg riverty.svg + rm -f ideal-qr.svg paybybank.svg pos-nfc.svg riverty.svg cd ${{ github.workspace }}/Media cp -R "Payment methods/SVG/." ${{ github.workspace }}/view/base/web/images/svg/ - name: Copy creditcards icons @@ -35,11 +35,15 @@ jobs: rm -f vvvlekkerweg.svg vvvshopchill.svg cd ${{ github.workspace }}/Media cp -R "Giftcards/SVG/." ${{ github.workspace }}/view/base/web/images/giftcards/ - - name: Copy payment issuers icons run: | cd Media cp -R "iDEAL bank issuers/SVG/." ${{ github.workspace }}/view/base/web/images/ideal/ + - name: Copy Identification methods icons + run: | + cd "${{ github.workspace }}/Media/Identification methods/SVG/" + rm -f pim.svg + cp -R ./. ${{ github.workspace }}/view/base/web/images/ - name: Cleanup run: | rm -rd Media diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 3e5c7300a..178d62a9b 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -27,10 +27,10 @@ jobs: ES_JAVA_OPTS: "-Xms64m -Xmx512m" options: --health-cmd="curl localhost:9200/_cluster/health?wait_for_status=yellow&timeout=60s" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - - uses: actions/checkout@v2 - - name: M2 Integration Tests with Magento 2 (Php 7.4) - uses: extdn/github-actions-m2/magento-integration-tests/7.4@master + - uses: actions/checkout@v3 + - name: M2 Integration Tests with Magento 2 (Php 8.1) + uses: extdn/github-actions-m2/magento-integration-tests/8.1@master with: module_name: Buckaroo_Magento2 composer_name: buckaroo/magento2 - ce_version: '2.4.0' + ce_version: '2.4.6' diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d67294eae..1854707f1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ jobs: - name: setup php uses: shivammathur/setup-php@v2 with: - php-version: 7.3 + php-version: 8.1 tools: composer:v2 - uses: actions/checkout@v2 - name: validate composer json @@ -33,11 +33,11 @@ jobs: curl $url > files_changed cat files_changed | grep '"filename"' | sed 's/\"filename\"\: \"//' | sed 's/\",//' | xargs ls echo '{"http-basic": {"repo.magento.com": {"username": "${{ secrets.REPO_USERNAME }}","password": "${{ secrets.REPO_PASS }}"}}}' > auth.json - composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.3.6 m23 - mkdir -p m23/app/code/Buckaroo/Magento2/ - rsync -r --exclude='m23' ./ m23/app/code/Buckaroo/Magento2/ - cat files_changed | grep '"filename"' | sed 's/\"filename\"\: \"//' | sed 's/\",//' | xargs ./m23/vendor/bin/phpcs --standard=Magento2 - cd m23 + composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.4 m244 + mkdir -p m244/app/code/Buckaroo/Magento2/ + rsync -r --exclude='m244' ./ m244/app/code/Buckaroo/Magento2/ + cat files_changed | grep '"filename"' | sed 's/\"filename\"\: \"//' | sed 's/\",//' | xargs ./m244/vendor/bin/phpcs --standard=Magento2 + cd m244 bin/magento module:enable --all bin/magento setup:di:compile vendor/phpunit/phpunit/phpunit -c dev/tests/unit/phpunit.xml.dist app/code/Buckaroo/Magento2 diff --git a/.github/workflows/rename-icons.php b/.github/workflows/rename-icons.php index 3def83c20..adeb6ffba 100644 --- a/.github/workflows/rename-icons.php +++ b/.github/workflows/rename-icons.php @@ -7,7 +7,10 @@ ); foreach ($di as $name => $fio) { - $newname = $fio->getPath() . DIRECTORY_SEPARATOR . strtolower(str_replace(" ","",str_replace("&","-",$fio->getFilename()))); + $newname = $fio->getPath() + . DIRECTORY_SEPARATOR + . strtolower(str_replace(" ", "", str_replace("&", "-", $fio->getFilename()))); + // phpcs:ignore Magento2.Security.LanguageConstruct.DirectOutput echo $newname, "\r\n"; rename($name, $newname); } diff --git a/.github/workflows/sonarqube_pr_analysis.yml b/.github/workflows/sonarqube_pr_analysis.yml index 0115a6e3c..be31a8790 100644 --- a/.github/workflows/sonarqube_pr_analysis.yml +++ b/.github/workflows/sonarqube_pr_analysis.yml @@ -1,9 +1,8 @@ on: push: branches: - - master - - develop - - 'releases/**' + - feature/payment_provider_gateway + - sonarqube-refactor-fixes pull_request: types: [opened, synchronize, reopened] @@ -19,4 +18,4 @@ jobs: uses: sonarsource/sonarqube-scan-action@master env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} \ No newline at end of file + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} diff --git a/Api/AddressHandlerInterface.php b/Api/AddressHandlerInterface.php new file mode 100644 index 000000000..918f6daaa --- /dev/null +++ b/Api/AddressHandlerInterface.php @@ -0,0 +1,40 @@ +groupTransaction = $groupTransaction; + $this->giftcardCollection = $giftcardCollection; + $this->logoService = $logoService; + } + + /** + * @inheritdoc + */ + protected function _construct() + { + parent::_construct(); + $this->setTemplate('Buckaroo_Magento2::info/payment_method.phtml'); + } + + /** + * Get giftcards + * + * @return array + * @throws LocalizedException + */ + public function getGiftCards() + { + $result = []; + + if ($this->getInfo()->getOrder() && $this->getInfo()->getOrder()->getIncrementId()) { + $items = $this->groupTransaction->getGroupTransactionItems($this->getInfo()->getOrder()->getIncrementId()); + foreach ($items as $giftcard) { + if ($foundGiftcard = $this->giftcardCollection + ->getItemByColumnValue('servicecode', $giftcard['servicecode']) + ) { + $result[] = [ + 'code' => $giftcard['servicecode'], + 'label' => $foundGiftcard['label'], + ]; + } + + if ($giftcard['servicecode'] == 'buckaroovoucher') { + $result[] = [ + 'code' => $giftcard['servicecode'], + 'label' => 'Buckaroo Voucher', + ]; + } + } + } + + return $result; + } + + /** + * Get PayPerEmail label payment method + * + * @return array|false + * @throws LocalizedException + */ + public function getPayPerEmailMethod() + { + $payment = $this->getInfo()->getOrder()->getPayment(); + if ($payment->getAdditionalInformation('isPayPerEmail')) { + return [ + 'label' => __('Buckaroo PayPerEmail'), + ]; + } + return false; + } + + /** + * Get payment method logo + * + * @param string $method + * @return string + */ + public function getPaymentLogo(string $method): string + { + return $this->logoService->getPayment($method); + } + + /** + * Get giftcard logo url by code + * + * @param string $code + * @return string + */ + public function getGiftcardLogo(string $code): string + { + return $this->logoService->getGiftcardLogo($code); + } + + /** + * Get creditcard logo by code + * + * @param string $code + * @return string + */ + public function getCreditcardLogo(string $code): string + { + return $this->logoService->getCreditcard($code); + } + + /** + * Get Specific Payment Details set on Success Push to display on Payment Order Information + * + * @return array + * @throws LocalizedException + */ + public function getSpecificPaymentDetails(): array + { + $details = $this->getInfo()->getAdditionalInformation('specific_payment_details'); + + if (!$details || !is_array($details)) { + return []; + } + + $transformedKeys = array_map([$this, 'getLabel'], array_keys($details)); + $transformedValues = array_map(function ($value) { + return $this->getValueView('', (string)$value); + }, $details); + + return array_combine($transformedKeys, $transformedValues); + } + + /** + * Prepare information specific to current payment method + * + * @param null|DataObject|array $transport + * @return DataObject + * @throws LocalizedException + */ + protected function _prepareSpecificInformation($transport = null): DataObject + { + $transport = parent::_prepareSpecificInformation($transport); + if ($transferDetails = $this->getInfo()->getAdditionalInformation('transfer_details')) { + foreach ($transferDetails as $key => $transferDetail) { + $transport->setData( + (string)$this->getLabel($key), + $this->getValueView($key, $transferDetail) + ); + } + } + return $transport; + } + + /** + * Returns label + * + * @param string $field + * @return Phrase + */ + protected function getLabel($field) + { + $words = explode('_', $field); + $transformedWords = array_map('ucfirst', $words); + return __(implode(' ', $transformedWords)); + } + + /** + * Sets data to transport + * + * @param \Magento\Framework\DataObject $transport + * @param string $field + * @param string|array $value + * @return void + */ + protected function setDataToTransfer( + \Magento\Framework\DataObject $transport, + $field, + $value + ) { + if (is_array($value)) { + foreach ($value as $key => $val) { + $transport->setData( + (string)$this->getLabel($key), + (string)$this->getValueView( + $key, + $val + ) + ); + } + } else { + $transport->setData( + (string)$this->getLabel($field), + (string)$this->getValueView( + $field, + $value + ) + ); + } + } +} diff --git a/Block/Adminhtml/Config/Support/BodyClass.php b/Block/Adminhtml/Config/Support/BodyClass.php index cca23a80a..7da0d6438 100644 --- a/Block/Adminhtml/Config/Support/BodyClass.php +++ b/Block/Adminhtml/Config/Support/BodyClass.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,6 +17,7 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Block\Adminhtml\Config\Support; use Magento\Backend\Block\Template; @@ -32,7 +33,7 @@ class BodyClass extends Template implements BlockInterface /** * @param Context $context - * @param array $data + * @param array $data */ public function __construct(Context $context, array $data = []) { diff --git a/Block/Adminhtml/Config/Support/SupportTab.php b/Block/Adminhtml/Config/Support/SupportTab.php index 57d61a2fb..06a72565f 100644 --- a/Block/Adminhtml/Config/Support/SupportTab.php +++ b/Block/Adminhtml/Config/Support/SupportTab.php @@ -1,12 +1,13 @@ ['7.3' => ['+'], '7.4' => ['+']], + /** + * @var array + */ + private array $phpVersionSupport = [ '2.4' => ['7.4' => ['+'], '8.1' => ['+'], '8.2' => ['+']], ]; /** - * @var \Magento\Framework\Setup\ModuleContextInterface + * @var SoftwareData */ - private $moduleContext; + private SoftwareData $softwareData; /** - * @var SoftwareData + * @var Curl */ - private $softwareData; + private Curl $curl; /** * Override the parent constructor to require our own dependencies. * - * @param \Magento\Framework\View\Element\Template\Context $context - * @param \Magento\Framework\Module\ModuleResource $moduleContext - * @param SoftwareData $softwareData - * @param array $data + * @param Context $context + * @param SoftwareData $softwareData + * @param Curl $curl + * @param array $data */ public function __construct( - \Magento\Framework\View\Element\Template\Context $context, - \Magento\Framework\Module\ModuleResource $moduleContext, + Context $context, SoftwareData $softwareData, + Curl $curl, array $data = [] ) { parent::__construct($context, $data); - $this->moduleContext = $moduleContext; $this->softwareData = $softwareData; + $this->curl = $curl; } /** - * @param AbstractElement $element + * Render form element as HTML * + * @param AbstractElement $element * @return string */ - public function render(AbstractElement $element) + public function render(AbstractElement $element): string { /** * @noinspection PhpUndefinedMethodInspection + * @phpstan-ignore-next-line */ $this->setElement($element); @@ -82,54 +92,87 @@ public function render(AbstractElement $element) /** * Retrieve the version number from constant * - * @return bool|false|string + * @return string */ - public function getVersionNumber() + public function getVersionNumber(): string { - $version = $this->softwareData->getModuleVersion(); - - return $version; + return $this->softwareData->getModuleVersion(); } /** - * @return bool|int + * PHP Version Check + * + * @return int */ - public function phpVersionCheck() + public function phpVersionCheck(): int { + $result = -1; + $magentoVersion = $this->getMagentoVersionArray(); $phpVersion = $this->getPhpVersionArray(); - if (!is_array($magentoVersion) || !is_array($phpVersion)) { - return -1; - } + if (!empty($magentoVersion) && !empty($phpVersion)) { + $magentoMajorMinor = $magentoVersion[0] . '.' . $magentoVersion[1]; + $phpMajorMinor = $phpVersion[0] . '.' . $phpVersion[1]; + $phpPatch = (int)$phpVersion[2]; - $magentoMajorMinor = $magentoVersion[0] . '.' . $magentoVersion[1]; - $phpMajorMinor = $phpVersion[0] . '.' . $phpVersion[1]; - $phpPatch = (int) $phpVersion[2]; - - if (!isset($this->phpVersionSupport[$magentoMajorMinor]) || - !isset($this->phpVersionSupport[$magentoMajorMinor][$phpMajorMinor])) { - return 0; + if (isset($this->phpVersionSupport[$magentoMajorMinor][$phpMajorMinor])) { + $currentVersion = $this->phpVersionSupport[$magentoMajorMinor][$phpMajorMinor]; + $result = $this->checkPhpCompatibility($currentVersion, $phpPatch); + } else { + $result = 0; + } } - $currentVersion = $this->phpVersionSupport[$magentoMajorMinor][$phpMajorMinor]; - if (isset($currentVersion)) { + return $result; + } - if (in_array($phpPatch, $currentVersion)) { - return true; - } elseif (in_array('+', $currentVersion) && $phpPatch >= max($currentVersion)) { - return true; + /** + * Check PHP Compatibility + * + * @param $currentVersion + * @param $phpPatch + * @return int + */ + private function checkPhpCompatibility($currentVersion, $phpPatch): int + { + if (!empty($currentVersion)) { + if (in_array($phpPatch, $currentVersion) || + (in_array('+', $currentVersion) && $phpPatch >= max($currentVersion))) { + return 1; } else { - return false; + return 0; } } return -1; } - public function getPhpVersionArray() + /** + * Get Magento Versions + * + * @return array + */ + private function getMagentoVersionArray(): array { - $version = false; + $version = []; + $currentVersion = $this->softwareData->getProductMetaData()->getVersion(); + + if (!empty($currentVersion)) { + $version = explode('.', $currentVersion); + } + + return $version; + } + + /** + * Get PHP Versions + * + * @return string[] + */ + private function getPhpVersionArray(): array + { + $version = []; if (defined('PHP_VERSION')) { $version = explode('.', PHP_VERSION); } elseif (function_exists('phpversion')) { @@ -140,31 +183,41 @@ public function getPhpVersionArray() } /** - * @return array|bool + * Get latest tag from GitHub repository + * + * @return string */ - public function getMagentoVersionArray() + public function getLatestPluginVersion(): string { - $version = false; - $currentVersion = $this->softwareData->getProductMetaData()->getVersion(); + $url = "https://api.github.com/repos/buckaroo-it/Magento2/tags"; + $this->curl->addHeader('User-Agent', 'Magento 2 Buckaroo Plugin'); + $this->curl->get($url); + $result = json_decode($this->curl->getBody(), true); - if (isset($currentVersion)) { - $version = explode('.', $currentVersion); + if (is_array($result) && isset($result[0]['name'])) { + return $result[0]['name']; } - - return $version; + return "v" . $this->getVersionNumber(); } /** - * @return array|bool + * Get all php compatible versions + * + * @return string */ - public function getMagentoVersionTidyString() + public function getPhpVersions(): string { $magentoVersion = $this->getMagentoVersionArray(); + if (empty($magentoVersion)) { + return __('Cannot determine compatible PHP versions'); + } - if (is_array($magentoVersion)) { - return $magentoVersion[0] . '.' . $magentoVersion[1]; + $magentoMajorMinor = $magentoVersion[0] . '.' . $magentoVersion[1]; + if (!isset($this->phpVersionSupport[$magentoMajorMinor])) { + return __('Cannot determine compatible PHP versions'); } - return false; + $versions = array_keys($this->phpVersionSupport[$magentoMajorMinor]); + return implode(', ', $versions); } } diff --git a/Block/Adminhtml/Form/Field/SortIssuers.php b/Block/Adminhtml/Form/Field/SortIssuers.php index 529c2a4f9..9335a3197 100644 --- a/Block/Adminhtml/Form/Field/SortIssuers.php +++ b/Block/Adminhtml/Form/Field/SortIssuers.php @@ -22,7 +22,7 @@ use Buckaroo\Magento2\Exception; use Buckaroo\Magento2\Model\ConfigProvider\Method\ConfigProviderInterface; -use Buckaroo\Magento2\Model\ConfigProvider\Method\Factory as ConfigProviderFactory; +use Buckaroo\Magento2\Model\ConfigProvider\Factory as ConfigProviderFactory; use Magento\Backend\Block\Template\Context; use Magento\Config\Block\System\Config\Form\Field; use Magento\Framework\Data\Form\Element\AbstractElement; diff --git a/Block/Adminhtml/Giftcard/Edit.php b/Block/Adminhtml/Giftcard/Edit.php index 0d0624fcf..3d74d71af 100644 --- a/Block/Adminhtml/Giftcard/Edit.php +++ b/Block/Adminhtml/Giftcard/Edit.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,30 +20,53 @@ namespace Buckaroo\Magento2\Block\Adminhtml\Giftcard; +use Buckaroo\Magento2\Api\Data\BuckarooGiftcardDataInterface; use Magento\Backend\Block\Widget\Context; -use Magento\Framework\Registry; +use Magento\Backend\Block\Widget\Form\Container; -class Edit extends \Magento\Backend\Block\Widget\Form\Container +class Edit extends Container { /** - * @var Registry + * @var BuckarooGiftcardDataInterface */ - protected $_coreRegistry = null; + protected BuckarooGiftcardDataInterface $buckarooGiftcardData; /** - * @param Context $context - * @param Registry $registry - * @param array $data + * @param Context $context + * @param BuckarooGiftcardDataInterface $buckarooGiftcardData + * @param array $data */ public function __construct( Context $context, - Registry $registry, + BuckarooGiftcardDataInterface $buckarooGiftcardData, array $data = [] ) { - $this->_coreRegistry = $registry; + $this->buckarooGiftcardData = $buckarooGiftcardData; parent::__construct($context, $data); } + /** + * Get header text + * + * @return \Magento\Framework\Phrase + */ + public function getHeaderText() + { + $giftcard = $this->buckarooGiftcardData->getGiftcardModel() ?? null; + + if ($giftcard && $giftcard->getId()) { + $giftcardTitle = $this->escapeHtml($giftcard->getLabel()); + return __("Edit Giftcard '%s'", $giftcardTitle); + } else { + return __('Add Giftcard'); + } + } + + /** + * Initialize form. + * + * @return void + */ protected function _construct() { $this->_objectId = 'entity_id'; @@ -58,12 +81,12 @@ protected function _construct() $this->buttonList->add( 'saveandcontinue', [ - 'label' => __('Save and Continue'), - 'class' => 'save', + 'label' => __('Save and Continue'), + 'class' => 'save', 'data_attribute' => [ 'mage-init' => [ 'button' => [ - 'event' => 'saveAndContinueEdit', + 'event' => 'saveAndContinueEdit', 'target' => '#edit_form' ] ] @@ -71,19 +94,4 @@ protected function _construct() ] ); } - - /** - * @return \Magento\Framework\Phrase - */ - public function getHeaderText() - { - $registry = $this->_coreRegistry->registry('buckaroo_giftcard'); - - if ($registry->getId()) { - $giftcardTitle = $this->escapeHtml($registry->getLabel()); - return __("Edit Giftcard '%s'", $giftcardTitle); - } else { - return __('Add Giftcard'); - } - } } diff --git a/Block/Adminhtml/Giftcard/Edit/Form.php b/Block/Adminhtml/Giftcard/Edit/Form.php index 601759a13..ebee58c01 100644 --- a/Block/Adminhtml/Giftcard/Edit/Form.php +++ b/Block/Adminhtml/Giftcard/Edit/Form.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,20 +20,48 @@ namespace Buckaroo\Magento2\Block\Adminhtml\Giftcard\Edit; +use Buckaroo\Magento2\Api\Data\BuckarooGiftcardDataInterface; use Buckaroo\Magento2\Model\Giftcard\Request\Giftcard; +use Magento\Backend\Block\Template\Context; +use Magento\Backend\Block\Widget\Form\Generic; +use Magento\Framework\Data\FormFactory; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Registry; -class Form extends \Magento\Backend\Block\Widget\Form\Generic +class Form extends Generic { /** + * @var BuckarooGiftcardDataInterface + */ + private BuckarooGiftcardDataInterface $buckarooGiftcardData; + + /** + * @param Context $context + * @param Registry $registry + * @param FormFactory $formFactory + * @param BuckarooGiftcardDataInterface $buckarooGiftcardData + * @param array $data + */ + public function __construct( + Context $context, + Registry $registry, + FormFactory $formFactory, + BuckarooGiftcardDataInterface $buckarooGiftcardData, + array $data = [] + ) { + $this->buckarooGiftcardData = $buckarooGiftcardData; + parent::__construct($context, $registry, $formFactory, $data); + } + + /** + * Edit Giftcards Form + * * @return $this - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ protected function _prepareForm() { - /** - * @var \Buckaroo\Magento2\Model\Giftcard $model - */ - $model = $this->_coreRegistry->registry('buckaroo_giftcard'); + $model = $this->buckarooGiftcardData->getGiftcardModel(); /** * @var \Magento\Framework\Data\Form $form @@ -41,7 +69,7 @@ protected function _prepareForm() $form = $this->_formFactory->create( [ 'data' => [ - 'id' => 'edit_form', + 'id' => 'edit_form', 'enctype' => 'multipart/form-data', 'action' => $this->getData('action'), 'method' => 'post' @@ -69,10 +97,10 @@ protected function _prepareForm() 'servicecode', 'text', [ - 'name' => 'servicecode', - 'label' => __('Service Code'), + 'name' => 'servicecode', + 'label' => __('Service Code'), 'required' => true, - 'value' => $model->getServicecode() + 'value' => $model->getServicecode() ] ); @@ -80,10 +108,10 @@ protected function _prepareForm() 'label', 'text', [ - 'name' => 'label', - 'label' => __('Label'), + 'name' => 'label', + 'label' => __('Label'), 'required' => true, - 'value' => $model->getLabel() + 'value' => $model->getLabel() ] ); @@ -110,7 +138,8 @@ protected function _prepareForm() 'title' => __('Giftcard logo'), 'label' => __('Giftcard logo'), 'name' => 'logo', - 'note' => 'Allow image type: jpg, jpeg, gif, png'] + 'note' => 'Allow image type: jpg, jpeg, gif, png' + ] ); $form->setValues($model->getData()); diff --git a/Block/Adminhtml/Giftcard/Grid.php b/Block/Adminhtml/Giftcard/Grid.php index fb6837f76..3d5776527 100644 --- a/Block/Adminhtml/Giftcard/Grid.php +++ b/Block/Adminhtml/Giftcard/Grid.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,7 +20,9 @@ namespace Buckaroo\Magento2\Block\Adminhtml\Giftcard; -class Grid extends \Magento\Backend\Block\Widget\Grid\Container +use Magento\Backend\Block\Widget\Grid\Container; + +class Grid extends Container { protected function _construct() { diff --git a/Block/Adminhtml/Giftcard/Sort.php b/Block/Adminhtml/Giftcard/Sort.php index 57883d08e..e63ee12e8 100644 --- a/Block/Adminhtml/Giftcard/Sort.php +++ b/Block/Adminhtml/Giftcard/Sort.php @@ -1,13 +1,12 @@ setTemplate('Buckaroo_Magento2::giftcards_sort_widget.phtml'); + } + /** * Return element html * - * @param AbstractElement $element + * @param AbstractElement $element * @return string + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ protected function _getElementHtml(AbstractElement $element) { return $this->_toHtml(); } + /** + * Get sorted giftcards + * + * @return mixed + */ public function getConfigGiftCardsSort() { return $this->helperData->getConfigGiftCardsSort(); diff --git a/Block/Adminhtml/Grid/Renderer/Image.php b/Block/Adminhtml/Grid/Renderer/Image.php index b6bf58470..c87c0241c 100644 --- a/Block/Adminhtml/Grid/Renderer/Image.php +++ b/Block/Adminhtml/Grid/Renderer/Image.php @@ -1,13 +1,12 @@ _authorization = $context->getAuthorization(); } + /** + * Renders grid column + * + * @param DataObject $row + * @return string + * @throws NoSuchEntityException + */ public function render(DataObject $row) { if ($img = $row['logo']) { @@ -47,5 +63,7 @@ public function render(DataObject $row) ); return ''; } + + return ''; } } diff --git a/Block/Adminhtml/Sales/Order/Creditmemo/Create/BankFields.php b/Block/Adminhtml/Sales/Order/Creditmemo/Create/BankFields.php index 6fbe80024..7c6eaa317 100644 --- a/Block/Adminhtml/Sales/Order/Creditmemo/Create/BankFields.php +++ b/Block/Adminhtml/Sales/Order/Creditmemo/Create/BankFields.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,33 +20,33 @@ namespace Buckaroo\Magento2\Block\Adminhtml\Sales\Order\Creditmemo\Create; -class BankFields extends \Magento\Backend\Block\Template -{ - - protected $orderPaymentBlock = 'order_payment'; +use Buckaroo\Magento2\Model\RefundFieldsFactory; +use Magento\Backend\Block\Template; +use Magento\Backend\Block\Template\Context; +use Magento\Framework\Exception\LocalizedException; +use Magento\Sales\Block\Adminhtml\Order\Payment; +class BankFields extends Template +{ /** - * @var \Buckaroo\Magento2\Model\RefundFieldsFactory + * @var string */ - protected $refundFieldsFactory; + protected $orderPaymentBlock = 'order_payment'; /** - * @var \Buckaroo\Magento2\Gateway\Http\TransactionBuilderFactory + * @var RefundFieldsFactory */ - protected $transactionBuilder; + protected $refundFieldsFactory; /** - * @param \Magento\Backend\Block\Template\Context $context - * @param \Buckaroo\Magento2\Gateway\Http\TransactionBuilderFactory $transactionBuilderFactory - * @param \Buckaroo\Magento2\Model\RefundFieldsFactory $refundFieldsFactory + * @param Context $context + * @param RefundFieldsFactory|null $refundFieldsFactory */ public function __construct( - \Magento\Backend\Block\Template\Context $context, - \Buckaroo\Magento2\Gateway\Http\TransactionBuilderFactory $transactionBuilderFactory = null, - \Buckaroo\Magento2\Model\RefundFieldsFactory $refundFieldsFactory = null + Context $context, + RefundFieldsFactory $refundFieldsFactory = null ) { $this->refundFieldsFactory = $refundFieldsFactory; - $this->transactionBuilder = $transactionBuilderFactory; parent::__construct($context); } @@ -54,6 +54,7 @@ public function __construct( * Get the payment method and dynamically find which extra fields (if any) need to be shown. * * @return array + * @throws LocalizedException */ public function getExtraFields() { @@ -61,8 +62,8 @@ public function getExtraFields() $paymentMethod = $this->getPaymentMethod(); /** - * If no payment method is found, return the empty array. - */ + * If no payment method is found, return the empty array. + */ if (!$paymentMethod) { return $extraFields; } @@ -74,8 +75,8 @@ public function getExtraFields() $fields = $this->refundFieldsFactory->get($paymentMethod); /** - * Parse the code and label in the same array, to keep the data paired. - */ + * Parse the code and label in the same array, to keep the data paired. + */ if ($fields) { foreach ($fields as $field) { $extraFields[$field['label']] = $field['code']; @@ -88,8 +89,8 @@ public function getExtraFields() /** * Returns the Payment Method name. If something goes wrong, this will return false. * - * @return string | false (when not found) - * @throws \Magento\Framework\Exception\LocalizedException + * @return string|false (when not found) + * @throws LocalizedException */ public function getPaymentMethod() { @@ -97,14 +98,14 @@ public function getPaymentMethod() $layout = $this->getLayout(); /** - * @var \Magento\Sales\Block\Adminhtml\Order\Payment $paymentBlock + * @var Payment $paymentBlock */ $paymentBlock = $layout->getBlock($this->orderPaymentBlock); if ($paymentBlock) { /** - * @noinspection PhpUndefinedMethodInspection - */ + * @noinspection PhpUndefinedMethodInspection + */ $paymentMethod = $paymentBlock->getPayment()->getMethod(); } diff --git a/Block/Adminhtml/Sales/Order/Creditmemo/Create/RoundingWarning.php b/Block/Adminhtml/Sales/Order/Creditmemo/Create/RoundingWarning.php index 4a33942de..7f9f7efcb 100644 --- a/Block/Adminhtml/Sales/Order/Creditmemo/Create/RoundingWarning.php +++ b/Block/Adminhtml/Sales/Order/Creditmemo/Create/RoundingWarning.php @@ -1,13 +1,12 @@ registry->registry('current_creditmemo'); + if (!$this->shouldShowWarning()) { + return ''; + } + + return parent::_toHtml(); } /** * @return bool - * @throws \LogicException - * @throws \Buckaroo\Magento2\Exception + * @throws \LogicException|Exception|LocalizedException */ protected function shouldShowWarning() { @@ -103,7 +111,7 @@ protected function shouldShowWarning() } /** - * @var \Buckaroo\Magento2\Model\Method\AbstractMethod $paymentMethodInstance + * @var \Buckaroo\Magento2\Model\Method\BuckarooAdapter $paymentMethodInstance */ $paymentMethodInstance = $payment->getMethodInstance(); @@ -126,14 +134,12 @@ protected function shouldShowWarning() } /** - * {@inheritdoc} + * Retrieve creditmemo model instance + * + * @return Creditmemo */ - protected function _toHtml() + public function getCreditmemo() { - if (!$this->shouldShowWarning()) { - return ''; - } - - return parent::_toHtml(); + return $this->registry->registry('current_creditmemo'); } } diff --git a/Block/Adminhtml/Sales/Order/Invoice/KlarnaDiscountPartialInformation.php b/Block/Adminhtml/Sales/Order/Invoice/KlarnaDiscountPartialInformation.php index 2e961c258..9298efdcd 100644 --- a/Block/Adminhtml/Sales/Order/Invoice/KlarnaDiscountPartialInformation.php +++ b/Block/Adminhtml/Sales/Order/Invoice/KlarnaDiscountPartialInformation.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,47 +17,68 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Block\Adminhtml\Sales\Order\Invoice; -class KlarnaDiscountPartialInformation extends \Magento\Framework\View\Element\Template -{ +use Buckaroo\Magento2\Model\ConfigProvider\Factory; +use Magento\Backend\Block\Template\Context; +use Magento\Framework\View\Element\Template; +use Magento\Sales\Api\Data\OrderInterface; +class KlarnaDiscountPartialInformation extends Template +{ + /** + * @var OrderInterface + */ protected $order; /** - * @var \Buckaroo\Magento2\Model\ConfigProvider\Method\Factory + * @var Factory */ protected $configProviderFactory; /** * RoundingWarning constructor. * - * @param \Magento\Sales\Api\Data\OrderInterface $order - * @param \Buckaroo\Magento2\Model\ConfigProvider\Method\Factory $configProviderFactory - * @param \Magento\Backend\Block\Template\Context $context - * @param array $data + * @param OrderInterface $order + * @param Factory $configProviderFactory + * @param Context $context + * @param array $data */ public function __construct( - \Magento\Sales\Api\Data\OrderInterface $order, - \Buckaroo\Magento2\Model\ConfigProvider\Method\Factory $configProviderFactory, - \Magento\Backend\Block\Template\Context $context, + OrderInterface $order, + Factory $configProviderFactory, + Context $context, array $data = [] ) { parent::__construct($context, $data); - $this->order = $order; + $this->order = $order; $this->configProviderFactory = $configProviderFactory; } /** + * @inheritdoc + */ + protected function _toHtml() + { + if (!$this->shouldShowWarning()) { + return ''; + } + + return parent::_toHtml(); + } + + /** + * Should show the warning regarding partial discount + * * @return bool * @throws \LogicException - * @throws \Buckaroo\Magento2\Exception */ protected function shouldShowWarning() { - if ($order_id = $this->getRequest()->getParam('order_id')) { - $order = $this->order->load($order_id); + if ($orderId = $this->getRequest()->getParam('order_id')) { + $order = $this->order->load($orderId); $payment = $order->getPayment(); /** @@ -78,16 +99,4 @@ protected function shouldShowWarning() return true; } - - /** - * {@inheritdoc} - */ - protected function _toHtml() - { - if (!$this->shouldShowWarning()) { - return ''; - } - - return parent::_toHtml(); - } } diff --git a/Block/Adminhtml/Sales/Totals.php b/Block/Adminhtml/Sales/Totals.php index ec4787963..b4731a427 100644 --- a/Block/Adminhtml/Sales/Totals.php +++ b/Block/Adminhtml/Sales/Totals.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,33 +17,42 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Block\Adminhtml\Sales; -class Totals extends \Magento\Framework\View\Element\Template +use Buckaroo\Magento2\Helper\PaymentFee; +use Magento\Framework\DataObject; +use Magento\Framework\Pricing\PriceCurrencyInterface; +use Magento\Framework\View\Element\Template; +use Magento\Framework\View\Element\Template\Context; +use Magento\Sales\Model\Order\Creditmemo; + +class Totals extends Template { /** - * @var \Buckaroo\Magento2\Helper\PaymentFee + * @var PaymentFee */ protected $helper = null; /** - * @var \Magento\Framework\Pricing\PriceCurrencyInterface + * @var PriceCurrencyInterface */ - protected $_currency; + protected $currency; + /** - * @param \Magento\Framework\View\Element\Template\Context $context - * @param \Buckaroo\Magento2\Helper\PaymentFee $helper - * @param \Magento\Framework\Pricing\PriceCurrencyInterface $currency - * @param array $data + * @param Context $context + * @param PaymentFee $helper + * @param PriceCurrencyInterface $currency + * @param array $data */ public function __construct( - \Magento\Framework\View\Element\Template\Context $context, - \Buckaroo\Magento2\Helper\PaymentFee $helper, - \Magento\Framework\Pricing\PriceCurrencyInterface $currency, + Context $context, + PaymentFee $helper, + PriceCurrencyInterface $currency, array $data = [] ) { $this->helper = $helper; - $this->_currency = $currency; + $this->currency = $currency; parent::__construct($context, $data); } @@ -55,45 +64,16 @@ public function __construct( public function initTotals() { $parent = $this->getParentBlock(); - /** - * @noinspection PhpUndefinedMethodInspection - */ $source = $parent->getSource(); $totals = $this->getTotalsForCreditmemo($source); foreach ($totals as $total) { - /** - * @noinspection PhpUndefinedMethodInspection - */ - $this->getParentBlock()->addTotalBefore(new \Magento\Framework\DataObject($total), 'grand_total'); + $this->getParentBlock()->addTotalBefore(new DataObject($total), 'grand_total'); } return $this; } - public function getTotals() - { - $parent = $this->getParentBlock(); - /** - * @noinspection PhpUndefinedMethodInspection - */ - $source = $parent->getSource(); - - - return $this->getTotalsForCreditmemo($source); - } - - /** - * Get currency symbol for current locale and currency code - * - * @return string - */ - public function getCurrentCurrencySymbol() - { - return $this->_currency->getCurrency()->getCurrencySymbol(); - } - /** - * For credit memo display the fees from invoice/order, - * check if invoice has that fee and set selected + * For credit memo display the fees from invoice/order, check if invoice has that fee and set selected * * @param mixed $source * @@ -101,45 +81,45 @@ public function getCurrentCurrencySymbol() */ protected function getTotalsForCreditmemo($source) { - if ($source instanceof \Magento\Sales\Model\Order\Creditmemo) { + if ($source instanceof Creditmemo) { $creditTotals = $this->helper->getTotals($source); $order = $source->getOrder(); $invoice = $source->getInvoice(); - $salesModel = ($invoice != null? $invoice : $order); + $salesModel = ($invoice != null ? $invoice : $order); $saleTotals = $this->helper->getTotals($salesModel); - - $saleTotals = array_map(function($saleTotal) use($creditTotals) { - if (in_array($saleTotal['code'],['buckaroo_fee', 'buckaroo_fee_excl'] )) { + + $saleTotals = array_map(function ($saleTotal) use ($creditTotals) { + if (in_array($saleTotal['code'], ['buckaroo_fee', 'buckaroo_fee_excl'])) { $saleTotal['block_name'] = "buckaroo_fee"; $saleTotal['is_selected'] = $this->isCreditmemoTotalSelected($creditTotals, $saleTotal); } return $saleTotal; }, $saleTotals); - return array_merge( $this->getTotalsByCode($creditTotals, 'buckaroo_already_paid'), $this->getTotalsExceptCode($saleTotals, 'buckaroo_already_paid') ); - } return $this->helper->getTotals($source); } - private function getTotalsByCode($totals, $code) + /** + * Get creditmemo totals + * + * @return array + */ + public function getTotals() { - return array_filter($totals, function ($total) use ($code) { - return $total['code'] === $code; - }); - } - + $parent = $this->getParentBlock(); + /** + * @noinspection PhpUndefinedMethodInspection + */ + $source = $parent->getSource(); - private function getTotalsExceptCode($totals, $code) - { - return array_filter($totals, function ($total) use ($code) { - return $total['code'] !== $code; - }); + return $this->getTotalsForCreditmemo($source); } + /** * Check if fee is in creditmemo * @@ -151,12 +131,48 @@ private function getTotalsExceptCode($totals, $code) private function isCreditmemoTotalSelected($creditTotals, $saleTotal) { foreach ($creditTotals as $creditTotal) { - if ( - isset($creditTotal['code']) && $creditTotal['code'] === $saleTotal['code'] - ) { - return true; + if (isset($creditTotal['code']) && $creditTotal['code'] === $saleTotal['code']) { + return true; } } return false; } + + /** + * Get specific totals by code + * + * @param array $totals + * @param string $code + * @return array + */ + private function getTotalsByCode($totals, $code) + { + return array_filter($totals, function ($total) use ($code) { + return $total['code'] === $code; + }); + } + + /** + * Get all totals excluding the total with the code + * + * @param array $totals + * @param string $code + * @return array + */ + private function getTotalsExceptCode($totals, $code) + { + return array_filter($totals, function ($total) use ($code) { + return $total['code'] !== $code; + }); + } + + /** + * Get currency symbol for current locale and currency code + * + * @return string + */ + public function getCurrentCurrencySymbol() + { + return $this->currency->getCurrency()->getCurrencySymbol(); + } } diff --git a/Block/Adminhtml/System/Config/CredentialsChecker.php b/Block/Adminhtml/System/Config/CredentialsChecker.php index 29a3160ee..ba2c99e7c 100644 --- a/Block/Adminhtml/System/Config/CredentialsChecker.php +++ b/Block/Adminhtml/System/Config/CredentialsChecker.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,30 +17,57 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Block\Adminhtml\System\Config; -use Magento\Framework\Data\Form\Element\AbstractElement; +use Magento\Backend\Block\Widget\Button; use Magento\Config\Block\System\Config\Form\Field; +use Magento\Framework\Data\Form\Element\AbstractElement; +use Magento\Framework\Exception\LocalizedException; class CredentialsChecker extends Field { - protected $_template = 'Buckaroo_Magento2::credentials_checker.phtml'; + /** + * @inheritdoc + */ + protected function _construct() + { + parent::_construct(); + $this->setTemplate('Buckaroo_Magento2::credentials_checker.phtml'); + } + /** + * @inheritdoc + */ public function render(AbstractElement $element) { $element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue(); return parent::render($element); } + /** + * Get Test Credentials button html + * + * @return string + * @throws LocalizedException + */ public function getHtml() { - return $this->getLayout()->createBlock(\Magento\Backend\Block\Widget\Button::class)->setData([ + return $this->getLayout()->createBlock(Button::class)->setData([ 'id' => 'buckaroo_magento2_credentials_checker_button', 'label' => __('Test Credentials') ])->toHtml(); } - public function _getElementHtml(AbstractElement $element) + /** + * Return element html + * + * @param AbstractElement $element + * @return string + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function _getElementHtml(AbstractElement $element): string { return $this->_toHtml(); } diff --git a/Block/Adminhtml/System/Config/Fieldset/Payment.php b/Block/Adminhtml/System/Config/Fieldset/Payment.php index 84bf56061..4debcc356 100644 --- a/Block/Adminhtml/System/Config/Fieldset/Payment.php +++ b/Block/Adminhtml/System/Config/Fieldset/Payment.php @@ -17,38 +17,46 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Block\Adminhtml\System\Config\Fieldset; +use Magento\Backend\Block\Context; +use Magento\Backend\Model\Auth\Session; +use Magento\Config\Block\System\Config\Form\Fieldset; +use Magento\Config\Model\Config; +use Magento\Framework\Data\Form\Element\AbstractElement; +use Magento\Framework\View\Helper\Js; + /** * Fieldset renderer for Buckaroo solution */ -class Payment extends \Magento\Config\Block\System\Config\Form\Fieldset +class Payment extends Fieldset { /** - * @var \Magento\Config\Model\Config + * @var Config */ - protected $_backendConfig; + protected Config $backendConfig; /** - * @param \Magento\Backend\Block\Context $context - * @param \Magento\Backend\Model\Auth\Session $authSession - * @param \Magento\Framework\View\Helper\Js $jsHelper - * @param \Magento\Config\Model\Config $backendConfig + * @param Context $context + * @param Session $authSession + * @param Js $jsHelper + * @param Config $backendConfig * @param array $data */ public function __construct( - \Magento\Backend\Block\Context $context, - \Magento\Backend\Model\Auth\Session $authSession, - \Magento\Framework\View\Helper\Js $jsHelper, - \Magento\Config\Model\Config $backendConfig, + Context $context, + Session $authSession, + Js $jsHelper, + Config $backendConfig, array $data = [] ) { - $this->_backendConfig = $backendConfig; + $this->backendConfig = $backendConfig; parent::__construct($context, $authSession, $jsHelper, $data); } /** - * @param \Magento\Framework\Data\Form\Element\AbstractElement $element + * @param AbstractElement $element * @return string * @SuppressWarnings(PHPMD.NPathComplexity) */ @@ -58,8 +66,8 @@ protected function _getHeaderTitleHtml($element) $groupConfig = $element->getGroup(); - $disabledAttributeString = $this->_isPaymentEnabled($element) ? '' : ' disabled="disabled"'; - $disabledClassString = $this->_isPaymentEnabled($element) ? '' : ' disabled'; + $disabledAttributeString = $this->isPaymentEnabled($element) ? '' : ' disabled="disabled"'; + $disabledClassString = $this->isPaymentEnabled($element) ? '' : ' disabled'; $htmlId = $element->getHtmlId(); $html .= '
'; if (!empty($groupConfig['more_url'])) { - $html .= '' . __( - 'Learn More' - ) . ''; + $html .= '' + . __('Learn More') . ''; } if (!empty($groupConfig['demo_url'])) { - $html .= '' . __( - 'View Demo' - ) . ''; + $html .= '' + . __('View Demo') . ''; } $html .= '
'; @@ -102,7 +108,20 @@ protected function _getHeaderTitleHtml($element) } /** - * @param \Magento\Framework\Data\Form\Element\AbstractElement $element + * Check whether current payment method is enabled + * + * @param AbstractElement $element + * @return bool + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function isPaymentEnabled($element) + { + return (bool)(string)$this->backendConfig->getConfigDataValue('buckaroo_magento2/account/active') > 0; + } + + /** + * @param AbstractElement $element * @return string * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -112,7 +131,7 @@ protected function _getHeaderCommentHtml($element) } /** - * @param \Magento\Framework\Data\Form\Element\AbstractElement $element + * @param AbstractElement $element * @return false * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -122,7 +141,7 @@ protected function _isCollapseState($element) } /** - * @param \Magento\Framework\Data\Form\Element\AbstractElement $element + * @param AbstractElement $element * @return string * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -151,21 +170,12 @@ protected function _getExtraJs($element) } /** - * @param \Magento\Framework\Data\Form\Element\AbstractElement $element + * @param AbstractElement $element * @return string */ protected function _getFrontendClass($element) { - $enabledString = $this->_isPaymentEnabled($element) ? ' enabled' : ''; + $enabledString = $this->isPaymentEnabled($element) ? ' enabled' : ''; return parent::_getFrontendClass($element) . ' with-button' . $enabledString; } - - /** - * @param \Magento\Framework\Data\Form\Element\AbstractElement $element - * @return bool - */ - protected function _isPaymentEnabled($element) - { - return (bool)(string) $this->_backendConfig->getConfigDataValue('buckaroo_magento2/account/active') > 0; - } } diff --git a/Block/Cart/BuckarooConfig.php b/Block/Cart/BuckarooConfig.php index 20be07519..21bbe5763 100644 --- a/Block/Cart/BuckarooConfig.php +++ b/Block/Cart/BuckarooConfig.php @@ -1,37 +1,53 @@ configProviderFactory = $configProviderFactory; } /** - * {@inheritdoc} + * @inheritdoc */ public function process($jsLayout) { /** - * @var \Buckaroo\Magento2\Model\ConfigProvider\Account $configProvider - */ + * @var Account $configProvider + */ $configProvider = $this->configProviderFactory->get('account'); $paymentFeeLabel = $configProvider->getPaymentFeeLabel(); diff --git a/Block/Catalog/Product/View/Applepay.php b/Block/Catalog/Product/View/Applepay.php index b56485b71..61584f066 100644 --- a/Block/Catalog/Product/View/Applepay.php +++ b/Block/Catalog/Product/View/Applepay.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,31 +17,38 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Block\Catalog\Product\View; +use Buckaroo\Magento2\Model\ConfigProvider\Method\Applepay as ApplepayConfig; use Magento\Checkout\Model\Cart; use Magento\Checkout\Model\CompositeConfigProvider; use Magento\Framework\View\Element\Template; use Magento\Framework\View\Element\Template\Context; -use Buckaroo\Magento2\Model\ConfigProvider\Method\Applepay as ApplepayConfig; class Applepay extends Template { - /** @var Cart */ + /** + * @var Cart + */ private $cart; - /** @var CompositeConfigProvider */ + /** + * @var CompositeConfigProvider + */ private $compositeConfigProvider; - /** @var ApplepayConfig */ + /** + * @var ApplepayConfig + */ private $applepayConfigProvider; /** - * @param Context $context - * @param Cart $cart + * @param Context $context + * @param Cart $cart * @param CompositeConfigProvider $compositeConfigProvider - * @param ApplepayConfig $applepayConfigProvider - * @param array $data + * @param ApplepayConfig $applepayConfigProvider + * @param array $data */ public function __construct( Context $context, @@ -58,46 +65,43 @@ public function __construct( } /** + * Can show apple pay button on product page + * * @return bool */ - public function canShowButton() + public function canShowProductButton() { - $result = false; - - if ($this->cart->getSummaryQty() - && - ($this->applepayConfigProvider->getActive() != 0) - && - ($this->applepayConfigProvider->getAvailableButtons()) - && - (in_array('Cart', $this->applepayConfigProvider->getAvailableButtons())) + if (($this->applepayConfigProvider->getActive() != 0) + && ($this->applepayConfigProvider->getAvailableButtons()) + && (in_array('Product', $this->applepayConfigProvider->getAvailableButtons())) ) { - $result = true; + return true; } - return $result; + return false; } /** + * Can show apple pay button on cart + * * @return bool */ - public function canShowProductButton() + public function canShowButton() { - $result = false; - - if (($this->applepayConfigProvider->getActive() != 0) - && - ($this->applepayConfigProvider->getAvailableButtons()) - && - (in_array('Product', $this->applepayConfigProvider->getAvailableButtons())) + if ($this->cart->getSummaryQty() + && ($this->applepayConfigProvider->getActive() != 0) + && ($this->applepayConfigProvider->getAvailableButtons()) + && (in_array('Cart', $this->applepayConfigProvider->getAvailableButtons())) ) { - $result = true; + return true; } - return $result; + return false; } /** + * Get checkout config + * * @return false|string */ public function getCheckoutConfig() @@ -110,6 +114,8 @@ public function getCheckoutConfig() } /** + * Get apple pay config + * * @return false|string */ public function getApplepayConfig() diff --git a/Block/Catalog/Product/View/Idin.php b/Block/Catalog/Product/View/Idin.php index 6e3c41060..ba2a1833a 100644 --- a/Block/Catalog/Product/View/Idin.php +++ b/Block/Catalog/Product/View/Idin.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,38 +17,55 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Block\Catalog\Product\View; +use Buckaroo\Magento2\Exception; use Buckaroo\Magento2\Model\ConfigProvider\Account as AccountConfig; +use Magento\Catalog\Model\Product; use Magento\Checkout\Model\Cart; use Magento\Checkout\Model\CompositeConfigProvider; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Registry; use Magento\Framework\View\Element\Template; use Magento\Framework\View\Element\Template\Context; -use \Magento\Framework\Registry; class Idin extends Template { - /** @var Cart */ + /** + * @var Registry + */ + protected $registry; + + /** + * @var Cart + */ private $cart; - /** @var CompositeConfigProvider */ + /** + * @var CompositeConfigProvider + */ private $compositeConfigProvider; - /** @var AccountConfig */ + /** + * @var AccountConfig + */ private $idinConfigProvider; - /** @var Registry */ - protected $registry; - - /** * @var Product */ + /** + * @var Product + */ private $product; /** - * @param Context $context - * @param Cart $cart + * Idin constructor + * + * @param Context $context + * @param Cart $cart * @param CompositeConfigProvider $compositeConfigProvider - * @param AccountConfig $idinConfigProvider - * @param array $data + * @param AccountConfig $idinConfigProvider + * @param Registry $registry + * @param array $data */ public function __construct( Context $context, @@ -60,14 +77,28 @@ public function __construct( ) { parent::__construct($context, $data); - $this->registry = $registry; - $this->cart = $cart; + $this->registry = $registry; + $this->cart = $cart; $this->compositeConfigProvider = $compositeConfigProvider; - $this->idinConfigProvider = $idinConfigProvider; + $this->idinConfigProvider = $idinConfigProvider; } /** + * Get product name + * + * @return string + * @throws LocalizedException + */ + public function getProductName() + { + return $this->getProduct()->getName(); + } + + /** + * Retrieve current product model + * * @return Product + * @throws LocalizedException */ private function getProduct() { @@ -82,32 +113,31 @@ private function getProduct() return $this->product; } - public function getProductName() - { - return $this->getProduct()->getName(); - } - /** + * Show Idin Notification about the age + * * @return bool + * @throws LocalizedException */ public function canShowProductIdin() { + $idinMode = $this->idinConfigProvider->getIdinMode(); $result = false; - if ($this->idinConfigProvider->getIdin() != 0) { - switch ($this->idinConfigProvider->getIdinMode()) { - case 1: - if (null !== $this->getProduct()->getCustomAttribute('buckaroo_product_idin')) { - $result = $this->getProduct()->getCustomAttribute('buckaroo_product_idin')->getValue() == 1 ? - true : false; - } - break; - case 2: - foreach ($this->getProduct()->getCategoryIds() as $key => $cat) { - if (in_array($cat, explode(',', (string)$this->idinConfigProvider->getIdinCategory()))) { - $result = true; - } + + if ($idinMode !== 0) { + $product = $this->getProduct(); + + if ($idinMode === 1) { + $customAttribute = $product->getCustomAttribute('buckaroo_product_idin'); + $result = $customAttribute !== null && $customAttribute->getValue() == 1; + } elseif ($idinMode === 2) { + $idinCategories = explode(',', (string)$this->idinConfigProvider->getIdinCategory()); + foreach ($product->getCategoryIds() as $category) { + if (in_array($category, $idinCategories)) { + $result = true; + break; } - break; + } } } @@ -115,7 +145,10 @@ public function canShowProductIdin() } /** + * Get idin account config + * * @return false|string + * @throws Exception */ public function getAccountConfig() { diff --git a/Block/Catalog/Product/View/PaypalExpress.php b/Block/Catalog/Product/View/PaypalExpress.php index 0d174cf32..33f104247 100644 --- a/Block/Catalog/Product/View/PaypalExpress.php +++ b/Block/Catalog/Product/View/PaypalExpress.php @@ -6,8 +6,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -21,29 +21,38 @@ namespace Buckaroo\Magento2\Block\Catalog\Product\View; +use Buckaroo\Magento2\Model\ConfigProvider\Account; +use Buckaroo\Magento2\Model\ConfigProvider\Method\Paypal; use Magento\Framework\Encryption\Encryptor; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\View\Element\Template; -use Buckaroo\Magento2\Model\ConfigProvider\Account; use Magento\Framework\View\Element\Template\Context; -use Buckaroo\Magento2\Model\ConfigProvider\Method\Paypal; class PaypalExpress extends Template { /** - * @var \Buckaroo\Magento2\Model\ConfigProvider\Account + * @var Account */ protected $configProviderAccount; /** - * @var \Magento\Framework\Encryption\Encryptor + * @var Encryptor */ protected $encryptor; /** - * @var \Buckaroo\Magento2\Model\ConfigProvider\Method\Paypal + * @var Paypal */ protected $paypalConfig; + /** + * @param Context $context + * @param Account $configProviderAccount + * @param Encryptor $encryptor + * @param Paypal $paypalConfig + * @param array $data + */ public function __construct( Context $context, Account $configProviderAccount, @@ -56,6 +65,13 @@ public function __construct( $this->encryptor = $encryptor; $this->paypalConfig = $paypalConfig; } + + /** + * Can show PayPal Express button on cart + * + * @return bool + * @throws NoSuchEntityException + */ public function canShowProductButton() { return $this->paypalConfig->canShowButtonForPage( @@ -63,6 +79,13 @@ public function canShowProductButton() $this->_storeManager->getStore() ); } + + /** + * Can show PayPal Express button on cart + * + * @return bool + * @throws NoSuchEntityException + */ public function canShowCartButton() { return $this->paypalConfig->canShowButtonForPage( @@ -70,23 +93,47 @@ public function canShowCartButton() $this->_storeManager->getStore() ); } + /** * Get all data required * * @return array */ - public function getConfig() + public function getConfig(): array { return [ 'currency' => $this->getCurrency(), 'buckarooWebsiteKey' => $this->getWebsiteKey(), 'paypalMerchantId' => $this->getMerchantId(), + 'style' => [ + "color" => $this->getButtonColor(), + "shape" => $this->getButtonShape(), + ], + 'isTestMode' => $this->isTestMode() ]; } + + /** + * Get shop currency + * + * @return string + * @throws NoSuchEntityException + * @throws LocalizedException + */ + protected function getCurrency() + { + return $this->_storeManager + ->getStore() + ->getCurrentCurrency() + ->getCode(); + } + /** * Get buckaroo website key * * @return string + * @throws NoSuchEntityException + * @throws \Exception */ protected function getWebsiteKey() { @@ -96,27 +143,56 @@ protected function getWebsiteKey() ) ); } + /** - * Get shop currency + * Get merchant id * - * @return string + * @return string|null + * @throws NoSuchEntityException */ - protected function getCurrency() + protected function getMerchantId() { - return $this->_storeManager - ->getStore() - ->getCurrentCurrency() - ->getCode(); + return $this->paypalConfig->getExpressMerchantId( + $this->_storeManager->getStore() + ); } + /** - * Get merchant id + * Get paypal express button color * * @return string|null + * @throws NoSuchEntityException */ - protected function getMerchantId() + protected function getButtonColor() { - return $this->paypalConfig->getExpressMerchantId( + return $this->paypalConfig->getButtonColor( $this->_storeManager->getStore() ); } + + /** + * Get paypal express button color + * + * @return string|null + * @throws NoSuchEntityException + */ + protected function getButtonShape() + { + return $this->paypalConfig->getButtonShape( + $this->_storeManager->getStore() + ); + } + + /** + * Get paypal express button color + * + * @return bool + * @throws NoSuchEntityException + */ + protected function isTestMode() + { + return $this->paypalConfig->getActive( + $this->_storeManager->getStore() + ) == 1; + } } diff --git a/Block/Checkout/Mrcash/Payconiq.php b/Block/Checkout/Mrcash/Payconiq.php new file mode 100644 index 000000000..1ca2704fc --- /dev/null +++ b/Block/Checkout/Mrcash/Payconiq.php @@ -0,0 +1,27 @@ +response = $this->getRequest()->getParams(); } /** + * Get transaction key + * * @return string */ public function getTransactionKey() { - $key = preg_replace('/[^\w]/', '', $this->response['Key']); - return $key; + return preg_replace('/[^\w]/', '', $this->response['Key']); } } diff --git a/Block/Checkout/Success.php b/Block/Checkout/Success.php index 75f5d81f5..64681b057 100644 --- a/Block/Checkout/Success.php +++ b/Block/Checkout/Success.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,27 +20,33 @@ namespace Buckaroo\Magento2\Block\Checkout; +use Magento\Checkout\Model\Session; +use Magento\Customer\Helper\Session\CurrentCustomer; +use Magento\Framework\App\Http\Context as HttpContext; +use Magento\Framework\View\Element\Template\Context as TemplateContext; +use Magento\Sales\Model\Order\Config; + class Success extends \Magento\Checkout\Block\Onepage\Success { /** - * @var \Magento\Customer\Helper\Session\CurrentCustomer + * @var CurrentCustomer */ protected $currentCustomer; /** - * @param Template\Context $context - * @param \Magento\Checkout\Model\Session $checkoutSession - * @param \Magento\Sales\Model\Order\Config $orderConfig - * @param \Magento\Framework\App\Http\Context $httpContext - * @param \Magento\Customer\Helper\Session\CurrentCustomer $currentCustomer + * @param TemplateContext $context + * @param Session $checkoutSession + * @param Config $orderConfig + * @param HttpContext $httpContext + * @param CurrentCustomer $currentCustomer * @param array $data */ public function __construct( - \Magento\Framework\View\Element\Template\Context $context, - \Magento\Checkout\Model\Session $checkoutSession, - \Magento\Sales\Model\Order\Config $orderConfig, - \Magento\Framework\App\Http\Context $httpContext, - \Magento\Customer\Helper\Session\CurrentCustomer $currentCustomer, + TemplateContext $context, + Session $checkoutSession, + Config $orderConfig, + HttpContext $httpContext, + CurrentCustomer $currentCustomer, array $data = [] ) { parent::__construct( diff --git a/Block/Checkout/Totals.php b/Block/Checkout/Totals.php index da6675048..028142317 100644 --- a/Block/Checkout/Totals.php +++ b/Block/Checkout/Totals.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,37 +20,38 @@ namespace Buckaroo\Magento2\Block\Checkout; -class Totals extends \Magento\Checkout\Block\Total\DefaultTotal -{ - /** - * Template file path - * - * @var string - */ - protected $_template = 'checkout/totals.phtml'; +use Buckaroo\Magento2\Exception; +use Buckaroo\Magento2\Helper\PaymentFee; +use Magento\Checkout\Block\Total\DefaultTotal; +use Magento\Checkout\Model\Session as CheckoutSession; +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Framework\View\Element\Template\Context; +use Magento\Sales\Model\Config; +class Totals extends DefaultTotal +{ /** - * Buckaroo fee helper + * Buckaroo fee helper. * - * @var \Buckaroo\Magento2\Helper\PaymentFee + * @var PaymentFee */ - protected $helper; + protected PaymentFee $helper; /** - * @param \Magento\Framework\View\Element\Template\Context $context - * @param \Magento\Customer\Model\Session $customerSession - * @param \Magento\Checkout\Model\Session $checkoutSession - * @param \Magento\Sales\Model\Config $salesConfig - * @param \Buckaroo\Magento2\Helper\PaymentFee $helper - * @param array $layoutProcessors - * @param array $data + * @param Context $context + * @param CustomerSession $customerSession + * @param CheckoutSession $checkoutSession + * @param Config $salesConfig + * @param PaymentFee $helper + * @param array $layoutProcessors + * @param array $data */ public function __construct( - \Magento\Framework\View\Element\Template\Context $context, - \Magento\Customer\Model\Session $customerSession, - \Magento\Checkout\Model\Session $checkoutSession, - \Magento\Sales\Model\Config $salesConfig, - \Buckaroo\Magento2\Helper\PaymentFee $helper, + Context $context, + CustomerSession $customerSession, + CheckoutSession $checkoutSession, + Config $salesConfig, + PaymentFee $helper, array $layoutProcessors = [], array $data = [] ) { @@ -60,15 +61,26 @@ public function __construct( } /** - * Return information for showing + * @inheritdoc + */ + protected function _construct() + { + parent::_construct(); + $this->setTemplate('Buckaroo_Magento2::checkout/totals.phtml'); + } + + /** + * Return information for showing. * * @return array + * @throws Exception */ public function getValues() { $values = []; /** * @noinspection PhpUndefinedMethodInspection + * @phpstan-ignore-next-line */ $total = $this->getTotal(); $totals = $this->helper->getTotals($total); @@ -76,6 +88,7 @@ public function getValues() $label = (string)$total['label']; $values[$label] = $total['value']; } + return $values; } } diff --git a/Block/Checkout/TotalsProcessor.php b/Block/Checkout/TotalsProcessor.php index b26d81519..4c5edbd06 100644 --- a/Block/Checkout/TotalsProcessor.php +++ b/Block/Checkout/TotalsProcessor.php @@ -1,41 +1,59 @@ configProviderFactory = $configProviderFactory; } /** - * {@inheritdoc} + * @inheritdoc */ public function process($jsLayout) { /** - * @var \Buckaroo\Magento2\Model\ConfigProvider\Account $configProvider + * @var Account $configProvider */ $configProvider = $this->configProviderFactory->get('account'); $paymentFeeLabel = $configProvider->getPaymentFeeLabel(); diff --git a/Block/Config/Form/Field/ApplepayButton.php b/Block/Config/Form/Field/ApplepayButton.php new file mode 100644 index 000000000..fc2ef5909 --- /dev/null +++ b/Block/Config/Form/Field/ApplepayButton.php @@ -0,0 +1,61 @@ +getId()); + $this->styleElement = $element->getForm()->getElement($elementId); + return $this->_toHtml(); + } + + public function getButtonStyle(): string + { + return (string) $this->styleElement->getDataByKey('value'); + } + + public function getButtonStyleElement(): string + { + return (string) $this->styleElement->getId(); + } +} diff --git a/Block/Config/Form/Field/ColorPicker.php b/Block/Config/Form/Field/ColorPicker.php index b9b9775fa..a40826921 100644 --- a/Block/Config/Form/Field/ColorPicker.php +++ b/Block/Config/Form/Field/ColorPicker.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,14 +17,24 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ +declare(strict_types=1); + namespace Buckaroo\Magento2\Block\Config\Form\Field; -use \Magento\Config\Block\System\Config\Form\Field; +use Magento\Config\Block\System\Config\Form\Field; +use Magento\Framework\Data\Form\Element\AbstractElement; class ColorPicker extends Field { - protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element) { + /** + * Color picker in admin + * + * @param AbstractElement $element + * @return string + */ + protected function _getElementHtml(AbstractElement $element): string + { $element->setData('type', 'color'); return $element->getElementHtml(); } -} \ No newline at end of file +} diff --git a/Block/Config/Form/Field/Fieldset.php b/Block/Config/Form/Field/Fieldset.php index 9b0b6adad..7e0c518bb 100644 --- a/Block/Config/Form/Field/Fieldset.php +++ b/Block/Config/Form/Field/Fieldset.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,22 +17,73 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Block\Config\Form\Field; +use Buckaroo\Magento2\Service\LogoService; +use Magento\Backend\Block\Context; +use Magento\Backend\Model\Auth\Session; use Magento\Config\Block\System\Config\Form\Fieldset as MagentoFieldset; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Data\Form\Element\AbstractElement; +use Magento\Framework\View\Helper\Js; +use Magento\Framework\View\Helper\SecureHtmlRenderer; use Magento\Store\Model\ScopeInterface; class Fieldset extends MagentoFieldset { /** - * {@inheritdoc} + * @var LogoService + */ + protected LogoService $logoService; + + /** + * @param Context $context + * @param Session $authSession + * @param Js $jsHelper + * @param LogoService $logoService + * @param array $data + * @param SecureHtmlRenderer|null $secureRenderer + */ + public function __construct( + Context $context, + Session $authSession, + Js $jsHelper, + LogoService $logoService, + array $data = [], + ?SecureHtmlRenderer $secureRenderer = null + ) { + parent::__construct($context, $authSession, $jsHelper, $data, $secureRenderer); + $this->logoService = $logoService; + } + + /** + * Collapsed or expanded fieldset when page loaded? + * + * @param AbstractElement $element + * @return bool * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - // @codingStandardsIgnoreLine - protected function _getFrontendClass($element) + protected function _isCollapseState($element): bool { - $value = $this->getElementValue($element); + return false; + } + + /** + * Get frontend class + * + * @param AbstractElement $element + * @return string + */ + protected function _getFrontendClass($element): string + { + if ($element->getGroup()['id'] === 'buckaroo_magento2_klarna_group') { + $value = $this->getActiveStatusByGroup($element); + } else { + $value = $this->getElementValue($element); + } + $class = 'payment_method_'; switch ($value) { @@ -48,37 +99,85 @@ protected function _getFrontendClass($element) } $classes = parent::_getFrontendClass($element); - $classes .= ' ' . $class; + $classes .= ' bk-payment-method ' . $class; return $classes; } /** - * @param $element + * Get element value * + * @param AbstractElement $element * @return string */ - private function getElementValue($element) + private function getElementValue(AbstractElement $element): string { $scopeValues = $this->getScopeValue(); $group = $element->getData('group'); - $value = $this->_scopeConfig->getValue( + return $this->_scopeConfig->getValue( $group['children']['active']['config_path'], $scopeValues['scope'], $scopeValues['scopevalue'] ); + } + + /** + * Get active status for a group + * + * @param AbstractElement $element + * @return string + */ + private function getActiveStatusByGroup(AbstractElement $element): string + { + $children = $element->getGroup()['children']; + $status = '0'; + + foreach ($children as $child) { + $childStatus = $this->getElementValueByConfigPath($child['children']['active']['config_path'] ?? ''); + if($childStatus === '1') { + $status = '1'; + continue; + } + if($childStatus === '2') { + return '2'; + } + + } + + return $status; + + } + + /** + * Get element value + * + * @param string $configPath + * @return string + */ + private function getElementValueByConfigPath(string $configPath): string + { + if (empty($configPath)) { + return ''; + } + $scopeValues = $this->getScopeValue(); - return $value; + return $this->_scopeConfig->getValue( + $configPath, + $scopeValues['scope'], + $scopeValues['scopevalue'] + ); } /** + * Get scope value + * * @return array */ - private function getScopeValue() + private function getScopeValue(): array { $scopeValues = [ - 'scope' => ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + 'scope' => ScopeConfigInterface::SCOPE_TYPE_DEFAULT, 'scopevalue' => null ]; @@ -97,4 +196,53 @@ private function getScopeValue() return $scopeValues; } + + /** + * Get the header title HTML including a logo. + * + * @param AbstractElement $element + * @return string + */ + protected function _getHeaderTitleHtml($element): string + { + if (!isset($element->getGroup()['id']) || + !is_string($element->getGroup()['id']) + ) { + return parent::_getHeaderTitleHtml($element); + } + + $element->setLegend($this->getTabImgAndLink($element)); + return parent::_getHeaderTitleHtml($element); + } + + /** + * @param AbstractElement $element + * @return string + */ + private function getTabImgAndLink($element) { + $method = str_replace("buckaroo_magento2_", "", $element->getGroup()['id']); + $logo = $this->getPaymentLogo($method); + return '
'. + $element->getLegend(). + "
"; + } + + /** + * Get payment method logo + * + * @param string $method + * @return string + */ + private function getPaymentLogo(string $method): string + { + if ($method == "voucher") { + $method = "buckaroovoucher"; + } + + if ($method == "klarna_group") { + $method = "klarna"; + } + + return $this->logoService->getPayment($method, true); + } } diff --git a/Block/Config/Form/Field/PaypalButton.php b/Block/Config/Form/Field/PaypalButton.php new file mode 100644 index 000000000..02962eca5 --- /dev/null +++ b/Block/Config/Form/Field/PaypalButton.php @@ -0,0 +1,77 @@ +setTemplate('Buckaroo_Magento2::paypal.phtml'); + } + + /** + * Return element html + * + * @param AbstractElement $element + * @return string + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function _getElementHtml(AbstractElement $element) + { + $elementId = $element->getId(); + $this->colorElement = $element->getForm()->getElement( str_replace("preview","color",$elementId)); + $this->shapeElement = $element->getForm()->getElement( str_replace("preview","rounded",$elementId)); + return $this->_toHtml(); + } + + public function getButtonColor(): string + { + return $this->colorElement->getDataByKey('value') ?? PaypalButtonStyle::COLOR_DEFAULT; + } + + public function getButtonShape(): string + { + return $this->shapeElement->getDataByKey('value') ?? "0"; + } + public function getButtonColorElement():string + { + return $this->colorElement->getId(); + } + + public function getButtonShapeElement():string + { + return $this->shapeElement->getId(); + } +} diff --git a/Block/Config/Form/Field/VerificationMethod.php b/Block/Config/Form/Field/VerificationMethod.php new file mode 100644 index 000000000..e7cba3a60 --- /dev/null +++ b/Block/Config/Form/Field/VerificationMethod.php @@ -0,0 +1,115 @@ +logoService = $logoService; + } + + /** + * Get frontend class + * + * @param AbstractElement $element + * @return string + */ + protected function _getFrontendClass($element): string + { + return parent::_getFrontendClass($element). ' bk-payment-method'; + } + + + + /** + * Get the header title HTML including a logo. + * + * @param AbstractElement $element + * @return string + */ + protected function _getHeaderTitleHtml($element): string + { + if (!isset($element->getGroup()['id']) || + !is_string($element->getGroup()['id']) + ) { + return parent::_getHeaderTitleHtml($element); + } + + $element->setLegend($this->getTabImgAndLink($element)); + return parent::_getHeaderTitleHtml($element); + } + + /** + * @param AbstractElement $element + * @return string + */ + private function getTabImgAndLink($element) { + $code = str_replace("buckaroo_magento2_", "", $element->getGroup()['id']); + $logo = $this->getLogo($code); + return '
'. + $element->getLegend(). + "
"; + } + + /** + * Get logo + * + * @param string $code + * @return string + */ + private function getLogo(string $code): string + { + if ($code === 'idin') { + return $this->logoService->getAssetUrl("Buckaroo_Magento2::images/idin.svg"); + } + + return ''; + } +} diff --git a/Block/Frontend/ThemeBodyClass.php b/Block/Frontend/ThemeBodyClass.php index efecc64c4..9195bc31c 100644 --- a/Block/Frontend/ThemeBodyClass.php +++ b/Block/Frontend/ThemeBodyClass.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,17 +17,24 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Block\Frontend; -class ThemeBodyClass extends \Magento\Framework\View\Element\Template +use Magento\Backend\Block\Template\Context; +use Magento\Framework\View\Element\Template; + +class ThemeBodyClass extends Template { + /** + * @var Context + */ private $contextCopy; /** - * @param \Magento\Backend\Block\Template\Context $context - * @param array $data + * @param Context $context + * @param array $data */ - public function __construct(\Magento\Backend\Block\Template\Context $context, array $data = []) + public function __construct(Context $context, array $data = []) { $this->contextCopy = $context; parent::__construct($context, $data); diff --git a/Block/Info.php b/Block/Info.php index fe76fec66..75e47b366 100644 --- a/Block/Info.php +++ b/Block/Info.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,58 +20,84 @@ namespace Buckaroo\Magento2\Block; -use Magento\Framework\UrlInterface; -use Magento\Framework\View\Asset\Repository; use Buckaroo\Magento2\Helper\PaymentGroupTransaction; use Buckaroo\Magento2\Model\ResourceModel\Giftcard\Collection as GiftcardCollection; +use Buckaroo\Magento2\Service\LogoService; +use Magento\Framework\DataObject; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Phrase; +use Magento\Framework\UrlInterface; +use Magento\Framework\View\Element\Template\Context; class Info extends \Magento\Payment\Block\Info { /** - * @var string + * @var PaymentGroupTransaction */ - protected $_template = 'Buckaroo_Magento2::info/payment_method.phtml'; - protected $groupTransaction; - protected $giftcardCollection; + protected PaymentGroupTransaction $groupTransaction; - protected Repository $assetRepo; + /** + * @var GiftcardCollection + */ + protected GiftcardCollection $giftcardCollection; protected UrlInterface $baseUrl; /** - * @param \Magento\Framework\View\Element\Template\Context $context - * @param array $data - * @param \Buckaroo\Magento2\Model\ConfigProvider\Method\Creditcard $configProvider + * @var LogoService + */ + protected LogoService $logoService; + + /** + * @param Context $context + * @param PaymentGroupTransaction $groupTransaction + * @param GiftcardCollection $giftcardCollection + * @param LogoService $logoService + * @param UrlInterface $baseUrl + * @param array $data */ public function __construct( - \Magento\Framework\View\Element\Template\Context $context, + Context $context, PaymentGroupTransaction $groupTransaction, GiftcardCollection $giftcardCollection, - Repository $assetRepo, + LogoService $logoService, UrlInterface $baseUrl, array $data = [] ) { parent::__construct($context, $data); $this->groupTransaction = $groupTransaction; $this->giftcardCollection = $giftcardCollection; - $this->assetRepo = $assetRepo; + $this->logoService = $logoService; $this->baseUrl = $baseUrl; } + /** + * Get giftcards + * + * @return array + * @throws LocalizedException + */ public function getGiftCards() { $result = []; if ($this->getInfo()->getOrder() && $this->getInfo()->getOrder()->getIncrementId()) { $items = $this->groupTransaction->getGroupTransactionItems($this->getInfo()->getOrder()->getIncrementId()); - foreach ($items as $key => $giftcard) { + foreach ($items as $giftcard) { if ($foundGiftcard = $this->giftcardCollection ->getItemByColumnValue('servicecode', $giftcard['servicecode']) ) { $result[] = [ - 'code' => $giftcard['servicecode'], + 'code' => $giftcard['servicecode'], 'label' => $foundGiftcard['label'], - 'logo' => $foundGiftcard['logo'] + 'logo' => $foundGiftcard['logo'] + ]; + } + + if ($giftcard['servicecode'] == 'buckaroovoucher') { + $result[] = [ + 'code' => $giftcard['servicecode'], + 'label' => 'Buckaroo Voucher', ]; } } @@ -80,91 +106,129 @@ public function getGiftCards() return $result; } + /** + * Get PayPerEmail label payment method + * + * @return array|false + * @throws LocalizedException + */ public function getPayPerEmailMethod() { $payment = $this->getInfo()->getOrder()->getPayment(); - if ($servicecode = $payment->getAdditionalInformation('isPayPerEmail')) { + if ($payment->getAdditionalInformation('isPayPerEmail')) { return [ - 'label' => __('Buckaroo PayPerEmail'), - ]; + 'label' => __('Buckaroo PayPerEmail'), + ]; } return false; } + /** + * Get payment method logo + * + * @param string $method + * @return string + */ public function getPaymentLogo(string $method): string { - $mappings = [ - "afterpay2" => "svg/afterpay.svg", - "afterpay20" => "svg/afterpay.svg", - "capayablein3" => "svg/in3.svg", - "capayablepostpay" => "svg/in3.svg", - "creditcard" => "svg/creditcards.svg", - "creditcards" => "svg/creditcards.svg", - "giftcards" => "svg/giftcards.svg", - "idealprocessing" => "svg/ideal.svg", - "klarnain" => "svg/klarna.svg", - "klarnakp" => "svg/klarna.svg", - "mrcash" => "svg/bancontact.svg", - "p24" => "svg/przelewy24.svg", - "sepadirectdebit" => "svg/sepa-directdebit.svg", - "sofortbanking" => "svg/sofort.svg", - "emandate" => "emandate.png", - "pospayment" => "pos.png", - "transfer" => "svg/sepa-credittransfer.svg", - "paybybank" => "paybybank.gif" - ]; - - $name = "svg/{$method}.svg"; - - if(isset($mappings[$method])) { - $name = $mappings[$method]; - } + return $this->logoService->getPayment($method); + } - return $this->assetRepo->getUrl("Buckaroo_Magento2::images/{$name}"); + /** + * Get giftcard logo url by code + * + * @param array $code + * @return string + */ + public function getGiftcardLogo(array $code): string + { + return $this->logoService->getGiftcardLogo($code); } - public function getGiftcardLogo(array $giftcard): string + + /** + * Get creditcard logo by code + * + * @param string $code + * @return string + */ + public function getCreditcardLogo(string $code): string { - if ( - isset($giftcard['logo']) && - is_string($giftcard['logo']) && - strlen(trim($giftcard['logo'])) - ) { - return $this->baseUrl->getDirectUrl( - $giftcard['logo'], - ['_type' => UrlInterface::URL_TYPE_MEDIA] - ); + return $this->logoService->getCreditcard($code); + } + + /** + * Get Specific Payment Details set on Success Push to display on Payment Order Information + * + * @return array + * @throws LocalizedException + */ + public function getSpecificPaymentDetails(): array + { + $details = $this->getInfo()->getAdditionalInformation('specific_payment_details'); + + if (!$details || !is_array($details)) { + return []; } - return $this->getGiftcardLogoDefaults($giftcard['code']); + $transformedKeys = array_map([$this, 'getLabel'], array_keys($details)); + $transformedValues = array_map(function ($value) { + return $this->getValueView((string)$value); + }, $details); + + return array_combine($transformedKeys, $transformedValues); } - private function getGiftcardLogoDefaults(string $code) { - $name = "svg/giftcards.svg"; - - $mappings = [ - "ajaxgiftcard" => "ajaxgiftcard", - "boekenbon" => "boekenbon", - "cjpbetalen" => "cjp", - "digitalebioscoopbon" => "nationaletuinbon", - "fashioncheque" => "fashioncheque", - "fashionucadeaukaart" => "fashiongiftcard", - "nationaletuinbon" => "nationalebioscoopbon", - "nationaleentertainmentcard" => "nationaleentertainmentcard", - "podiumcadeaukaart" => "podiumcadeaukaart", - "sportfitcadeau" => "sport-fitcadeau", - "vvvgiftcard" => "vvvgiftcard" - ]; - - if(isset($mappings[$code])) { - $name = "giftcards/{$mappings[$code]}.svg"; - } - return $this->assetRepo->getUrl("Buckaroo_Magento2::images/{$name}"); + + /** + * Returns value view + * + * @param string $value + * @return string + */ + protected function getValueView(string $value): string + { + return $value; } - public function getCreditcardLogo(string $code): string + + /** + * @inheritdoc + */ + protected function _construct() + { + parent::_construct(); + $this->setTemplate('Buckaroo_Magento2::info/payment_method.phtml'); + } + + /** + * Prepare information specific to current payment method + * + * @param null|DataObject|array $transport + * @return DataObject + * @throws LocalizedException + */ + protected function _prepareSpecificInformation($transport = null): DataObject { - if($code === 'cartebleuevisa') { - $code = 'cartebleue'; + $transport = parent::_prepareSpecificInformation($transport); + if ($transferDetails = $this->getInfo()->getAdditionalInformation('transfer_details')) { + foreach ($transferDetails as $key => $transferDetail) { + $transport->setData( + (string)$this->getLabel($key), + $this->getValueView($transferDetail) + ); + } } - - return $this->assetRepo->getUrl("Buckaroo_Magento2::images/creditcards/{$code}.svg"); + return $transport; + } + + /** + * Returns label + * + * @param string $field + * @return Phrase + */ + protected function getLabel(string $field) + { + $words = explode('_', $field); + $transformedWords = array_map('ucfirst', $words); + return __(implode(' ', $transformedWords)); } } diff --git a/Block/Info/Creditcard.php b/Block/Info/Creditcard.php index 6eb551d95..c0f46047e 100644 --- a/Block/Info/Creditcard.php +++ b/Block/Info/Creditcard.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,65 +20,69 @@ namespace Buckaroo\Magento2\Block\Info; -use Magento\Framework\UrlInterface; +use Buckaroo\Magento2\Block\Info; use Magento\Framework\View\Asset\Repository; +use Magento\Framework\UrlInterface; use Buckaroo\Magento2\Helper\PaymentGroupTransaction; +use Buckaroo\Magento2\Model\ConfigProvider\Method\Creditcard as ConfigProviderCreditcard; use Buckaroo\Magento2\Model\ResourceModel\Giftcard\Collection as GiftcardCollection; +use Buckaroo\Magento2\Service\LogoService; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\View\Element\Template\Context; -class Creditcard extends \Buckaroo\Magento2\Block\Info +class Creditcard extends Info { /** - * @var string + * @var string|null */ - protected $cardType; + protected ?string $cardType = null; /** - * @var array + * @var array|null */ - protected $mpiStatus; + protected ?array $mpiStatus = null; /** - * @var \Buckaroo\Magento2\Model\ConfigProvider\Method\Creditcard + * @var ConfigProviderCreditcard */ - protected $configProvider; + protected ConfigProviderCreditcard $configProvider; /** - * @var string + * @param Context $context + * @param PaymentGroupTransaction $groupTransaction + * @param GiftcardCollection $giftcardCollection + * @param LogoService $logoService + * @param UrlInterface $baseUrl + * @param array $data + * @param ConfigProviderCreditcard|null $configProvider */ - protected $_template = 'Buckaroo_Magento2::info/creditcard.phtml'; - public function __construct( - \Magento\Framework\View\Element\Template\Context $context, + Context $context, PaymentGroupTransaction $groupTransaction, GiftcardCollection $giftcardCollection, - Repository $assetRepo, + LogoService $logoService, UrlInterface $baseUrl, array $data = [], - \Buckaroo\Magento2\Model\ConfigProvider\Method\Creditcard $configProvider = null + ConfigProviderCreditcard $configProvider = null ) { - parent::__construct($context, $groupTransaction, $giftcardCollection, $assetRepo, $baseUrl, $data); + parent::__construct($context, $groupTransaction, $giftcardCollection, $logoService, $baseUrl, $data); $this->configProvider = $configProvider; } /** - * Get the selected creditcard for this order. - * - * @return string + * @inheritdoc */ - public function getCardType() + protected function _construct() { - if ($this->cardType === null) { - $this->cardType = $this->configProvider->getCardName( - $this->getInfo()->getAdditionalInformation('card_type') - ); - } - return $this->cardType; + parent::_construct(); + $this->setTemplate('Buckaroo_Magento2::info/creditcard.phtml'); } /** * Get the order's MPI status. * * @return array + * @throws LocalizedException */ public function getMpiStatus() { @@ -89,7 +93,10 @@ public function getMpiStatus() } /** + * Get card code + * * @return string + * @throws LocalizedException */ public function getCardCode() { @@ -99,6 +106,24 @@ public function getCardCode() } /** + * Get the selected creditcard for this order. + * + * @return string + * @throws LocalizedException + */ + public function getCardType() + { + if ($this->cardType === null) { + $this->cardType = $this->configProvider->getCardName( + $this->getInfo()->getAdditionalInformation('card_type') + ); + } + return $this->cardType; + } + + /** + * Render as PDF + * * @return string */ public function toPdf() diff --git a/Block/Order/Creditmemo/Totals.php b/Block/Order/Creditmemo/Totals.php index 40e4ab6fd..192159dff 100644 --- a/Block/Order/Creditmemo/Totals.php +++ b/Block/Order/Creditmemo/Totals.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,11 +20,11 @@ namespace Buckaroo\Magento2\Block\Order\Creditmemo; +use Buckaroo\Magento2\Helper\PaymentFee; use Magento\Framework\DataObject; use Magento\Framework\Registry; use Magento\Framework\View\Element\Template\Context; use Magento\Sales\Block\Order\Creditmemo\Totals as CreditmemoTotals; -use Buckaroo\Magento2\Helper\PaymentFee; class Totals extends CreditmemoTotals { @@ -34,10 +34,10 @@ class Totals extends CreditmemoTotals protected $helper = null; /** - * @param Context $context - * @param Registry $registry + * @param Context $context + * @param Registry $registry * @param PaymentFee $helper - * @param array $data + * @param array $data */ public function __construct( Context $context, @@ -50,12 +50,11 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getTotals($area = null) { $this->addBuckarooFeeTotals(); - return parent::getTotals($area); } diff --git a/Block/Order/Creditmemo/TotalsEmail.php b/Block/Order/Creditmemo/TotalsEmail.php index bcea1f8d1..e4fa049af 100644 --- a/Block/Order/Creditmemo/TotalsEmail.php +++ b/Block/Order/Creditmemo/TotalsEmail.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,10 +17,14 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Block\Order\Creditmemo; class TotalsEmail extends \Buckaroo\Magento2\Block\Order\TotalsEmail { + /** + * @inheritdoc + */ public function initTotals() { $creditmemo = $this->getParentBlock()->getCreditmemo(); diff --git a/Block/Order/Invoice/Totals.php b/Block/Order/Invoice/Totals.php index ade41359e..bb97837fa 100644 --- a/Block/Order/Invoice/Totals.php +++ b/Block/Order/Invoice/Totals.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,11 +20,11 @@ namespace Buckaroo\Magento2\Block\Order\Invoice; +use Buckaroo\Magento2\Helper\PaymentFee; use Magento\Framework\DataObject; use Magento\Framework\Registry; use Magento\Framework\View\Element\Template\Context; use Magento\Sales\Block\Order\Invoice\Totals as InvoiceTotals; -use Buckaroo\Magento2\Helper\PaymentFee; class Totals extends InvoiceTotals { @@ -34,10 +34,10 @@ class Totals extends InvoiceTotals protected $helper = null; /** - * @param Context $context - * @param Registry $registry + * @param Context $context + * @param Registry $registry * @param PaymentFee $helper - * @param array $data + * @param array $data */ public function __construct( Context $context, @@ -50,7 +50,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getTotals($area = null) { diff --git a/Block/Order/Invoice/TotalsEmail.php b/Block/Order/Invoice/TotalsEmail.php index 09696efdc..8b6b8c6c4 100644 --- a/Block/Order/Invoice/TotalsEmail.php +++ b/Block/Order/Invoice/TotalsEmail.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,10 +17,14 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Block\Order\Invoice; class TotalsEmail extends \Buckaroo\Magento2\Block\Order\TotalsEmail { + /** + * @inheritdoc + */ public function initTotals() { $invoice = $this->getParentBlock()->getInvoice(); diff --git a/Block/Order/TotalsEmail.php b/Block/Order/TotalsEmail.php index e702aff10..277227fe1 100644 --- a/Block/Order/TotalsEmail.php +++ b/Block/Order/TotalsEmail.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,23 +20,25 @@ namespace Buckaroo\Magento2\Block\Order; +use Buckaroo\Magento2\Helper\PaymentFee; use Magento\Framework\DataObject; use Magento\Framework\View\Element\AbstractBlock; use Magento\Framework\View\Element\Context; use Magento\Sales\Model\Order; -use Magento\Sales\Model\Order\Invoice; use Magento\Sales\Model\Order\Creditmemo; -use Buckaroo\Magento2\Helper\PaymentFee; +use Magento\Sales\Model\Order\Invoice; class TotalsEmail extends AbstractBlock { - /** @var PaymentFee|null */ + /** + * @var PaymentFee|null + */ protected $helper = null; /** * @param PaymentFee $helper - * @param Context $context - * @param array $data + * @param Context $context + * @param array $data */ public function __construct( PaymentFee $helper, @@ -48,6 +50,11 @@ public function __construct( parent::__construct($context, $data); } + /** + * Add Buckaroo fee totals + * + * @return void + */ public function initTotals() { $order = $this->getParentBlock()->getOrder(); @@ -55,6 +62,8 @@ public function initTotals() } /** + * Add Buckaroo fee totals + * * @param Order|Invoice|Creditmemo $order */ public function addBuckarooFeeTotals($order) diff --git a/Block/Order/TotalsFee.php b/Block/Order/TotalsFee.php index 327c489e9..ba0dd9ec0 100644 --- a/Block/Order/TotalsFee.php +++ b/Block/Order/TotalsFee.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,11 +20,11 @@ namespace Buckaroo\Magento2\Block\Order; +use Buckaroo\Magento2\Helper\PaymentFee; use Magento\Framework\DataObject; use Magento\Framework\Registry; use Magento\Framework\View\Element\Template\Context; use Magento\Sales\Block\Order\Totals; -use Buckaroo\Magento2\Helper\PaymentFee; class TotalsFee extends Totals { @@ -34,10 +34,10 @@ class TotalsFee extends Totals protected $helper = null; /** - * @param Context $context - * @param Registry $registry + * @param Context $context + * @param Registry $registry * @param PaymentFee $helper - * @param array $data + * @param array $data */ public function __construct( Context $context, @@ -50,7 +50,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getTotals($area = null) { diff --git a/Block/Widget/Button/Toolbar.php b/Block/Widget/Button/Toolbar.php index dcf916306..def784d08 100644 --- a/Block/Widget/Button/Toolbar.php +++ b/Block/Widget/Button/Toolbar.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -18,12 +18,12 @@ * @license https://tldrlegal.com/license/mit-license */ - namespace Buckaroo\Magento2\Block\Widget\Button; +use Magento\Backend\Block\Widget\Button\ButtonList; use Magento\Backend\Block\Widget\Button\Toolbar as ToolbarContext; use Magento\Framework\View\Element\AbstractBlock; -use Magento\Backend\Block\Widget\Button\ButtonList; +use Magento\Sales\Block\Adminhtml\Order\Invoice\View; class Toolbar { @@ -40,7 +40,6 @@ class Toolbar 'buckaroo_magento2_creditcard', 'buckaroo_magento2_creditcards', 'buckaroo_magento2_ideal', - 'buckaroo_magento2_idealprocessing', 'buckaroo_magento2_mrcash', 'buckaroo_magento2_paypal', 'buckaroo_magento2_payconiq', @@ -54,7 +53,6 @@ class Toolbar 'buckaroo_magento2_klarna', 'buckaroo_magento2_klarnakp', 'buckaroo_magento2_klarnain', - 'buckaroo_magento2_emandate', 'buckaroo_magento2_applepay', 'buckaroo_magento2_capayablein3', 'buckaroo_magento2_capayablepostpay', @@ -66,51 +64,49 @@ class Toolbar ]; /** + * Display cannot refund message for refunds that works only via the Buckaroo Payment Plaza + * * @param ToolbarContext $toolbar - * @param AbstractBlock $context - * @param ButtonList $buttonList + * @param AbstractBlock $context + * @param ButtonList $buttonList * @return array + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function beforePushButtons( ToolbarContext $toolbar, - \Magento\Framework\View\Element\AbstractBlock $context, - \Magento\Backend\Block\Widget\Button\ButtonList $buttonList + AbstractBlock $context, + ButtonList $buttonList ) { - if ($this->_isOrderInvoiceView($context)) { - return $this->_creditMemoNotAllowed($context, $buttonList); + if ($this->isOrderInvoiceView($context)) { + return $this->creditMemoNotAllowed($context, $buttonList); } return [$context, $buttonList]; } /** - * @param $context - * @return bool - */ - private function _isOrderView($context) - { - if ($context instanceof \Magento\Sales\Block\Adminhtml\Order\View) { - return true; - } - } - - /** - * @param $context + * Check if is invoice view + * + * @param AbstractBlock $context * @return bool */ - private function _isOrderInvoiceView($context) + private function isOrderInvoiceView($context) { - if ($context instanceof \Magento\Sales\Block\Adminhtml\Order\Invoice\View) { + if ($context instanceof View) { return true; } + return false; } /** - * @param $context - * @param $buttonList + * Display credit memo not allowed messages + * + * @param AbstractBlock $context + * @param ButtonList $buttonList * @return array */ - private function _creditMemoNotAllowed($context, $buttonList) + private function creditMemoNotAllowed($context, $buttonList) { $orderPayment = $context->getInvoice()->getOrder(); $paymentMethod = $orderPayment->getPayment()->getMethod(); diff --git a/Console/Command/PushSend.php b/Console/Command/PushSend.php deleted file mode 100644 index 4bc8c998f..000000000 --- a/Console/Command/PushSend.php +++ /dev/null @@ -1,126 +0,0 @@ -appState = $appState; - $this->asyncHttpClient = $asyncHttpClient; - $this->configProviderAccount = $configProviderAccount; - $this->encryptor = $encryptor; - - parent::__construct('buckaroo:push:send'); - } - - protected function configure() - { - $this->setDescription('Buckaroo. Sign and send a push notitification.'); - parent::configure(); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $this->appState->setAreaCode('global'); - $this->pushValidator = \Magento\Framework\App\ObjectManager::getInstance()->get(Push::class); - - $postData = [ - 'ADD_initiated_by_magento' => '1', - 'ADD_service_action_from_magento' => 'pay', - 'brq_amount' => '43.84', - 'brq_currency' => 'EUR', - 'brq_customer_name' => 'J. de Tèster', - 'brq_description' => 'Default Store View', - 'brq_invoicenumber' => '051400250', - 'brq_mutationtype' => 'Collecting', - 'brq_ordernumber' => '051400250', - // @codingStandardsIgnoreStart - 'brq_payer_hash' => '2d26d34584a4eafeeaa97eed10cfdae22ae64cdce1649a80a55fafca8850e3e22cb32eb7c8fc95ef0c6f96669a21651d4734cc568816f9bd59c2092911e6c0da', - // @codingStandardsIgnoreEnd - 'brq_payment' => 'E6CB308C8BDC4609A7D5A4C00BD316FA', - 'brq_SERVICE_ideal_consumerBIC' => 'RABONL2U', - 'brq_SERVICE_ideal_consumerIBAN' => 'NL44RABO0123456789', - 'brq_SERVICE_ideal_consumerIssuer' => 'ABN AMRO', - 'brq_SERVICE_ideal_consumerName' => 'J. de Tèster', - 'brq_SERVICE_ideal_transactionId' => '0000000000000001', - 'brq_statuscode' => '190', - 'brq_statuscode_detail' => 'S001', - 'brq_statusmessage' => 'Transaction successfully processed', - 'brq_test' => 'true', - 'brq_timestamp' => '2022-02-09 10:49:49', - 'brq_transaction_method' => 'ideal', - 'brq_transaction_type' => 'C021', - 'brq_transactions' => '52F3C5A0E8D74F13A4F7767C2D029AB3', - 'brq_websitekey' => $this->encryptor->decrypt($this->configProviderAccount->getMerchantKey()), - ]; - - $signature = $this->pushValidator->calculateSignature($postData); - $output->writeln($signature); - $postData['brq_signature'] = $signature; - - $responses = []; - - for ($i = 0; $i < $this->requests; $i++) { - $request = new Request( - $this->url, - Request::METHOD_POST, - ['Content-Type' => 'application/x-www-form-urlencoded'], - http_build_query($postData) - ); - - try { - $responses[] = $this->asyncHttpClient->request($request); - } catch (\Exception $e) { - $output->writeln($e->getMessage()); - return false; - } - } - - foreach ($responses as $response) { - $output->writeln($response->get()->getBody()); - } - } -} diff --git a/Controller/Adminhtml/Giftcard/Delete.php b/Controller/Adminhtml/Giftcard/Delete.php index bc39e0329..74dc6006b 100644 --- a/Controller/Adminhtml/Giftcard/Delete.php +++ b/Controller/Adminhtml/Giftcard/Delete.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,8 +20,17 @@ namespace Buckaroo\Magento2\Controller\Adminhtml\Giftcard; -class Delete extends \Buckaroo\Magento2\Controller\Adminhtml\Giftcard\Index +use Magento\Backend\Model\View\Result\Page; +use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\App\ResponseInterface; + +class Delete extends Index implements HttpPostActionInterface { + /** + * Delete Giftcard + * + * @return Page|ResponseInterface + */ public function execute() { $giftcardId = $this->getRequest()->getParam('entity_id'); @@ -31,19 +40,21 @@ public function execute() $giftcardModel->load($giftcardId); if (!$giftcardModel->getId()) { - $this->messageManager->addError(__('This giftcard no longer exists.')); + $this->messageManager->addErrorMessage(__('This giftcard no longer exists.')); } else { try { $giftcardModel->delete(); - $this->messageManager->addSuccess(__('The giftcard has been deleted.')); + $this->messageManager->addSuccessMessage(__('The giftcard has been deleted.')); - $this->_redirect('*/*/'); - return; + return $this->_redirect('*/*/'); } catch (\Exception $e) { - $this->messageManager->addError($e->getMessage()); - $this->_redirect('*/*/edit', ['id' => $giftcardModel->getId()]); + $this->messageManager->addErrorMessage($e->getMessage()); + return $this->_redirect('*/*/edit', ['id' => $giftcardModel->getId()]); } } } + + $this->messageManager->addErrorMessage(__('We can\'t find a Giftcard to delete.')); + return $this->_redirect('*/*/'); } } diff --git a/Controller/Adminhtml/Giftcard/Edit.php b/Controller/Adminhtml/Giftcard/Edit.php index f59d9bd0f..a99f1396d 100644 --- a/Controller/Adminhtml/Giftcard/Edit.php +++ b/Controller/Adminhtml/Giftcard/Edit.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,26 +20,71 @@ namespace Buckaroo\Magento2\Controller\Adminhtml\Giftcard; -class Edit extends \Buckaroo\Magento2\Controller\Adminhtml\Giftcard\Index +use Buckaroo\Magento2\Api\Data\BuckarooGiftcardDataInterface; +use Buckaroo\Magento2\Model\Giftcard; +use Buckaroo\Magento2\Model\GiftcardFactory; +use Magento\Backend\App\Action; +use Magento\Backend\App\Action\Context; +use Magento\Backend\Model\View\Result\Page; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\ResponseInterface; +use Magento\Framework\View\Result\PageFactory; + +class Edit extends Action implements HttpGetActionInterface { /** - * @return \Magento\Backend\Model\View\Result\Page|void + * @var PageFactory + */ + protected $resultPageFactory; + + /** + * @var GiftcardFactory + */ + protected $giftcardFactory; + + /** + * @var BuckarooGiftcardDataInterface + */ + private BuckarooGiftcardDataInterface $buckarooGiftcardData; + + /** + * @param Context $context + * @param PageFactory $resultPageFactory + * @param GiftcardFactory $giftcardFactory + * @param BuckarooGiftcardDataInterface $buckarooGiftcardData + */ + public function __construct( + Context $context, + PageFactory $resultPageFactory, + GiftcardFactory $giftcardFactory, + BuckarooGiftcardDataInterface $buckarooGiftcardData + ) { + parent::__construct($context); + + $this->buckarooGiftcardData = $buckarooGiftcardData; + $this->resultPageFactory = $resultPageFactory; + $this->giftcardFactory = $giftcardFactory; + } + + /** + * Edit Giftcard + * + * @return ResponseInterface|Page */ public function execute() { $giftcardId = $this->getRequest()->getParam('entity_id'); /** - * @var \Buckaroo\Magento2\Model\Giftcard $model + * @var Giftcard $model */ $model = $this->giftcardFactory->create(); if ($giftcardId) { $model->load($giftcardId); if (!$model->getId()) { - $this->messageManager->addError(__('This giftcard no longer exists.')); - $this->_redirect('*/*/'); - return; + $this->messageManager->addErrorMessage(__('This giftcard no longer exists.')); + return $this->_redirect('*/*/'); } } @@ -47,10 +92,11 @@ public function execute() if (!empty($data)) { $model->setData($data); } - $this->_coreRegistry->register('buckaroo_giftcard', $model); + + $this->buckarooGiftcardData->setGiftcardModel($model); /** - * @var \Magento\Backend\Model\View\Result\Page $resultPage + * @var Page $resultPage */ $resultPage = $this->resultPageFactory->create(); $resultPage->setActiveMenu('Buckaroo_Magento2::buckaroo_giftcards'); diff --git a/Controller/Adminhtml/Giftcard/Index.php b/Controller/Adminhtml/Giftcard/Index.php index d0c606362..9b154b80b 100644 --- a/Controller/Adminhtml/Giftcard/Index.php +++ b/Controller/Adminhtml/Giftcard/Index.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,46 +17,56 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Controller\Adminhtml\Giftcard; -use Magento\Backend\App\Action\Context; -use Magento\Framework\Registry; -use Magento\Framework\View\Result\PageFactory; use Buckaroo\Magento2\Model\GiftcardFactory; +use Magento\Backend\App\Action; +use Magento\Backend\App\Action\Context; +use Magento\Backend\Model\View\Result\Page; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\Filesystem; -use Magento\MediaStorage\Model\File\UploaderFactory; use Magento\Framework\Image\AdapterFactory; +use Magento\Framework\View\Result\PageFactory; +use Magento\MediaStorage\Model\File\UploaderFactory; -class Index extends \Magento\Backend\App\Action +class Index extends Action implements HttpGetActionInterface { /** - * @var PageFactory + * @var PageFactory */ protected $resultPageFactory; - /** - * @var Registry - */ - protected $_coreRegistry; - /** * @var GiftcardFactory */ protected $giftcardFactory; + /** + * @var Filesystem + */ protected $fileSystem; + + /** + * @var UploaderFactory + */ protected $uploaderFactory; + + /** + * @var AdapterFactory + */ protected $adapterFactory; /** - * @param Context $context - * @param Registry $coreRegistry - * @param PageFactory $resultPageFactory + * @param Context $context + * @param PageFactory $resultPageFactory * @param GiftcardFactory $giftcardFactory + * @param Filesystem $fileSystem + * @param UploaderFactory $uploaderFactory + * @param AdapterFactory $adapterFactory */ public function __construct( Context $context, - Registry $coreRegistry, PageFactory $resultPageFactory, GiftcardFactory $giftcardFactory, Filesystem $fileSystem, @@ -66,7 +76,6 @@ public function __construct( parent::__construct($context); $this->resultPageFactory = $resultPageFactory; - $this->_coreRegistry = $coreRegistry; $this->giftcardFactory = $giftcardFactory; $this->fileSystem = $fileSystem; $this->adapterFactory = $adapterFactory; @@ -74,12 +83,14 @@ public function __construct( } /** - * @return \Magento\Backend\Model\View\Result\Page + * Giftcard Grid + * + * @return Page */ public function execute() { /** - * @var \Magento\Backend\Model\View\Result\Page $resultPage + * @var Page $resultPage */ $resultPage = $this->resultPageFactory->create(); $resultPage->setActiveMenu('Buckaroo_Magento2::buckaroo_giftcards'); @@ -89,7 +100,7 @@ public function execute() } /** - * Is the user allowed to view the blog post grid. + * Is the user allowed to view the giftcards grid. * * @return bool */ diff --git a/Controller/Adminhtml/Giftcard/NewAction.php b/Controller/Adminhtml/Giftcard/NewAction.php index 5cc2725e4..9817a5080 100644 --- a/Controller/Adminhtml/Giftcard/NewAction.php +++ b/Controller/Adminhtml/Giftcard/NewAction.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,13 +17,27 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ +declare(strict_types=1); namespace Buckaroo\Magento2\Controller\Adminhtml\Giftcard; -class NewAction extends \Buckaroo\Magento2\Controller\Adminhtml\Giftcard\Index +use Magento\Backend\App\Action; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\Controller\Result\Forward; +use Magento\Framework\Controller\ResultFactory; +use Magento\Framework\Controller\ResultInterface; + +class NewAction extends Action implements HttpGetActionInterface { - public function execute() + /** + * New action + * + * @return ResultInterface + */ + public function execute(): ResultInterface { - $this->_forward('edit'); + /** @var Forward $resultForward */ + $resultForward = $this->resultFactory->create(ResultFactory::TYPE_FORWARD); + return $resultForward->forward('edit'); } } diff --git a/Controller/Adminhtml/Giftcard/Save.php b/Controller/Adminhtml/Giftcard/Save.php index 39879f03b..e28f1e482 100644 --- a/Controller/Adminhtml/Giftcard/Save.php +++ b/Controller/Adminhtml/Giftcard/Save.php @@ -1,4 +1,5 @@ getRequest()->getPost(); - if ($isPost) { - $giftcardModel = $this->giftcardFactory->create(); - $giftcardId = $this->getRequest()->getParam('entity_id'); + $giftcardId = $this->getRequest()->getParam('entity_id'); if ($giftcardId) { $giftcardModel->load($giftcardId); } - $formData = $this->getRequest()->getParam('giftcard'); - - $filesData = $this->getRequest()->getFiles('logo'); - - if ((isset($filesData['name'])) && ($filesData['name'] != '') && (!isset($formData['logo']['delete']))) { - try { - $uploaderFactory = $this->uploaderFactory->create(['fileId' => 'logo']); - $uploaderFactory->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']); - $imageAdapter = $this->adapterFactory->create(); - $uploaderFactory->setAllowRenameFiles(true); - $uploaderFactory->setFilesDispersion(true); - $mediaDirectory = $this->fileSystem->getDirectoryRead(DirectoryList::MEDIA); - $destinationPath = $mediaDirectory->getAbsolutePath('buckaroo'); - $result = $uploaderFactory->save($destinationPath); - - if (!$result) { - throw new LocalizedException(__('File cannot be saved to path: $1', $destinationPath)); - } - - $formData['logo'] = 'buckaroo' . $result['file']; - - } catch (\Exception $e) { - $this->messageManager->addError($e->getMessage()); - } - } - - if (isset($formData['logo']['delete'])) { - $formData['logo'] = ''; - } - + $formData = $this->getFormData(); $giftcardModel->setData($formData); try { @@ -74,18 +52,53 @@ public function execute() $this->messageManager->addSuccess(__('The giftcard has been saved.')); if ($this->getRequest()->getParam('back')) { - $this->_redirect('*/*/edit', ['entity_id' => $giftcardModel->getId(), '_current' => true]); - return; + return $this->_redirect('*/*/edit', ['entity_id' => $giftcardModel->getId(), '_current' => true]); } - $this->_redirect('*/*/'); - return; + return $this->_redirect('*/*/'); } catch (\Exception $e) { $this->messageManager->addError($e->getMessage()); } $this->_getSession()->setFormData($formData); - $this->_redirect('*/*/edit', ['id' => $giftcardId]); + return $this->_redirect('*/*/edit', ['id' => $giftcardId]); } } + + /** + * Return form data + * + * @return array + */ + private function getFormData() + { + $formData = $this->getRequest()->getParam('giftcard'); + $filesData = $this->getRequest()->getFiles('logo'); + + if ((isset($filesData['name'])) && ($filesData['name'] != '') && (!isset($formData['logo']['delete']))) { + try { + $uploaderFactory = $this->uploaderFactory->create(['fileId' => 'logo']); + $uploaderFactory->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']); + $uploaderFactory->setAllowRenameFiles(true); + $uploaderFactory->setFilesDispersion(true); + $mediaDirectory = $this->fileSystem->getDirectoryRead(DirectoryList::MEDIA); + $destinationPath = $mediaDirectory->getAbsolutePath('buckaroo'); + $result = $uploaderFactory->save($destinationPath); + + if (!$result) { + throw new LocalizedException(__('File cannot be saved to path: $1', $destinationPath)); + } + + $formData['logo'] = 'buckaroo' . $result['file']; + } catch (\Exception $e) { + $this->messageManager->addErrorMessage($e->getMessage()); + } + } + + if (isset($formData['logo']['delete'])) { + $formData['logo'] = ''; + } + + return $formData; + } } diff --git a/Controller/Adminhtml/Log/Index.php b/Controller/Adminhtml/Log/Index.php new file mode 100644 index 000000000..2a861b9df --- /dev/null +++ b/Controller/Adminhtml/Log/Index.php @@ -0,0 +1,42 @@ +resultFactory->create(ResultFactory::TYPE_PAGE); + $resultPage->getConfig()->getTitle()->prepend(__("Log")); + return $resultPage; + } +} diff --git a/Controller/Adminhtml/Notification/MarkUserNotified.php b/Controller/Adminhtml/Notification/MarkUserNotified.php index f5f5e292c..a3dfe5324 100644 --- a/Controller/Adminhtml/Notification/MarkUserNotified.php +++ b/Controller/Adminhtml/Notification/MarkUserNotified.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,26 +20,33 @@ namespace Buckaroo\Magento2\Controller\Adminhtml\Notification; -use Magento\Framework\Controller\ResultInterface; +use Magento\Backend\App\Action; +use Magento\Backend\App\Action\Context; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; +use Magento\Framework\Controller\ResultInterface; use Magento\Framework\FlagManager; use Psr\Log\LoggerInterface; -class MarkUserNotified extends \Magento\Backend\App\Action +class MarkUserNotified extends Action implements HttpPostActionInterface { - /** @var FlagManager $flagManager */ - private $flagManager; + /** + * @var FlagManager $flagManager + */ + private FlagManager $flagManager; - /** @var LoggerInterface $logger */ - private $logger; + /** + * @var LoggerInterface $logger + */ + private LoggerInterface $logger; /** - * @param \Magento\Backend\App\Action\Context $context + * @param Context $context * @param FlagManager $flagManager * @param LoggerInterface $logger */ public function __construct( - \Magento\Backend\App\Action\Context $context, + Context $context, FlagManager $flagManager, LoggerInterface $logger ) { @@ -50,6 +57,8 @@ public function __construct( } /** + * Buckaroo Release notification + * * @return ResultInterface */ public function execute() @@ -60,7 +69,11 @@ public function execute() 'error_message' => '' ]; } catch (\Exception $e) { - $this->logger->error($e->getMessage()); + $this->logger->error(sprintf( + '[ReleaseNotification] | [Controller] | [%s] - Failed to set flag release notification | [ERROR]: %s', + __METHOD__, + $e->getMessage() + )); $responseContent = [ 'success' => false, 'error_message' => __('Failed to set flag that user has seen screen') diff --git a/Controller/Adminhtml/PayLink/Index.php b/Controller/Adminhtml/PayLink/Index.php index 701f141f4..04fac3b29 100644 --- a/Controller/Adminhtml/PayLink/Index.php +++ b/Controller/Adminhtml/PayLink/Index.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,139 +17,93 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ +declare(strict_types=1); + namespace Buckaroo\Magento2\Controller\Adminhtml\PayLink; -use Buckaroo\Magento2\Gateway\Http\TransactionBuilder\Order; -use Buckaroo\Magento2\Model\ConfigProvider\Method\Factory; +use Magento\Backend\App\Action; use Magento\Backend\App\Action\Context; -use Magento\Framework\View\Result\PageFactory; -use \Magento\Framework\Controller\ResultFactory; - -class Index extends \Magento\Backend\App\Action +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Request\Http; +use Magento\Framework\Controller\ResultFactory; +use Magento\Framework\Controller\ResultInterface; +use Magento\Framework\Exception\NotFoundException; +use Magento\Payment\Gateway\Command\CommandException; +use Magento\Payment\Gateway\Command\CommandManagerPoolInterface; +use Magento\Sales\Api\OrderRepositoryInterface; + +class Index extends Action implements HttpGetActionInterface { - protected $resultPageFactory; - - protected $request; - - private $order; - - protected $transactionBuilderFactory; - - /** @var Factory */ - protected $configProviderMethodFactory; - - /** @var \Buckaroo\Magento2\Gateway\GatewayInterface */ - protected $gateway; - - protected $_messageManager; - + /** + * @var Http + */ + protected Http $request; + + /** + * @var CommandManagerPoolInterface + */ + private CommandManagerPoolInterface $commandManagerPool; + + /** + * @var OrderRepositoryInterface + */ + private OrderRepositoryInterface $orderRepository; + + /** + * @param Context $context + * @param Http $request + * @param OrderRepositoryInterface $orderRepository + * @param CommandManagerPoolInterface $commandManagerPool + */ public function __construct( Context $context, - PageFactory $resultPageFactory, - \Magento\Framework\App\Request\Http $request, - \Magento\Sales\Api\Data\OrderInterface $order, - \Buckaroo\Magento2\Gateway\Http\TransactionBuilderFactory $transactionBuilderFactory, - Factory $configProviderMethodFactory, - \Buckaroo\Magento2\Gateway\GatewayInterface $gateway, - \Magento\Framework\Message\ManagerInterface $messageManager, - ResultFactory $resultFactory + Http $request, + OrderRepositoryInterface $orderRepository, + CommandManagerPoolInterface $commandManagerPool ) { parent::__construct($context); - $this->request = $request; - $this->resultPageFactory = $resultPageFactory; - $this->order = $order; - $this->transactionBuilderFactory = $transactionBuilderFactory; - $this->configProviderMethodFactory = $configProviderMethodFactory; - $this->gateway = $gateway; - $this->_messageManager = $messageManager; - $this->resultFactory = $resultFactory; + $this->request = $request; + $this->orderRepository = $orderRepository; + $this->commandManagerPool = $commandManagerPool; } - public function execute() + /** + * Generate PayLink from Sales Order View Admin + * + * @return ResultInterface + * @throws \Exception + */ + public function execute(): ResultInterface { - $order_id = $this->request->getParam('order_id'); - $order = $this->order->load($order_id); + $orderId = $this->request->getParam('order_id'); + $order = $this->orderRepository->get($orderId); - if (!$order_id) { - $this->_messageManager->addErrorMessage('Order not found!'); + if (!$orderId) { + $this->messageManager->addErrorMessage('Order not found!'); $redirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); return $redirect->setUrl($this->_redirect->getRefererUrl()); } - $config = $this->configProviderMethodFactory->get('paylink'); - $payment = $order->getPayment(); - $store = $payment->getMethodInstance()->getStore(); - $services = [ - 'Name' => 'payperemail', - 'Action' => 'PaymentInvitation', - 'Version' => 1, - 'RequestParameter' => [ - [ - '_' => 'true', - 'Name' => 'MerchantSendsEmail', - ], - [ - '_' => $order->getCustomerGender() ?? 1, - 'Name' => 'CustomerGender', - ], - [ - '_' => $order->getCustomerEmail(), - 'Name' => 'CustomerEmail', - ], - [ - '_' => $order->getCustomerFirstname(), - 'Name' => 'CustomerFirstName', - ], - [ - '_' => $order->getCustomerLastname(), - 'Name' => 'CustomerLastName', - ], - [ - '_' => $config->getPaymentMethod($store), - 'Name' => 'PaymentMethodsAllowed', - ], - ] - ]; - $currentPayment = $payment->getMethod(); $payment->setMethod('buckaroo_magento2_payperemail'); $payment->save(); $order->save(); - $transactionBuilder = $this->transactionBuilderFactory->get('order'); - - $transactionBuilder->setOrder($order) - ->setServices($services) - ->setAdditionalParameter('fromPayLink', 1) - ->setAdditionalParameter('fromPayPerEmail', 1) - ->setMethod('TransactionRequest'); - try { - $transaction = $transactionBuilder->build(); - $this->gateway->setMode($config->getActive($order->getStore())); - - $response = $this->gateway->authorize($transaction); - if (is_array($response[0]->Services->Service->ResponseParameter)) { - foreach ($response[0]->Services->Service->ResponseParameter as $parameter) { - if ($parameter->Name == 'PayLink') { - $payLink = $parameter->_; - } - } - } - } catch (\Exception $e) { - $this->_messageManager->addErrorMessage($e->getMessage()); - } + $commandExecutor = $this->commandManagerPool->get('buckaroo'); - if (empty($payLink)) { - $this->_messageManager->addErrorMessage('Error creating PayLink'); - } else { - $this->_messageManager->addSuccess( - __( - 'Your PayLink %1', - $payLink - ) + $commandExecutor->executeByCode( + 'paylink', + $payment, + [ + 'amount' => $order->getGrandTotal() + ] ); + } catch (NotFoundException|CommandException $exception) { + $this->messageManager->addErrorMessage($exception->getMessage()); + } catch (\Exception $e) { + $this->messageManager->addErrorMessage($e->getMessage()); } $payment = $order->getPayment(); diff --git a/Controller/Applepay/AbstractApplepay.php b/Controller/Applepay/AbstractApplepay.php new file mode 100644 index 000000000..9b1824366 --- /dev/null +++ b/Controller/Applepay/AbstractApplepay.php @@ -0,0 +1,114 @@ +resultJsonFactory = $resultJsonFactory; + $this->request = $request; + $this->logger = $logger; + } + + /** + * Get Params + * + * @return array + */ + public function getParams(): array + { + return $this->request->getParams(); + } + + /** + * Get totals + * + * @param Address|null $address + * @param AddressTotal[] $quoteTotals + * @return array + */ + public function gatherTotals(?Address $address, array $quoteTotals): array + { + $shippingTotalInclTax = 0; + if ($address !== null) { + $shippingTotalInclTax = $address->getData('shipping_incl_tax'); + } + + return [ + 'subtotal' => $quoteTotals['subtotal']->getValue(), + 'discount' => isset($quoteTotals['discount']) ? $quoteTotals['discount']->getValue() : null, + 'shipping' => $shippingTotalInclTax, + 'grand_total' => $quoteTotals['grand_total']->getValue() + ]; + } + + /** + * Return Json Response from array + * + * @param array|string $data + * @param string|bool $errorMessage + * @return Json + */ + protected function commonResponse($data, $errorMessage): Json + { + if ($errorMessage || empty($data)) { + $response = ['success' => 'false', 'error' => $errorMessage]; + } else { + $response = ['success' => 'true', 'data' => $data]; + } + + $resultJson = $this->resultJsonFactory->create(); + return $resultJson->setData($response); + } +} diff --git a/Controller/Applepay/Add.php b/Controller/Applepay/Add.php index faf0c9238..c6801a8e1 100644 --- a/Controller/Applepay/Add.php +++ b/Controller/Applepay/Add.php @@ -1,13 +1,12 @@ formKey = $formKey; - $this->product = $product; $this->addService = $addService; - $this->context = $context; } /** - * @return Page + * Add Applepay + * + * @return Json */ public function execute() { - return $this->commonResponse( - $this->addService->process($this->getRequest()), - false - ); + $this->logger->addDebug(sprintf( + '[ApplePay] | [Controller] | [%s:%s] - Add Product to Cart | request: %s', + __METHOD__, + __LINE__, + var_export($this->getParams(), true) + )); + + $data = $this->addService->process($this->getParams()); + $errorMessage = $data['error'] ?? false; + + $this->logger->addDebug(sprintf( + '[ApplePay] | [Controller] | [%s:%s] - Add Product to Cart | response: %s', + __METHOD__, + __LINE__, + var_export($data, true) + )); + + return $this->commonResponse($data, $errorMessage); } } diff --git a/Controller/Applepay/Common.php b/Controller/Applepay/Common.php deleted file mode 100644 index cd951a6d1..000000000 --- a/Controller/Applepay/Common.php +++ /dev/null @@ -1,361 +0,0 @@ -resultPageFactory = $resultPageFactory; - $this->resultJsonFactory = $resultJsonFactory; - $this->inlineParser = $inlineParser; - $this->logger = $logger; - $this->cart = $cart; - $this->totalsCollector = $totalsCollector; - $this->converter = $converter; - $this->customerSession = $customerSession ?? ObjectManager::getInstance()->get(CustomerSession::class); - } - - // @codingStandardsIgnoreStart - public function execute() - { - /** - * call the parent, method required part of the interface - */ - parent::execute(); - } - // @codingStandardsIgnoreEnd - - /** - * @param $address - * @param $quoteTotals - * - * @return array - */ - public function gatherTotals($address, $quoteTotals) - { - $shippingTotalInclTax = 0; - if ($address !== null) { - $shippingTotalInclTax = $address->getData('shipping_incl_tax'); - } - - return [ - 'subtotal' => $quoteTotals['subtotal']->getValue(), - 'discount' => isset($quoteTotals['discount']) ? $quoteTotals['discount']->getValue() : null, - 'shipping' => $shippingTotalInclTax, - 'grand_total' => $quoteTotals['grand_total']->getValue() - ]; - } - - /** - * @param $wallet - * @param string $type - * - * @return array - */ - public function processAddressFromWallet($wallet, $type = 'shipping') - { - $address = [ - 'prefix' => '', - 'firstname' => isset($wallet['givenName']) ? $wallet['givenName'] : '', - 'middlename' => '', - 'lastname' => isset($wallet['familyName']) ? $wallet['familyName'] : '', - 'street' => [ - '0' => isset($wallet['addressLines'][0]) ? $wallet['addressLines'][0] : '', - '1' => isset($wallet['addressLines'][1]) ? $wallet['addressLines'][1] : null - ], - 'city' => isset($wallet['locality']) ? $wallet['locality'] : '', - 'country_id' => isset($wallet['countryCode']) ? strtoupper($wallet['countryCode']) : '', - 'region' => isset($wallet['administrativeArea']) ? $wallet['administrativeArea'] : '', - 'region_id' => '', - 'postcode' => isset($wallet['postalCode']) ? $wallet['postalCode'] : '', - 'telephone' => isset($wallet['phoneNumber']) ? $wallet['phoneNumber'] : 'N/A', - 'fax' => '', - 'vat_id' => '' - ]; - $address['street'] = implode("\n",$address['street']); - if ($type == 'shipping') { - $address['email'] = isset($wallet['emailAddress']) ? $wallet['emailAddress'] : ''; - } - - return $address; - } - - protected function commonResponse($data, $errorMessage) - { - if ($errorMessage || empty($data)) { - $response = ['success' => 'false']; - } else { - $response = ['success' => 'true', 'data' => $data]; - } - $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true); - - /** @var \Magento\Framework\Controller\Result\Json $resultJson */ - $resultJson = $this->resultJsonFactory->create(); - - return $resultJson->setData($response); - } - - protected function setShippingAddress(&$quote, $data) - { - $this->logger->addDebug(__METHOD__ . '|1|'); - - $shippingAddress = $this->processAddressFromWallet($data, 'shipping'); - $quote->getShippingAddress()->addData($shippingAddress); - $quote->setShippingAddress($quote->getShippingAddress()); - - $errors = $quote->getShippingAddress()->validate(); - return $this->setCommonAddressProceed($errors, 'shipping'); - } - - protected function setBillingAddress(&$quote, $data) - { - $this->logger->addDebug(__METHOD__ . '|1|'); - - $billingAddress = $this->processAddressFromWallet($data, 'billing'); - $quote->getBillingAddress()->addData($billingAddress); - $quote->setBillingAddress($quote->getBillingAddress()); - - $errors = $quote->getBillingAddress()->validate(); - return $this->setCommonAddressProceed($errors, 'billing'); - } - - protected function setCommonAddressProceed($errors, $addressType) - { - $this->logger->addDebug(__METHOD__ . '|1|'); - $this->logger->addDebug(var_export($errors, true)); - - $errorFields = []; - if ($errors && is_array($errors)) { - foreach ($errors as $error) { - if (($arguments = $error->getArguments()) && !empty($arguments['fieldName'])) { - if ($arguments['fieldName'] === 'postcode') { - $errorFields[] = $arguments['fieldName']; - $this->logger->addDebug(var_export($error->getArguments()['fieldName'], true)); - $this->messageManager->addErrorMessage(__( - 'Error: ' . $addressType . ' address: postcode is required' - )); - } - } - } - } - - if (empty($errorFields)) { - $this->logger->addDebug(__METHOD__ . '|2|'); - return true; - } else { - $this->logger->addDebug(__METHOD__ . '|3|'); - return false; - } - } - - protected function getShippingMethods(&$quote, $objectManager) - { - $this->logger->addDebug(__METHOD__ . '|1|'); - - $quoteRepository = $objectManager->get(\Magento\Quote\Model\QuoteRepository::class); - - $quote->getPayment()->setMethod(\Buckaroo\Magento2\Model\Method\Applepay::PAYMENT_METHOD_CODE); - $quote->getShippingAddress()->setCollectShippingRates(true); - - $shippingMethodsResult = []; - if (!$quote->getIsVirtual()) { - $shippingMethods = $this->getShippingMethods2($quote, $quote->getShippingAddress()); - - if (count($shippingMethods) == 0) { - $errorMessage = __( - 'Apple Pay payment failed, because no shipping methods were found for the selected address. '. - 'Please select a different shipping address within the pop-up or within your Apple Pay Wallet.' - ); - $this->messageManager->addErrorMessage($errorMessage); - return []; - - } else { - - foreach ($shippingMethods as $shippingMethod) { - $shippingMethodsResult[] = [ - 'carrier_title' => $shippingMethod->getCarrierTitle(), - 'price_incl_tax' => round($shippingMethod->getAmount(), 2), - 'method_code' => $shippingMethod->getCarrierCode() . '_' . $shippingMethod->getMethodCode(), - 'method_title' => $shippingMethod->getMethodTitle(), - ]; - } - - $this->logger->addDebug(__METHOD__ . '|2|'); - - $quote->getShippingAddress()->setShippingMethod($shippingMethodsResult[0]['method_code']); - } - } - $quote->setTotalsCollectedFlag(false); - $quote->collectTotals(); - $totals = $this->gatherTotals($quote->getShippingAddress(), $quote->getTotals()); - if ($quote->getSubtotal() != $quote->getSubtotalWithDiscount()) { - $totals['discount'] = round($quote->getSubtotalWithDiscount() - $quote->getSubtotal(), 2); - } - $data = [ - 'shipping_methods' => $shippingMethodsResult, - 'totals' => $totals - ]; - $quoteRepository->save($quote); - $this->cart->save(); - - $this->logger->addDebug(__METHOD__ . '|3|'); - - return $data; - } - - /** - * Get transform address interface into Array - * - * @param \Magento\Framework\Api\ExtensibleDataInterface $address - * @return array - */ - private function extractAddressData($address) - { - $className = \Magento\Customer\Api\Data\AddressInterface::class; - if ($address instanceof \Magento\Quote\Api\Data\AddressInterface) { - $className = \Magento\Quote\Api\Data\AddressInterface::class; - } elseif ($address instanceof EstimateAddressInterface) { - $className = EstimateAddressInterface::class; - } - return $this->getDataObjectProcessor()->buildOutputDataArray( - $address, - $className - ); - } - - /** - * Gets the data object processor - * - * @return \Magento\Framework\Reflection\DataObjectProcessor - * @deprecated 101.0.0 - */ - private function getDataObjectProcessor() - { - if ($this->dataProcessor === null) { - $this->dataProcessor = ObjectManager::getInstance() - ->get(DataObjectProcessor::class); - } - return $this->dataProcessor; - } - - /** - * Get list of available shipping methods - * - * @param \Magento\Quote\Model\Quote $quote - * @param \Magento\Framework\Api\ExtensibleDataInterface $address - * @return \Magento\Quote\Api\Data\ShippingMethodInterface[] - */ - private function getShippingMethods2(Quote $quote, $address) - { - $output = []; - $shippingAddress = $quote->getShippingAddress(); - $extractedAddressData = $this->extractAddressData($address); - if (array_key_exists('extension_attributes', $extractedAddressData)) { - unset($extractedAddressData['extension_attributes']); - } - $shippingAddress->addData($extractedAddressData); - - $shippingAddress->setCollectShippingRates(true); - - $this->totalsCollector->collectAddressTotals($quote, $shippingAddress); - $quoteCustomerGroupId = $quote->getCustomerGroupId(); - $customerGroupId = $this->customerSession->getCustomerGroupId(); - $isCustomerGroupChanged = $quoteCustomerGroupId !== $customerGroupId; - if ($isCustomerGroupChanged) { - $quote->setCustomerGroupId($customerGroupId); - } - $shippingRates = $shippingAddress->getGroupedAllShippingRates(); - foreach ($shippingRates as $carrierRates) { - foreach ($carrierRates as $rate) { - $output[] = $this->converter->modelToDataObject($rate, $quote->getQuoteCurrencyCode()); - } - } - if ($isCustomerGroupChanged) { - $quote->setCustomerGroupId($quoteCustomerGroupId); - } - return $output; - } -} diff --git a/Controller/Applepay/GetShippingMethods.php b/Controller/Applepay/GetShippingMethods.php index 81299e60b..84483ca18 100644 --- a/Controller/Applepay/GetShippingMethods.php +++ b/Controller/Applepay/GetShippingMethods.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,90 +17,135 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Controller\Applepay; -use Buckaroo\Magento2\Logging\Log; -use Magento\Framework\App\Action\Action; -use Magento\Framework\App\Action\Context; -use Magento\Framework\View\Result\Page; -use Magento\Framework\View\Result\PageFactory; -use Buckaroo\Magento2\Service\Applepay\GetShippingMethods as GetShippingMethodsService; -use Magento\Quote\Model\Cart\ShippingMethodConverter; -use Magento\Quote\Model\Quote\TotalsCollector; -use Magento\Customer\Model\Session as CustomerSession; -use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; -use Magento\Quote\Api\CartRepositoryInterface; - -class GetShippingMethods extends Common +use Buckaroo\Magento2\Logging\BuckarooLoggerInterface; +use Buckaroo\Magento2\Model\ConfigProvider\Method\Applepay; +use Buckaroo\Magento2\Model\Service\ApplePayFormatData; +use Buckaroo\Magento2\Model\Service\QuoteService; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Controller\Result\Json; +use Magento\Framework\Controller\Result\JsonFactory; +use Magento\Framework\Exception\NoSuchEntityException; + +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class GetShippingMethods extends AbstractApplepay { /** - * @var MaskedQuoteIdToQuoteIdInterface + * @var QuoteService */ - private MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId; + private QuoteService $quoteService; /** - * @var CartRepositoryInterface + * @var ApplePayFormatData */ - private CartRepositoryInterface $cartRepository; + private ApplePayFormatData $applePayFormatData; + /** + * @param JsonFactory $resultJsonFactory + * @param RequestInterface $request + * @param BuckarooLoggerInterface $logger + * @param QuoteService $quoteService + * @param ApplePayFormatData $applePayFormatData + */ public function __construct( - Context $context, - PageFactory $resultPageFactory, - \Magento\Framework\Translate\Inline\ParserInterface $inlineParser, - \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory, - Log $logger, - \Magento\Checkout\Model\Cart $cart, - \Magento\Quote\Model\Quote\TotalsCollector $totalsCollector, - \Magento\Quote\Model\Cart\ShippingMethodConverter $converter, - CustomerSession $customerSession = null, - MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, - CartRepositoryInterface $cartRepository - + JsonFactory $resultJsonFactory, + RequestInterface $request, + BuckarooLoggerInterface $logger, + QuoteService $quoteService, + ApplePayFormatData $applePayFormatData ) { parent::__construct( - $context, - $resultPageFactory, - $inlineParser, $resultJsonFactory, - $logger, - $cart, - $totalsCollector, - $converter, - $customerSession + $request, + $logger ); - $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->cartRepository = $cartRepository; + $this->quoteService = $quoteService; + $this->applePayFormatData = $applePayFormatData; } + /** - * @return Page + * Return Shipping Methods + * + * @return Json */ public function execute() { - $isPost = $this->getRequest()->getPostValue(); + $postValues = $this->getParams(); + + $this->logger->addDebug(sprintf( + '[ApplePay] | [Controller] | [%s:%s] - Get Shipping Methods | request: %s', + __METHOD__, + __LINE__, + var_export($postValues, true) + )); - $errorMessage = false; $data = []; - if ($isPost) { - if (($wallet = $this->getRequest()->getParam('wallet')) - ) { - $cart_hash = $this->getRequest()->getParam('id'); - $objectManager = \Magento\Framework\App\ObjectManager::getInstance();//instance of object manager - - if($cart_hash) { - $cartId = $this->maskedQuoteIdToQuoteId->execute($cart_hash); - $quote = $this->cartRepository->get($cartId); - } else { - - $checkoutSession = $objectManager->get(\Magento\Checkout\Model\Session::class); - $quote = $checkoutSession->getQuote(); - } - - if (!$quote->getIsVirtual() && !$this->setShippingAddress($quote, $wallet)) { - return $this->commonResponse(false, true); + $errorMessage = false; + if (!empty($postValues) && isset($postValues['wallet'])) { + try { + // Get Cart + $cartHash = $postValues['id'] ?? null; + $this->quoteService->getQuote($cartHash); + + // Get Shipping Address From Request + $shippingAddressRequest = $this->applePayFormatData->getShippingAddressObject($postValues['wallet']); + + // Add Shipping Address on Quote + $this->quoteService->addAddressToQuote($shippingAddressRequest); + + //Set Payment Method + $this->quoteService->setPaymentMethod(Applepay::CODE); + + // Get Shipping Methods + $shippingMethodsResult = []; + if (!$this->quoteService->getQuote()->getIsVirtual()) { + $shippingMethods = $this->quoteService->getAvailableShippingMethods(); + if (count($shippingMethods) <= 0) { + $errorMessage = __( + 'Apple Pay payment failed, because no shipping methods were found for the selected address. ' . + 'Please select a different shipping address within the pop-up or within your Apple Pay Wallet.' + ); + } else { + foreach ($shippingMethods as $shippingMethod) { + $shippingMethodsResult[] = [ + 'carrier_title' => $shippingMethod->getCarrierTitle(), + 'price_incl_tax' => round($shippingMethod->getAmount(), 2), + 'method_code' => $shippingMethod->getCarrierCode() . '_' . $shippingMethod->getMethodCode(), + 'method_title' => $shippingMethod->getMethodTitle(), + ]; + } + + $this->logger->addDebug(__METHOD__ . '|2|'); + + $this->quoteService->setShippingMethod($shippingMethodsResult[0]['method_code']); + } } - $data = $this->getShippingMethods($quote, $objectManager); + // Calculate Quote Totals + $this->quoteService->calculateQuoteTotals(); + + // Get Totals + $totals = $this->quoteService->gatherTotals(); + + $data = [ + 'shipping_methods' => $shippingMethodsResult, + 'totals' => $totals + ]; + } catch (\Exception $exception) { + $this->logger->addError(sprintf( + '[ApplePay] | [Controller] | [%s:%s] - Get Shipping Methods | [ERROR]: %s', + __METHOD__, + __LINE__, + $exception->getMessage() + )); + $errorMessage = __('Get shipping methods failed'); } + } else { + $errorMessage = __('Details from Wallet ApplePay are not received.'); } return $this->commonResponse($data, $errorMessage); diff --git a/Controller/Applepay/SaveOrder.php b/Controller/Applepay/SaveOrder.php index 6b6ca60a8..d040bff14 100644 --- a/Controller/Applepay/SaveOrder.php +++ b/Controller/Applepay/SaveOrder.php @@ -1,4 +1,5 @@ quoteManagement = $quoteManagement; - $this->customer = $customer; + $this->customerSession = $customerSession; $this->objectFactory = $objectFactory; - $this->registry = $registry; - $this->order = $order; - $this->checkoutSession = $checkoutSession; + $this->buckarooResponseData = $buckarooResponseData; + $this->orderRepository = $orderRepository; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->checkoutSession = $checkoutSession; + $this->quoteAddressService = $quoteAddressService; $this->accountConfig = $configProviderFactory->get('account'); } + //phpcs:ignore:Generic.Metrics.NestingLevel + + /** + * Save Order + * + * @return Json + * @throws LocalizedException + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ public function execute() { - $isPost = $this->getRequest()->getPostValue(); + $isPost = $this->getParams(); $errorMessage = false; $data = []; - $shippingMethodsResult = []; - if ($isPost) { - if (($payment = $this->getRequest()->getParam('payment')) - && - ($extra = $this->getRequest()->getParam('extra')) + if ($isPost + && ($payment = $isPost['payment']) + && ($extra = $isPost['extra']) + ) { + $this->logger->addDebug(sprintf( + '[ApplePay] | [Controller] | [%s:%s] - Save Order | request: %s', + __METHOD__, + __LINE__, + var_export($isPost, true) + )); + + // Get Cart + $quote = $this->checkoutSession->getQuote(); + + // Set Address + if (!$quote->getIsVirtual() && !$this->quoteAddressService->setShippingAddress($quote, $payment['shippingContact'])) { + return $this->commonResponse(false, true); + } + if ( + !$this->quoteAddressService->setBillingAddress( + $quote, + $payment['billingContact'], + $payment['shippingContact']['phoneNumber'] ?? null + ) ) { - $this->logger->addDebug(__METHOD__.'|1|'); - $this->logger->addDebug(var_export($payment, true)); - $this->logger->addDebug(var_export($extra, true)); + return $this->commonResponse(false, true); + } - $objectManager = \Magento\Framework\App\ObjectManager::getInstance();//instance of object manager - $checkoutSession = $objectManager->get(\Magento\Checkout\Model\Session::class); - $quote = $checkoutSession->getQuote(); + // Place Order + $this->submitQuote($quote, $extra, $payment); - if (!$quote->getIsVirtual() && !$this->setShippingAddress($quote, $payment['shippingContact'])) { - return $this->commonResponse(false, true); - } - if (!$this->setBillingAddress($quote, $payment['billingContact'])) { - return $this->commonResponse(false, true); - } + // Handle the response + $data = $this->handleResponse(); + } - $this->logger->addDebug(__METHOD__.'|2|'); + return $this->commonResponse($data, $errorMessage); + } - $emailAddress = $quote->getShippingAddress()->getEmail(); + /** + * Submit quote + * + * @param Quote $quote + * @param array|string $extra + * @return void + * @throws LocalizedException + */ + private function submitQuote($quote, $extra, $payment) + { + try { + $emailAddress = $quote->getShippingAddress()->getEmail(); - if ($quote->getIsVirtual()) { - $emailAddress = isset($payment['shippingContact']['emailAddress']) ? $payment['shippingContact']['emailAddress']: null; - } + if ($quote->getIsVirtual()) { + $emailAddress = $payment['shippingContact']['emailAddress'] ?? null; + } - if (!($this->customer->getCustomer() && $this->customer->getCustomer()->getId())) { - $quote->setCheckoutMethod('guest') - ->setCustomerId(null) - ->setCustomerEmail($emailAddress) - ->setCustomerIsGuest(true) - ->setCustomerGroupId(\Magento\Customer\Model\Group::NOT_LOGGED_IN_ID); - } + if (!($this->customerSession->getCustomer() && $this->customerSession->getCustomer()->getId())) { + $quote->setCheckoutMethod('guest') + ->setCustomerId(null) + ->setCustomerEmail($emailAddress) + ->setCustomerIsGuest(true) + ->setCustomerGroupId(Group::NOT_LOGGED_IN_ID); + } + + $quote->collectTotals()->save(); - $payment = $quote->getPayment(); - $payment->setMethod(Applepay::PAYMENT_METHOD_CODE); - $quote->setPayment($payment); - - $quote->collectTotals()->save(); - - $obj = $this->objectFactory->create(); - $obj->setData($extra); - $quote->getPayment()->getMethodInstance()->assignData($obj); - - $order = $this->quoteManagement->submit($quote); - - $data = []; - if ($this->registry && $this->registry->registry('buckaroo_response')) { - $data = $this->registry->registry('buckaroo_response')[0]; - $this->logger->addDebug(__METHOD__.'|4|'.var_export($data, true)); - if (!empty($data->RequiredAction->RedirectURL)) { - //test mode - $this->logger->addDebug(__METHOD__.'|5|'); - $data = [ - 'RequiredAction' => $data->RequiredAction - ]; - } else { - //live mode - $this->logger->addDebug(__METHOD__.'|6|'); - if (!empty($data->Status->Code->Code) - && - ($data->Status->Code->Code == '190') - && - !empty($data->Order) - ) { - $this->order->loadByIncrementId($data->Order); - - if ($this->order->getId()) { - $this->checkoutSession - ->setLastQuoteId($this->order->getQuoteId()) - ->setLastSuccessQuoteId($this->order->getQuoteId()) - ->setLastOrderId($this->order->getId()) - ->setLastRealOrderId($this->order->getIncrementId()) - ->setLastOrderStatus($this->order->getStatus()); - - $store = $this->order->getStore(); - $url = $store->getBaseUrl() . '/' . $this->accountConfig->getSuccessRedirect($store); - $this->logger->addDebug(__METHOD__.'|7|'.var_export($url, true)); - $data = [ - 'RequiredAction' => [ - 'RedirectURL' => $url - ] - ]; - } - } - } + $obj = $this->objectFactory->create(); + $obj->setData($extra); + $quote->getPayment()->setMethod($obj->getMethod()); + $quote->getPayment()->getMethodInstance()->assignData($obj); + + $this->quoteManagement->submit($quote); + } catch (\Throwable $th) { + $this->logger->addError(sprintf( + '[ApplePay] | [Controller] | [%s:%s] - Submit Quote | [ERROR]: %s', + __METHOD__, + __LINE__, + $th->getMessage() + )); + } + } + + /** + * Handle the response after placing order + * + * @return array + */ + private function handleResponse() + { + $data = []; + $buckarooResponseData = $this->buckarooResponseData->getResponse(); + if ($buckarooResponseData) { + $data = $buckarooResponseData->toArray(); + $this->logger->addDebug(sprintf( + '[ApplePay] | [Controller] | [%s:%s] - Save Order Handle Response | buckarooResponse: %s', + __METHOD__, + __LINE__, + var_export($data, true) + )); + if ($buckarooResponseData->hasRedirect()) { + //test mode + $data = [ + 'RequiredAction' => $buckarooResponseData->getRequiredAction() + ]; + } else { + //live mode + if ($buckarooResponseData->isSuccess() && !empty($buckarooResponseData->getOrder())) { + $data = $this->processBuckarooResponse($buckarooResponseData, $data); } } } - return $this->commonResponse($data, $errorMessage); + return $data; + } + + /** + * Set Order and Quote Data on Checkout Session + * + * @param TransactionResponse $buckarooResponseData + * @param array $data + * @return array + */ + private function processBuckarooResponse(TransactionResponse $buckarooResponseData, array $data): array + { + $searchCriteria = $this->searchCriteriaBuilder->addFilter( + 'increment_id', + $buckarooResponseData->getOrder() + )->create(); + $order = $this->orderRepository->getList($searchCriteria)->getFirstItem(); + + if ($order->getId()) { + $this->checkoutSession + ->setLastQuoteId($order->getQuoteId()) + ->setLastSuccessQuoteId($order->getQuoteId()) + ->setLastOrderId($order->getId()) + ->setLastRealOrderId($order->getIncrementId()) + ->setLastOrderStatus($order->getStatus()); + + $store = $order->getStore(); + $url = $store->getBaseUrl() . '/' . $this->accountConfig->getSuccessRedirect($store); + $this->logger->addDebug(sprintf( + '[ApplePay] | [Controller] | [%s:%s] - Save Order - Redirect URL | redirectURL: %s', + __METHOD__, + __LINE__, + $url + )); + $data = [ + 'RequiredAction' => [ + 'RedirectURL' => $url + ] + ]; + } + + return $data; } } diff --git a/Controller/Applepay/UpdateShippingMethods.php b/Controller/Applepay/UpdateShippingMethods.php index 10abb386a..af029a6a2 100644 --- a/Controller/Applepay/UpdateShippingMethods.php +++ b/Controller/Applepay/UpdateShippingMethods.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,48 +17,89 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Controller\Applepay; -use Magento\Framework\App\Action\Action; -use Magento\Framework\App\Action\Context; -use Magento\Framework\View\Result\Page; -use Magento\Framework\View\Result\PageFactory; +use Buckaroo\Magento2\Logging\BuckarooLoggerInterface; +use Magento\Checkout\Model\Session as CheckoutSession; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Controller\Result\JsonFactory; +use Magento\Quote\Model\QuoteRepository; -class UpdateShippingMethods extends Common +class UpdateShippingMethods extends AbstractApplepay { + /** + * @var CheckoutSession + */ + private $checkoutSession; + + /** + * @var QuoteRepository + */ + private QuoteRepository $quoteRepository; + + /** + * @param JsonFactory $resultJsonFactory + * @param RequestInterface $request + * @param BuckarooLoggerInterface $logger + * @param QuoteRepository $quoteRepository + * @param CheckoutSession $checkoutSession + */ + public function __construct( + JsonFactory $resultJsonFactory, + RequestInterface $request, + BuckarooLoggerInterface $logger, + QuoteRepository $quoteRepository, + CheckoutSession $checkoutSession + ) { + parent::__construct( + $resultJsonFactory, + $request, + $logger + ); + + $this->checkoutSession = $checkoutSession; + $this->quoteRepository = $quoteRepository; + } + + /** + * Set Shipping Method + */ public function execute() { - $isPost = $this->getRequest()->getPostValue(); + $postValues = $this->getParams(); $errorMessage = false; $data = []; - if ($isPost) { - if ($wallet = $this->getRequest()->getParam('wallet')) { - $objectManager = \Magento\Framework\App\ObjectManager::getInstance();//instance of object manager - $checkoutSession = $objectManager->get(\Magento\Checkout\Model\Session::class); - $quoteRepository = $objectManager->get(\Magento\Quote\Model\QuoteRepository::class); - $quote = $checkoutSession->getQuote(); + if (!empty($postValues) && isset($postValues['wallet'])) { + try { + // Get Cart + $quote = $this->checkoutSession->getQuote(); + if (!$quote->getIsVirtual()) { - ////shipping + // Set Shipping Method $quote->getShippingAddress()->setCollectShippingRates(true); - $quote->getShippingAddress()->setShippingMethod($wallet['identifier']); + $quote->getShippingAddress()->setShippingMethod($postValues['wallet']['identifier']); + // Recalculate Totals after setting new shipping method $quote->setTotalsCollectedFlag(false); $quote->collectTotals(); $totals = $this->gatherTotals($quote->getShippingAddress(), $quote->getTotals()); - $quoteRepository->save($quote); + + // Save Cart + $this->quoteRepository->save($quote); $data = [ 'shipping_methods' => [ - 'code' => $wallet['identifier'] + 'code' => $postValues['wallet']['identifier'] ], 'totals' => $totals ]; - - //resave proper method - $quote->getShippingAddress()->setShippingMethod($wallet['identifier']); - $quote->getShippingAddress()->save(); } + } catch (\Exception $exception) { + $errorMessage = "Setting the new Shipping Method failed."; } + } else { + $errorMessage = "The request for updating shipping method is wrong."; } return $this->commonResponse($data, $errorMessage); diff --git a/Controller/Checkout/Giftcard.php b/Controller/Checkout/Giftcard.php index 6b4736aa2..2558240a2 100644 --- a/Controller/Checkout/Giftcard.php +++ b/Controller/Checkout/Giftcard.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,80 +20,81 @@ namespace Buckaroo\Magento2\Controller\Checkout; -use Magento\Quote\Model\Quote; -use Buckaroo\Magento2\Logging\Log; -use Magento\Framework\Controller\ResultFactory; +use Buckaroo\Magento2\Logging\BuckarooLoggerInterface; use Buckaroo\Magento2\Model\Giftcard\Api\ApiException; use Buckaroo\Magento2\Model\Giftcard\Request\GiftcardInterface; use Buckaroo\Magento2\Model\Giftcard\Response\Giftcard as GiftcardResponse; +use Buckaroo\Transaction\Response\TransactionResponse; +use Magento\Checkout\Model\Session; +use Magento\Framework\App\Action\Action; +use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\App\ResponseInterface; +use Magento\Framework\Controller\ResultFactory; +use Magento\Framework\Phrase; +use Magento\Quote\Model\Quote; -class Giftcard extends \Magento\Framework\App\Action\Action +class Giftcard extends Action implements HttpPostActionInterface, HttpGetActionInterface { - /** - * @var Log + * @var BuckarooLoggerInterface */ - protected $logger; + protected BuckarooLoggerInterface $logger; /** - * @var \Magento\Framework\Controller\Result\JsonFactory - */ - protected $jsonResultFactory; - - /** - * @var \Buckaroo\Magento2\Model\Giftcard\Request\GiftcardInterface + * @var GiftcardInterface */ - protected $giftcardRequest; + protected GiftcardInterface $giftcardRequest; /** - * @var \Buckaroo\Magento2\Model\Giftcard\Response\Giftcard + * @var GiftcardResponse */ - protected $giftcardResponse; + protected GiftcardResponse $giftcardResponse; /** - * @var \Magento\Checkout\Model\Session + * @var Session */ - protected $checkoutSession; + protected Session $checkoutSession; /** - * - * @throws \Buckaroo\Magento2\Exception + * @param Context $context + * @param Session $checkoutSession + * @param GiftcardInterface $giftcardRequest + * @param GiftcardResponse $giftcardResponse + * @param BuckarooLoggerInterface $logger */ public function __construct( - \Magento\Framework\App\Action\Context $context, - \Magento\Framework\Controller\Result\JsonFactory $jsonResultFactory, - \Magento\Checkout\Model\Session $checkoutSession, + Context $context, + Session $checkoutSession, GiftcardInterface $giftcardRequest, GiftcardResponse $giftcardResponse, - Log $logger + BuckarooLoggerInterface $logger ) { parent::__construct($context); - $this->jsonResultFactory = $jsonResultFactory; $this->checkoutSession = $checkoutSession; $this->giftcardRequest = $giftcardRequest; $this->giftcardResponse = $giftcardResponse; $this->logger = $logger; - } /** * Process action * - * @return \Magento\Framework\App\ResponseInterface + * @return ResponseInterface * @throws \Exception */ public function execute() { - if ($this->getRequest()->getParam('cardNumber') === null) { return $this->displayError(__('A card number is required')); } - if ($this->getRequest()->getParam('pin') === null) { + if ($this->getRequest()->getParam('pin') === null) { return $this->displayError(__('A card pin is required')); } - if ($this->getRequest()->getParam('card') === null) { + if ($this->getRequest()->getParam('card') === null) { return $this->displayError(__('A card type is required')); } @@ -105,30 +106,53 @@ public function execute() $this->build($quote)->send() ); } catch (ApiException $th) { - $this->logger->addDebug(__METHOD__.(string)$th); + $this->logger->addError(sprintf( + '[Giftcard] | [Controller] | [%s:%s] - Apply Inline Giftcard | [ERROR]: %s', + __METHOD__, + __LINE__, + $th->getMessage() + )); return $this->displayError($th->getMessage()); } catch (\Throwable $th) { - $this->logger->addDebug(__METHOD__.(string)$th); + $this->logger->addError(sprintf( + '[Giftcard] | [Controller] | [%s:%s] - Apply Inline Giftcard | [ERROR]: %s', + __METHOD__, + __LINE__, + $th->getMessage() + )); return $this->displayError(__('Unknown buckaroo error has occurred')); } } + /** + * Return response with error message + * + * @param Phrase|string $message + * @return mixed + */ protected function displayError($message) { return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData([ "error" => $message ]); } - protected function getGiftcardResponse(Quote $quote, $response) - { + /** + * Get inline giftcard response + * + * @param Quote $quote + * @param TransactionResponse $response + * @return mixed + * @throws ApiException + */ + protected function getGiftcardResponse(Quote $quote, TransactionResponse $response) + { $this->giftcardResponse->set($response, $quote); if ($this->giftcardResponse->getErrorMessage() !== null) { throw new ApiException($this->giftcardResponse->getErrorMessage()); } - $buttonMessage = ''; $remainingAmount = $this->giftcardResponse->getRemainderAmount(); @@ -144,7 +168,9 @@ protected function getGiftcardResponse(Quote $quote, $response) ); $buttonMessage = __( - 'Pay remaining amount: %1 %2',$remainingAmount, $this->giftcardResponse->getCurrency() + 'Pay remaining amount: %1 %2', + $remainingAmount, + $this->giftcardResponse->getCurrency() ); } @@ -155,21 +181,20 @@ protected function getGiftcardResponse(Quote $quote, $response) 'message' => $textMessage ]); } + /** * Build giftcard request * * @param Quote $quote * - * @return GiftcardRequest + * @return GiftcardInterface */ protected function build(Quote $quote) { - return $this->giftcardRequest ->setCardId($this->getRequest()->getParam('card')) ->setCardNumber($this->getRequest()->getParam('cardNumber')) ->setPin($this->getRequest()->getParam('pin')) ->setQuote($quote); } - } diff --git a/Controller/Checkout/Idin.php b/Controller/Checkout/Idin.php index 605db694d..2da366d4a 100644 --- a/Controller/Checkout/Idin.php +++ b/Controller/Checkout/Idin.php @@ -1,13 +1,12 @@ transactionBuilder = $transactionBuilderFactory->get('idin'); - $this->gateway = $gateway; - $this->logger = $logger; + $this->logger = $logger; + $this->requestDataBuilder = $requestDataBuilder; + $this->transferFactory = $transferFactory; + $this->clientInterface = $clientInterface; } /** * Process action * - * @return \Magento\Framework\App\ResponseInterface + * @return Json */ - public function execute() + public function execute(): Json { $data = $this->getRequest()->getParams(); + $response = ['error' => 'Unknown buckaroo error occurred']; - if (!isset($data['issuer']) || empty($data['issuer'])) { + if (empty($data['issuer'])) { return $this->json( ['error' => 'Issuer not valid'] ); } try { - $response = $this->sendIdinRequest($data['issuer']); - } catch (\Throwable $th) { - $this->logger->debug($th->getMessage()); - return $this->json( - ['error' => 'Unknown buckaroo error occurred'] + $transferO = $this->transferFactory->create( + $this->requestDataBuilder->build($data) ); + + $response = $this->clientInterface->placeRequest($transferO); + + if (isset($response["object"]) && $response["object"] instanceof TransactionResponse) { + if ($response["object"]->isSuccess() || $response["object"]->isPendingProcessing()) { + $response = $response["object"]->toArray(); + } else { + $response = ['error' => $response['object']->getSomeError()]; + } + } else { + $response = ['error' => 'TransactionResponse is not valid']; + } + } catch (\Throwable $th) { + $this->logger->addError(sprintf( + '[iDIN] | [Controller] | [%s:%s] - Validate iDIN | [ERROR]: %s', + __METHOD__, + __LINE__, + $th->getMessage() + )); } return $this->json($response); } + /** * Return json response * * @param array $data * - * @return \Magento\Framework\App\ResponseInterface + * @return Json */ - protected function json($data) + protected function json(array $data): Json { return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($data); } - /** - * Send idin request - * - * @param string $issuer - * - * @return mixed $response - * @throws \Exception - */ - protected function sendIdinRequest($issuer) - { - $transaction = $this->transactionBuilder - ->setIssuer($issuer) - ->build(); - - return $this->gateway->setMode($this->transactionBuilder->getMode()) - ->authorize($transaction)[0]; - } } diff --git a/Controller/CredentialsChecker/Index.php b/Controller/CredentialsChecker/Index.php index a94f8443c..22d51a99b 100644 --- a/Controller/CredentialsChecker/Index.php +++ b/Controller/CredentialsChecker/Index.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,162 +20,117 @@ namespace Buckaroo\Magento2\Controller\CredentialsChecker; -use Buckaroo\Magento2\Logging\Log; +use Buckaroo\Magento2\Exception as BuckarooException; +use Buckaroo\Magento2\Gateway\Http\Client\Json as HttpClientJson; +use Buckaroo\Magento2\Helper\Data; use Buckaroo\Magento2\Model\ConfigProvider\Account; +use Buckaroo\Magento2\Model\ConfigProvider\Factory; +use Magento\Checkout\Model\ConfigProviderInterface; +use Magento\Framework\App\Action\Action; +use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\Controller\Result\Json; +use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Encryption\Encryptor; +use Magento\Framework\Phrase; -class Index extends \Magento\Framework\App\Action\Action +class Index extends Action implements HttpPostActionInterface { /** - * @var array + * @var ConfigProviderInterface */ - protected $response; + protected $accountConfig; /** - * @var Log + * @var Encryptor */ - protected $logger; + private $encryptor; /** - * @var \Magento\Framework\Controller\Result\JsonFactory + * @var Account */ - protected $resultJsonFactory; + private $configProviderAccount; /** - * @var \Magento\Checkout\Model\ConfigProviderInterface + * @var HttpClientJson */ - protected $accountConfig; - - private $urlBuilder; - private $formKey; - private $helper; - private $encryptor; - private $configProviderAccount; - private $transactionBuilderFactory; - private $gateway; - private $validatorFactory; private $client; /** - * @param \Magento\Framework\App\Action\Context $context - * @param Log $logger - * @param \Magento\Sales\Model\Order $order + * Check Credentials in Admin * - * @throws \Buckaroo\Magento2\Exception + * @param Context $context + * @param Factory $configProviderFactory + * @param Encryptor $encryptor + * @param Account $configProviderAccount + * @param HttpClientJson $client + * @throws BuckarooException */ public function __construct( - \Magento\Framework\App\Action\Context $context, - Log $logger, - \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory, - \Buckaroo\Magento2\Model\ConfigProvider\Factory $configProviderFactory, - \Magento\Framework\UrlInterface $urlBuilder, - \Magento\Framework\Data\Form\FormKey $formKey, - \Buckaroo\Magento2\Helper\Data $helper, + Context $context, + Factory $configProviderFactory, Encryptor $encryptor, Account $configProviderAccount, - \Buckaroo\Magento2\Gateway\Http\TransactionBuilderFactory $transactionBuilderFactory, - \Buckaroo\Magento2\Gateway\GatewayInterface $gateway, - \Buckaroo\Magento2\Model\ValidatorFactory $validatorFactory, - \Buckaroo\Magento2\Gateway\Http\Client\Json $client + HttpClientJson $client ) { parent::__construct($context); - $this->logger = $logger; - $this->resultJsonFactory = $resultJsonFactory; - $this->accountConfig = $configProviderFactory->get('account'); - $this->urlBuilder = $urlBuilder; - $this->formKey = $formKey; - $this->helper = $helper; - $this->encryptor = $encryptor; + $this->accountConfig = $configProviderFactory->get('account'); + $this->encryptor = $encryptor; $this->configProviderAccount = $configProviderAccount; - $this->transactionBuilderFactory = $transactionBuilderFactory; - $this->gateway = $gateway; - $this->validatorFactory = $validatorFactory; $this->client = $client; } + /** + * Check Buckaroo Credentials Secret Key and Merchant Key + * + * @return Json + * @throws \Exception + */ public function execute() { - if ($params = $this->getRequest()->getParams()) { - if (!empty($params['secretKey']) && !empty($params['merchantKey'])) { - - if (preg_match('/[^\*]/', $params['secretKey'])) { - $secretKey = $params['secretKey']; - } else { - $secretKey = $this->encryptor->decrypt($this->configProviderAccount->getSecretKey()); - } - - if (preg_match('/[^\*]/', $params['merchantKey'])) { - $merchantKey = $params['merchantKey']; - } else { - $merchantKey = $this->encryptor->decrypt($this->configProviderAccount->getMerchantKey()); - } - - $mode = $params['mode'] ?? \Buckaroo\Magento2\Helper\Data::MODE_TEST; - - if (!$this->testXml($mode, $merchantKey, $message)) { - return $this->doResponse([ - 'success' => false, - 'error_message' => $message - ]); - } - - if (!$this->testJson($mode, $merchantKey, $secretKey, $message)) { - return $this->doResponse([ - 'success' => false, - 'error_message' => $message - ]); - } + if (($params = $this->getRequest()->getParams()) + && (!empty($params['secretKey']) && !empty($params['merchantKey']))) { + if (preg_match('/[^\*]/', $params['secretKey'])) { + $secretKey = $params['secretKey']; + } else { + $secretKey = $this->encryptor->decrypt($this->configProviderAccount->getSecretKey()); + } + + if (preg_match('/[^\*]/', $params['merchantKey'])) { + $merchantKey = $params['merchantKey']; + } else { + $merchantKey = $this->encryptor->decrypt($this->configProviderAccount->getMerchantKey()); + } + $mode = $params['mode'] ?? Data::MODE_TEST; + + if (!$this->testJson($mode, $merchantKey, $secretKey, $message)) { return $this->doResponse([ - 'success' => true + 'success' => false, + 'error_message' => $message ]); } + + return $this->doResponse([ + 'success' => true + ]); } return $this->doResponse([ - 'success' => false, + 'success' => false, 'error_message' => __('Failed to start validation process due to lack of data') ]); } - private function testXml($mode, $merchantKey, &$message) - { - - $services = [ - 'Name' => 'Idin', - 'Action' => 'verify', - 'Version' => 0, - 'RequestParameter' => [ - [ - '_' => 'BANKNL2Y', - 'Name' => 'issuerId', - ], - ], - ]; - - $transactionBuilder = $this->transactionBuilderFactory->get('datarequest'); - $transactionBuilder->setMerchantKey($merchantKey); - $transaction = $transactionBuilder - ->setServices($services) - ->setMethod('DataRequest') - ->setReturnUrl('') - ->build(); - - try { - $response = $this->gateway->setMode($mode)->authorize($transaction); - } catch (\Exception $e) { - $message = __('It seems like "Merchant key" and/or "Certificate file" are incorrect'); - return false; - } - - if (!$this->validatorFactory->get('transaction_response')->validate($response)) { - $message = __('It seems like "Certificate file" is incorrect'); - return false; - } - - return true; - } - + /** + * Create test request + * + * @param int|string $mode + * @param string $merchantKey + * @param string $secretKey + * @param Phrase|string $message + * @return bool + */ private function testJson($mode, $merchantKey, $secretKey, &$message) { $this->client->setSecretKey($secretKey); @@ -200,7 +155,7 @@ private function testJson($mode, $merchantKey, $secretKey, &$message) $this->client->doRequest($data, $mode); - if ($this->client->getStatus() == 200) { + if ($this->client->getStatus() == 200) { return true; } else { $message = __('It seems like "Merchant key" and/or "Secret key" are incorrect'); @@ -208,10 +163,15 @@ private function testJson($mode, $merchantKey, $secretKey, &$message) } } - private function doResponse($response) + /** + * Set Response on resultJson + * + * @param array $response + * @return Json + */ + private function doResponse(array $response): Json { $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true); - $resultJson = $this->resultJsonFactory->create(); - return $resultJson->setData($response); + return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($response); } } diff --git a/Controller/Mrcash/Pay.php b/Controller/Mrcash/Pay.php index dfdddb180..0cc39c82d 100644 --- a/Controller/Mrcash/Pay.php +++ b/Controller/Mrcash/Pay.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,6 +17,7 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Controller\Mrcash; class Pay extends \Buckaroo\Magento2\Controller\Payconiq\Pay diff --git a/Controller/Mrcash/Process.php b/Controller/Mrcash/Process.php index ba14c639c..030824d05 100644 --- a/Controller/Mrcash/Process.php +++ b/Controller/Mrcash/Process.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,8 +17,11 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Controller\Mrcash; +use Magento\Framework\App\Action\HttpPostActionInterface; + class Process extends \Buckaroo\Magento2\Controller\Payconiq\Process { } diff --git a/Controller/Payconiq/Pay.php b/Controller/Payconiq/Pay.php index 93745a496..613ed2028 100644 --- a/Controller/Payconiq/Pay.php +++ b/Controller/Payconiq/Pay.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,20 +17,26 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Controller\Payconiq; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\App\ResponseInterface; use Magento\Framework\View\Result\Page; use Magento\Framework\View\Result\PageFactory; -class Pay extends Action +class Pay extends Action implements HttpGetActionInterface, HttpPostActionInterface { - /** @var PageFactory */ - protected $resultPageFactory; + /** + * @var PageFactory + */ + protected PageFactory $resultPageFactory; /** - * @param Context $context + * @param Context $context * @param PageFactory $resultPageFactory */ public function __construct( @@ -42,25 +48,27 @@ public function __construct( } /** - * @return Page + * Display Payconiq page + * + * @return Page|ResponseInterface */ public function execute() { $canShowPage = $this->canShowPage(); if (!$canShowPage) { - $this->_forward('defaultNoRoute'); - return; + return $this->_redirect('defaultNoRoute'); } - $resultPage = $this->resultPageFactory->create(); - return $resultPage; + return $this->resultPageFactory->create(); } /** + * Check if Payconiq page should be displayed + * * @return bool */ - protected function canShowPage() + protected function canShowPage(): bool { $key = $this->getRequest()->getParam('Key'); diff --git a/Controller/Payconiq/Process.php b/Controller/Payconiq/Process.php index 10aeef432..881102c4e 100644 --- a/Controller/Payconiq/Process.php +++ b/Controller/Payconiq/Process.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,111 +17,160 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ +declare(strict_types=1); + namespace Buckaroo\Magento2\Controller\Payconiq; -use Buckaroo\Magento2\Logging\Log; +use Buckaroo\Magento2\Exception; +use Buckaroo\Magento2\Logging\BuckarooLoggerInterface; use Buckaroo\Magento2\Model\LockManagerWrapper; +use Buckaroo\Magento2\Model\BuckarooStatusCode; +use Buckaroo\Magento2\Model\ConfigProvider\Account as AccountConfig; +use Buckaroo\Magento2\Model\OrderStatusFactory; +use Buckaroo\Magento2\Model\RequestPush\RequestPushFactory; +use Buckaroo\Magento2\Model\Service\Order as OrderService; +use Buckaroo\Magento2\Service\Push\OrderRequestService; +use Buckaroo\Magento2\Service\Sales\Quote\Recreate; +use Magento\Checkout\Model\Session as CheckoutSession; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Model\ResourceModel\CustomerFactory; +use Magento\Customer\Model\Session as CustomerSession; use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\App\ResponseInterface; -use Magento\Framework\Controller\ResultInterface; -use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Event\ManagerInterface; +use Magento\Quote\Model\Quote; use Magento\Sales\Api\Data\TransactionInterface; use Magento\Sales\Api\Data\TransactionSearchResultInterface; use Magento\Sales\Api\TransactionRepositoryInterface; use Magento\Sales\Model\Order\Payment\Transaction; -use Buckaroo\Magento2\Model\Service\Order as OrderService; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class Process extends \Buckaroo\Magento2\Controller\Redirect\Process { - /** @var null|Transaction */ - protected $transaction = null; + /** + * @var null|Transaction + */ + protected ?Transaction $transaction = null; - /** @var SearchCriteriaBuilder */ - protected $searchCriteriaBuilder; + /** + * @var SearchCriteriaBuilder + */ + protected SearchCriteriaBuilder $searchCriteriaBuilder; - /** @var TransactionRepositoryInterface */ - protected $transactionRepository; + /** + * @var TransactionRepositoryInterface + */ + protected TransactionRepositoryInterface $transactionRepository; /** * @var LockManagerWrapper */ protected LockManagerWrapper $lockManager; + /** + * @param Context $context + * @param BuckarooLoggerInterface $logger + * @param Quote $quote + * @param AccountConfig $accountConfig + * @param OrderRequestService $orderRequestService + * @param OrderStatusFactory $orderStatusFactory + * @param CheckoutSession $checkoutSession + * @param CustomerSession $customerSession + * @param CustomerRepositoryInterface $customerRepository + * @param OrderService $orderService + * @param ManagerInterface $eventManager + * @param Recreate $quoteRecreate + * @param RequestPushFactory $requestPushFactory + * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param TransactionRepositoryInterface $transactionRepository + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ public function __construct( - \Magento\Framework\App\Action\Context $context, - \Buckaroo\Magento2\Helper\Data $helper, - \Magento\Checkout\Model\Cart $cart, - \Magento\Sales\Model\Order $order, - \Magento\Quote\Model\Quote $quote, - TransactionInterface $transaction, - Log $logger, - \Buckaroo\Magento2\Model\ConfigProvider\Factory $configProviderFactory, - \Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender, - \Buckaroo\Magento2\Model\OrderStatusFactory $orderStatusFactory, - \Magento\Checkout\Model\Session $checkoutSession, - \Magento\Customer\Model\Session $customerSession, - \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository, - \Magento\Customer\Model\SessionFactory $sessionFactory, - \Magento\Customer\Model\Customer $customerModel, - \Magento\Customer\Model\ResourceModel\CustomerFactory $customerFactory, + Context $context, + BuckarooLoggerInterface $logger, + Quote $quote, + AccountConfig $accountConfig, + OrderRequestService $orderRequestService, + OrderStatusFactory $orderStatusFactory, + CheckoutSession $checkoutSession, + CustomerSession $customerSession, + CustomerRepositoryInterface $customerRepository, OrderService $orderService, + ManagerInterface $eventManager, + Recreate $quoteRecreate, + RequestPushFactory $requestPushFactory, SearchCriteriaBuilder $searchCriteriaBuilder, TransactionRepositoryInterface $transactionRepository, - \Magento\Framework\Event\ManagerInterface $eventManager, - \Buckaroo\Magento2\Service\Sales\Quote\Recreate $quoteRecreate, LockManagerWrapper $lockManagerWrapper ) { parent::__construct( $context, - $helper, - $cart, - $order, - $quote, - $transaction, $logger, - $configProviderFactory, - $orderSender, + $quote, + $accountConfig, + $orderRequestService, $orderStatusFactory, $checkoutSession, $customerSession, $customerRepository, - $sessionFactory, - $customerModel, - $customerFactory, $orderService, $eventManager, $quoteRecreate, + $requestPushFactory, $lockManagerWrapper ); - $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->transactionRepository = $transactionRepository; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->transactionRepository = $transactionRepository; } /** - * @return ResponseInterface|ResultInterface - * @throws LocalizedException - * @throws \Buckaroo\Magento2\Exception + * Redirect Process Payconiq + * + * @return ResponseInterface + * @throws Exception */ public function execute() { if (!$this->getTransactionKey()) { - $this->_forward('defaultNoRoute'); - return; + return $this->_redirect('defaultNoRoute'); } $transaction = $this->getTransaction(); $this->order = $transaction->getOrder(); + $this->payment = $this->order->getPayment(); + + if ($this->customerSession->getCustomerId() != $this->order->getCustomerId()) { + $errorMessage = 'Customer is different then the customer that start Payconiq process request.'; + $this->logger->addError(sprintf( + '[REDIRECT - Payconiq] | [Controller] | [%s:%s] - %s - customerSessionid: %s != customerOrderId: %s', + __METHOD__, + __LINE__, + $errorMessage, + var_export($this->customerSession->getCustomerId(), true), + var_export($this->order->getCustomerId(), true) + )); + $this->messageManager->addErrorMessage($errorMessage); + return $this->handleProcessedResponse( + 'checkout', + [ + '_fragment' => 'payment', + '_query' => ['bk_e' => 1] + ] + ); + } $this->quote->load($this->order->getQuoteId()); // @codingStandardsIgnoreStart try { - $this->handleFailed( - $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_CANCELLED_BY_USER') - ); + $this->handleFailed(BuckarooStatusCode::CANCELLED_BY_USER); } catch (\Exception $exception) { + // handle failed exception } // @codingStandardsIgnoreEnd @@ -129,6 +178,8 @@ public function execute() } /** + * Get transaction key + * * @return bool|mixed */ protected function getTransactionKey() @@ -144,8 +195,10 @@ protected function getTransactionKey() } /** - * @return TransactionInterface|Transaction - * @throws \Buckaroo\Magento2\Exception + * Get transaction object + * + * @return TransactionInterface|Transaction|null + * @throws Exception */ protected function getTransaction() { @@ -156,7 +209,7 @@ protected function getTransaction() $list = $this->getList(); if ($list->getTotalCount() <= 0) { - throw new \Buckaroo\Magento2\Exception(__('There was no transaction found by transaction Id')); + throw new Exception(__('There was no transaction found by transaction Id')); } $items = $list->getItems(); @@ -166,21 +219,21 @@ protected function getTransaction() } /** + * Get the transaction list + * * @return TransactionSearchResultInterface - * @throws \Buckaroo\Magento2\Exception + * @throws Exception */ - protected function getList() + protected function getList(): TransactionSearchResultInterface { $transactionKey = $this->getTransactionKey(); if (!$transactionKey) { - throw new \Buckaroo\Magento2\Exception(__('There was no transaction found by transaction Id')); + throw new Exception(__('There was no transaction found by transaction Id')); } $searchCriteria = $this->searchCriteriaBuilder->addFilter('txn_id', $transactionKey); $searchCriteria->setPageSize(1); - $list = $this->transactionRepository->getList($searchCriteria->create()); - - return $list; + return $this->transactionRepository->getList($searchCriteria->create()); } } diff --git a/Controller/Pos/CheckOrderStatus.php b/Controller/Pos/CheckOrderStatus.php index 18f784a41..84d64da82 100644 --- a/Controller/Pos/CheckOrderStatus.php +++ b/Controller/Pos/CheckOrderStatus.php @@ -1,103 +1,126 @@ logger = $logger; - $this->order = $order; - $this->resultJsonFactory = $resultJsonFactory; - $this->accountConfig = $configProviderFactory->get('account'); - $this->storeManager = $storeManager; - $this->urlBuilder = $urlBuilder; - $this->formKey = $formKey; - $this->helper = $helper; + $this->order = $order; + $this->resultJsonFactory = $resultJsonFactory; + $this->accountConfig = $configProviderFactory->get('account'); + $this->storeManager = $storeManager; + $this->urlBuilder = $urlBuilder; + $this->formKey = $formKey; + $this->customerSession = $customerSession; } /** * Process action * - * @return \Magento\Framework\App\ResponseInterface + * @return Json * @throws \Exception */ public function execute() { - $this->logger->addDebug(__METHOD__.'|1|'); $response = ['success' => 'false', 'redirect' => '']; if (($params = $this->getRequest()->getParams()) && !empty($params['orderId'])) { $this->order->loadByIncrementId($params['orderId']); - if ($this->order->getId()) { + if ($this->customerSession->getCustomerId() === $this->order->getCustomerId() && $this->order->getId()) { $store = $this->order->getStore(); $url = ''; @@ -107,14 +130,15 @@ public function execute() if (in_array($this->order->getState(), ['canceled', 'closed'])) { $returnUrl = $this->urlBuilder->setScope($this->storeManager->getStore()->getStoreId()); - $url = $returnUrl->getRouteUrl('buckaroo/redirect/process') . '?form_key=' . $this->formKey->getFormKey(); + $url = $returnUrl->getRouteUrl('buckaroo/redirect/process') + . '?form_key=' . $this->formKey->getFormKey(); $extraData = [ 'brq_invoicenumber' => $params['orderId'], - 'brq_ordernumber' => $params['orderId'], - 'brq_statuscode' => $this->helper->getStatusCode('BUCKAROO_MAGENTO2_ORDER_FAILED'), + 'brq_ordernumber' => $params['orderId'], + 'brq_statuscode' => BuckarooStatusCode::ORDER_FAILED, ]; - $url = $url . '&'. http_build_query($extraData); + $url = $url . '&' . http_build_query($extraData); } $response = ['success' => 'true', 'redirect' => $url]; @@ -123,9 +147,7 @@ public function execute() $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true); - /** @var \Magento\Framework\Controller\Result\Json $resultJson */ $resultJson = $this->resultJsonFactory->create(); - return $resultJson->setData($response); } } diff --git a/Controller/Pos/SetTerminal.php b/Controller/Pos/SetTerminal.php index a10b0e72e..6e83b9d7c 100644 --- a/Controller/Pos/SetTerminal.php +++ b/Controller/Pos/SetTerminal.php @@ -1,28 +1,38 @@ logger = $logger; + $this->logger = $logger; $this->accountConfig = $configProviderFactory->get('account'); $this->storemanager = $storemanager; $this->cookieManager = $cookieManager; @@ -71,14 +92,20 @@ public function __construct( /** * Process action * - * @return \Magento\Framework\App\ResponseInterface + * @return ResponseInterface * @throws \Exception */ public function execute() { - $this->logger->addDebug(__METHOD__.'|1|'.var_export($this->getRequest()->getParams(), true)); + $params = $this->getRequest()->getParams(); + $this->logger->addDebug(sprintf( + '[POS] | [Controller] | [%s:%s] - Set Terminal | request: %s', + __METHOD__, + __LINE__, + var_export($params, true) + )); - if (($params = $this->getRequest()->getParams()) && !empty($params['id'])) { + if (!empty($params['id'])) { $metadata = $this->cookieMetadataFactory ->createPublicCookieMetadata() ->setPath('/') @@ -88,10 +115,9 @@ public function execute() $params['id'], $metadata ); - $this->logger->addDebug(__METHOD__.'|2|'); } - $redirectUrl= $this->storemanager->getStore()->getBaseUrl(); - $this->_redirect($redirectUrl); + $redirectUrl = $this->storemanager->getStore()->getBaseUrl(); + return $this->_redirect($redirectUrl); } } diff --git a/Controller/Redirect/IdinProcess.php b/Controller/Redirect/IdinProcess.php new file mode 100644 index 000000000..ea867342f --- /dev/null +++ b/Controller/Redirect/IdinProcess.php @@ -0,0 +1,196 @@ +customerResourceFactory = $customerFactory; + } + + /** + * @return ResponseInterface|void + * @throws \Buckaroo\Magento2\Exception + */ + public function execute(): ResponseInterface + { + // Initialize the order, quote, payment + if ($this->redirectRequest->hasPostData('primary_service', 'IDIN')) { + if ($this->setCustomerIDIN()) { + $this->addSuccessMessage(__('Your iDIN verified succesfully!')); + } else { + $this->addErrorMessage( + __( + 'Unfortunately iDIN not verified!' + ) + ); + } + + return $this->redirectToCheckout(); + } + + return $this->handleProcessedResponse('checkout'); + } + + /** + * Set consumer bin IDIN on customer + * + * @return bool + */ + private function setCustomerIDIN(): bool + { + if (!empty($this->redirectRequest->getServiceIdinConsumerbin()) + && !empty($this->redirectRequest->getServiceIdinIseighteenorolder()) + && $this->redirectRequest->getServiceIdinIseighteenorolder() == 'True' + ) { + $this->checkoutSession->setCustomerIDIN($this->redirectRequest->getServiceIdinConsumerbin()); + $this->checkoutSession->setCustomerIDINIsEighteenOrOlder(true); + $idinCid = $this->redirectRequest->getAdditionalInformation('idin_cid'); + if (!empty($idinCid)) { + try { + /** @var Customer $customerNew */ + $customerNew = $this->customerRepository->getById((int)$idinCid); + } catch (\Exception $e) { + $this->addErrorMessage(__('Unfortunately customer was not find by IDIN id: "%1"!', $idinCid)); + $this->logger->addError(sprintf( + '[REDIRECT - iDIN] | [Controller] | [%s:%s] - Customer was not find by IDIN id | [ERROR]: %s', + __METHOD__, + __LINE__, + $e->getMessage() + )); + return false; + } + $customerData = $customerNew->getDataModel(); + $customerData->setCustomAttribute('buckaroo_idin', $this->redirectRequest->getServiceIdinConsumerbin()); + $customerData->setCustomAttribute('buckaroo_idin_iseighteenorolder', 1); + $customerNew->updateData($customerData); + + $customerResource = $this->customerResourceFactory->create(); + $customerResource->saveAttribute($customerNew, 'buckaroo_idin'); + $customerResource->saveAttribute($customerNew, 'buckaroo_idin_iseighteenorolder'); + } + return true; + } + return false; + } + + /** + * Create redirect response + * + * @return ResponseInterface + */ + protected function redirectToCheckout(): ResponseInterface + { + $this->logger->addDebug('[REDIRECT - iDIN] | [Controller] | ['.__METHOD__.'] - start redirectToCheckout'); + + try { + $this->checkoutSession->restoreQuote(); + } catch (\Exception $e) { + $this->logger->addError(sprintf( + '[REDIRECT - iDIN] | [Controller] | [%s:%s] - Could not restore the quote | [ERROR]: %s', + __METHOD__, + __LINE__, + $e->getMessage() + )); + } + + return $this->handleProcessedResponse('checkout', ['_query' => ['bk_e' => 1]]); + } +} diff --git a/Controller/Redirect/Process.php b/Controller/Redirect/Process.php index ca604b69f..314fe46e8 100644 --- a/Controller/Redirect/Process.php +++ b/Controller/Redirect/Process.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,91 +17,118 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ +declare(strict_types=1); namespace Buckaroo\Magento2\Controller\Redirect; -use Buckaroo\Magento2\Logging\Log; +use Buckaroo\Magento2\Api\PushRequestInterface; +use Buckaroo\Magento2\Logging\BuckarooLoggerInterface; +use Buckaroo\Magento2\Model\BuckarooStatusCode; use Buckaroo\Magento2\Model\Config\Source\InvoiceHandlingOptions; +use Buckaroo\Magento2\Model\ConfigProvider\Account as AccountConfig; +use Buckaroo\Magento2\Model\Method\BuckarooAdapter; +use Buckaroo\Magento2\Model\OrderStatusFactory; +use Buckaroo\Magento2\Model\RequestPush\RequestPushFactory; +use Buckaroo\Magento2\Model\Service\Order as OrderService; +use Buckaroo\Magento2\Service\Push\OrderRequestService; +use Buckaroo\Magento2\Service\Sales\Quote\Recreate; +use Magento\Checkout\Model\Session as CheckoutSession; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Model\ResourceModel\CustomerFactory; +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Framework\App\Action\Action; +use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\App\Request\Http as Http; -use Magento\Sales\Api\Data\TransactionInterface; +use Magento\Framework\App\ResponseInterface; +use Magento\Framework\Event\ManagerInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Phrase; +use Magento\Quote\Model\Quote; +use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\OrderPaymentInterface; -use Buckaroo\Magento2\Model\Method\AbstractMethod; -use Buckaroo\Magento2\Model\Service\Order as OrderService; +use Magento\Sales\Model\Order; use Buckaroo\Magento2\Model\LockManagerWrapper; -class Process extends \Magento\Framework\App\Action\Action +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class Process extends Action implements HttpPostActionInterface, HttpGetActionInterface { + private const GENERAL_ERROR_MESSAGE = 'Unfortunately an error occurred while processing your payment. ' . + 'Please try again. If this error persists, please choose a different payment method.'; + /** - * @var array + * @var Order $order */ - protected $response; + protected Order $order; /** - * @var \Magento\Sales\Model\Order $order + * @var Quote $quote */ - protected $order; + protected Quote $quote; /** - * @var \Magento\Quote\Model\Quote $quote + * @var OrderPaymentInterface|null */ - protected $quote; - - /** @var TransactionInterface */ - private $transaction; + protected ?OrderPaymentInterface $payment; /** - * @var \Buckaroo\Magento2\Helper\Data $helper + * @var AccountConfig */ - protected $helper; + protected AccountConfig $accountConfig; /** - * @var \Magento\Checkout\Model\Cart + * @var OrderRequestService */ - protected $cart; + protected OrderRequestService $orderRequestService; /** - * @var \Magento\Checkout\Model\ConfigProviderInterface + * @var OrderStatusFactory */ - protected $accountConfig; + protected OrderStatusFactory $orderStatusFactory; /** - * @var \Magento\Sales\Model\Order\Email\Sender\OrderSender + * @var BuckarooLoggerInterface */ - protected $orderSender; + protected BuckarooLoggerInterface $logger; /** - * @var \Buckaroo\Magento2\Model\OrderStatusFactory + * @var CheckoutSession */ - protected $orderStatusFactory; + protected CheckoutSession $checkoutSession; /** - * @var Log + * @var CustomerSession */ - protected $logger; + protected CustomerSession $customerSession; /** - * @var \Magento\Checkout\Model\Session + * @var CustomerRepositoryInterface */ - protected $checkoutSession; + protected CustomerRepositoryInterface $customerRepository; /** - * @var \Magento\Customer\Model\Session + * @var OrderService */ - public $customerSession; - protected $customerRepository; - protected $_sessionFactory; + protected OrderService $orderService; - protected $customerModel; - protected $customerResourceFactory; - - protected $orderService; + /** + * @var ManagerInterface + */ + protected ManagerInterface $eventManager; /** - * @var EventManager + * @var Recreate */ - private $eventManager; + protected Recreate $quoteRecreate; - private $quoteRecreate; + /** + * @var PushRequestInterface + */ + protected PushRequestInterface $redirectRequest; /** * @var LockManagerWrapper @@ -109,73 +136,49 @@ class Process extends \Magento\Framework\App\Action\Action protected LockManagerWrapper $lockManager; /** - * @param \Magento\Framework\App\Action\Context $context - * @param \Buckaroo\Magento2\Helper\Data $helper - * @param \Magento\Checkout\Model\Cart $cart - * @param \Magento\Sales\Model\Order $order - * @param \Magento\Quote\Model\Quote $quote - * @param TransactionInterface $transaction - * @param Log $logger - * @param \Buckaroo\Magento2\Model\ConfigProvider\Factory $configProviderFactory - * @param \Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender - * @param \Buckaroo\Magento2\Model\OrderStatusFactory $orderStatusFactory - * @param \Magento\Checkout\Model\Session $checkoutSession, - * @param \Magento\Customer\Model\Session $customerSession, - * @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository, - * @param \Magento\Customer\Model\SessionFactory $sessionFactory, - * @param \Magento\Customer\Model\Customer $customerModel, - * @param \Magento\Customer\Model\ResourceModel\CustomerFactory $customerFactory, - * @param OrderService $orderService, - * @param \Magento\Framework\Event\ManagerInterface $eventManager, - * @param \Buckaroo\Magento2\Service\Sales\Quote\Recreate $quoteRecreate, - * @param LockManagerWrapper $lockManager - * - * @throws \Buckaroo\Magento2\Exception + * @param Context $context + * @param BuckarooLoggerInterface $logger + * @param Quote $quote + * @param AccountConfig $accountConfig + * @param OrderRequestService $orderRequestService + * @param OrderStatusFactory $orderStatusFactory + * @param CheckoutSession $checkoutSession + * @param CustomerSession $customerSession + * @param CustomerRepositoryInterface $customerRepository + * @param OrderService $orderService + * @param ManagerInterface $eventManager + * @param Recreate $quoteRecreate + * @param RequestPushFactory $requestPushFactory + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( - \Magento\Framework\App\Action\Context $context, - \Buckaroo\Magento2\Helper\Data $helper, - \Magento\Checkout\Model\Cart $cart, - \Magento\Sales\Model\Order $order, - \Magento\Quote\Model\Quote $quote, - TransactionInterface $transaction, - Log $logger, - \Buckaroo\Magento2\Model\ConfigProvider\Factory $configProviderFactory, - \Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender, - \Buckaroo\Magento2\Model\OrderStatusFactory $orderStatusFactory, - \Magento\Checkout\Model\Session $checkoutSession, - \Magento\Customer\Model\Session $customerSession, - \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository, - \Magento\Customer\Model\SessionFactory $sessionFactory, - \Magento\Customer\Model\Customer $customerModel, - \Magento\Customer\Model\ResourceModel\CustomerFactory $customerFactory, + Context $context, + BuckarooLoggerInterface $logger, + Quote $quote, + AccountConfig $accountConfig, + OrderRequestService $orderRequestService, + OrderStatusFactory $orderStatusFactory, + CheckoutSession $checkoutSession, + CustomerSession $customerSession, + CustomerRepositoryInterface $customerRepository, OrderService $orderService, - \Magento\Framework\Event\ManagerInterface $eventManager, - \Buckaroo\Magento2\Service\Sales\Quote\Recreate $quoteRecreate, + ManagerInterface $eventManager, + Recreate $quoteRecreate, + RequestPushFactory $requestPushFactory, LockManagerWrapper $lockManager ) { parent::__construct($context); - $this->helper = $helper; - $this->cart = $cart; - $this->order = $order; - $this->quote = $quote; - $this->transaction = $transaction; - $this->logger = $logger; - $this->orderSender = $orderSender; + $this->logger = $logger; + $this->orderRequestService = $orderRequestService; $this->orderStatusFactory = $orderStatusFactory; - $this->checkoutSession = $checkoutSession; - $this->customerSession = $customerSession; + $this->checkoutSession = $checkoutSession; + $this->customerSession = $customerSession; $this->customerRepository = $customerRepository; - $this->_sessionFactory = $sessionFactory; - - $this->customerModel = $customerModel; - $this->customerResourceFactory = $customerFactory; - - $this->accountConfig = $configProviderFactory->get('account'); - + $this->accountConfig = $accountConfig; $this->orderService = $orderService; $this->eventManager = $eventManager; $this->quoteRecreate = $quoteRecreate; + $this->quote = $quote; $this->lockManager = $lockManager; // @codingStandardsIgnoreStart @@ -187,22 +190,33 @@ public function __construct( } } // @codingStandardsIgnoreEnd + $this->redirectRequest = $requestPushFactory->create(); } /** * Process action * - * @return \Magento\Framework\App\ResponseInterface + * @return ResponseInterface|void * @throws \Exception + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function execute() { - $this->logger->addDebug(__METHOD__ . '|' . var_export($this->getRequest()->getParams(), true)); + $this->logger->addDebug(sprintf( + '[REDIRECT] | [Controller] | [%s:%s] - Original Request | originalRequest: %s', + __METHOD__, + __LINE__, + var_export($this->redirectRequest->getOriginalRequest(), true) + )); + + if (count($this->redirectRequest->getData()) === 0 || empty($this->redirectRequest->getStatusCode())) { + return $this->handleProcessedResponse('/'); + } - $this->response = $this->getRequest()->getParams(); - $this->response = array_change_key_case($this->response, CASE_LOWER); + $this->order = $this->orderRequestService->getOrderByRequest($this->redirectRequest); - $orderIncrementID = $this->getOrderIncrementId(); + $orderIncrementID = $this->order->getIncrementId(); $this->logger->addDebug(__METHOD__ . '|Lock Name| - ' . var_export($orderIncrementID, true)); $lockAcquired = $this->lockManager->lockOrder($orderIncrementID, 5); @@ -212,193 +226,49 @@ public function execute() } try { - return $this->redirectProcess(); - } catch (\Exception $e) { - $this->addErrorMessage('Could not process the request.'); - $this->logger->addError(__METHOD__ . '|Exception|' . $e->getMessage()); - } finally { - $this->lockManager->unlockOrder($orderIncrementID); - $this->logger->addDebug(__METHOD__ . '|Lock released|'); - } - - $this->logger->addDebug(__METHOD__ . '|9|'); - return $this->_response; - } - - private function redirectProcess() { - /** - * Check if there is a valid response. If not, redirect to home. - */ - if (count($this->response) === 0 || !array_key_exists('brq_statuscode', $this->response)) { - return $this->handleProcessedResponse('/'); - } - - if ($this->hasPostData('brq_primary_service', 'IDIN')) { - if ($this->setCustomerIDIN()) { - $this->addSuccessMessage(__('Your iDIN verified succesfully!')); + $statusCode = (int)$this->redirectRequest->getStatusCode(); + if (!$this->order->getId()) { + $statusCode = BuckarooStatusCode::ORDER_FAILED; } else { - $this->addErrorMessage( - __( - 'Unfortunately iDIN not verified!' - ) - ); + $this->quote->load($this->order->getQuoteId()); } - return $this->redirectToCheckout(); - } - - $statusCode = (int)$this->response['brq_statuscode']; - - $this->loadOrder(); - $this->helper->setRestoreQuoteLastOrder(false); - - if (!$this->order->getId()) { - $statusCode = $this->helper->getStatusCode('BUCKAROO_MAGENTO2_ORDER_FAILED'); - } else { - $this->quote->load($this->order->getQuoteId()); - } - - $payment = $this->order->getPayment(); - - if ($payment) { - $this->setPaymentOutOfTransit($payment); - } - - if (!method_exists($payment->getMethodInstance(), 'canProcessPostData')) { - return $this->handleProcessedResponse('/'); - } - - if (!$payment->getMethodInstance()->canProcessPostData($payment, $this->response)) { - return $this->handleProcessedResponse('/'); - } - - $this->logger->addDebug(__METHOD__ . '|2|' . var_export($statusCode, true)); - - if (($payment->getMethodInstance()->getCode() == 'buckaroo_magento2_paypal') - && ($statusCode == $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_PENDING_PROCESSING')) - ) { - $statusCode = $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_CANCELLED_BY_USER'); - $this->logger->addDebug(__METHOD__ . '|22|' . var_export($statusCode, true)); - } + $this->payment = $this->order->getPayment(); + if ($this->payment) { + $this->setPaymentOutOfTransit($this->payment); + } - switch ($statusCode) { - case $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_SUCCESS'): - case $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_PENDING_PROCESSING'): - $debugInfo = [ - $this->order->getStatus(), - $this->orderStatusFactory->get( - $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_SUCCESS'), - $this->order - ), - ]; - $this->logger->addDebug(__METHOD__ . '|3|' . var_export($debugInfo, true)); - - if ($this->order->canInvoice() && !$this->isInvoiceCreatedAfterShipment($payment)) { - $this->logger->addDebug(__METHOD__ . '|31|'); - if ($statusCode == $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_SUCCESS')) { - //do nothing - push will change a status - $this->logger->addDebug(__METHOD__ . '|32|'); - } else { - $this->logger->addDebug(__METHOD__ . '|33|'); - // Set the 'Pending payment status' here - $pendingStatus = $this->orderStatusFactory->get( - $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_PENDING_PROCESSING'), - $this->order - ); - if ($pendingStatus) { - $this->logger->addDebug(__METHOD__ . '|34|' . var_export($pendingStatus, true)); - $this->order->setStatus($pendingStatus); - $this->order->save(); - } - } + $this->checkoutSession->setRestoreQuoteLastOrder(false); - } + if ($this->skipWaitingOnConsumerForProcessingOrder()) { + return $this->handleProcessedResponse('/'); + } - $payment->getMethodInstance()->processCustomPostData($payment, $this->response); - - /** @var \Magento\Payment\Model\MethodInterface $paymentMethod */ - $paymentMethod = $this->order->getPayment()->getMethodInstance(); - $store = $this->order->getStore(); - - // Send order confirmation mail if we're supposed to - /** - * @noinspection PhpUndefinedMethodInspection - */ - if (!$this->order->getEmailSent() - && ($this->accountConfig->getOrderConfirmationEmail($store) === "1" - || $paymentMethod->getConfigData('order_email', $store) === "1" - ) - ) { - if (!($this->hasPostData('add_initiated_by_magento', 1) && - $this->hasPostData('brq_primary_service', 'KlarnaKp') && - $this->hasPostData('add_service_action_from_magento', 'reserve') && - !empty($this->response['brq_service_klarnakp_reservationnumber']) - )) { - if ($statusCode == $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_SUCCESS')) { - $this->logger->addDebug(__METHOD__ . '|sendemail|'); - $this->orderSender->send($this->order, true); - } - } - } + if (($this->payment->getMethodInstance()->getCode() == 'buckaroo_magento2_paypal') + && ($statusCode == BuckarooStatusCode::PENDING_PROCESSING) + ) { + $statusCode = BuckarooStatusCode::CANCELLED_BY_USER; + } - $pendingCode = $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_PENDING_PROCESSING'); - if (($statusCode == $pendingCode) - && !$this->hasPostData('brq_payment_method', 'sofortueberweisung') - ) { - $this->addErrorMessage( - __( - 'Unfortunately an error occurred while processing your payment.' . - 'Please try again. If this error persists, please choose a different payment method.' - ) - ); - $this->logger->addDebug(__METHOD__ . '|5|'); - - $this->removeCoupon(); - $this->removeAmastyGiftcardOnFailed(); - - return $this->handleProcessedResponse('/'); - } + $this->logger->addDebug(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Status Code | statusCode: %s', + $this->payment->getMethod(), + __METHOD__, + __LINE__, + $statusCode + )); - $this->logger->addDebug(__METHOD__ . '|51|' . var_export([ - $this->checkoutSession->getLastSuccessQuoteId(), - $this->checkoutSession->getLastQuoteId(), - $this->checkoutSession->getLastOrderId(), - $this->checkoutSession->getLastRealOrderId(), - $this->order->getQuoteId(), - $this->order->getId(), - $this->order->getIncrementId(), - ], true)); - - if (!$this->checkoutSession->getLastSuccessQuoteId() && $this->order->getQuoteId()) { - $this->logger->addDebug(__METHOD__ . '|52|'); - $this->checkoutSession->setLastSuccessQuoteId($this->order->getQuoteId()); - } - if (!$this->checkoutSession->getLastQuoteId() && $this->order->getQuoteId()) { - $this->logger->addDebug(__METHOD__ . '|53|'); - $this->checkoutSession->setLastQuoteId($this->order->getQuoteId()); - } - if (!$this->checkoutSession->getLastOrderId() && $this->order->getId()) { - $this->logger->addDebug(__METHOD__ . '|54|'); - $this->checkoutSession->setLastOrderId($this->order->getId()); - } - if (!$this->checkoutSession->getLastRealOrderId() && $this->order->getIncrementId()) { - $this->logger->addDebug(__METHOD__ . '|55|'); - $this->checkoutSession->setLastRealOrderId($this->order->getIncrementId()); - } - $this->logger->addDebug(__METHOD__ . '|6|'); - // Redirect to success page - return $this->redirectSuccess(); - case $this->helper->getStatusCode('BUCKAROO_MAGENTO2_ORDER_FAILED'): - case $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_FAILED'): - case $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_REJECTED'): - case $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_CANCELLED_BY_USER'): - return $this->handleFailed($statusCode); - break; - //no default + } catch (\Exception $e) { + $this->addErrorMessage('Could not process the request.'); + $this->logger->addError(__METHOD__ . '|Exception|' . $e->getMessage()); + } finally { + $this->lockManager->unlockOrder($orderIncrementID); + $this->logger->addDebug(__METHOD__ . '|Lock released|'); } - return $this->response; + return $this->processRedirectByStatus($statusCode); } + /** * Handle final response * @@ -407,203 +277,199 @@ private function redirectProcess() { * * @return ResponseInterface */ - public function handleProcessedResponse($path, $arguments = []) + public function handleProcessedResponse(string $path, array $arguments = []): ResponseInterface { - $this->logger->addDebug(__METHOD__ . '|15|'); return $this->_redirect($path, $arguments); } + /** - * Get order - * - * @return \Magento\Sales\Api\Data\OrderInterface - */ - public function getOrder() - { - return $this->order; - } - /** - * Add error message to be displayed to the user - * - * @param string $message - * - * @return void - */ - public function addErrorMessage(string $message) - { - $this->messageManager->addErrorMessage($message); - } - /** - * Add success message to be displayed to the user - * - * @param string $message + * Set flag if user is on the payment provider page * + * @param OrderPaymentInterface $payment * @return void + * @throws \Exception */ - public function addSuccessMessage(string $message) + protected function setPaymentOutOfTransit(OrderPaymentInterface $payment): void { - $this->messageManager->addSuccessMessage($message); + $payment->setAdditionalInformation(BuckarooAdapter::BUCKAROO_PAYMENT_IN_TRANSIT, false); } /** - * Get response parameters - * - * @return array - */ - public function getResponseParameters() - { - return $this->response; - } - /** - * Set flag if user is on the payment provider page - * - * @param OrderPaymentInterface $payment + * Skip process redirect for Processing Order when the status of the request is WaitingOnConsumer * - * @return void + * @return bool */ - protected function setPaymentOutOfTransit(OrderPaymentInterface $payment) - { - $payment - ->setAdditionalInformation(AbstractMethod::BUCKAROO_PAYMENT_IN_TRANSIT, false) - ->save(); - } - protected function handleFailed($statusCode) + public function skipWaitingOnConsumerForProcessingOrder(): bool { - $this->logger->addDebug(__METHOD__ . '|7|'); - - $this->eventManager->dispatch('buckaroo_process_handle_failed_before'); - - $this->removeCoupon(); - $this->removeAmastyGiftcardOnFailed(); - - if (!$this->getSkipHandleFailedRecreate()) { - if (!$this->quoteRecreate->recreate($this->quote)) { - $this->logging->addError('Could not recreate the quote.'); + if (in_array( + $this->payment->getMethod(), + [ + 'buckaroo_magento2_creditcards', + 'buckaroo_magento2_paylink', + 'buckaroo_magento2_payperemail', + 'buckaroo_magento2_transfer' + ] + )) { + $transactionKey = (string)$this->payment->getAdditionalInformation(BuckarooAdapter::BUCKAROO_ORIGINAL_TRANSACTION_KEY_KEY); + if (strpos($this->redirectRequest->getTransactions(), $transactionKey) === false) { + return true; } - } - - /* - * Something went wrong, so we're going to have to - * 1) recreate the quote for the user - * 2) cancel the order we had to create to even get here - * 3) redirect back to the checkout page to offer the user feedback & the option to try again - */ - // StatusCode specified error messages - $statusCodeAddErrorMessage = []; - $statusCodeAddErrorMessage[$this->helper->getStatusCode('BUCKAROO_MAGENTO2_ORDER_FAILED')] = - 'Unfortunately an error occurred while processing your payment. Please try again. If this' . - ' error persists, please choose a different payment method.'; - $statusCodeAddErrorMessage[$this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_FAILED')] = - 'Unfortunately an error occurred while processing your payment. Please try again. If this' . - ' error persists, please choose a different payment method.'; - $statusCodeAddErrorMessage[$this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_REJECTED')] = - 'Unfortunately an error occurred while processing your payment. Please try again. If this' . - ' error persists, please choose a different payment method.'; - $statusCodeAddErrorMessage[ - $this->helper->getStatusCode('BUCKAROO_MAGENTO2_STATUSCODE_CANCELLED_BY_USER') - ] = 'According to our system, you have canceled the payment. If this' . - ' is not the case, please contact us.'; - - $this->addErrorMessage( - __( - $statusCodeAddErrorMessage[$statusCode] - ) - ); - - //skip cancel order for PPE - if (isset($this->response['add_frompayperemail'])) { - return $this->redirectFailure(); + $orderState = $this->order->getState(); + if ($orderState == Order::STATE_PROCESSING + && $this->redirectRequest->getStatusCode() == BuckarooStatusCode::WAITING_ON_CONSUMER) { + return true; + } } - if (!$this->cancelOrder($statusCode)) { - $this->logger->addError('Could not cancel the order.'); - } - $this->logger->addDebug(__METHOD__ . '|8|'); - return $this->redirectFailure(); + return false; } /** - * @throws \Buckaroo\Magento2\Exception + * Processes a redirect based on the given status code. + * + * @param int $statusCode + * @return ResponseInterface + * @throws LocalizedException + * @throws NoSuchEntityException */ - private function loadOrder() + private function processRedirectByStatus(int $statusCode): ResponseInterface { - $brqOrderId = $this->getOrderIncrementId(); - - $this->order->loadByIncrementId($brqOrderId); - - if (!$this->order->getId()) { - $this->logger->addDebug('Order could not be loaded by brq_invoicenumber or brq_ordernumber'); - $this->order = $this->getOrderByTransactionKey(); + $result = null; + + if ($statusCode == BuckarooStatusCode::SUCCESS) { + $result = $this->processSucceededRedirect($statusCode); + } elseif ($statusCode == BuckarooStatusCode::PENDING_PROCESSING) { + $result = $this->processPendingRedirect($statusCode); + } elseif (in_array($statusCode, [ + BuckarooStatusCode::ORDER_FAILED, + BuckarooStatusCode::FAILED, + BuckarooStatusCode::REJECTED, + BuckarooStatusCode::CANCELLED_BY_USER + ])) { + $result = $this->handleFailed($statusCode); } + + return $result ?? $this->_response; } /** - * Get the order increment ID based on the invoice number or order number from push + * Processes a successful redirect based on the given status code. + * + * - Sends a Klarna KP order confirmation using the status code. + * - Sets the last quote and order. + * - Returns a successful redirect response. * - * @return string|null + * @param $statusCode + * @return ResponseInterface + * @throws \Exception */ - protected function getOrderIncrementId(): ?string + private function processSucceededRedirect($statusCode): ResponseInterface { - $brqOrderId = false; - - if (isset($this->response['brq_invoicenumber']) && !empty($this->response['brq_invoicenumber'])) { - $brqOrderId = $this->response['brq_invoicenumber']; - } + $this->sendKlarnaKpOrderConfirmation($statusCode); + $this->setLastQuoteOrder(); - if (isset($this->response['brq_ordernumber']) && !empty($this->response['brq_ordernumber'])) { - $brqOrderId = $this->response['brq_ordernumber']; - } - - return $brqOrderId; + return $this->redirectSuccess(); } /** - * @return bool - * @throws \Buckaroo\Magento2\Exception + * Sends a Klarna KP order confirmation based on the given status code. + * + * - Retrieves the payment method and store from the order object. + * - Checks if the order confirmation email has not been sent and if the order confirmation email + * setting is enabled either globally or specifically for the payment method. + * - Validates if the redirect request contains specific post data and additional information related to Klarna KP + * - If all conditions are met, and the status code is SUCCESS, sends the order confirmation email. + * + * @param int $statusCode The status code representing the result of a payment or related process. + * @return void + * @throws \Exception If an exception occurs within the called methods. + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - private function getOrderByTransactionKey() + private function sendKlarnaKpOrderConfirmation(int $statusCode): void { - $trxId = ''; + $paymentMethod = $this->payment->getMethodInstance(); + $store = $this->order->getStore(); - if (isset($this->response['brq_transactions']) && !empty($this->response['brq_transactions'])) { - $trxId = $this->response['brq_transactions']; - } + $isKlarnaKpReserve = ($this->redirectRequest->hasPostData('primary_service', 'KlarnaKp') + && $this->redirectRequest->hasAdditionalInformation('service_action_from_magento', 'reserve') + && !empty($this->redirectRequest->getServiceKlarnakpReservationnumber())); - if (isset($this->response['brq_datarequest']) && !empty($this->response['brq_datarequest'])) { - $trxId = $this->response['brq_datarequest']; + if(empty($this->order->getBuckarooReservationNumber()) && $isKlarnaKpReserve) + { + $this->order->setBuckarooReservationNumber($this->redirectRequest->getServiceKlarnakpReservationnumber()); + $this->order->save(); } - $this->transaction->load($trxId, 'txn_id'); - $order = $this->transaction->getOrder(); - - if (!$order) { - throw new \Buckaroo\Magento2\Exception(__('There was no order found by transaction Id')); + if (!$this->order->getEmailSent() + && ( + $this->accountConfig->getOrderConfirmationEmail($store) === "1" + || $paymentMethod->getConfigData('order_email', $store) === "1" + ) + && (!($this->redirectRequest->hasAdditionalInformation('initiated_by_magento', 1) + && $isKlarnaKpReserve + && $statusCode == BuckarooStatusCode::SUCCESS) + ) + ) { + $this->logger->addDebug(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Send Klarna Reservation Mail', + $this->payment->getMethod(), + __METHOD__, + __LINE__ + )); + $this->orderRequestService->sendOrderEmail($this->order, true); } - - return $order; } /** - * If possible, cancel the order + * Sets the last quote and order information in the checkout session. * - * @param $statusCode + * - Logs the current status of the last successful quote ID, last quote ID, last order ID + * - If the last successful quote ID, last quote ID, last order ID, or last real order ID is not set + * in the checkout session, it updates them with the corresponding information from the order object. * - * @return bool + * @return void */ - protected function cancelOrder($statusCode) + private function setLastQuoteOrder(): void { - return $this->orderService->cancel($this->order, $statusCode); + $this->logger->addDebug(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Set Last Quote Order | currentQuoteOrder: %s', + $this->payment->getMethod(), + __METHOD__, + __LINE__, + var_export([ + $this->checkoutSession->getLastSuccessQuoteId(), + $this->checkoutSession->getLastQuoteId(), + $this->checkoutSession->getLastOrderId(), + $this->checkoutSession->getLastRealOrderId(), + $this->order->getQuoteId(), + $this->order->getId(), + $this->order->getIncrementId(), + ], true) + )); + + if (!$this->checkoutSession->getLastSuccessQuoteId() && $this->order->getQuoteId()) { + $this->checkoutSession->setLastSuccessQuoteId($this->order->getQuoteId()); + } + if (!$this->checkoutSession->getLastQuoteId() && $this->order->getQuoteId()) { + $this->checkoutSession->setLastQuoteId($this->order->getQuoteId()); + } + if (!$this->checkoutSession->getLastOrderId() && $this->order->getId()) { + $this->checkoutSession->setLastOrderId($this->order->getId()); + } + if (!$this->checkoutSession->getLastRealOrderId() && $this->order->getIncrementId()) { + $this->checkoutSession->setLastRealOrderId($this->order->getIncrementId()); + } } /** * Redirect to Success url, which means everything seems to be going fine * - * @return \Magento\Framework\App\ResponseInterface + * @return ResponseInterface */ - protected function redirectSuccess() + protected function redirectSuccess(): ResponseInterface { - $this->logger->addDebug(__METHOD__ . '|1|'); - $this->eventManager->dispatch('buckaroo_process_redirect_success_before'); $store = $this->order->getStore(); @@ -617,182 +483,135 @@ protected function redirectSuccess() $this->quote->setReservedOrderId(null); - if (!empty($this->response['brq_payment_method']) - && - ($this->response['brq_payment_method'] == 'applepay') - && - !empty($this->response['brq_statuscode']) - && - ($this->response['brq_statuscode'] == '190') - && - !empty($this->response['brq_test']) - && - ($this->response['brq_test'] == 'true') - ) { - $this->redirectSuccessApplePay(); - } + $this->redirectSuccessApplePay(); - $this->logger->addDebug(__METHOD__ . '|2|' . var_export($url, true)); + $this->logger->addDebug(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Redirect Success | redirectURL: %s', + $this->payment->getMethod(), + __METHOD__, + __LINE__, + $url, + )); return $this->handleProcessedResponse($url); } - protected function redirectSuccessApplePay() - { - $this->logger->addDebug(__METHOD__); - - $this->checkoutSession - ->setLastQuoteId($this->order->getQuoteId()) - ->setLastSuccessQuoteId($this->order->getQuoteId()) - ->setLastOrderId($this->order->getId()) - ->setLastRealOrderId($this->order->getIncrementId()) - ->setLastOrderStatus($this->order->getStatus()); - } - /** - * Redirect to Failure url, which means we've got a problem + * Add success message to be displayed to the user * - * @return \Magento\Framework\App\ResponseInterface + * @param string|Phrase $message + * + * @return void */ - protected function redirectFailure() + public function addSuccessMessage($message): void { - $store = $this->order->getStore(); - $this->logger->addDebug('start redirectFailure'); - if ($this->accountConfig->getFailureRedirectToCheckout($store)) { - $this->logger->addDebug('getFailureRedirectToCheckout'); - if (!$this->customerSession->isLoggedIn() && ($this->order->getCustomerId() > 0)) { - $this->logger->addDebug('not isLoggedIn'); - $this->logger->addDebug('getCustomerId > 0'); - try { - $customer = $this->customerRepository->getById($this->order->getCustomerId()); - $this->customerSession->setCustomerDataAsLoggedIn($customer); - - if (!$this->checkoutSession->getLastRealOrderId() && $this->order->getIncrementId()) { - $this->checkoutSession->setLastRealOrderId($this->order->getIncrementId()); - $this->logger->addDebug(__METHOD__ . '|setLastRealOrderId|'); - if (!$this->getSkipHandleFailedRecreate()) { - $this->checkoutSession->restoreQuote(); - $this->logger->addDebug(__METHOD__ . '|restoreQuote|'); - } - } - $this->setSkipHandleFailedRecreate(false); - } catch (\Exception $e) { - $this->logger->addError('Could not load customer'); - } - } - $this->logger->addDebug('ready for redirect'); - return $this->handleProcessedResponse('checkout', ['_fragment' => 'payment', '_query' => ['bk_e' => 1]]); - } - - /** - * @noinspection PhpUndefinedMethodInspection - */ - $url = $this->accountConfig->getFailureRedirect($store); - - return $this->handleProcessedResponse($url); + $this->messageManager->addSuccessMessage($message); } - protected function redirectToCheckout() + /** + * Redirect if the transaction is of the success Apple Pay type + * + * @return void + */ + protected function redirectSuccessApplePay(): void { - $store = $this->order->getStore(); - $this->logger->addDebug('start redirectToCheckout'); - if (!$this->customerSession->isLoggedIn()) { - $this->logger->addDebug('not isLoggedIn'); - if ($this->order->getCustomerId() > 0) { - $this->logger->addDebug('getCustomerId > 0'); - try { - $customer = $this->customerRepository->getById($this->order->getCustomerId()); - $this->customerSession->setCustomerDataAsLoggedIn($customer); - - if (!$this->checkoutSession->getLastRealOrderId() && $this->order->getIncrementId()) { - $this->checkoutSession->setLastRealOrderId($this->order->getIncrementId()); - $this->logger->addDebug(__METHOD__ . '|setLastRealOrderId|'); - $this->checkoutSession->restoreQuote(); - $this->logger->addDebug(__METHOD__ . '|restoreQuote|'); - } elseif ($this->hasPostData('brq_primary_service', 'IDIN')) { - $this->checkoutSession->restoreQuote(); - } - - } catch (\Exception $e) { - $this->logger->addError('Could not load customer'); - } - } + if ($this->redirectRequest->hasPostData('payment_method', 'applepay') + && $this->redirectRequest->hasPostData('status_code', '190') + && $this->redirectRequest->hasPostData('test', 'true') + ) { + $this->checkoutSession + ->setLastQuoteId($this->order->getQuoteId()) + ->setLastSuccessQuoteId($this->order->getQuoteId()) + ->setLastOrderId($this->order->getId()) + ->setLastRealOrderId($this->order->getIncrementId()) + ->setLastOrderStatus($this->order->getStatus()); } - $this->logger->addDebug('ready for redirect'); - return $this->handleProcessedResponse('checkout', ['_query' => ['bk_e' => 1]]); } /** - * @param $name - * @param $value - * @return bool + * Processes a pending redirect based on the given status code. + * + * - If the order can be invoiced, it sets the 'Pending payment status' and saves the order. + * - Sends a Klarna KP order confirmation using the status code. + * - If the redirect request does not contain specific post data for the 'sofortueberweisung' payment method, + * it adds an error message, removes an Amasty gift card if failed, and redirect to home. + * - Sets the last quote and order. + * - Returns a successful redirect response. + * + * @param $statusCode + * @return ResponseInterface + * @throws LocalizedException + * @throws \Exception */ - private function hasPostData($name, $value) + private function processPendingRedirect($statusCode): ResponseInterface { - if (is_array($value) && - isset($this->response[$name]) && - in_array($this->response[$name], $value) - ) { - return true; + if ($this->order->canInvoice() && !$this->isInvoiceCreatedAfterShipment()) { + $pendingStatus = $this->orderStatusFactory->get( + BuckarooStatusCode::PENDING_PROCESSING, + $this->order + ); + if ($pendingStatus) { + $this->logger->addDebug(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Redirect Pending Set Status | pendingStatus: %s', + $this->payment->getMethod(), + __METHOD__, + __LINE__, + var_export($pendingStatus, true), + )); + $this->order->setStatus($pendingStatus); + $this->order->save(); + } } - if (isset($this->response[$name]) && - $this->response[$name] == $value - ) { - return true; - } + $this->sendKlarnaKpOrderConfirmation($statusCode); - return false; - } + if (!$this->redirectRequest->hasPostData('payment_method', 'sofortueberweisung')) { + $this->addErrorMessage(__(self::GENERAL_ERROR_MESSAGE)); - private function setCustomerIDIN() - { - if (isset($this->response['brq_service_idin_consumerbin']) - && !empty($this->response['brq_service_idin_consumerbin']) - && isset($this->response['brq_service_idin_iseighteenorolder']) - && $this->response['brq_service_idin_iseighteenorolder'] == 'True' - ) { - $this->checkoutSession->setCustomerIDIN($this->response['brq_service_idin_consumerbin']); - $this->checkoutSession->setCustomerIDINIsEighteenOrOlder(true); - if (isset($this->response['add_idin_cid']) && !empty($this->response['add_idin_cid'])) { - $customerNew = $this->customerModel->load((int) $this->response['add_idin_cid']); - $customerData = $customerNew->getDataModel(); - $customerData->setCustomAttribute('buckaroo_idin', $this->response['brq_service_idin_consumerbin']); - $customerData->setCustomAttribute('buckaroo_idin_iseighteenorolder', 1); - $customerNew->updateData($customerData); - $customerResource = $this->customerResourceFactory->create(); - $customerResource->saveAttribute($customerNew, 'buckaroo_idin'); - $customerResource->saveAttribute($customerNew, 'buckaroo_idin_iseighteenorolder'); - } - return true; + $this->logger->addDebug(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Redirect Pending NOT Sofort - Remove Coupon & Giftcard', + $this->payment->getMethod(), + __METHOD__, + __LINE__ + )); + + $this->removeCoupon(); + $this->removeAmastyGiftcardOnFailed(); + + return $this->handleProcessedResponse('/'); } - return false; - } - public function getSkipHandleFailedRecreate() - { - return false; + $this->setLastQuoteOrder(); + + return $this->redirectSuccess(); } - public function setSkipHandleFailedRecreate($value) + /** + * Add error message to be displayed to the user + * + * @param string|Phrase $message + * + * @return void + */ + public function addErrorMessage($message): void { - return true; + $this->messageManager->addErrorMessage($message); } /** * Remove coupon from failed order if magento enterprise - * + * * @return void */ protected function removeCoupon() { - if (method_exists($this->order,'getCouponCode')) { + if (method_exists($this->order, 'getCouponCode')) { $couponCode = $this->order->getCouponCode(); $couponFactory = $this->_objectManager->get(\Magento\SalesRule\Model\CouponFactory::class); if (!(is_object($couponFactory) && method_exists($couponFactory, 'load'))) { return; } - + $coupon = $couponFactory->load($couponCode, 'code'); $resourceModel = $this->_objectManager->get(\Magento\SalesRule\Model\Spi\CouponResourceInterface::class); if (!(is_object($resourceModel) && method_exists($resourceModel, 'delete'))) { @@ -810,13 +629,16 @@ protected function removeCoupon() * * @return void */ - protected function removeAmastyGiftcardOnFailed() + protected function removeAmastyGiftcardOnFailed(): void { - $class = \Amasty\GiftCardAccount\Model\GiftCardAccount\Repository::class; - if (class_exists($class)) { + if (class_exists(\Amasty\GiftCardAccount\Model\GiftCardAccount\Repository::class)) { + $giftcardAccountRepository = $this->_objectManager->get( + \Amasty\GiftCardAccount\Model\GiftCardAccount\Repository::class + ); - $giftcardAccountRepository = $this->_objectManager->get($class); - $giftcardOrderRepository = $this->_objectManager->get(\Amasty\GiftCardAccount\Model\GiftCardExtension\Order\Repository::class); + $giftcardOrderRepository = $this->_objectManager->get( + \Amasty\GiftCardAccount\Model\GiftCardExtension\Order\Repository::class/** @phpstan-ignore-line */ + ); try { $giftcardOrder = $giftcardOrderRepository->getByOrderId($this->order->getId()); @@ -830,21 +652,266 @@ protected function removeAmastyGiftcardOnFailed() $giftcardAccountRepository->save($giftcard); } } catch (\Throwable $th) { - $this->logger->addDebug($th->getMessage()); + $this->logger->addError(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Remove Amasty Giftcard | [ERROR]: %s', + $this->payment->getMethod(), + __METHOD__, + __LINE__, + $th->getMessage() + )); return; } } } + /** + * Handle failed transactions + * + * @param int|null $statusCode + * @return ResponseInterface + * @throws \Magento\Framework\Exception\NoSuchEntityException|\Exception + */ + protected function handleFailed($statusCode): ResponseInterface + { + $this->eventManager->dispatch('buckaroo_process_handle_failed_before'); + + $this->removeAmastyGiftcardOnFailed(); + + if (!$this->getSkipHandleFailedRecreate() + && (!$this->quoteRecreate->recreate($this->quote))) { + $this->logger->addError(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Could not Recreate Quote on Failed ', + $this->payment->getMethod(), + __METHOD__, + __LINE__ + )); + } + + /* + * Something went wrong, so we're going to have to + * 1) recreate the quote for the user + * 2) cancel the order we had to create to even get here + * 3) redirect back to the checkout page to offer the user feedback & the option to try again + */ + $this->addErrorMessageByStatus($statusCode); + + //skip cancel order for PPE + if (!empty($this->redirectRequest->getAdditionalInformation('frompayperemail'))) { + return $this->redirectFailure(); + } + + if (!$this->cancelOrder($statusCode)) { + $this->logger->addError(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Could not Cancel the Order.', + $this->payment->getMethod(), + __METHOD__, + __LINE__ + )); + } + + $this->logger->addDebug(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Redirect Failure', + $this->payment->getMethod(), + __METHOD__, + __LINE__ + )); + + return $this->redirectFailure(); + } + + /** + * Function used by external plugins to skip recreate quote + * + * @return false + */ + public function getSkipHandleFailedRecreate() + { + return false; + } + + /** + * Adds an error message to the session based on the given status code. + * + * @param int $statusCode + * @return void + */ + public function addErrorMessageByStatus(int $statusCode): void + { + $statusCodeAddErrorMessage = []; + $statusCodeAddErrorMessage[BuckarooStatusCode::ORDER_FAILED] = __(self::GENERAL_ERROR_MESSAGE); + $statusCodeAddErrorMessage[BuckarooStatusCode::FAILED] = __(self::GENERAL_ERROR_MESSAGE); + $statusCodeAddErrorMessage[BuckarooStatusCode::REJECTED] = __(self::GENERAL_ERROR_MESSAGE); + $statusCodeAddErrorMessage[BuckarooStatusCode::CANCELLED_BY_USER] + = __('According to our system, you have canceled the payment. If this is not the case, please contact us.'); + + $this->addErrorMessage(__($statusCodeAddErrorMessage[$statusCode])); + } + + /** + * Redirect to Failure url, which means we've got a problem + * + * @return ResponseInterface + * @throws \Exception + */ + protected function redirectFailure(): ResponseInterface + { + $store = $this->order->getStore(); + if ($this->accountConfig->getFailureRedirectToCheckout($store)) { + return $this->redirectOnCheckoutForFailedTransaction(); + } + + $url = $this->accountConfig->getFailureRedirect($store); + + return $this->handleProcessedResponse($url); + } + + /** + * Redirects to the checkout page for a failed transaction. + * + * - Logs the attempt to redirect to checkout for a failed transaction. + * - If the customer is not logged in, and there's an associated customer ID with the order, + * it attempts to retrieve the customer, log them in, and set necessary session data. + * - If the last real order ID is not set in the checkout session, and the order has an increment ID, + * it sets the last real order ID and may restore the quote. + * - Finally, it handles the processed response for a redirect to the checkout page, specifically + * to the payment section, with a query parameter indicating an error. + * + * @return ResponseInterface + * @throws \Exception + */ + private function redirectOnCheckoutForFailedTransaction(): ResponseInterface + { + $this->setCustomerAndRestoreQuote('failed'); + + $this->logger->addDebug(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Redirect Failure To Checkout', + $this->payment->getMethod(), + __METHOD__, + __LINE__ + )); + + return $this->handleProcessedResponse('checkout', ['_fragment' => 'payment', '_query' => ['bk_e' => 1]]); + } + + /** + * Set customer if it is set on order and not on session and restore quote + * + * @param string $status + * @return void + */ + protected function setCustomerAndRestoreQuote(string $status): void + { + if (!$this->customerSession->isLoggedIn() && $this->order->getCustomerId() > 0) { + $this->logger->addDebug(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Redirect %s To Checkout - Customer is not logged in', + $this->payment->getMethod(), + __METHOD__, + __LINE__, + $status + )); + try { + $customer = $this->customerRepository->getById($this->order->getCustomerId()); + $this->customerSession->setCustomerDataAsLoggedIn($customer); + + if (!$this->checkoutSession->getLastRealOrderId() && $this->order->getIncrementId()) { + $this->checkoutSession->setLastRealOrderId($this->order->getIncrementId()); + if ($status == 'success' || !$this->getSkipHandleFailedRecreate()) { + $this->checkoutSession->restoreQuote(); + $this->logger->addDebug(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Redirect %s To Checkout - Restore Quote', + $this->payment->getMethod(), + __METHOD__, + __LINE__, + $status + )); + } + if ($status == 'failed') { + $this->setSkipHandleFailedRecreate(); + } + } + } catch (\Exception $e) { + $this->logger->addError(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Redirect %s To Checkout ' . + '- Could not load customer | [ERROR]: %s', + $this->payment->getMethod(), + __METHOD__, + __LINE__, + $status, + $e->getMessage() + )); + } + } + } + + /** + * Set skip recreating quote on failed transaction + * + * @return true + */ + public function setSkipHandleFailedRecreate() + { + return true; + } + + /** + * If possible, cancel the order + * + * @param int|null $statusCode + * @return bool + * @throws LocalizedException + */ + protected function cancelOrder(?int $statusCode): bool + { + return $this->orderService->cancel($this->order, $statusCode); + } + + /** + * Get order + * + * @return OrderInterface + */ + public function getOrder() + { + return $this->order; + } + + /** + * Get Response Parameters + * + * @return array + */ + public function getResponseParameters() + { + return $this->redirectRequest->getData(); + } + + /** + * Create redirect response + * + * @return ResponseInterface + */ + protected function redirectToCheckout(): ResponseInterface + { + $this->logger->addDebug(sprintf( + '[REDIRECT - %s] | [Controller] | [%s:%s] - Redirect To Checkout', + $this->payment->getMethod(), + __METHOD__, + __LINE__ + )); + + $this->setCustomerAndRestoreQuote('success'); + + return $this->handleProcessedResponse('checkout', ['_query' => ['bk_e' => 1]]); + } + /** * Is the invoice for the current order is created after shipment * - * @param OrderPaymentInterface $payment * @return bool */ - private function isInvoiceCreatedAfterShipment(OrderPaymentInterface $payment): bool + private function isInvoiceCreatedAfterShipment(): bool { - return $payment->getAdditionalInformation( + return $this->payment->getAdditionalInformation( InvoiceHandlingOptions::INVOICE_HANDLING ) == InvoiceHandlingOptions::SHIPMENT; } diff --git a/Cron/CancelExpiredOrders.php b/Cron/CancelExpiredOrders.php index 0d5db24ec..c3846a3ac 100644 --- a/Cron/CancelExpiredOrders.php +++ b/Cron/CancelExpiredOrders.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,19 +17,29 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Cron; use Buckaroo\Magento2\Model\Service\Order as OrderService; class CancelExpiredOrders { - protected $orderService; + /** + * @var OrderService + */ + protected OrderService $orderService; + /** + * @param OrderService $orderService + */ public function __construct(OrderService $orderService) { $this->orderService = $orderService; } + /** + * Cancel expire Transfer and PPE orders + */ public function execute() { $this->orderService->cancelExpiredTransferOrders(); diff --git a/Cron/LogCleaner.php b/Cron/LogCleaner.php new file mode 100644 index 000000000..6be4c6132 --- /dev/null +++ b/Cron/LogCleaner.php @@ -0,0 +1,186 @@ +resource = $resource; + $this->accountConfig = $accountConfig; + $this->resourceConnection = $resourceConnection; + $this->logger = $logger; + $this->directoryList = $directoryList; + $this->driverFile = $driverFile; + $this->ioFile = $ioFile; + } + + /** + * Cron that clean the logs after specific period + */ + public function execute() + { + $retentionPeriod = (int) $this->accountConfig->getLogRetention(); + $logHandlerType = (int) $this->accountConfig->getLogHandler(); + + if ($retentionPeriod) { + if ($logHandlerType == LogHandler::TYPE_DB) { + $this->proceedDb($retentionPeriod); + } + if ($logHandlerType == LogHandler::TYPE_FILES) { + $this->proceedFiles($retentionPeriod); + } + } + return $this; + } + + /** + * Delete logs from data base + * + * @param int $retentionPeriod + * @return void + */ + private function proceedDb(int $retentionPeriod) + { + try { + $this->resourceConnection->getConnection()->delete( + $this->resource->getMainTable(), + ['time <= date_sub(now(),interval ' . $retentionPeriod . ' second)'] + ); + } catch (\Exception $e) { + $this->logger->error(sprintf( + '[LOGGING] | [CRON] | [%s:%s] - Delete logs from data base. Proceed DB error. | [ERROR]: %s', + __METHOD__, + __LINE__, + $e->getMessage() + )); + } + } + + /** + * Delete files that contains logs + * + * @param int $retentionPeriod + * @return void + * @throws FileSystemException + */ + private function proceedFiles(int $retentionPeriod) + { + if ($files = $this->getAllFiles(DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR . 'Buckaroo')) { + $retentionTime = strtotime(gmdate('Y-m-d', time() - $retentionPeriod)); + foreach ($files as $file) { + $fileInfo = $this->ioFile->getPathInfo($file); + $fileName = $fileInfo['filename']; + if (preg_match('/[\d]{4}\-\d{2}\-\d{2}/', $fileName) + && (strtotime($fileName) <= $retentionTime)) { + $this->driverFile->deleteFile($file); + } + } + } + } + + /** + * Get all files from log directory + * + * @param string $path + * @return array + */ + private function getAllFiles(string $path): array + { + $paths = []; + try { + $path = $this->directoryList->getPath('var') . $path; + $paths = $this->driverFile->readDirectory($path); + } catch (FileSystemException $e) { + $this->logger->error(sprintf( + '[LOGGING] | [CRON] | [%s:%s] - Get all files from log directory. | [ERROR]: %s', + __METHOD__, + __LINE__, + $e->getMessage() + )); + } + + return $paths; + } +} diff --git a/Exception.php b/Exception.php index 0ae2a3abe..ad04739d8 100644 --- a/Exception.php +++ b/Exception.php @@ -1,13 +1,12 @@ requestBuilder = $requestBuilder; + $this->transferFactory = $transferFactory; + $this->client = $client; + $this->handler = $handler; + $this->validator = $validator; + $this->logger = $logger; + $this->errorMessageMapper = $errorMessageMapper; + $this->skipCommand = $skipCommand; + $this->spamLimitService = $spamLimitService; + $this->cancelOrder = $cancelOrder; + } + + /** + * Executes command basing on business object + * + * @param array $commandSubject + * @return void + * @throws CommandException + * @throws ClientException + * @throws ConverterException + */ + public function execute(array $commandSubject): void + { + $paymentDO = SubjectReader::readPayment($commandSubject); + + $this->cancelOrder->cancelPreviousPendingOrder($paymentDO); + + if ($this->client instanceof TransactionPayRemainder) { + $orderIncrementId = $paymentDO->getOrder()->getOrder()->getIncrementId(); + $commandSubject['action'] = $this->client->setServiceAction($orderIncrementId); + } + + if ($this->skipCommand !== null && $this->skipCommand->isSkip($commandSubject)) { + return; + } + + // @TODO implement exceptions catching + $transferO = $this->transferFactory->create( + $this->requestBuilder->build($commandSubject) + ); + + $response = $this->client->placeRequest($transferO); + if ($this->validator !== null) { + $result = $this->validator->validate(array_merge($commandSubject, ['response' => $response])); + if (!$result->isValid()) { + try { + $paymentInstance = $paymentDO->getPayment()->getMethodInstance(); + $this->spamLimitService->updateRateLimiterCount($paymentDO->getPayment()->getMethodInstance()); + } catch (LimitReachException $th) { + $this->spamLimitService->setMaxAttemptsFlags($paymentInstance, $th->getMessage()); + return; + } + $this->processErrors($result); + } + } + + if ($this->handler) { + $this->handler->handle( + $commandSubject, + $response + ); + } + } + + /** + * Tries to map error messages from validation result and logs processed message. + * Throws an exception with mapped message or default error. + * + * @param ResultInterface $result + * @throws CommandException + */ + private function processErrors(ResultInterface $result) + { + $messages = []; + if (empty($result->getFailsDescription())) { + $errorsSource = array_merge($result->getErrorCodes(), $result->getFailsDescription()); + foreach ($errorsSource as $errorCodeOrMessage) { + $errorCodeOrMessage = (string)$errorCodeOrMessage; + + // error messages mapper can be not configured if payment method doesn't have custom error messages. + if ($this->errorMessageMapper !== null) { + $mapped = (string)$this->errorMessageMapper->getMessage($errorCodeOrMessage); + if (!empty($mapped)) { + $messages[] = $mapped; + $errorCodeOrMessage = $mapped; + } + } + $this->logger->critical('Payment Error: ' . $errorCodeOrMessage); + } + } else { + $messages[] = (string)$result->getFailsDescription()[0] ?? ''; + } + + + $errorMessage = ''; + if (!empty($messages)) { + foreach ($messages as $message) { + $errorMessage .= __($message) . PHP_EOL; + } + $errorMessage = rtrim($errorMessage); + } else { + $errorMessage ='Transaction has been declined. Please try again later.'; + } + + throw new CommandException(__($errorMessage)); + } +} diff --git a/Gateway/Command/SkipCommandInterface.php b/Gateway/Command/SkipCommandInterface.php new file mode 100644 index 000000000..09c974bea --- /dev/null +++ b/Gateway/Command/SkipCommandInterface.php @@ -0,0 +1,33 @@ +order = $order; + $this->addressAdapterFactory = $addressAdapterFactory; + } + + /** + * Returns currency code + * + * @return string + */ + public function getCurrencyCode(): string + { + return $this->order->getBaseCurrencyCode(); + } + + /** + * Returns order increment id + * + * @return string + */ + public function getOrderIncrementId(): string + { + return $this->order->getIncrementId(); + } + + /** + * Returns customer ID + * + * @return int|null + */ + public function getCustomerId(): ?int + { + return $this->order->getCustomerId(); + } + + /** + * Returns billing address + * + * @return AddressAdapterInterface|null + */ + public function getBillingAddress(): ?AddressAdapterInterface + { + if ($this->order->getBillingAddress()) { + return $this->addressAdapterFactory->create( + ['address' => $this->order->getBillingAddress()] + ); + } + + return null; + } + + /** + * Returns shipping address + * + * @return AddressAdapterInterface|null + */ + public function getShippingAddress(): ?AddressAdapterInterface + { + if ($this->order->getShippingAddress()) { + return $this->addressAdapterFactory->create( + ['address' => $this->order->getShippingAddress()] + ); + } + + return null; + } + + /** + * Returns order store id + * + * @return int|null + */ + public function getStoreId(): ?int + { + return (int)$this->order->getStoreId(); + } + + /** + * Returns order id + * + * @return mixed + */ + public function getId() + { + return $this->order->getEntityId(); + } + + /** + * Returns order grand total amount + * + * @return float + */ + public function getGrandTotalAmount(): float + { + return $this->order->getBaseGrandTotal(); + } + + /** + * Returns list of line items in the cart + * + * @return OrderItemInterface[] + */ + public function getItems(): array + { + return $this->order->getItems(); + } + + /** + * Gets the remote IP address for the order. + * + * @return string|null Remote IP address. + */ + public function getRemoteIp(): ?string + { + return $this->order->getRemoteIp(); + } + + /** + * Get entire order object + * + * @return Order + */ + public function getOrder(): Order + { + return $this->order; + } +} diff --git a/Gateway/ErrorMapper/ErrorMessageMapper.php b/Gateway/ErrorMapper/ErrorMessageMapper.php new file mode 100644 index 000000000..b9e7d87fb --- /dev/null +++ b/Gateway/ErrorMapper/ErrorMessageMapper.php @@ -0,0 +1,55 @@ +messageMapping = $messageMapping; + } + + /** + * @inheritdoc + */ + public function getMessage(string $code): ?Phrase + { + if (strlen($code) > 4) { + $message = $code; + } else { + $message = $this->messageMapping->get($code); + } + return $message ? __($message) : null; + } +} diff --git a/Gateway/GatewayInterface.php b/Gateway/GatewayInterface.php deleted file mode 100644 index 941d60f3c..000000000 --- a/Gateway/GatewayInterface.php +++ /dev/null @@ -1,74 +0,0 @@ -client = $client; - $this->transferBuilder = $transferBuilder; - $this->configProviderPredefined = $configProviderPredefined; - $this->configProviderRefund = $configProviderRefund; - $this->logger = $logger; - } - - /** - * @param int $mode - * - * @return $this - */ - public function setMode($mode) - { - $this->mode = $mode; - - return $this; - } - - /** - * @param \Buckaroo\Magento2\Gateway\Http\Transaction $transaction - * - * @return array - * @throws \Exception - */ - public function order(Transaction $transaction) - { - return $this->doRequest($transaction); - } - - /** - * @param \Buckaroo\Magento2\Gateway\Http\Transaction $transaction - * - * @return array - * @throws \Exception - */ - public function capture(Transaction $transaction) - { - return $this->doRequest($transaction); - } - - /** - * @param \Buckaroo\Magento2\Gateway\Http\Transaction $transaction - * - * @return array - * @throws \Exception - */ - public function authorize(Transaction $transaction) - { - return $this->doRequest($transaction); - } - - /** - * @param \Buckaroo\Magento2\Gateway\Http\Transaction $transaction - * - * @return array - * @throws \Exception|\Buckaroo\Magento2\Exception - */ - public function refund(Transaction $transaction) - { - if ($this->configProviderRefund->getEnabled()) { - return $this->doRequest($transaction); - } - - $this->logger->addDebug('Failed to refund because the configuration is set to disabled'); - throw new \Buckaroo\Magento2\Exception( - __("Online refunds are currently disabled for Buckaroo payment methods.") - ); - } - - /** - * @param \Buckaroo\Magento2\Gateway\Http\Transaction $transaction - * - * @return array - * @throws \Exception - */ - public function cancel(Transaction $transaction) - { - return $this->void($transaction); - } - - /** - * @param \Buckaroo\Magento2\Gateway\Http\Transaction $transaction - * - * @return array - * @throws \Exception - */ - public function void(Transaction $transaction) - { - return $this->doRequest($transaction); - } - - /** - * @return string - * - * @throws \Buckaroo\Magento2\Exception|\LogicException - */ - protected function getWsdl() - { - if (!$this->mode) { - throw new \LogicException("Cannot do a Buckaroo transaction when 'mode' is not set or set to 0."); - } - - switch ($this->mode) { - case \Buckaroo\Magento2\Helper\Data::MODE_TEST: - $wsdl = $this->configProviderPredefined->getWsdlTestWeb(); - break; - case \Buckaroo\Magento2\Helper\Data::MODE_LIVE: - $wsdl = $this->configProviderPredefined->getWsdlLiveWeb(); - break; - default: - throw new \Buckaroo\Magento2\Exception( - __( - "Invalid mode set: %1", - [ - $this->mode - ] - ) - ); - } - - return $wsdl; - } - - /** - * @param Transaction $transaction - * - * @return array - * @throws \Exception - */ - public function doRequest(Transaction $transaction) - { - $this->logger->addDebug(__METHOD__.'|1|'); - $this->logger->addDebug(var_export($transaction->getBody(), true)); - - $clientConfig = [ - 'wsdl' => $this->getWsdl() - ]; - - $transfer = $this->transferBuilder->setClientConfig($clientConfig); - $transfer->setHeaders($transaction->getHeaders()); - $transfer->setBody($transaction->getBody()); - $transfer->setAuthUsername(null); // The authorization is done by the request headers and encryption. - $transfer->setAuthPassword(null); - $transfer->setMethod($transaction->getMethod()); - $transfer->setUri(''); // The URI is part of the wsdl file. - $transfer->shouldEncode(false); - - $transfer = $transfer->build(); - - $this->client->setStore($transaction->getStore()); - - return $this->client->placeRequest($transfer); - } -} diff --git a/Gateway/Http/Client/DefaultTransaction.php b/Gateway/Http/Client/DefaultTransaction.php new file mode 100644 index 000000000..ae1684ede --- /dev/null +++ b/Gateway/Http/Client/DefaultTransaction.php @@ -0,0 +1,120 @@ +logger = $logger; + $this->paymentLogger = $paymentLogger; + $this->adapter = $adapter; + $this->action = $action; + } + + /** + * @inheritdoc + */ + public function placeRequest(TransferInterface $transferObject): array + { + $data = $transferObject->getBody(); + $log = [ + 'request' => $data, + 'client' => static::class + ]; + $response['object'] = []; + $paymentMethod = $data['payment_method']; + unset($data['payment_method']); + + try { + $response['object'] = $this->process($paymentMethod, $data); + } catch (\Exception $e) { + $message = __($e->getMessage() ?: 'Sorry, but something went wrong'); + $this->logger->critical($message); + throw new ClientException($message); + } finally { + $log['response'] = (array)$response['object']; + $this->paymentLogger->debug($log); + } + + return $response; + } + + /** + * Process http request + * + * @param string $paymentMethod + * @param array $data + * @return TransactionResponse + * @throws \Throwable + */ + protected function process(string $paymentMethod, array $data): TransactionResponse + { + if (isset($data['encryptedCardData'])) { + $this->action = TransactionType::PAY_ENCRYPTED; + } + return $this->adapter->execute($this->action, $paymentMethod, $data); + } +} diff --git a/Gateway/Http/Client/Json.php b/Gateway/Http/Client/Json.php index 1dfd4c5e9..ae1fea0c4 100644 --- a/Gateway/Http/Client/Json.php +++ b/Gateway/Http/Client/Json.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,170 +20,161 @@ namespace Buckaroo\Magento2\Gateway\Http\Client; -use Buckaroo\Magento2\Logging\Log; +use Buckaroo\Magento2\Helper\Data; +use Buckaroo\Magento2\Logging\BuckarooLoggerInterface; use Magento\Framework\HTTP\Client\Curl; class Json { + /** + * @var Curl + */ private $client; - private $logger; + /** + * @var BuckarooLoggerInterface + */ + private BuckarooLoggerInterface $logger; + + /** + * @var string + */ private $secretKey; + + /** + * @var string + */ private $websiteKey; + /** + * @param Curl $client + * @param BuckarooLoggerInterface $logger + */ public function __construct( Curl $client, - Log $logger + BuckarooLoggerInterface $logger ) { $this->client = $client; $this->logger = $logger; } + /** + * Create post request to payment engine + * + * @param array $data + * @param string|int $mode + * @return false|mixed + */ public function doRequest(array $data, $mode) { - $url = $mode == \Buckaroo\Magento2\Helper\Data::MODE_LIVE ? - 'checkout.buckaroo.nl' : 'testcheckout.buckaroo.nl'; - $uri = 'https://' . $url . '/json/Transaction'; - $uri2 = strtolower(rawurlencode($url . '/json/Transaction')); + $urls = $this->getUrls($mode); - $this->logger->addDebug(__METHOD__ . '|5|' . var_export($data, true)); - - $options = $this->getOptions($uri, $uri2, $data, 'POST'); + $this->logger->addDebug(sprintf( + '[HTTP_JSON] | [Gateway] | [%s:%s] - Create post request to payment engine | request: %s', + __METHOD__, + __LINE__, + var_export($data, true) + )); + $options = $this->getOptions($urls['uri'], $urls['uri2'], $data, 'POST'); $this->client->setOptions($options); - try { - $this->client->post($uri, $data); - $response = json_decode($this->client->getBody(), true); - } catch (\Exception $e) { - $this->logger->addDebug(__METHOD__ . '|10|' . var_export($e->getMessage(), true)); - return false; - } - - $this->logger->addDebug(__METHOD__ . '|15|' . var_export( - [ - $response, - $this->client->getStatus(), - ], - true - )); - - return $response; + return $this->getResponse($urls['uri'], $data); } + /** + * Create cancel request to payment engine + * + * @param string $key + * @param int $mode + * @return false|mixed + */ public function doCancelRequest($key, $mode) { - $url = $mode == \Buckaroo\Magento2\Helper\Data::MODE_LIVE ? - 'checkout.buckaroo.nl' : 'testcheckout.buckaroo.nl'; - $uri = 'https://' . $url . '/json/Transaction/cancel/' . $key; - $uri2 = strtolower(rawurlencode($url . '/json/Transaction/cancel/' . $key)); + $urls = $this->getUrls($mode, 'cancel', $key); - $options = $this->getOptions($uri, $uri2, [], 'GET'); + $options = $this->getOptions($urls['uri'], $urls['uri2'], [], 'GET'); $this->client->setOptions($options); - try { - $this->client->get($uri); - $response = json_decode($this->client->getBody(), true); - } catch (\Exception $e) { - $this->logger->addDebug(__METHOD__ . '|10|' . var_export($e->getMessage(), true)); - return false; - } - - $this->logger->addDebug(__METHOD__ . '|15|' . var_export( - [ - $response, - $this->client->getStatus(), - ], - true - )); - - return $response; + return $this->getResponse($urls['uri']); } /** - * Do a status request on transaction by transaction_id + * Create a status request on transaction by transaction_id * - * @param string $transaction_id + * @param string $transactionId * @param int $mode - * * @return void */ - public function doStatusRequest($transaction_id, $mode) + public function doStatusRequest($transactionId, $mode) { - $url = $mode == \Buckaroo\Magento2\Helper\Data::MODE_LIVE ? - 'checkout.buckaroo.nl' : 'testcheckout.buckaroo.nl'; - $uri = 'https://' . $url . '/json/Transaction/status/' . $transaction_id; - $uri2 = strtolower(rawurlencode($url . '/json/Transaction/status/' . $transaction_id)); + $urls = $this->getUrls($mode, 'status', $transactionId); - $options = $this->getOptions($uri, $uri2, [], 'GET'); + $options = $this->getOptions($urls['uri'], $urls['uri2'], [], 'GET'); $this->client->setOptions($options); - $this->logger->addDebug(__METHOD__ . '|10|' . var_export($options, true)); - - try { - $this->client->get($uri); - $response = json_decode($this->client->getBody(), true); - } catch (\Exception $e) { - $this->logger->addDebug(__METHOD__ . '|10|' . var_export($e->getMessage(), true)); - return false; - } - - $this->logger->addDebug(__METHOD__ . '|15|' . var_export( - [ - $response, - $this->client->getStatus(), - ], - true + $this->logger->addDebug(sprintf( + '[HTTP_JSON] | [Gateway] | [%s:%s] - Create a status request by transaction_id | request: %s', + __METHOD__, + __LINE__, + var_export($options, true) )); - return $response; + return $this->getResponse($urls['uri']); } - public function getOptions($uri, $uri2, $data, $httpMethod) + /** + * Get CURL options + * + * @param string $uri + * @param string $uri2 + * @param array $data + * @param string $httpMethod + * @return array + */ + public function getOptions(string $uri, string $uri2, array $data, string $httpMethod): array { $timeStamp = time(); - $nonce = $this->stringRandom(); - $json = json_encode($data, JSON_PRETTY_PRINT); + $nonce = $this->stringRandom(); + $json = \json_encode($data, JSON_PRETTY_PRINT); // phpcs:disable $md5 = md5($json, true); // phpcs:enable $encodedContent = base64_encode($md5); $rawData = $this->websiteKey . $httpMethod . $uri2 . $timeStamp . $nonce . $encodedContent; - $hash = hash_hmac('sha256', $rawData, $this->secretKey, true); - $hmac = base64_encode($hash); + $hash = hash_hmac('sha256', $rawData, $this->secretKey, true); + $hmac = base64_encode($hash); - $hmac_full = $this->websiteKey . ':' . $hmac . ':' . $nonce . ':' . $timeStamp; + $hmacFull = $this->websiteKey . ':' . $hmac . ':' . $nonce . ':' . $timeStamp; $headers = [ 'Content-Type: application/json; charset=utf-8', 'Accept: application/json', - 'Authorization: hmac ' . $hmac_full, + 'Authorization: hmac ' . $hmacFull, ]; return [ - CURLOPT_HTTPHEADER => $headers, + CURLOPT_HTTPHEADER => $headers, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => false, - CURLOPT_USERAGENT => 'Magento2', - CURLOPT_URL => $uri, - CURLOPT_CUSTOMREQUEST => $httpMethod, - CURLOPT_POSTFIELDS => $json, - //ZAK - //CURLOPT_SSL_VERIFYHOST => 0, - //CURLOPT_SSL_VERIFYPEER => 0 + CURLOPT_USERAGENT => 'Magento2', + CURLOPT_URL => $uri, + CURLOPT_CUSTOMREQUEST => $httpMethod, + CURLOPT_POSTFIELDS => $json ]; } - public function getStatus() - { - return $this->client->getStatus(); - } - + /** + * Get random string + * + * @param int $length + * @return string + */ private function stringRandom($length = 16) { $chars = str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'); - $str = ""; + $str = ""; for ($i = 0; $i < $length; $i++) { $key = array_rand($chars); @@ -193,13 +184,100 @@ private function stringRandom($length = 16) return $str; } + /** + * Get Client status + * + * @return int + */ + public function getStatus() + { + return $this->client->getStatus(); + } + + /** + * Set Buckaroo Secret Key + * + * @param string $secretKey + * @return void + */ public function setSecretKey($secretKey) { $this->secretKey = $secretKey; } + /** + * Set Merchant Key + * + * @param string $websiteKey + * @return void + */ public function setWebsiteKey($websiteKey) { $this->websiteKey = $websiteKey; } + + /** + * Get Response after JSON request + * + * @param string $uri + * @param array $data + * @return false|mixed + */ + public function getResponse(string $uri, array $data = []) + { + try { + if (!empty($data)) { + $this->client->post($uri, $data); + } else { + $this->client->get($uri); + } + + $response = json_decode($this->client->getBody(), true); + } catch (\Exception $e) { + $this->logger->addError(sprintf( + '[HTTP_JSON] | [Gateway] | [%s:%s] - Get Response after JSON request | [ERROR]: %s', + __METHOD__, + __LINE__, + $e->getMessage() + )); + return false; + } + + $this->logger->addDebug(sprintf( + '[HTTP_JSON] | [Gateway] | [%s:%s] - Get Response after JSON request | response: %s', + __METHOD__, + __LINE__, + var_export(['response' => $response, 'clientStatus' => $this->client->getStatus()], true) + )); + + return $response; + } + + /** + * Get URLs by mode and action + * + * @param string|int $mode + * @param string $action + * @param string $transactionId + * @return array + */ + private function getUrls($mode, string $action = '', string $transactionId = ''): array + { + + $url = ($mode == Data::MODE_LIVE) ? 'checkout.buckaroo.nl' : 'testcheckout.buckaroo.nl'; + $url .= '/json/Transaction'; + + if (!empty($action)) { + $url .= '/' . $action; + } + + if (!empty($transactionId)) { + $url .= '/' . $transactionId; + } + + return [ + 'uri' => 'https://' . $url, + 'uri2' => strtolower(rawurlencode($url)) + ]; + } } diff --git a/Gateway/Http/Client/Soap.php b/Gateway/Http/Client/Soap.php deleted file mode 100644 index a3b1f3c0a..000000000 --- a/Gateway/Http/Client/Soap.php +++ /dev/null @@ -1,59 +0,0 @@ -clientFactory = $clientFactory; - } - - /** - * @param null|\Magento\Store\Model\Store $store - * - * @return $this - */ - public function setStore($store) - { - $this->clientFactory->setStore($store); - - return $this; - } -} diff --git a/Gateway/Http/Client/TransactionPayOrInInstallments.php b/Gateway/Http/Client/TransactionPayOrInInstallments.php new file mode 100644 index 000000000..dd89c07ca --- /dev/null +++ b/Gateway/Http/Client/TransactionPayOrInInstallments.php @@ -0,0 +1,41 @@ +adapter->execute($action, $paymentMethod, $data); + } +} diff --git a/Gateway/Http/Client/TransactionPayRemainder.php b/Gateway/Http/Client/TransactionPayRemainder.php new file mode 100644 index 000000000..205f013ef --- /dev/null +++ b/Gateway/Http/Client/TransactionPayRemainder.php @@ -0,0 +1,93 @@ +payReminderService = $payReminderService; + $this->serviceAction = $serviceAction; + $this->newServiceAction = $newServiceAction; + } + + /** + * @inheritdoc + */ + protected function process(string $paymentMethod, array $data): TransactionResponse + { + $orderIncrementId = $data['invoice'] ?? $data['order'] ?? ''; + + $serviceAction = $this->payReminderService->getServiceAction( + $orderIncrementId, + $this->serviceAction, + $this->newServiceAction + ); + + return $this->adapter->execute($serviceAction, $paymentMethod, $data); + } + + /** + * Set service action before request builders + * + * @param string $orderIncrementId + * @return string + */ + public function setServiceAction(string $orderIncrementId): string + { + return $this->payReminderService->getServiceAction( + $orderIncrementId, + $this->serviceAction, + $this->newServiceAction + ); + } +} diff --git a/Gateway/Http/Client/TransactionType.php b/Gateway/Http/Client/TransactionType.php new file mode 100644 index 000000000..592e2fb69 --- /dev/null +++ b/Gateway/Http/Client/TransactionType.php @@ -0,0 +1,53 @@ +transferBuilder = $transferBuilder; + } + + /** + * Builds gateway transfer object + * + * @param array $request + * @return TransferInterface + */ + public function create(array $request): TransferInterface + { + return $this->transferBuilder + ->setBody($request) + ->setMethod('POST') + ->build(); + } +} diff --git a/Gateway/Http/Transaction.php b/Gateway/Http/Transaction.php deleted file mode 100644 index 10a005a0d..000000000 --- a/Gateway/Http/Transaction.php +++ /dev/null @@ -1,122 +0,0 @@ -body; - } - - /** - * @param array $body - * - * @return $this - */ - public function setBody($body) - { - $this->body = $body; - - return $this; - } - - /** - * @returns array - */ - public function getHeaders() - { - return $this->headers; - } - - /** - * @param array $headers - * - * @return $this - */ - public function setHeaders($headers) - { - $this->headers = $headers; - - return $this; - } - - /** - * @return string - */ - public function getMethod() - { - return $this->method; - } - - /** - * @param string $method - * - * @return $this - */ - public function setMethod($method) - { - $this->method = $method; - - return $this; - } - - /** - * @param \Magento\Store\Model\Store $store - * - * @return $this - */ - public function setStore($store) - { - $this->store = $store; - - return $this; - } - - /** - * @return \Magento\Store\Model\Store|null - */ - public function getStore() - { - return $this->store; - } -} diff --git a/Gateway/Http/TransactionBuilder/AbstractTransactionBuilder.php b/Gateway/Http/TransactionBuilder/AbstractTransactionBuilder.php deleted file mode 100644 index 37de38054..000000000 --- a/Gateway/Http/TransactionBuilder/AbstractTransactionBuilder.php +++ /dev/null @@ -1,654 +0,0 @@ -scopeConfig = $scopeConfig; - $this->softwareData = $softwareData; - $this->configProviderAccount = $configProviderAccount; - $this->transaction = $transaction; - $this->urlBuilder = $urlBuilder; - $this->formKey = $formKey; - $this->encryptor = $encryptor; - $this->logging = $logging; - - if ($amount !== null) { - $this->amount = $amount; - } - - if ($currency !== null) { - $this->currency = $currency; - } - - $this->configProviderMethodFactory = $configProviderMethodFactory; - } - - /** - * {@inheritdoc} - */ - public function setOriginalTransactionKey($originalTransactionKey) - { - $this->originalTransactionKey = $originalTransactionKey; - - return $this; - } - - /** - * @return null|string - */ - public function getOriginalTransactionKey() - { - return $this->originalTransactionKey; - } - - /** - * {@inheritdoc} - */ - public function setChannel($channel) - { - $this->channel = $channel; - - return $this; - } - - /** - * @return null|string - */ - public function getChannel() - { - return $this->channel; - } - - /** - * @param boolean $startRecurrent - * - * @return $this - */ - public function setStartRecurrent($startRecurrent) - { - $this->startRecurrent = $startRecurrent; - - return $this; - } - - /** - * @return string - */ - public function getFormKey() - { - return $this->formKey->getFormKey(); - } - - /** - * @return int - */ - public function getAmount() - { - return $this->amount; - } - - /** - * @param int $amount - * - * @return $this - */ - public function setAmount($amount) - { - $this->amount = $amount; - - return $this; - } - - /** - * @return int - */ - public function getInvoiceId() - { - $order = $this->getOrder(); - - if (empty($this->invoiceId) - || - (!$this->isCustomInvoiceId && ($this->invoiceId != $order->getIncrementId())) - ) { - $this->setInvoiceId($order->getIncrementId(), false); - } - - return $this->invoiceId; - } - - /** - * @param string $invoiceId - * - * @return $this - */ - public function setInvoiceId($invoiceId, $isCustomInvoiceId = true) - { - $this->invoiceId = $invoiceId; - $this->isCustomInvoiceId = $isCustomInvoiceId; - - return $this; - } - - /** - * @return string - */ - public function getCurrency() - { - return $this->currency; - } - - /** - * @param string $currency - * - * @return $this - */ - public function setCurrency($currency) - { - $this->currency = $currency; - - return $this; - } - - /** - * @return \Magento\Sales\Model\Order - */ - public function getOrder() - { - return $this->order; - } - - /** - * {@inheritdoc} - */ - public function setOrder($order) - { - $this->order = $order; - - return $this; - } - - /** - * @return array - */ - public function getServices() - { - return $this->services; - } - - /** - * {@inheritdoc} - */ - public function setServices($services) - { - $this->services = $services; - - return $this; - } - - /** - * @return array - */ - public function getCustomVars() - { - return $this->customVars; - } - - /** - * {@inheritdoc} - */ - public function setCustomVars($customVars) - { - $this->customVars = $customVars; - - return $this; - } - - /** - * @return string - */ - public function getMethod() - { - return $this->method; - } - - /** - * {@inheritdoc} - */ - public function setMethod($method) - { - $this->method = $method; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setType($type) - { - $this->type = $type; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getType() - { - return $this->type; - } - - /** - * {@inheritdoc} - */ - public function setReturnUrl($url) - { - $routeUrl = $this->urlBuilder->getRouteUrl($url); - - $this->returnUrl = $routeUrl; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getReturnUrl() - { - - $returnUrl = $this->getReturnUrlFromPayment(); - if($returnUrl !== null) { - $this->setReturnUrl($returnUrl); - return $returnUrl; - } - - - if ($this->returnUrl === null) { - $url = $this->urlBuilder->setScope($this->order->getStoreId()); - $url = $url->getRouteUrl('buckaroo/redirect/process') . '?form_key=' . $this->getFormKey(); - - $this->setReturnUrl($url); - } - - return $this->returnUrl; - } - - public function getReturnUrlFromPayment() - { - if( - $this->getOrder() === null || - $this->getOrder()->getPayment() === null || - $this->getOrder()->getPayment()->getAdditionalInformation(self::ADDITIONAL_RETURN_URL) === null - ) { - return; - } - $returnUrl = $this->getOrder()->getPayment()->getAdditionalInformation(self::ADDITIONAL_RETURN_URL); - if( - !filter_var($returnUrl, FILTER_VALIDATE_URL) === false && - in_array(parse_url($returnUrl, PHP_URL_SCHEME), ['http','https']) - ) { - return $returnUrl; - } - } - - /** - * @return Transaction - */ - public function build() - { - $this->logging->addDebug(__METHOD__ . '|1|'); - - $transaction = $this->transaction->setBody($this->getBody()); - $transaction->setHeaders($this->getHeaders()); - $transaction->setMethod($this->getMethod()); - - if ($this->getOrder()) { - $store = $this->getOrder()->getStore(); - $transaction->setStore($store); - } - - return $transaction; - } - - /** - * @return array - */ - abstract public function getBody(); - - /** - * @returns array - */ - public function getHeaders() - { - if ($this->getOrder() && ($store = $this->getOrder()->getStore())) { - $localeCountry = $this->scopeConfig->getValue('general/locale/code', ScopeInterface::SCOPE_STORE, $store); - $localeCountry = str_replace('_', '-', $localeCountry); - - $merchantKey = $this->encryptor->decrypt($this->configProviderAccount->getMerchantKey($store)); - - $payment = $this->getOrder()->getPayment(); - } - - $headers[] = new \SoapHeader( - 'https://checkout.buckaroo.nl/PaymentEngine/', - 'MessageControlBlock', - [ - 'Id' => '_control', - 'WebsiteKey' => $merchantKey ?? $this->getMerchantKey(), - 'Culture' => $localeCountry ?? 'en-US', - 'TimeStamp' => time(), - 'Channel' => $this->channel, - 'Software' => $this->softwareData->get($payment ?? null) - ], - false - ); - - $headers[] = new \SoapHeader( - 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd', - 'Security', - [ - 'Signature' => [ - 'SignedInfo' => [ - 'CanonicalizationMethod' => [ - 'Algorithm' => 'http://www.w3.org/2001/10/xml-exc-c14n#', - ], - 'SignatureMethod' => [ - 'Algorithm' => 'http://www.w3.org/2000/09/xmldsig#rsa-sha1', - ], - 'Reference' => [ - [ - 'Transforms' => [ - [ - 'Algorithm' => 'http://www.w3.org/2001/10/xml-exc-c14n#', - ] - ], - 'DigestMethod' => [ - 'Algorithm' => 'http://www.w3.org/2000/09/xmldsig#sha1', - ], - 'DigestValue' => '', - 'URI' => '#_body', - 'Id' => null, - ], - [ - 'Transforms' => [ - [ - 'Algorithm' => 'http://www.w3.org/2001/10/xml-exc-c14n#', - ] - ], - 'DigestMethod' => [ - 'Algorithm' => 'http://www.w3.org/2000/09/xmldsig#sha1', - ], - 'DigestValue' => '', - 'URI' => '#_control', - 'Id' => null, - ] - ] - ], - 'SignatureValue' => '', - ], - 'KeyInfo' => ' ', - ], - false - ); - - return $headers; - } - - protected function getIp($order) - { - $ip = $order->getRemoteIp(); - $store = $order->getStore(); - - $ipHeaders = $this->configProviderAccount->getIpHeader($store); - - if ($ipHeaders) { - $ipHeaders = explode(',', (string)strtoupper($ipHeaders)); - foreach ($ipHeaders as &$ipHeader) { - $ipHeader = 'HTTP_' . str_replace('-', '_', (string)$ipHeader); - } - $ip = $order->getPayment()->getMethodInstance()->getRemoteAddress(false, $ipHeaders); - } - - //trustly anyway should be w/o private ip - if ((isset($order->getPayment()->getMethodInstance()->buckarooPaymentMethodCode) && - $order->getPayment()->getMethodInstance()->buckarooPaymentMethodCode == 'trustly' - ) - && - $this->isIpPrivate($ip) - && - $order->getXForwardedFor() - ) { - $ip = $order->getXForwardedFor(); - } - - if (!$ip) { - $ip = $order->getPayment()->getMethodInstance()->getRemoteAddress(); - } - - return $ip; - } - - private function isIpPrivate($ip) - { - if (!$ip) { - return false; - } - - $pri_addrs = [ - '10.0.0.0|10.255.255.255', // single class A network - '172.16.0.0|172.31.255.255', // 16 contiguous class B network - '192.168.0.0|192.168.255.255', // 256 contiguous class C network - '169.254.0.0|169.254.255.255', // Link-local address also referred to as Automatic Private IP Addressing - '127.0.0.0|127.255.255.255' // localhost - ]; - - $long_ip = ip2long($ip); - if ($long_ip != -1) { - - foreach ($pri_addrs as $pri_addr) { - list ($start, $end) = explode('|', $pri_addr); - - if ($long_ip >= ip2long($start) && $long_ip <= ip2long($end)) { - return true; - } - } - } - - return false; - } - - public function setAdditionalParameter($key, $value) - { - $this->additionaParameters[$key] = $value; - - return $this; - } - - public function getAdditionalParameter($key) - { - return $this->additionaParameters[$key]; - } - - public function getAllAdditionalParameters() - { - return $this->additionaParameters; - } - - public function setMerchantKey($merchantKey) - { - $this->merchantKey = $merchantKey; - - return $this; - } - - public function getMerchantKey() - { - return $this->merchantKey; - } -} diff --git a/Gateway/Http/TransactionBuilder/DataRequest.php b/Gateway/Http/TransactionBuilder/DataRequest.php deleted file mode 100644 index 9c846f0a5..000000000 --- a/Gateway/Http/TransactionBuilder/DataRequest.php +++ /dev/null @@ -1,94 +0,0 @@ - (object)[ - '_' => $ip, - 'Type' => strpos($ip, ':') === false ? 'IPv4' : 'IPv6', - ], - 'ReturnURL' => $this->getReturnUrl(), - 'Services' => (object)[ - 'Service' => $this->getServices() - ], - 'AdditionalParameters' => (object)[ - 'AdditionalParameter' => $this->getAdditionalParameters() - ], - ]; - - return $body; - } - - /** - * @return array - */ - private function getAdditionalParameters() - { - $parameterLine = []; - if (isset($this->getServices()['Action'])) { - $parameterLine[] = $this->getParameterLine( - 'service_action_from_magento', - strtolower($this->getServices()['Action']) - ); - } - - $parameterLine[] = $this->getParameterLine('initiated_by_magento', 1); - - if ($additionalParameters = $this->getAllAdditionalParameters()) { - foreach ($additionalParameters as $key => $value) { - $parameterLine[] = $this->getParameterLine($key, $value); - } - } - - return $parameterLine; - } - - /** - * @param $name - * @param $value - * - * @return array - */ - private function getParameterLine($name, $value) - { - $line = [ - '_' => $value, - 'Name' => $name, - ]; - - return $line; - } -} diff --git a/Gateway/Http/TransactionBuilder/Idin.php b/Gateway/Http/TransactionBuilder/Idin.php deleted file mode 100644 index df7433e50..000000000 --- a/Gateway/Http/TransactionBuilder/Idin.php +++ /dev/null @@ -1,219 +0,0 @@ -store = $storeManager->getStore(); - $this->customerId = $customerSession->getCustomerId(); - $this->encryptor = $encryptor; - $this->configProviderAccount = $configProviderAccount; - - parent::__construct( - $scopeConfig, - $softwareData, - $configProviderAccount, - $transaction, - $urlBuilder, - $formKey, - $encryptor, - $configProviderMethodFactory, - $logging - ); - } - - /** - * Set issuer - * - * @param string $issuer - * - * @return $this - */ - public function setIssuer(string $issuer) - { - $this->issuer = $issuer; - return $this; - } - /** - * @return array - */ - public function getBody() - { - $additionalParameter = array_merge( - [ - [ - '_' => $this->customerId, - 'Name' => 'idin_cid', - ] - ], - $this->getAdditionalFormattedParameters() - ); - - $body = [ - 'ReturnURL' => $this->getReturnUrl(), - 'Services' => (object)[ - 'Service' => [ - 'Name' => 'Idin', - 'Action' => 'verify', - 'Version' => 0, - 'RequestParameter' => [ - [ - '_' => trim($this->issuer), - 'Name' => 'issuerId', - ], - ], - ] - ], - 'AdditionalParameters' => (object)[ - 'AdditionalParameter' => $additionalParameter - ], - ]; - - return $body; - } - /** - * Get merchant key for store - * - * @return mixed - */ - public function getMerchantKey() - { - return $this->encryptor->decrypt( - $this->configProviderAccount->getMerchantKey($this->store) - ); - } - /** - * Get idin mode - * - * @return int - */ - public function getMode() - { - return $this->configProviderAccount->getIdin($this->store); - } - /** - * {@inheritdoc} - */ - public function getReturnUrl() - { - if ($this->returnUrl === null) { - $url = $this->urlBuilder->setScope($this->store->getId()); - $url = $url->getRouteUrl('buckaroo/redirect/process') . '?form_key=' . $this->getFormKey(); - - $this->setReturnUrl($url); - } - - return $this->returnUrl; - } - /** @inheritDoc */ - public function build() - { - if ($this->issuer === null) { - throw new \Exception("Issuer is required in idin transaction builder", 1); - } - $this->setMethod('DataRequest'); - - return parent::build(); - } - /** - * Get any additional formatted parameters - * - * @return void - */ - private function getAdditionalFormattedParameters() - { - $parameters = []; - - if (!is_array($this->getAllAdditionalParameters())) { - return $parameters; - } - - foreach ($this->getAllAdditionalParameters() as $key => $value) { - $parameters[] = [ - '_' => $value, - 'Name' => $key, - ]; - } - return $parameters; - } -} diff --git a/Gateway/Http/TransactionBuilder/Order.php b/Gateway/Http/TransactionBuilder/Order.php deleted file mode 100644 index d6071ef50..000000000 --- a/Gateway/Http/TransactionBuilder/Order.php +++ /dev/null @@ -1,427 +0,0 @@ -getCurrency()) { - $this->setOrderCurrency(); - } - - if ($this->getAmount() < 0.01) { - $this->setOrderAmount(); - } - - $creditAmount = 0; - if ($this->getType() == 'void') { - $creditAmount = $this->getAmount(); - $this->setAmount(0); - } - - $order = $this->getOrder(); - $store = $order->getStore(); - - if ($this->configProviderAccount->getCreateOrderBeforeTransaction($store)) { - $newStatus = $this->configProviderAccount->getOrderStatusNew($store); - $orderState = 'new'; - if (!$newStatus) { - $newStatus = $order->getConfig()->getStateDefaultStatus($orderState); - } - - $order->setState($orderState); - $order->setStatus($newStatus); - $order->save(); - } - - $ip = $this->getIp($order); - - $billingData = $order->getBillingAddress(); - $shippingData = $order->getShippingAddress(); - $customParametersKey = $this->configProviderAccount->getCustomerAdditionalInfo($store); - - $body = [ - 'Currency' => $this->getCurrency(), - 'AmountDebit' => $this->getAmount(), - 'AmountCredit' => $creditAmount, - 'Invoice' => $this->getInvoiceId(), - 'Order' => $order->getIncrementId(), - 'ClientIP' => (object)[ - '_' => $ip, - 'Type' => strpos($ip, ':') === false ? 'IPv4' : 'IPv6', - ], - 'ReturnURL' => $this->getReturnUrl(), - 'ReturnURLCancel' => $this->getReturnUrl(), - 'ReturnURLError' => $this->getReturnUrl(), - 'ReturnURLReject' => $this->getReturnUrl(), - 'OriginalTransactionKey' => $this->originalTransactionKey, - 'StartRecurrent' => $this->startRecurrent, - 'PushURL' => $this->urlBuilder->getDirectUrl('rest/V1/buckaroo/push'), - 'Services' => (object)[ - 'Service' => $this->getServices() - ], - 'AdditionalParameters' => (object)[ - 'AdditionalParameter' => $this->getAdditionalParameters(), - ] - ]; - - if (!empty($customParametersKey)) { - $body['CustomParameters']['CustomParameter'] = $this->getCustomInfo( - $customParametersKey, - $billingData, - $shippingData - ); - } - - if (!$this->emptyDescriptionFlag) { - $body['Description'] = $this->configProviderAccount->getParsedLabel($store, $order); - } - - $body = $this->filterBody($body); - - $customVars = $this->getCustomVars(); - if (is_array($customVars) && count($customVars) > 0) { - foreach ($customVars as $key => $val) { - $body[$key] = $val; - } - } - - return $body; - } - - /** - * @return array - */ - private function getAdditionalParameters() - { - $parameterLine = []; - if (isset($this->getServices()['Action'])) { - $parameterLine[] = $this->getParameterLine( - 'service_action_from_magento', - strtolower($this->getServices()['Action']) - ); - } - - $parameterLine[] = $this->getParameterLine('initiated_by_magento', 1); - - if ($additionalParameters = $this->getAllAdditionalParameters()) { - foreach ($additionalParameters as $key => $value) { - $parameterLine[] = $this->getParameterLine($key, $value); - } - } - - return $parameterLine; - } - - private function getCustomInfo($customParametersKey, $billingData, $shippingData) - { - $customParameters = $this->getCustomNeededFieldsList($customParametersKey); - $customDataList = []; - $customParamList = []; - - $customerBillingArray = $this->formatCustomData($customParameters, 'billing'); - $customerShippingArray = $this->formatCustomData($customParameters, 'shipping'); - - $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); - - foreach ($customerBillingArray as $key => $value) { - if ($value != 'housenumber' && $value != 'houseadditionalnumber') { - $customerBillingArray[$key] = ''; - } - if (!empty($billingData->getData($value))) { - $customerBillingArray[$key] = $billingData->getData($value); - } - if ($value == 'country') { - $customerBillingArray[$key] = $this->getCountryName($objectManager, $billingData); - } - } - $this->setStreetData('CustomerBillingStreet', $customerBillingArray); - $customerBillingArray = $this->getNotEmptyCustomData($customerBillingArray); - - if ($shippingData === null) { - $shippingData = $billingData; - } - foreach ($customerShippingArray as $key => $value) { - if ($value != 'housenumber' && $value != 'houseadditionalnumber') { - $customerShippingArray[$key] = ''; - } - if (!empty($shippingData->getData($value))) { - $customerShippingArray[$key] = $shippingData->getData($value); - } - if ($value == 'country') { - $customerShippingArray[$key] = $this->getCountryName($objectManager, $shippingData); - } - } - $this->setStreetData('CustomerShippingStreet', $customerShippingArray); - $customerShippingArray = $this->getNotEmptyCustomData($customerShippingArray); - - $customDataList = array_merge($customerBillingArray, $customerShippingArray); - foreach ($customDataList as $key => $value) { - $customParamList[] = $this->getParameterLine($key, $value); - } - - return $customParamList; - } - - private function setStreetData($addressData, &$customerData) - { - $streetFormat = []; - if (!empty($customerData[$addressData])) { - $street = preg_replace('[\s]', ' ', $customerData[$addressData]); - $streetFormat = $this->formatStreet($street); - $customerData[$addressData] = 'street'; - - foreach ($customerData as $customerDataKey => $value) { - if ($value == 'street') { - $customerData[$customerDataKey] = $streetFormat['street']; - } - if ($value == 'housenumber') { - $customerData[$customerDataKey] = $streetFormat['housenumber']; - } - if ($value == 'houseadditionalnumber') { - $customerData[$customerDataKey] = $streetFormat['numberaddition']; - } - } - } - foreach ($customerData as $customerDataKey => $value) { - if ($value == 'housenumber' || $value == 'houseadditionalnumber') { - $customerData[$customerDataKey] = ''; - } - } - } - - private function getCountryName($objectManager, $data) - { - $countryName = $objectManager - ->create(\Magento\Directory\Model\Country::class) - ->load($data->getData('country_id')) - ->getName(); - - return $countryName; - } - - private function getNotEmptyCustomData($customData) - { - foreach ($customData as $key => $value) { - if (empty($value)) { - unset($customData[$key]); - } - } - - return $customData; - } - - private function formatCustomData($customParameters, $address) - { - $customDataList = []; - - foreach ($customParameters[$address] as $customParameter) { - $customParameterLabel = $this->getCustomParameterLabel($customParameter); - $customValue = $this->getCustomParameterValue($customParameter); - - $customDataList[$customParameterLabel] = $customValue; - } - - return $customDataList; - } - - private function formatStreet($street) - { -// $street = implode(' ', $street); -// $street = preg_split('[\s]', $street); - - $format = [ - 'housenumber' => '', - 'numberaddition' => '', - 'street' => $street - ]; - - if (preg_match('#^(.*?)([0-9\-]+)(.*)#s', $street, $matches)) { - // Check if the number is at the beginning of streetname - if ('' == $matches[1]) { - $format['housenumber'] = trim($matches[2]); - $format['street'] = trim($matches[3]); - } else { - if (preg_match('#^(.*?)([0-9]+)(.*)#s', $street, $matches)) { - $format['street'] = trim($matches[1]); - $format['housenumber'] = trim($matches[2]); - $format['numberaddition'] = trim($matches[3]); - } - } - } - - return $format; - } - /** - * @param $name - * @param $value - * - * @return array - */ - private function getParameterLine($name, $value) - { - $line = [ - '_' => $value, - 'Name' => $name, - ]; - - return $line; - } - - /** - * @param array $body - * - * @return array - */ - private function filterBody($body) - { - if ($this->getMethod() == 'CancelTransaction') { - $body['Transaction'] = ['Key' => $body['OriginalTransactionKey']]; - unset($body['OriginalTransactionKey']); - } - - $services = $this->getServices(); - - if (!isset($services['Name']) || !isset($services['Action'])) { - return $body; - } - - if ($services['Name'] == 'emandate' && $this->getMethod() == 'DataRequest') { - unset($body['Invoice']); - } - - if (in_array($services['Name'], ['klarnakp']) && $services['Action'] == 'Pay') { - unset($body['OriginalTransactionKey']); - } - - if (($services['Name'] == 'capayable' && $services['Action'] == 'PayInInstallments')) { - unset($body['Order']); - } - - if ($services['Name'] == 'CreditManagement3' && $services['Action'] == 'CreateCreditNote') { - unset($body['AmountCredit']); - unset($body['OriginalTransactionKey']); - } - - return $body; - } - - /** - * @return array - * @throws \Buckaroo\Magento2\Exception - */ - private function getAllowedCurrencies() - { - /** - * @var \Buckaroo\Magento2\Model\Method\AbstractMethod $methodInstance - */ - $methodInstance = $this->order->getPayment()->getMethodInstance(); - $method = $methodInstance->buckarooPaymentMethodCode ?? 'buckaroo_magento2_ideal'; - - $configProvider = $this->configProviderMethodFactory->get($method); - return $configProvider->getAllowedCurrencies(); - } - - /** - * @return $this - */ - private function setOrderAmount() - { - if ($this->getCurrency() == $this->order->getOrderCurrencyCode()) { - return $this->setAmount($this->order->getGrandTotal()); - } - - return $this->setAmount($this->order->getBaseGrandTotal()); - } - - /** - * @return $this - * @throws \Buckaroo\Magento2\Exception - */ - private function setOrderCurrency() - { - if (in_array($this->order->getOrderCurrencyCode(), $this->getAllowedCurrencies())) { - return $this->setCurrency($this->order->getOrderCurrencyCode()); - } - - if (in_array($this->order->getBaseCurrencyCode(), $this->getAllowedCurrencies())) { - return $this->setCurrency($this->order->getBaseCurrencyCode()); - } - - throw new \Buckaroo\Magento2\Exception( - __("The selected payment method does not support the selected currency or the store's base currency.") - ); - } - - public function setEmptyDescriptionFlag($enabled) - { - $this->emptyDescriptionFlag = $enabled; - } - - private function getCustomNeededFieldsList($customParameters) - { - $customParametersArray = explode(',', $customParameters); - $customBillingData = []; - $customShippingData = []; - foreach ($customParametersArray as $customParameter) { - if (strpos($customParameter, 'billing') !== false) { - $customBillingData[] = $customParameter; - } else { - $customShippingData[] = $customParameter; - } - } - $customParametersArray = null; - $customParametersArray['billing'] = $customBillingData; - $customParametersArray['shipping'] = $customShippingData; - - return $customParametersArray; - } - - public function getCustomParameterLabel($parameterKey) - { - $parameterLabel = str_replace(' ', '', ucwords(str_replace('_', ' ', $parameterKey))); - - return $parameterLabel; - } - - public function getCustomParameterValue($parameterKey) - { - $value = str_replace('_', '', preg_replace('/^customer_(billing|shipping)_/', '', $parameterKey)); - - return $value; - } -} diff --git a/Gateway/Http/TransactionBuilder/Refund.php b/Gateway/Http/TransactionBuilder/Refund.php deleted file mode 100644 index 32120f2b2..000000000 --- a/Gateway/Http/TransactionBuilder/Refund.php +++ /dev/null @@ -1,142 +0,0 @@ -order->getPayment()->getMethodInstance(); - $method = $methodInstance->buckarooPaymentMethodCode; - - $configProvider = $this->configProviderMethodFactory->get($method); - $allowedCurrencies = $configProvider->getAllowedCurrencies($this->order->getStore()); - - if (in_array($this->order->getOrderCurrencyCode(), $allowedCurrencies)) { - /** - * @todo find a way to fix the cumulative rounding issue that occurs in creditmemos. - * This problem occurs when the creditmemo is being refunded in the order's currency, rather than the - * store's base currency. - */ - $this->setCurrency($this->order->getOrderCurrencyCode()); - $this->setAmount(round($this->getAmount() * $this->order->getBaseToOrderRate(), 2)); - } elseif (in_array($this->order->getBaseCurrencyCode(), $allowedCurrencies)) { - $this->setCurrency($this->order->getBaseCurrencyCode()); - } else { - throw new \Buckaroo\Magento2\Exception( - __("The selected payment method does not support the selected currency or the store's base currency.") - ); - } - } - - /** - * @return array - */ - public function getBody() - { - if (!$this->getCurrency()) { - $this->setRefundCurrencyAndAmount(); - } - - $order = $this->getOrder(); - $store = $order->getStore(); - - $ip = $this->getIp($order); - - $body = [ - 'Currency' => $this->getCurrency(), - 'AmountDebit' => 0, - 'AmountCredit' => $this->getAmount(), - 'Invoice' => $this->getInvoiceId(), - 'Order' => $order->getIncrementId(), - 'Description' => $this->configProviderAccount->getParsedLabel($store, $order), - 'ClientIP' => (object)[ - '_' => $ip, - 'Type' => strpos($ip, ':') === false ? 'IPv4' : 'IPv6', - ], - 'ReturnURL' => $this->getReturnUrl(), - 'ReturnURLCancel' => $this->getReturnUrl(), - 'ReturnURLError' => $this->getReturnUrl(), - 'ReturnURLReject' => $this->getReturnUrl(), - 'OriginalTransactionKey' => $this->originalTransactionKey, - 'StartRecurrent' => $this->startRecurrent, - 'PushURL' => $this->urlBuilder->getDirectUrl('rest/V1/buckaroo/push'), - 'Services' => (object)[ - 'Service' => $this->getServices() - ], - 'AdditionalParameters' => (object)[ - 'AdditionalParameter' => $this->getAdditionalParameters() - ], - ]; - - return $body; - } - - /** - * @return array - */ - private function getAdditionalParameters() - { - $parameterLine = []; - if (isset($this->getServices()['Action'])) { - $parameterLine[] = $this->getParameterLine( - 'service_action_from_magento', - strtolower($this->getServices()['Action']) - ); - } - - $parameterLine[] = $this->getParameterLine('initiated_by_magento', 1); - - return $parameterLine; - } - - /** - * @param $name - * @param $value - * - * @return array - */ - private function getParameterLine($name, $value) - { - $line = [ - '_' => $value, - 'Name' => $name, - ]; - - return $line; - } -} diff --git a/Gateway/Http/TransactionBuilder/RefundPartial.php b/Gateway/Http/TransactionBuilder/RefundPartial.php deleted file mode 100644 index 95491a4ae..000000000 --- a/Gateway/Http/TransactionBuilder/RefundPartial.php +++ /dev/null @@ -1,221 +0,0 @@ -groupTransaction = $groupTransaction; - return $this; - } - - /** - * Set originating http request - * - * @param RequestInterface $request - * - * @return self - */ - public function setRequest(RequestInterface $request) - { - $this->httpRequest = $request; - return $this; - } - - /** - * Set current store - * - * @param Store $store - * - * @return self - */ - public function setStore(Store $store) - { - $this->store = $store; - return $this; - } - /** - * @return array - */ - public function getBody() - { - if (!$this->store instanceof Store) { - throw new \Exception("`store` must be instance of Magento\Store\Model\Store"); - } - - - if (!$this->groupTransaction instanceof GroupTransaction) { - throw new \Exception("`groupTransaction` must be instance of Buckaroo\Magento2\Model\GroupTransaction"); - } - - $ip = $this->getUserIp($this->store); - - $body = [ - 'Currency' => $this->groupTransaction->getCurrency(), - 'AmountDebit' => 0, - 'AmountCredit' => $this->groupTransaction->getRemainingAmount(), - 'Invoice' => $this->groupTransaction->getOrderIncrementId(), - 'Order' => $this->groupTransaction->getOrderIncrementId(), - 'Description' => $this->configProviderAccount->getTransactionLabel($this->store), - 'ClientIP' => (object)[ - '_' => $ip, - 'Type' => strpos($ip, ':') === false ? 'IPv4' : 'IPv6', - ], - 'ReturnURL' => $this->getReturnUrl(), - 'ReturnURLCancel' => $this->getReturnUrl(), - 'ReturnURLError' => $this->getReturnUrl(), - 'ReturnURLReject' => $this->getReturnUrl(), - 'OriginalTransactionKey' => $this->groupTransaction->getTransactionId(), - 'StartRecurrent' => $this->startRecurrent, - 'PushURL' => $this->urlBuilder->getDirectUrl('rest/V1/buckaroo/push'), - 'Services' => (object)[ - 'Service' => [ - 'Name' => $this->groupTransaction->getServicecode(), - 'Action' => 'Refund', - ] - ], - 'AdditionalParameters' => (object)[ - 'AdditionalParameter' => $this->getAdditionalParameters() - ], - ]; - - return $body; - } - - /** - * Get merchant key for store - * - * @return mixed - */ - public function getMerchantKey() - { - return $this->encryptor->decrypt( - $this->configProviderAccount->getMerchantKey($this->store) - ); - } - /** - * @return array - */ - private function getAdditionalParameters() - { - return [ - $this->getParameterLine('service_action_from_magento', 'refund'), - $this->getParameterLine('initiated_by_magento', 1) - ]; - } - - /** - * @param $name - * @param $value - * - * @return array - */ - private function getParameterLine($name, $value) - { - $line = [ - '_' => $value, - 'Name' => $name, - ]; - - return $line; - } - /** - * {@inheritdoc} - */ - public function getReturnUrl() - { - if ($this->returnUrl === null) { - $url = $this->urlBuilder->setScope($this->store->getId()); - $url = $url->getRouteUrl('buckaroo/redirect/process') . '?form_key=' . $this->getFormKey(); - - $this->setReturnUrl($url); - } - - return $this->returnUrl; - } - /** - * Get user ip - * - * @param Store $store - * - * @return string - * @throws \Exception - */ - protected function getUserIp($store) - { - - if (!$this->httpRequest instanceof RequestInterface) { - throw new \Exception("Required parameter `httpRequest` must be instance of Magento\Framework\App\RequestInterface"); - } - - $ipHeaders = $this->configProviderAccount->getIpHeader($store); - - $headers = []; - if ($ipHeaders) { - $ipHeaders = explode(',', strtoupper($ipHeaders)); - foreach ($ipHeaders as $ipHeader) { - $headers[] = 'HTTP_' . str_replace('-', '_', $ipHeader); - } - } - - $remoteAddress = new RemoteAddress( - $this->httpRequest, - $headers - ); - - return $remoteAddress->getRemoteAddress(); - } -} diff --git a/Gateway/Http/TransactionBuilderFactory.php b/Gateway/Http/TransactionBuilderFactory.php deleted file mode 100644 index 0ebc01908..000000000 --- a/Gateway/Http/TransactionBuilderFactory.php +++ /dev/null @@ -1,86 +0,0 @@ -objectManager = $objectManager; - $this->transactionBuilders = $transactionBuilders; - } - - /** - * Retrieve proper transaction builder for the specified transaction type. - * - * @param string $builderType - * - * @return TransactionBuilderInterface - * @throws \LogicException|\Buckaroo\Magento2\Exception - */ - public function get($builderType) - { - if (empty($this->transactionBuilders)) { - throw new \LogicException('Transaction builder adapter is not set.'); - } - foreach ($this->transactionBuilders as $transactionBuilderMetaData) { - $transactionBuilderType = $transactionBuilderMetaData['type']; - if ($transactionBuilderType == $builderType) { - $transactionBuilderClass = $transactionBuilderMetaData['model']; - break; - } - } - - if (!isset($transactionBuilderClass) || empty($transactionBuilderClass)) { - throw new \Buckaroo\Magento2\Exception( - new \Magento\Framework\Phrase( - 'Unknown transaction builder type requested: %1.', - [$builderType] - ) - ); - } - - $transactionBuilder = $this->objectManager->create($transactionBuilderClass); - if (!$transactionBuilder instanceof TransactionBuilderInterface) { - throw new \LogicException( - 'The transaction builder must implement "Buckaroo\Magento2\Gateway\Http\TransactionBuilderInterface".' - ); - } - return $transactionBuilder; - } -} diff --git a/Gateway/Http/TransactionBuilderInterface.php b/Gateway/Http/TransactionBuilderInterface.php deleted file mode 100644 index c4e98c667..000000000 --- a/Gateway/Http/TransactionBuilderInterface.php +++ /dev/null @@ -1,167 +0,0 @@ -setPayment($buildSubject['payment']->getPayment()); + $this->setOrder($buildSubject['payment']->getOrder()->getOrder()); + + return ['payment' => $this->getPayment(), 'order' => $this->getOrder()]; + } + + /** + * Retrieves the payment + * + * @return InfoInterface + */ + public function getPayment(): InfoInterface + { + return $this->payment; + } + + /** + * Sets the payment + * + * @param InfoInterface $payment + * @return $this + */ + public function setPayment(InfoInterface $payment): AbstractDataBuilder + { + $this->payment = $payment; + + return $this; + } + + /** + * Retrieves the order associated with the payment. + * + * @return Order + */ + public function getOrder(): Order + { + return $this->order; + } + + /** + * Sets the order associated with the payment. + * + * @param Order $order + * @return $this + */ + public function setOrder(Order $order): AbstractDataBuilder + { + $this->order = $order; + + return $this; + } +} diff --git a/Gateway/Request/AdditionalInformation/ApplepayDataBuilder.php b/Gateway/Request/AdditionalInformation/ApplepayDataBuilder.php new file mode 100644 index 000000000..eeee87fb3 --- /dev/null +++ b/Gateway/Request/AdditionalInformation/ApplepayDataBuilder.php @@ -0,0 +1,65 @@ + base64_encode( + (string)$paymentDO->getPayment()->getAdditionalInformation('applepayTransaction') + ), + 'customerCardName' => $this->getCustomerCardName($paymentDO), + ]; + } + + /** + * Get customer card name from Apple Pay transaction + * + * @param PaymentDataObjectInterface $paymentDO + * @return string|null + */ + protected function getCustomerCardName(PaymentDataObjectInterface $paymentDO): ?string + { + $billingContact = \json_decode( + stripslashes((string)$paymentDO->getPayment()->getAdditionalInformation('billingContact')) + ); + if ($billingContact && + !empty($billingContact->givenName) && + !empty($billingContact->familyName) + ) { + return $billingContact->givenName . ' ' . $billingContact->familyName; + } + + return null; + } +} diff --git a/Gateway/Request/AdditionalInformation/CreditcardEncryptedDataBuilder.php b/Gateway/Request/AdditionalInformation/CreditcardEncryptedDataBuilder.php new file mode 100644 index 000000000..22506e838 --- /dev/null +++ b/Gateway/Request/AdditionalInformation/CreditcardEncryptedDataBuilder.php @@ -0,0 +1,59 @@ +getPayment(); + + $additionalInformation = $payment->getAdditionalInformation(); + + if (!isset($additionalInformation['customer_encrypteddata'])) { + throw new Exception(__( + 'An error occured trying to send the encrypted creditcard data to Buckaroo.' + )); + } + + if (!isset($additionalInformation['customer_creditcardcompany'])) { + throw new Exception(__( + 'An error occured trying to send the creditcard company data to Buckaroo.' + )); + } + + return [ + 'name' => $additionalInformation['customer_creditcardcompany'], + 'encryptedCardData' => $additionalInformation['customer_encrypteddata'] + ]; + } +} diff --git a/Gateway/Request/AdditionalInformation/CreditcardTypeDataBuilder.php b/Gateway/Request/AdditionalInformation/CreditcardTypeDataBuilder.php new file mode 100644 index 000000000..5fd77ad2c --- /dev/null +++ b/Gateway/Request/AdditionalInformation/CreditcardTypeDataBuilder.php @@ -0,0 +1,38 @@ + $paymentDO->getPayment()->getAdditionalInformation('card_type')]; + } +} diff --git a/Gateway/Request/AdditionalInformation/ExpressOrderIdDataBuilder.php b/Gateway/Request/AdditionalInformation/ExpressOrderIdDataBuilder.php new file mode 100644 index 000000000..e9e2f9c33 --- /dev/null +++ b/Gateway/Request/AdditionalInformation/ExpressOrderIdDataBuilder.php @@ -0,0 +1,43 @@ +getPayment()->getAdditionalInformation('express_order_id'); + if ($expressOrderId !== null) { + return ['payPalOrderId' => $expressOrderId]; + } + + return []; + } +} diff --git a/Gateway/Request/AdditionalInformation/GiftcardNameDataBuilder.php b/Gateway/Request/AdditionalInformation/GiftcardNameDataBuilder.php new file mode 100644 index 000000000..6e27b1f6e --- /dev/null +++ b/Gateway/Request/AdditionalInformation/GiftcardNameDataBuilder.php @@ -0,0 +1,40 @@ + $paymentDO->getPayment()->getAdditionalInformation('giftcard_method') + ]; + } +} diff --git a/Gateway/Request/AdditionalInformation/IssuerDataBuilder.php b/Gateway/Request/AdditionalInformation/IssuerDataBuilder.php new file mode 100644 index 000000000..891fe61d6 --- /dev/null +++ b/Gateway/Request/AdditionalInformation/IssuerDataBuilder.php @@ -0,0 +1,45 @@ +getPayment()->getAdditionalInformation('issuer'); + + if (empty($issuer)) { + return []; + } + return [ + 'issuer' => $issuer, + ]; + } +} diff --git a/Gateway/Request/AdditionalInformation/OriginalTransactionKeyDataBuilder.php b/Gateway/Request/AdditionalInformation/OriginalTransactionKeyDataBuilder.php new file mode 100644 index 000000000..61ed7d86e --- /dev/null +++ b/Gateway/Request/AdditionalInformation/OriginalTransactionKeyDataBuilder.php @@ -0,0 +1,44 @@ +getPayment(); + + $originalTransactionKey = $payment->getAdditionalInformation(self::BUCKAROO_ORIGINAL_TRANSACTION_KEY_KEY); + + return ['originalTransactionKey' => $originalTransactionKey]; + } +} diff --git a/Gateway/Request/AdditionalInformation/SepaDirectDebitDataBuilder.php b/Gateway/Request/AdditionalInformation/SepaDirectDebitDataBuilder.php new file mode 100644 index 000000000..d592fcfd2 --- /dev/null +++ b/Gateway/Request/AdditionalInformation/SepaDirectDebitDataBuilder.php @@ -0,0 +1,54 @@ +getPayment(); + + $customerBic = $payment->getAdditionalInformation('customer_bic'); + $customerIban = $payment->getAdditionalInformation('customer_iban'); + $customerAccountName = $payment->getAdditionalInformation('customer_account_name'); + + $data = [ + 'iban' => $customerIban, + 'customer' => [ + 'name' => $customerAccountName + ] + ]; + + if (!empty($customerBic)) { + $data = ['bic' => $customerBic]; + } + + return $data; + } +} diff --git a/Gateway/Request/AdditionalInformation/VATNumberDataBuilder.php b/Gateway/Request/AdditionalInformation/VATNumberDataBuilder.php new file mode 100644 index 000000000..016c71d14 --- /dev/null +++ b/Gateway/Request/AdditionalInformation/VATNumberDataBuilder.php @@ -0,0 +1,39 @@ +getPayment(); + + return ['vATNumber' => $payment->getAdditionalInformation('customer_VATNumber') ?? '']; + } +} diff --git a/Gateway/Request/Address/AbstractAddressDataBuilder.php b/Gateway/Request/Address/AbstractAddressDataBuilder.php new file mode 100644 index 000000000..e2d511e8a --- /dev/null +++ b/Gateway/Request/Address/AbstractAddressDataBuilder.php @@ -0,0 +1,110 @@ +getAddress(); + + $streetFormat = $this->formatStreet($address->getStreet()); + + $addressData = [ + 'street' => $streetFormat['street'], + 'houseNumber' => '', + 'houseNumberAdditional' => '', + 'zipcode' => $address->getPostcode(), + 'city' => $address->getCity(), + 'country' => $address->getCountryId() + ]; + + if (!empty($streetFormat['house_number'])) { + $addressData['houseNumber'] = $streetFormat['house_number']; + } + + if (!empty($streetFormat['number_addition'])) { + $addressData['houseNumberAdditional'] = $streetFormat['number_addition']; + } + + return ['address' => $addressData]; + } + + /** + * Get Billing/Shipping address + * + * @return Address + */ + abstract protected function getAddress(): Address; + + /** + * Format street address + * + * @param string[] $street + * @return array + */ + public function formatStreet(array $street = null): array + { + if (!is_array($street)) { + return [ + 'house_number' => '', + 'number_addition' => '', + 'street' => '', + ]; + } + + $street = implode(' ', $street); + + $format = [ + 'house_number' => '', + 'number_addition' => '', + 'street' => $street, + ]; + + if (preg_match('#^(.*?)([\d\-]+)(.*)#s', $street, $matches)) { + // Check if the number is at the beginning of street name + if ('' == $matches[1]) { + $format['house_number'] = trim($matches[2]); + $format['street'] = trim($matches[3]); + } else { + if (preg_match('#^(.*?)(\d+)(.*)#s', $street, $matches)) { + $format['street'] = trim($matches[1]); + $format['house_number'] = trim($matches[2]); + $format['number_addition'] = trim($matches[3]); + } + } + } + + return $format; + } +} diff --git a/Gateway/Http/Client/EmptyConverter.php b/Gateway/Request/Address/BillingAddressDataBuilder.php similarity index 57% rename from Gateway/Http/Client/EmptyConverter.php rename to Gateway/Request/Address/BillingAddressDataBuilder.php index 453fc86d5..c9af198b3 100644 --- a/Gateway/Http/Client/EmptyConverter.php +++ b/Gateway/Request/Address/BillingAddressDataBuilder.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,23 +17,22 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ -namespace Buckaroo\Magento2\Gateway\Http\Client; +declare(strict_types=1); -use Magento\Payment\Gateway\Http\ConverterInterface; +namespace Buckaroo\Magento2\Gateway\Request\Address; -class EmptyConverter implements ConverterInterface -{ +use Magento\Sales\Model\Order\Address; +class BillingAddressDataBuilder extends AbstractAddressDataBuilder +{ /** - * Converts gateway response to ENV structure - * - * @param mixed $response + * Get Billing Address * - * @return array - * @throws \Magento\Payment\Gateway\Http\ConverterException + * @return Address + * @throws \Exception */ - public function convert($response) + protected function getAddress(): Address { - return $response; + return $this->getOrder()->getBillingAddress(); } } diff --git a/Gateway/Request/Address/EmailAddressDataBuilder.php b/Gateway/Request/Address/EmailAddressDataBuilder.php new file mode 100644 index 000000000..e3d583c4c --- /dev/null +++ b/Gateway/Request/Address/EmailAddressDataBuilder.php @@ -0,0 +1,68 @@ +addressType = $addressType; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + /** + * @var OrderAddressInterface $billingAddress + */ + $address = $this->getAddress(); + + return ['email' => $address->getEmail()]; + } + + /** + * Get Address by address type + * + * @return OrderAddressInterface|Address|null + */ + private function getAddress() + { + return ($this->addressType == 'shipping') + ? $this->getOrder()->getShippingAddress() ?? $this->getOrder()->getBillingAddress() + : $this->getOrder()->getBillingAddress(); + } +} diff --git a/Gateway/Request/Address/PhoneDataBuilder.php b/Gateway/Request/Address/PhoneDataBuilder.php new file mode 100644 index 000000000..64ee08271 --- /dev/null +++ b/Gateway/Request/Address/PhoneDataBuilder.php @@ -0,0 +1,92 @@ +addressType = $addressType; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $order = $paymentDO->getOrder()->getOrder(); + /** + * @var OrderAddressInterface $billingAddress + */ + $address = $this->getAddress($order); + + $telephone = $paymentDO->getPayment()->getAdditionalInformation('customer_telephone'); + $telephone = (empty($telephone) ? $address->getTelephone() : $telephone); + + return $this->returnPhoneDetails($telephone, $telephone); + } + + /** + * Get Billing/Shipping Address + * + * @param Order $order + * @return OrderAddressInterface|null + */ + private function getAddress(Order $order): ?OrderAddressInterface + { + return ($this->addressType == 'shipping') + ? $order->getShippingAddress() + : $order->getBillingAddress(); + } + + /** + * Return Phone Details + * + * @param string $telephone + * @param string $landline + * @return array[] + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function returnPhoneDetails(string $telephone, string $landline = ''): array + { + return [ + 'phone' => [ + 'mobile' => $telephone + ] + ]; + } +} diff --git a/Gateway/Request/Address/PhoneLandlineDataBuilder.php b/Gateway/Request/Address/PhoneLandlineDataBuilder.php new file mode 100644 index 000000000..ba937c99c --- /dev/null +++ b/Gateway/Request/Address/PhoneLandlineDataBuilder.php @@ -0,0 +1,38 @@ + [ + 'mobile' => $telephone, + 'landline' => $landline + ] + ]; + } +} diff --git a/Gateway/Request/Address/ShippingAddressDataBuilder.php b/Gateway/Request/Address/ShippingAddressDataBuilder.php new file mode 100644 index 000000000..30cbd59e4 --- /dev/null +++ b/Gateway/Request/Address/ShippingAddressDataBuilder.php @@ -0,0 +1,123 @@ +addressHandlerPool = $addressHandlerPool; + } + + /** + * Get Shipping Address + * + * @return Address + * @throws \Exception + */ + protected function getAddress(): Address + { + if ($this->isAddressDataDifferent($this->getPayment()) || + $this->getOrder()->getShippingAddress() === null || + $this->getPayment()->getMethod() === Klarna::CODE || + $this->getPayment()->getMethod() === Klarnain::CODE + ) { + return $this->addressHandlerPool->getShippingAddress($this->getOrder()); + } else { + return $this->getOrder()->getShippingAddress(); + } + } + + /** + * Method to compare two addresses from the payment. + * + * Returns true if they are the same. + * + * @param OrderPaymentInterface|InfoInterface $payment + * + * @return boolean + */ + public function isAddressDataDifferent($payment): bool + { + $billingAddress = $payment->getOrder()->getBillingAddress(); + $shippingAddress = $payment->getOrder()->getShippingAddress(); + + if ($billingAddress === null || $shippingAddress === null) { + return false; + } + + $billingAddressData = $billingAddress->getData(); + $shippingAddressData = $shippingAddress->getData(); + + $arrayDifferences = $this->calculateAddressDataDifference($billingAddressData, $shippingAddressData); + + return !empty($arrayDifferences); + } + + /** + * Calculate differences between Billing and Shipping Address + * + * @param array $addressOne + * @param array $addressTwo + * + * @return array + */ + private function calculateAddressDataDifference(array $addressOne, array $addressTwo): array + { + $keysToExclude = array_flip([ + 'prefix', + 'telephone', + 'fax', + 'created_at', + 'email', + 'customer_address_id', + 'vat_request_success', + 'vat_request_date', + 'vat_request_id', + 'vat_is_valid', + 'vat_id', + 'address_type', + 'extension_attributes', + 'quote_address_id' + ]); + + $filteredAddressOne = array_diff_key($addressOne, $keysToExclude); + $filteredAddressTwo = array_diff_key($addressTwo, $keysToExclude); + return array_diff($filteredAddressOne, $filteredAddressTwo); + } +} diff --git a/Gateway/Request/AddressHandler/AbstractAddressHandler.php b/Gateway/Request/AddressHandler/AbstractAddressHandler.php new file mode 100644 index 000000000..5d05d8bff --- /dev/null +++ b/Gateway/Request/AddressHandler/AbstractAddressHandler.php @@ -0,0 +1,108 @@ +logger = $logger; + } + + /** + * Update shipping address specific mapping + * + * @param array $mapping + * @param array $requestData + * @return void + * + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + protected function updateShippingAddressCommonMappingV2(array $mapping, array &$requestData) + { + foreach ($mapping as $mappingItem) { + if (!empty($mappingItem[1])) { + $found = false; + foreach ($requestData as $key => $value) { + if ($requestData[$key]['Name'] == $mappingItem[0]) { + $requestData[$key]['_'] = $mappingItem[1]; + $found = true; + } + } + if (!$found) { + $requestData[] = [ + '_' => $mappingItem[1], + 'Name' => $mappingItem[0], + ]; + } + } + } + } + + /** + * Update shipping address specific mapping + * + * @param array $mapping + * @param array $requestData + * @return void + * + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + protected function updateShippingAddressCommonMapping(array $mapping, array &$requestData) + { + foreach ($mapping as $mappingItem) { + if (!empty($mappingItem[1])) { + $found = false; + foreach ($requestData as $key => $value) { + if ($requestData[$key]['Group'] == 'ShippingCustomer' + && $requestData[$key]['Name'] == $mappingItem[0]) { + $requestData[$key]['_'] = $mappingItem[1]; + $found = true; + } + } + if (!$found) { + $requestData[] = [ + '_' => $mappingItem[1], + 'Name' => $mappingItem[0], + 'Group' => 'ShippingCustomer', + 'GroupID' => '', + ]; + } + } + } + } +} diff --git a/Gateway/Request/AddressHandler/DHLParcelAddressHandler.php b/Gateway/Request/AddressHandler/DHLParcelAddressHandler.php new file mode 100644 index 000000000..b574084cf --- /dev/null +++ b/Gateway/Request/AddressHandler/DHLParcelAddressHandler.php @@ -0,0 +1,113 @@ +curl = $curl; + parent::__construct($logger); + } + + /** + * Update shipping address by DHL parcel service point + * + * @param Order $order + * @param OrderAddressInterface $shippingAddress + * @return Order + */ + public function handle(Order $order, OrderAddressInterface $shippingAddress): Order + { + if (($order->getShippingMethod() == 'dhlparcel_servicepoint') + && $order->getDhlparcelShippingServicepointId() + ) { + $this->updateShippingAddressByDhlParcel($order->getDhlparcelShippingServicepointId(), $shippingAddress); + } + + return $order; + } + + /** + * Set shipping address fields by DHL Parcel + * + * @param string $servicePointId + * @param OrderAddressInterface $shippingAddress + * @return Address|null + */ + public function updateShippingAddressByDhlParcel(string $servicePointId, OrderAddressInterface $shippingAddress) + { + $matches = []; + if (preg_match('/^(.*)-([A-Z]{2})-(.*)$/', $servicePointId, $matches)) { + $this->curl->get( + 'https://api-gw.dhlparcel.nl/parcel-shop-locations/' + . $matches[2] + . '/' + . $servicePointId + ); + if (($response = $this->curl->getBody()) + && + //phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged + ($parsedResponse = @json_decode($response)) + && + !empty($parsedResponse->address) + ) { + $shippingAddress->setStreet([ + $this->cleanStreetNumberAddition($parsedResponse->address->{'street'}), + property_exists($parsedResponse->address, 'number') ? $parsedResponse->address->{'number'} : '', + property_exists($parsedResponse->address, 'addition') ? $parsedResponse->address->{'addition'} : '', + ]); + $shippingAddress->setPostcode($parsedResponse->address->{'postalCode'}); + $shippingAddress->setCity($parsedResponse->address->{'city'}); + $shippingAddress->setCountryId($parsedResponse->address->{'countryCode'}); + } + } + + return $shippingAddress; + } + + /** + * Remove all non-word characters + * + * @param string $addition + * @return array|string|string[]|null + */ + private function cleanStreetNumberAddition($addition) + { + return preg_replace('/[\W]/', '', $addition); + } +} diff --git a/Gateway/Request/AddressHandler/DPDPickupAddressHandler.php b/Gateway/Request/AddressHandler/DPDPickupAddressHandler.php new file mode 100644 index 000000000..4d9e4b241 --- /dev/null +++ b/Gateway/Request/AddressHandler/DPDPickupAddressHandler.php @@ -0,0 +1,130 @@ +quoteRepository = $quoteRepository; + parent::__construct($logger); + } + + /** + * Update shipping address by DPD Pickup point + * + * @param Order $order + * @param OrderAddressInterface $shippingAddress + * @return Order + * @throws NoSuchEntityException + * + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + public function handle(Order $order, OrderAddressInterface $shippingAddress): Order + { + if ($order->getShippingMethod() == 'dpdpickup_dpdpickup') { + $quote = $this->quoteRepository->get($order->getQuoteId()); + $requestData = []; + $this->updateShippingAddressByDpdParcel($quote, $requestData); + } + + return $order; + } + + /** + * Set shipping address fields by DPD Parcel + * + * @param CartInterface $quote + * @param array $requestData + * @return void + * + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + public function updateShippingAddressByDpdParcel(CartInterface $quote, array &$requestData) + { + $fullStreet = $quote->getDpdStreet(); + $postalCode = $quote->getDpdZipcode(); + $city = $quote->getDpdCity(); + $country = $quote->getDpdCountry(); + + if (!$fullStreet && $quote->getDpdParcelshopId()) { + $this->logger->addDebug(sprintf( + '[CREATE_ORDER] | [Gateway] | [%s:%s] - Set shipping address fields by DPD Parcel | cookie: %s', + __METHOD__, + __LINE__, + var_export($_COOKIE, true) + )); + $fullStreet = $_COOKIE['dpd-selected-parcelshop-street'] ?? ''; + $postalCode = $_COOKIE['dpd-selected-parcelshop-zipcode'] ?? ''; + $city = $_COOKIE['dpd-selected-parcelshop-city'] ?? ''; + $country = $_COOKIE['dpd-selected-parcelshop-country'] ?? ''; + } + + $matches = false; + if ($fullStreet && preg_match('/(.*)\s(.+)$/', $fullStreet, $matches)) { + $street = $matches[1]; + $streetHouseNumber = $matches[2]; + + $mapping = [ + ['Street', $street], + ['PostalCode', $postalCode], + ['City', $city], + ['Country', $country], + ['StreetNumber', $streetHouseNumber], + ]; + + $this->logger->addDebug(sprintf( + '[CREATE_ORDER] | [Gateway] | [%s:%s] - Set shipping address fields by DPD Parcel | newAddress: %s', + __METHOD__, + __LINE__, + var_export($mapping, true) + )); + + $this->updateShippingAddressCommonMapping($mapping, $requestData); + + foreach ($requestData as $key => $value) { + if ($requestData[$key]['Group'] == 'ShippingCustomer' + && $requestData[$key]['Name'] == 'StreetNumberAdditional' + ) { + unset($requestData[$key]); + } + } + } + } +} diff --git a/Gateway/Request/AddressHandler/MyParcelAddressHandler.php b/Gateway/Request/AddressHandler/MyParcelAddressHandler.php new file mode 100644 index 000000000..32a52ff9a --- /dev/null +++ b/Gateway/Request/AddressHandler/MyParcelAddressHandler.php @@ -0,0 +1,151 @@ +helper = $helper; + parent::__construct($logger); + } + + /** + * Update Shipping Address By MyParcel + * + * @param Order $order + * @param OrderAddressInterface $shippingAddress + * @return Order + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + public function handle(Order $order, OrderAddressInterface $shippingAddress): Order + { + $myparcelFetched = false; + $myparcelOptions = $order->getData('myparcel_delivery_options'); + $requestData = $shippingAddress->getData(); + if (!empty($myparcelOptions)) { + try { + $myparcelOptions = json_decode($myparcelOptions, true); + $isPickup = $myparcelOptions['isPickup'] ?? false; + if ($isPickup) { + $this->updateShippingAddressByMyParcel( + $myparcelOptions['pickupLocation'], + $requestData + ); + $myparcelFetched = true; + } + } catch (\JsonException $je) { + $this->logger->addError(sprintf( + '[CREATE_ORDER] | [Gateway] | [%s:%s] - Error related to json_decode' . ' + (MyParcel plugin compatibility) | [ERROR]: %s', + __METHOD__, + __LINE__, + $je->getMessage() + )); + } + } + + if (!$myparcelFetched + && (strpos((string)$order->getShippingMethod(), 'myparcelnl') !== false) + && (strpos((string)$order->getShippingMethod(), 'pickup') !== false) + && $this->helper->getCheckoutSession()->getMyParcelNLBuckarooData() + && $myParcelNLData = $this->helper->getJson()->unserialize( + $this->helper->getCheckoutSession()->getMyParcelNLBuckarooData() + )) { + $this->updateShippingAddressByMyParcel($myParcelNLData, $requestData); + } + + + return $order; + } + + /** + * Update shipping address by DPD Pickup point + * + * @param array $myParcelLocation + * @param array $requestData + * @return void + */ + protected function updateShippingAddressByMyParcel(array $myParcelLocation, array &$requestData) + { + $mapping = [ + ['ShippingStreet', $myParcelLocation['street']], + ['ShippingPostalCode', $myParcelLocation['postal_code']], + ['ShippingCity', $myParcelLocation['city']], + ['ShippingCountryCode', $myParcelLocation['cc']], + ['ShippingHouseNumber', $myParcelLocation['number']], + ['ShippingHouseNumberSuffix', $myParcelLocation['number_suffix']], + ]; + + $this->logger->addDebug(sprintf( + '[CREATE_ORDER] | [Gateway] | [%s:%s] - Set shipping address fields by myParcelNL | newAddress: %s', + __METHOD__, + __LINE__, + var_export($mapping, true) + )); + + $this->updateShippingAddressCommonMappingV2($mapping, $requestData); + } + + /** + * Set shipping address fields by DPD Parcel + * + * @param array $myParcelLocation + * @param array $requestData + * @return void + */ + protected function updateShippingAddressByMyParcelV2(array $myParcelLocation, array &$requestData) + { + $mapping = [ + ['Street', $myParcelLocation['street']], + ['PostalCode', $myParcelLocation['postal_code']], + ['City', $myParcelLocation['city']], + ['Country', $myParcelLocation['cc']], + ['StreetNumber', $myParcelLocation['number']], + ['StreetNumberAdditional', $myParcelLocation['number_suffix']], + ]; + + $this->logger->addDebug(sprintf( + '[CREATE_ORDER] | [Gateway] | [%s:%s] - Set shipping address fields by myParcelNL V2 | newAddress: %s', + __METHOD__, + __LINE__, + var_export($mapping, true) + )); + + $this->updateShippingAddressCommonMapping($mapping, $requestData); + } +} diff --git a/Gateway/Request/AddressHandler/PostNLAddressHandler.php b/Gateway/Request/AddressHandler/PostNLAddressHandler.php new file mode 100644 index 000000000..35212c0f3 --- /dev/null +++ b/Gateway/Request/AddressHandler/PostNLAddressHandler.php @@ -0,0 +1,86 @@ +addressFactory = $addressFactory; + parent::__construct($logger); + } + + /** + * Update shipping address by PostNL + * + * @param Order $order + * @param OrderAddressInterface $shippingAddress + * @return Order + */ + public function handle(Order $order, OrderAddressInterface $shippingAddress): Order + { + $postNLPakjeGemakAddress = $this->getPostNLPakjeGemakAddressInQuote($order->getQuoteId()); + + if (!empty($postNLPakjeGemakAddress) && !empty($postNLPakjeGemakAddress->getData())) { + foreach ($postNLPakjeGemakAddress->getData() as $key => $value) { + $shippingAddress->setData($key, $value); + } + } + + return $order; + } + + /** + * Check if there is a "pakjegemak" address stored in the quote by this order. + * Afterpay wants to receive the "pakjegemak" address instead of the customer shipping address. + * + * @param int $quoteId + * + * @return array|Address + */ + protected function getPostNLPakjeGemakAddressInQuote($quoteId) + { + $quoteAddress = $this->addressFactory->create(); + + $collection = $quoteAddress->getCollection(); + $collection->addFieldToFilter('quote_id', $quoteId); + $collection->addFieldToFilter('address_type', 'pakjegemak'); + // @codingStandardsIgnoreLine + return $collection->setPageSize(1)->getFirstItem(); + } +} diff --git a/Gateway/Request/AddressHandler/SendCloudAddressHandler.php b/Gateway/Request/AddressHandler/SendCloudAddressHandler.php new file mode 100644 index 000000000..436a57525 --- /dev/null +++ b/Gateway/Request/AddressHandler/SendCloudAddressHandler.php @@ -0,0 +1,94 @@ +getShippingMethod() == 'sendcloud_sendcloud') + && $order->getSendcloudServicePointId() + ) { + $requestData = []; + $this->updateShippingAddressBySendcloud($order, $requestData); + } + + return $order; + } + + /** + * Set shipping address fields by SendCloud + * + * @param Order $order + * @param array $requestData + * @return void + * + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + protected function updateShippingAddressBySendcloud(Order $order, array &$requestData) + { + if ($order->getSendcloudServicePointId() > 0) { + $mapping = $this->getAddressMapping($order); + foreach ($requestData as $key => $value) { + if ($requestData[$key]['Group'] == 'ShippingCustomer') { + $this->updateAddressData($requestData[$key], $mapping); + } + } + } + } + + private function getAddressMapping(Order $order): array + { + return [ + ['Street', $order->getSendcloudServicePointStreet()], + ['PostalCode', $order->getSendcloudServicePointZipCode()], + ['City', $order->getSendcloudServicePointCity()], + ['Country', $order->getSendcloudServicePointCountry()], + ['StreetNumber', $order->getSendcloudServicePointHouseNumber()], + ]; + } + + private function updateAddressData(array &$addressData, array $mapping): void + { + foreach ($mapping as $mappingItem) { + if (($addressData['Name'] == $mappingItem[0]) && !empty($mappingItem[1])) { + $addressData['_'] = $mappingItem[1]; + } + } + + if ($addressData['Name'] == 'StreetNumberAdditional') { + unset($addressData); + } + } +} diff --git a/Gateway/Request/AddressHandlerPool.php b/Gateway/Request/AddressHandlerPool.php new file mode 100644 index 000000000..0eeca0334 --- /dev/null +++ b/Gateway/Request/AddressHandlerPool.php @@ -0,0 +1,72 @@ + $addressHandler) { + if (!($addressHandler instanceof AddressHandlerInterface)) { + throw new TypeError("$key - $addressHandler is not instance of AddressHandlerInterface"); + } + } + $this->addressHandlers = $addressHandlers; + } + + /** + * Change shipping address based on Shipping method + * + * @param Order $order + * @return OrderAddressInterface|Address|null + * @throws Exception + */ + public function getShippingAddress(Order $order) + { + try { + $orderShippingAddress = $order->getShippingAddress() ?? $order->getBillingAddress(); + $shippingAddress = clone $orderShippingAddress; + foreach ($this->addressHandlers as $addressHandler) { + $order = $addressHandler->handle($order, $shippingAddress); + } + } catch (\Throwable $th) { + throw new \Buckaroo\Magento2\Exception($th->getMessage(), 0, $th); + } + + return $shippingAddress; + } +} diff --git a/Gateway/Request/AfterpayOldDataBuilder.php b/Gateway/Request/AfterpayOldDataBuilder.php new file mode 100644 index 000000000..689048fab --- /dev/null +++ b/Gateway/Request/AfterpayOldDataBuilder.php @@ -0,0 +1,124 @@ +recipientAfterpay = $recipientAfterpay; + $this->clientIPDataBuilder = $clientIPDataBuilder; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + + $category = $this->recipientAfterpay->getCategory($this->getOrder(), $this->getPayment()); + $accept = 'false'; + if ($this->getPayment()->getAdditionalInformation('termsCondition')) { + $accept = 'true'; + } + + return [ + 'customerIPAddress' => $this->clientIPDataBuilder->getIp($this->getOrder()), + 'addressesDiffer' => $this->isAddressDataDifferent(), + 'b2b' => $category == RecipientCategory::COMPANY, + 'accept' => $accept + ]; + } + + /** + * Method to compare two addresses from the payment. Returns true if they are the same. + * + * @return boolean + */ + public function isAddressDataDifferent(): bool + { + $billingAddress = $this->getOrder()->getBillingAddress(); + $shippingAddress = $this->getOrder()->getShippingAddress(); + + if ($billingAddress === null || $shippingAddress === null) { + return false; + } + + $billingAddressData = $billingAddress->getData(); + $shippingAddressData = $shippingAddress->getData(); + + $arrayDifferences = $this->calculateAddressDataDifference($billingAddressData, $shippingAddressData); + + return !empty($arrayDifferences); + } + + /** + * Calculates the difference between two address data arrays. + * + * @param array $addressOne + * @param array $addressTwo + * + * @return array + */ + private function calculateAddressDataDifference(array $addressOne, array $addressTwo): array + { + $keysToExclude = array_flip([ + 'prefix', + 'telephone', + 'fax', + 'created_at', + 'email', + 'customer_address_id', + 'vat_request_success', + 'vat_request_date', + 'vat_request_id', + 'vat_is_valid', + 'vat_id', + 'address_type', + 'extension_attributes', + 'quote_address_id' + ]); + + $filteredAddressOne = array_diff_key($addressOne, $keysToExclude); + $filteredAddressTwo = array_diff_key($addressTwo, $keysToExclude); + return array_diff($filteredAddressOne, $filteredAddressTwo); + } +} diff --git a/Gateway/Request/AfterpaySCADataBuilder.php b/Gateway/Request/AfterpaySCADataBuilder.php new file mode 100644 index 000000000..33e443bba --- /dev/null +++ b/Gateway/Request/AfterpaySCADataBuilder.php @@ -0,0 +1,66 @@ +configAfterpay = $configAfterpay; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $payment = $paymentDO->getPayment(); + + $serviceVersion = $payment->getAdditionalInformation(self::BUCKAROO_SERVICE_VERSION_KEY); + + if (!empty($serviceVersion)) { + return ['serviceVersion' => $serviceVersion]; + } + + if ($this->configAfterpay->isEnabledSCA($paymentDO->getOrder()->getStoreId())) { + $payment->setAdditionalInformation(self::BUCKAROO_SERVICE_VERSION_KEY, 2); + return ['serviceVersion' => 2]; + } + + return []; + } +} diff --git a/Gateway/Request/Articles/ArticlesDataBuilder.php b/Gateway/Request/Articles/ArticlesDataBuilder.php new file mode 100644 index 000000000..afe370aa7 --- /dev/null +++ b/Gateway/Request/Articles/ArticlesDataBuilder.php @@ -0,0 +1,47 @@ +articlesHandlerFactory = $articlesHandlerFactory; + } + + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + + $articleHandler = $this->articlesHandlerFactory->create($this->getPayment()->getMethod()); + + return $articleHandler->getOrderArticlesData($this->getOrder(), $this->getPayment()); + } +} diff --git a/Gateway/Request/Articles/ArticlesHandler/AbstractArticlesHandler.php b/Gateway/Request/Articles/ArticlesHandler/AbstractArticlesHandler.php new file mode 100644 index 000000000..b74299417 --- /dev/null +++ b/Gateway/Request/Articles/ArticlesHandler/AbstractArticlesHandler.php @@ -0,0 +1,860 @@ +scopeConfig = $scopeConfig; + $this->buckarooLog = $buckarooLog; + $this->quoteFactory = $quoteFactory; + $this->taxCalculation = $taxCalculation; + $this->taxConfig = $taxConfig; + $this->configProviderBuckarooFee = $configProviderBuckarooFee; + $this->softwareData = $softwareData; + $this->configProviderMethodFactory = $configProviderMethodFactory; + $this->payReminderService = $payReminderService; + } + + /** + * @inheritdoc + */ + public function getOrderArticlesData(Order $order, InfoInterface $payment): array + { + $this->buckarooLog->addDebug(__METHOD__ . '|1|'); + + $this->setPayment($payment); + $this->setOrder($order); + + if ($this->payReminderService->isPayRemainder($order)) { + return ['articles' => [0 => $this->getRequestArticlesDataPayRemainder()]]; + } + + $articles['articles'] = $this->getItemsLines(); + + $serviceLine = $this->getServiceCostLine($this->getOrder()); + if (!empty($serviceLine)) { + $articles = array_merge_recursive($articles, $serviceLine); + } + + // Add additional shipping costs. + $shippingCosts = $this->getShippingCostsLine($this->getOrder()); + if (!empty($shippingCosts)) { + $articles = array_merge_recursive($articles, $shippingCosts); + } + + $discountline = $this->getDiscountLine(); + if (!empty($discountline)) { + $articles['articles'][] = $discountline; + } + + $additionalLines = $this->getAdditionalLines(); + if (!empty($additionalLines)) { + $articles = array_merge_recursive($articles, $additionalLines); + } + + return $articles; + } + + /** + * Get Pay Remainder article + * + * @return array + */ + protected function getRequestArticlesDataPayRemainder(): array + { + return $this->getArticleArrayLine( + 'PayRemainder', + 1, + 1, + round($this->payReminderService->getPayRemainder($this->getOrder()), 2), + $this->getTaxCategory($this->getOrder()) + ); + } + + /** + * Mapping item article + * + * @param string|null $articleDescription + * @param int|string|null $articleId + * @param int|float $articleQuantity + * @param string|float $articleUnitPrice + * @param string|float $articleVat + * @return array + */ + public function getArticleArrayLine( + ?string $articleDescription, + $articleId, + $articleQuantity, + $articleUnitPrice, + $articleVat = '' + ): array { + return [ + 'identifier' => $articleId, + 'description' => $articleDescription, + 'vatPercentage' => $articleVat, + 'quantity' => $articleQuantity, + 'price' => $articleUnitPrice + ]; + } + + /** + * Get order + * + * @return Order + */ + public function getOrder(): Order + { + return $this->order; + } + + /** + * Set order + * + * @param Order $order + * @return $this + */ + public function setOrder(Order $order): AbstractArticlesHandler + { + $this->order = $order; + + return $this; + } + + /** + * Get Quote + * + * @return Quote + */ + public function getQuote(): Quote + { + if (!$this->quote instanceof Quote) { + $this->quote = $this->quoteFactory->create()->load($this->getOrder()->getQuoteId()); + } + + return $this->quote; + } + + /** + * Set Quote + * + * @param Quote $quote + * @return $this + */ + public function setQuote(Quote $quote): AbstractArticlesHandler + { + $this->quote = $quote; + return $this; + } + + /** + * Get tax category + * + * @param Order|Invoice $order + * @return float|int + */ + protected function getTaxCategory($order) + { + $request = $this->taxCalculation->getRateRequest( + null, + null, + null, + $order->getStore() + ); + $taxClassId = $this->configProviderBuckarooFee->getTaxClass($order->getStore()); + return $this->taxCalculation->getRate($request->setProductClassId($taxClassId)); + } + + /** + * Get items lines + * + * @return array + */ + protected function getItemsLines(): array + { + $articles = []; + $count = 1; + $bundleProductQty = 0; + + $quote = $this->getQuote(); + $cartData = $quote->getAllItems(); + + /** + * @var Item $item + */ + foreach ($cartData as $item) { + if ($this->skipItem($item)) { + continue; + } + + if ($this->skipBundleProducts($item, $bundleProductQty)) { + continue; + } + + $article = $this->getArticleArrayLine( + $item->getName(), + $this->getIdentifier($item), + $bundleProductQty ?: $item->getQty(), + $this->calculateProductPrice($item), + $this->getItemTax($item) + ); + + $articles[] = $article; + + if ($count >= self::MAX_ARTICLE_COUNT) { + break; + } + + $count++; + } + + return $articles; + } + + /** + * Skip item if item has parent or total equal 0 + * + * @param Item|Invoice\Item|Creditmemo\Item $item + * @return bool + */ + protected function skipItem($item): bool + { + if ($item->getRowTotalInclTax() == 0 + || $item->hasParentItemId() + ) { + return true; + } + + return false; + } + + /** + * Skip bundles which have dynamic pricing on (0 = yes,1 = no) - the underlying simples are also in the quote + * + * @param Item $item + * @param int $bundleProductQty + * @return bool + */ + protected function skipBundleProducts(Item $item, int &$bundleProductQty): bool + { + if ($item->getProductType() == Type::TYPE_BUNDLE + && $item->getProduct()->getCustomAttribute('price_type') + && $item->getProduct()->getCustomAttribute('price_type')->getValue() == 0 + ) { + $bundleProductQty = $item->getQty(); + return true; + } + + if (!$item->getParentItemId()) { + $bundleProductQty = 0; + } + + return false; + } + + /** + * Get identifier, can be sku or product id + * + * @param Item|Invoice\Item|Creditmemo\Item $item + * @return mixed|string|null + */ + protected function getIdentifier($item) + { + return $item->getSku(); + } + + /** + * Calculate product price + * + * @param Item|Invoice\Item|Creditmemo\Item $productItem + * @return float + */ + public function calculateProductPrice($productItem): float + { + $includesTax = $this->scopeConfig->getValue( + static::TAX_CALCULATION_INCLUDES_TAX, + ScopeInterface::SCOPE_STORE + ); + + $productPrice = $productItem->getPriceInclTax(); + + if (!$includesTax + && $productItem->getDiscountAmount() >= 0.01) { + $productPrice = $productItem->getPrice() + + $productItem->getTaxAmount() / $productItem->getQty(); + } + + if ($productItem->getWeeeTaxAppliedAmount() > 0) { + $productPrice += $productItem->getWeeeTaxAppliedAmount(); + } + + return (float)$productPrice; + } + + /** + * Get discount amount + * + * @return float|int + */ + protected function getDiscountAmount() + { + $discount = 0; + $edition = $this->softwareData->getProductMetaData()->getEdition(); + + if ($this->order->getDiscountAmount() < 0) { + $discount -= abs((double)$this->order->getDiscountAmount()); + } + + if ($edition == 'Enterprise' && $this->order->getCustomerBalanceAmount() > 0) { + $discount -= abs((double)$this->order->getCustomerBalanceAmount()); + } + + return $discount; + } + + /** + * Get item tax category or percentage + * + * @param Item|Order\Item $item + * @return float + */ + protected function getItemTax($item): float + { + return (float)$item->getTaxPercent() ?? 0; + } + + /** + * Get payment fee line + * + * @param Order|Invoice|Creditmemo $order + * @param float $itemsTotalAmount + * @return array|array[] + */ + public function getServiceCostLine($order, &$itemsTotalAmount = 0, bool $creditmemo = false): array + { + $buckarooFeeLine = (double)$order->getBuckarooFeeInclTax(); + + if (!$buckarooFeeLine && ($order->getBuckarooFee() >= 0.01)) { + $this->buckarooLog->addDebug(__METHOD__ . '|5|'); + $buckarooFeeLine = (double)$order->getBuckarooFee(); + } + + $article = []; + + if ($buckarooFeeLine && $buckarooFeeLine > 0) { + $article = $this->getArticleArrayLine( + 'Servicekosten', + 1, + 1, + round($buckarooFeeLine, 2), + $this->getTaxCategory($order) + ); + if ($creditmemo) { + $article['refundType'] = 'Refund'; + } + $itemsTotalAmount += round($buckarooFeeLine, 2); + } + + return !empty($article) ? ['articles' => [$article]] : []; + } + + /** + * Get shipping cost line + * + * @param Order|Invoice|Creditmemo $order + * @param int $itemsTotalAmount + * @param bool $creditmemo + * @return array + */ + protected function getShippingCostsLine($order, &$itemsTotalAmount = 0, bool $creditmemo = false): array + { + $shippingCostsArticle = []; + + $shippingAmount = $this->getShippingAmount($order); + if ($shippingAmount <= 0) { + return $shippingCostsArticle; + } + + $request = $this->taxCalculation->getRateRequest(); + $taxClassId = $this->taxConfig->getShippingTaxClass(); + $percent = $this->taxCalculation->getRate($request->setProductClassId($taxClassId)); + + $shippingCostsArticle = $this->getArticleArrayLine( + 'Shipping fee', + 2, + 1, + $this->formatPrice($shippingAmount), + $this->formatShippingCostsLineVatPercentage($percent) + ); + + if ($creditmemo) { + $shippingCostsArticle['refundType'] = 'Refund'; + } + + $itemsTotalAmount += $shippingAmount; + + return !empty($shippingCostsArticle) ? ['articles' => [$shippingCostsArticle]] : []; + } + + /** + * Get shipping amount include taxes + * + * @param Order|Invoice|Creditmemo $order + * @return float|null + */ + protected function getShippingAmount($order): ?float + { + return (float)$order->getShippingInclTax(); + } + + /** + * Format price + * + * @param float|null $price + * @return float|null + */ + protected function formatPrice(?float $price): ?float + { + return $price; + } + + /** + * Format shipping cost line + * + * @param float $percent + * @return float + */ + protected function formatShippingCostsLineVatPercentage(float $percent): float + { + return $percent; + } + + /** + * Get the discount cost lines + * + * @return array + */ + public function getDiscountLine(): array + { + $article = []; + $discount = $this->getDiscountAmount(); + + if ($discount >= 0) { + return $article; + } + + return $this->getArticleArrayLine( + 'Korting', + 1, + 1, + round($discount, 2), + 0 + ); + } + + /** + * @inheritdoc + */ + public function getInvoiceArticlesData(Order $order, InfoInterface $payment): array + { + $this->buckarooLog->addDebug(__METHOD__ . '|1|'); + + $this->setPayment($payment); + $this->setOrder($order); + + $invoiceCollection = $this->getOrder()->getInvoiceCollection(); + $numberOfInvoices = $invoiceCollection->count(); + + /** + * @var Invoice $currentInvoice + */ + $currentInvoice = $invoiceCollection->getLastItem(); + + $articles['articles'] = $this->getInvoiceItemsLines($currentInvoice); + + if (is_array($articles) && $numberOfInvoices == 1) { + $serviceLine = $this->getServiceCostLine($currentInvoice); + if (!empty($serviceLine)) { + $articles = array_merge_recursive($articles, $serviceLine); + } + } + + $shippingCosts = $this->getShippingCostsLine($currentInvoice); + if (!empty($shippingCosts)) { + $articles = array_merge_recursive($articles, $shippingCosts); + } + + return $articles; + } + + /** + * Get items from invoice + * + * @param Invoice $invoice + * @return array + */ + protected function getInvoiceItemsLines(Invoice $invoice): array + { + $articles = []; + $count = 1; + + /** @var Invoice\Item $item */ + foreach ($invoice->getAllItems() as $item) { + if ($this->skipItem($item)) { + continue; + } + + $article = $this->getArticleArrayLine( + $item->getName(), + $this->getIdentifier($item), + $item->getQty(), + $this->calculateProductPrice($item), + $this->getItemTax($item->getOrderItem()) + ); + + $articles[] = $article; + + if ($item->getDiscountAmount() > 0) { + $count++; + $article = $this->getArticleArrayLine( + $this->getDiscountDescription($item), + $item->getSku(), + 1, + number_format(($item->getDiscountAmount() * -1), 2), + 0 + ); + $articles[] = $article; + } + + if ($count >= self::MAX_ARTICLE_COUNT) { + break; + } + + $count++; + } + + return $articles; + } + + /** + * Get invoice discount description + * + * @param Invoice\Item $item + * @return string + */ + protected function getDiscountDescription($item): string + { + return 'Korting op ' . $item->getName(); + } + + /** + * Get Items Data from Creditmemo (refund) + * + * @param Order $order + * @param InfoInterface $payment + * @return array|array[] + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + public function getCreditMemoArticlesData(Order $order, InfoInterface $payment): array + { + if ($this->payReminderService->isPayRemainder($order)) { + return ['articles' => [0 => $this->getCreditmemoArticleDataPayRemainder()]]; + } + + $this->setPayment($payment); + $this->setOrder($order); + + /** @var Creditmemo $creditmemo */ + $creditmemo = $payment->getCreditmemo(); + + $articles = []; + $count = 1; + $itemsTotalAmount = 0; + + /** + * @var Creditmemo\Item $item + */ + foreach ($creditmemo->getAllItems() as $item) { + if ($this->skipItem($item)) { + continue; + } + + $prodPrice = $this->calculateProductPrice($item); + $prodPriceWithoutDiscount = round($prodPrice - $item->getDiscountAmount() / $item->getQty(), 2); + $article = $this->getArticleRefundArrayLine( + $item->getName(), + $this->getIdentifier($item), + $item->getQty(), + $prodPriceWithoutDiscount, + $this->getItemTax($item->getOrderItem()) + ); + + $itemsTotalAmount += $item->getQty() * $prodPriceWithoutDiscount; + + $articles['articles'][] = $article; + + if ($count < self::MAX_ARTICLE_COUNT) { + $count++; + continue; + } + + break; + } + + if (!empty($articles) && !$payment->getOrder()->hasCreditmemos()) { + $serviceLine = $this->getServiceCostLine($creditmemo, $itemsTotalAmount, true); + if (!empty($serviceLine)) { + $articles = array_merge_recursive($articles, $serviceLine); + } + } + + $shippingCosts = $this->getShippingCostsLine($creditmemo, $itemsTotalAmount, true); + if (!empty($shippingCosts)) { + $articles = array_merge_recursive($articles, $shippingCosts); + } + + if (abs($creditmemo->getGrandTotal() - $itemsTotalAmount) > 0.01) { + $diff = $creditmemo->getGrandTotal() - $itemsTotalAmount; + $diffLine = $this->getDiffLine($diff, true); + $articles = array_merge_recursive($articles, $diffLine); + } + + return $articles; + } + + /** + * Get pay remainder article for credit memo + * + * @return array + */ + protected function getCreditmemoArticleDataPayRemainder(): array + { + $payRemainderAmount = round($this->payReminderService->getPayRemainder($this->getOrder()), 2); + return $this->getArticleRefundArrayLine( + 'PayRemainder', + 1, + 1, + $payRemainderAmount, + $this->getTaxCategory($this->getOrder()) + ); + } + + /** + * Get the structure of the array returned to request for refunded items + * + * @param string|null $articleDescription + * @param int|string|null $articleId + * @param int|float $articleQuantity + * @param string|float $articleUnitPrice + * @param string|float $articleVat + * @return array + */ + public function getArticleRefundArrayLine( + ?string $articleDescription, + $articleId, + $articleQuantity, + $articleUnitPrice, + $articleVat = '' + ): array { + return [ + 'refundType' => 'Refund', + 'identifier' => $articleId, + 'description' => $articleDescription, + 'vatPercentage' => $articleVat, + 'quantity' => $articleQuantity, + 'price' => $articleUnitPrice + ]; + } + + /** + * Get the difference between total and items total + * + * @param float $diff + * @param bool $creditmemo + * @return array[] + */ + protected function getDiffLine(float $diff, bool $creditmemo = false): array + { + $article = $this->getArticleArrayLine( + 'Discount/Fee', + 4, + 1, + round($diff, 2), + 4 + ); + + if ($creditmemo) { + $article['refundType'] = 'Refund'; + } + + return ['articles' => [$article]]; + } + + /** + * Get payment + * + * @return InfoInterface + */ + public function getPayment(): InfoInterface + { + return $this->payment; + } + + /** + * Set payment + * + * @param $payment + * @return $this + */ + public function setPayment($payment): AbstractArticlesHandler + { + $this->payment = $payment; + + return $this; + } + + /** + * Get Additional Lines for specific methods + * + * @return array + */ + protected function getAdditionalLines(): array + { + return []; + } +} diff --git a/Gateway/Request/Articles/ArticlesHandler/AfterpayHandler.php b/Gateway/Request/Articles/ArticlesHandler/AfterpayHandler.php new file mode 100644 index 000000000..ae320eb4e --- /dev/null +++ b/Gateway/Request/Articles/ArticlesHandler/AfterpayHandler.php @@ -0,0 +1,190 @@ +imageHelper = $imageHelper; + } + + /** + * Get the structure of the array returned to request for refunded items + * + * @param string|null $articleDescription + * @param int|string|null $articleId + * @param int|float $articleQuantity + * @param string|float $articleUnitPrice + * @param string|float $articleVat + * @return array + */ + public function getArticleRefundArrayLine( + ?string $articleDescription, + $articleId, + $articleQuantity, + $articleUnitPrice, + $articleVat = '' + ): array { + return [ + 'refundType' => 'Return', + 'identifier' => $articleId, + 'description' => $articleDescription, + 'vatPercentage' => $articleVat, + 'quantity' => $articleQuantity, + 'price' => $articleUnitPrice + ]; + } + + /** + * Get items lines + * + * @return array + */ + protected function getItemsLines(): array + { + $articles = []; + $count = 1; + $bundleProductQty = 0; + + $quote = $this->getQuote(); + $cartData = $quote->getAllItems(); + + /** + * @var Item $item + */ + foreach ($cartData as $item) { + if ($this->skipItem($item)) { + continue; + } + + if ($this->skipBundleProducts($item, $bundleProductQty)) { + continue; + } + + $article = $this->getArticleArrayLine( + $item->getName(), + $this->getIdentifier($item), + $bundleProductQty ?: $item->getQty(), + $this->calculateProductPrice($item), + $this->getItemTax($item), + $this->getProductImageUrl($item) + ); + + $articles[] = $article; + + if ($count >= self::MAX_ARTICLE_COUNT) { + break; + } + + $count++; + } + + return $articles; + } + + /** + * Get product image URL + * + * @param Item $item + * @return string + */ + protected function getProductImageUrl($item) + { + $product = $item->getProduct(); + return $this->imageHelper->init($product, 'thumbnail') + ->setImageFile($product->getImage()) + ->getUrl(); + } + + /** + * @inheritdoc + */ + public function getArticleArrayLine( + ?string $articleDescription, + $articleId, + $articleQuantity, + $articleUnitPrice, + $articleVat = '', + $imageUrl = '' + ): array { + return [ + 'identifier' => $articleId, + 'description' => $articleDescription, + 'vatPercentage' => $articleVat, + 'quantity' => $articleQuantity, + 'price' => $articleUnitPrice, + 'imageUrl' => $imageUrl + ]; + } +} diff --git a/Gateway/Request/Articles/ArticlesHandler/AfterpayOldHandler.php b/Gateway/Request/Articles/ArticlesHandler/AfterpayOldHandler.php new file mode 100644 index 000000000..9e1831204 --- /dev/null +++ b/Gateway/Request/Articles/ArticlesHandler/AfterpayOldHandler.php @@ -0,0 +1,144 @@ + $articleId, + 'description' => $articleDescription, + 'vatCategory' => $articleVat ?: self::DEFAULT_TAX_CATEGORY, + 'quantity' => $articleQuantity, + 'price' => $articleUnitPrice + ]; + } + + /** + * @inheritdoc + */ + public function getArticleRefundArrayLine( + ?string $articleDescription, + $articleId, + $articleQuantity, + $articleUnitPrice, + $articleVat = '' + ): array { + return [ + 'identifier' => $articleId, + 'description' => $articleDescription, + 'vatCategory' => $articleVat ?: self::DEFAULT_TAX_CATEGORY, + 'quantity' => $articleQuantity, + 'price' => $articleUnitPrice + ]; + } + + /** + * @inheritdoc + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function getItemTax($item): float + { + return $this->getTaxCategory($this->getOrder()); + } + + /** + * @inheritdoc + */ + protected function getTaxCategory($order) + { + $storeId = (int)$order->getStoreId(); + $taxClassId = $this->configProviderBuckarooFee->getTaxClass($storeId); + + $taxCategory = self::DEFAULT_TAX_CATEGORY; + + if (!$taxClassId) { + return $taxCategory; + } + /** + * @var Afterpay $afterPayConfig + */ + $afterPayConfig = $this->configProviderMethodFactory->get($this->getPayment()->getMethod()); + + $highClasses = explode(',', (string)$afterPayConfig->getHighTaxClasses($storeId)); + $middleClasses = explode(',', (string)$afterPayConfig->getMiddleTaxClasses($storeId)); + $lowClasses = explode(',', (string)$afterPayConfig->getLowTaxClasses($storeId)); + $zeroClasses = explode(',', (string)$afterPayConfig->getZeroTaxClasses($storeId)); + + if (in_array($taxClassId, $highClasses)) { + $taxCategory = self::HIGH_TAX_CATEGORY; + } elseif (in_array($taxClassId, $middleClasses)) { + $taxCategory = self::MIDDLE_TAX_CATEGORY; + } elseif (in_array($taxClassId, $lowClasses)) { + $taxCategory = self::LOW_TAX_CATEGORY; + } elseif (in_array($taxClassId, $zeroClasses)) { + $taxCategory = self::ZERO_TAX_CATEGORY; + } + + return $taxCategory; + } + + /** + * @inheritdoc + */ + protected function getIdentifier($item) + { + return $item->getProductId(); + } + + /** + * @inheritdoc + */ + protected function getShippingCostsLine($order, &$itemsTotalAmount = 0, bool $creditmemo = false): array + { + $shippingCostsArticle = []; + + $shippingAmount = $this->getShippingAmount($order); + if ($shippingAmount <= 0) { + return $shippingCostsArticle; + } + + $shippingCostsArticle = ['shippingCosts' => $shippingAmount]; + + $itemsTotalAmount += $shippingAmount; + + return $shippingCostsArticle; + } +} diff --git a/Gateway/Request/Articles/ArticlesHandler/ArticlesHandlerFactory.php b/Gateway/Request/Articles/ArticlesHandler/ArticlesHandlerFactory.php new file mode 100644 index 000000000..b2563d6ac --- /dev/null +++ b/Gateway/Request/Articles/ArticlesHandler/ArticlesHandlerFactory.php @@ -0,0 +1,83 @@ +objectManager = $objectManager; + $this->articlesHandlers = $articlesHandlers; + } + + /** + * @throws Exception + */ + public function create($payment) + { + try { + if (empty($this->articlesHandlers)) { + throw new \LogicException('There is no articles handler.'); + } + + $paymentMethodName = str_replace('buckaroo_magento2_', '', $payment); + + $articleHandlerClass = $this->articlesHandlers[$paymentMethodName] ?? $this->articlesHandlers['default']; + + if (empty($articleHandlerClass)) { + throw new \Buckaroo\Magento2\Exception( + new \Magento\Framework\Phrase( + 'Unknown Articles Handler type requested: %1.', + [$paymentMethodName] + ) + ); + } + + return $this->objectManager->get($articleHandlerClass); + } catch (\Exception $exception) { + throw new \Buckaroo\Magento2\Exception( + new \Magento\Framework\Phrase( + 'Unknown Articles Handler type requested: %1.' + ) + ); + } + } +} diff --git a/Gateway/Request/Articles/ArticlesHandler/BillinkHandler.php b/Gateway/Request/Articles/ArticlesHandler/BillinkHandler.php new file mode 100644 index 000000000..b6eab4de1 --- /dev/null +++ b/Gateway/Request/Articles/ArticlesHandler/BillinkHandler.php @@ -0,0 +1,95 @@ +quoteFactory->create()->load($this->getOrder()->getQuoteId()); + $cartData = $quote->getAllItems(); + + /** + * @var Item $item + */ + foreach ($cartData as $item) { + if ($this->skipItem($item)) { + continue; + } + + if ($this->skipBundleProducts($item, $bundleProductQty)) { + continue; + } + + $article = $this->getArticleArrayLine( + $item->getName(), + $this->getIdentifier($item), + $bundleProductQty ?: $item->getQty(), + $this->calculateProductPrice($item), + $this->getItemTax($item) + ); + + $articles[] = $article; + + if ($item->getDiscountAmount() > 0) { + $count++; + $article = $this->getArticleArrayLine( + 'Korting op ' . $item->getName(), + $item->getSku(), + 1, + number_format(($item->getDiscountAmount() * -1), 2), + $item->getTaxPercent() ?: 0 + ); + $articles[] = $article; + } + + if ($count >= self::MAX_ARTICLE_COUNT) { + break; + } + + $count++; + } + + return $articles; + } +} diff --git a/Gateway/Request/Articles/ArticlesHandler/CapayableIn3Handler.php b/Gateway/Request/Articles/ArticlesHandler/CapayableIn3Handler.php new file mode 100644 index 000000000..02c359219 --- /dev/null +++ b/Gateway/Request/Articles/ArticlesHandler/CapayableIn3Handler.php @@ -0,0 +1,44 @@ + $articleId, + 'description' => $articleDescription, + 'quantity' => $articleQuantity, + 'price' => floor($articleUnitPrice * 100) / 100, + 'vatPercentage' => $articleVat + ]; + } +} diff --git a/Gateway/Request/Articles/ArticlesHandler/DefaultHandler.php b/Gateway/Request/Articles/ArticlesHandler/DefaultHandler.php new file mode 100644 index 000000000..3de2c268c --- /dev/null +++ b/Gateway/Request/Articles/ArticlesHandler/DefaultHandler.php @@ -0,0 +1,26 @@ + [$this->getRewardLine()]]; + } + + /** + * Get the reward cost lines + * + * @return array + */ + public function getRewardLine() + { + $article = []; + $discount = (float)$this->getQuote()->getRewardCurrencyAmount(); + + if ($discount <= 0) { + return $article; + } + + return $this->getArticleArrayLine( + 'Discount Reward Points', + 5, + 1, + -$discount, + 0 + ); + } +} diff --git a/Gateway/Request/Articles/CreditmemoArticlesDataBuilder.php b/Gateway/Request/Articles/CreditmemoArticlesDataBuilder.php new file mode 100644 index 000000000..1048424f7 --- /dev/null +++ b/Gateway/Request/Articles/CreditmemoArticlesDataBuilder.php @@ -0,0 +1,49 @@ +articlesHandlerFactory = $articlesHandlerFactory; + } + + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + + /** @var ArticleHandlerInterface $articleHandler */ + $articleHandler = $this->articlesHandlerFactory->create($this->getPayment()->getMethod()); + + return $articleHandler->getCreditMemoArticlesData($this->getOrder(), $this->getPayment()); + } +} diff --git a/Gateway/Request/Articles/InvoicedArticlesDataBuilder.php b/Gateway/Request/Articles/InvoicedArticlesDataBuilder.php new file mode 100644 index 000000000..7de5cd985 --- /dev/null +++ b/Gateway/Request/Articles/InvoicedArticlesDataBuilder.php @@ -0,0 +1,47 @@ +articlesHandlerFactory = $articlesHandlerFactory; + } + + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + + $articleHandler = $this->articlesHandlerFactory->create($this->getPayment()->getMethod()); + + return $articleHandler->getInvoiceArticlesData($this->getOrder(), $this->getPayment()); + } +} diff --git a/Gateway/Request/BasicParameter/AdditionalParametersDataBuilder.php b/Gateway/Request/BasicParameter/AdditionalParametersDataBuilder.php new file mode 100644 index 000000000..c5d6f6a86 --- /dev/null +++ b/Gateway/Request/BasicParameter/AdditionalParametersDataBuilder.php @@ -0,0 +1,129 @@ +action = $action; + $this->additionalParameters = $additionalParameters; + } + + /** + * Set service action + * + * @param array $buildSubject + * @return array[] + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function build(array $buildSubject): array + { + return [ + 'additionalParameters' => $this->getAdditionalParameters($buildSubject) + ]; + } + + /** + * Get additional parameters + * + * @param array $buildSubject + * @return array + */ + private function getAdditionalParameters(array $buildSubject): array + { + $parameterLine = []; + + $action = $buildSubject['action'] ?? $this->getAction() ?? ''; + $parameterLine['service_action_from_magento'] = strtolower($action); + + $parameterLine['initiated_by_magento'] = 1; + + if ($additionalParameters = $this->getAllAdditionalParameters()) { + foreach ($additionalParameters as $key => $value) { + $parameterLine[$key] = $value; + } + } + + return $parameterLine; + } + + /** + * Get service action + * + * @return string + */ + public function getAction(): string + { + return $this->action; + } + + /** + * Set service action + * + * @param string $action + * @return $this + */ + public function setAction(string $action): AdditionalParametersDataBuilder + { + $this->action = $action; + + return $this; + } + + /** + * Get all additional parameters + * + * @return array + */ + public function getAllAdditionalParameters(): array + { + return $this->additionalParameters; + } + + /** + * Set additional parameter with key + * + * @param string $key + * @param string $value + * @return $this + */ + public function setAdditionalParameter(string $key, string $value): AdditionalParametersDataBuilder + { + $this->additionalParameters[$key] = $value; + + return $this; + } + + /** + * Get additional parameter by key + * + * @param string $key + * @return string|null + */ + public function getAdditionalParameter(string $key): ?string + { + return $this->additionalParameters[$key] ?? null; + } +} diff --git a/Gateway/Request/BasicParameter/AmountCreditDataBuilder.php b/Gateway/Request/BasicParameter/AmountCreditDataBuilder.php new file mode 100644 index 000000000..e7bbb91ab --- /dev/null +++ b/Gateway/Request/BasicParameter/AmountCreditDataBuilder.php @@ -0,0 +1,123 @@ +dataBuilderService = $dataBuilderService; + $this->refundGroupService = $refundGroupService; + } + + /** + * @inheritdoc + * @throws \InvalidArgumentException + * @throws ClientException + * @throws ConverterException + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $order = $paymentDO->getOrder()->getOrder(); + + $baseAmountToRefund = $buildSubject['amount'] ?? $order->getBaseGrandTotal(); + $this->refundAmount = (float)$baseAmountToRefund; + + if ($this->refundAmount <= 0) { + throw new \InvalidArgumentException('Credit Amount less than or equal to 0'); + } + + $this->refundGroupService->refundGroupTransactions($buildSubject); + $this->refundAmount = $this->refundGroupService->getAmountLeftToRefund(); + + $this->setRefundAmount($order); + + return [ + self::AMOUNT_CREDIT => $this->getRefundAmount() + ]; + } + + /** + * Get Refund Amount + * + * @return float + */ + public function getRefundAmount() + { + return $this->refundAmount; + } + + /** + * Set Refund Amount Based on Currency + * + * @param Order $order + */ + protected function setRefundAmount($order) + { + /** + * @todo find a way to fix the cumulative rounding issue that occurs in creditmemos. + * This problem occurs when the creditmemo is being refunded in the order's currency, rather than the + * store's base currency. + */ + if ($this->dataBuilderService->getElement('currency') == $order->getOrderCurrencyCode()) { + $this->refundAmount = round($this->refundAmount * $order->getBaseToOrderRate(), 2); + } + } +} diff --git a/Gateway/Request/BasicParameter/AmountDebitDataBuilder.php b/Gateway/Request/BasicParameter/AmountDebitDataBuilder.php new file mode 100644 index 000000000..3f29931ea --- /dev/null +++ b/Gateway/Request/BasicParameter/AmountDebitDataBuilder.php @@ -0,0 +1,88 @@ +dataBuilderService = $dataBuilderService; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $order = $paymentDO->getOrder()->getOrder(); + + if ($this->getAmount($order)) { + return [ + self::AMOUNT_DEBIT => $this->getAmount($order) + ]; + } else { + throw new BuckarooException(__('Total of the order can not be empty.')); + } + } + + /** + * Get Amount + * + * @param Order|null $order + * @return float|null + */ + public function getAmount(Order $order = null): ?float + { + if (empty($this->amount)) { + $this->setAmount($order); + } + + return $this->amount; + } + + /** + * Set Amount + * + * @param Order $order + * @return $this + */ + public function setAmount(Order $order): AmountDebitDataBuilder + { + if ($this->dataBuilderService->getElement('currency') == $order->getOrderCurrencyCode()) { + $this->amount = $order->getGrandTotal(); + } else { + $this->amount = $order->getBaseGrandTotal(); + } + + return $this; + } +} diff --git a/Gateway/Request/BasicParameter/ClientIPDataBuilder.php b/Gateway/Request/BasicParameter/ClientIPDataBuilder.php new file mode 100644 index 000000000..6587c22c6 --- /dev/null +++ b/Gateway/Request/BasicParameter/ClientIPDataBuilder.php @@ -0,0 +1,157 @@ +configProviderAccount = $configProviderAccount; + $this->httpRequest = $httpRequest; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $order = $paymentDO->getOrder()->getOrder(); + + $ip = $this->getIp($order); + + return [ + 'clientIP' => [ + 'address' => $ip, + 'type' => !str_contains($ip, ':') ? IPProtocolVersion::IPV4 : IPProtocolVersion::IPV6 + ] + ]; + } + + /** + * Get client ip + * + * @param Order $order + * @return false|float|string|null + */ + public function getIp(Order $order) + { + $ip = $order->getRemoteIp(); + $store = $order->getStore(); + + $ipHeaders = $this->configProviderAccount->getIpHeader($store); + + $headers = []; + if ($ipHeaders) { + $ipHeaders = explode(',', strtoupper($ipHeaders)); + foreach ($ipHeaders as $ipHeader) { + $headers[] = 'HTTP_' . str_replace('-', '_', (string)$ipHeader); + } + + $remoteAddress = new RemoteAddress( + $this->httpRequest, + $headers + ); + + return $remoteAddress->getRemoteAddress(); + } + + // trustly anyway should be w/o private ip + if (($order->getPayment()->getMethod() == 'trustly') + && $this->isIpPrivate($ip) + && $order->getXForwardedFor() + ) { + $ip = $order->getXForwardedFor(); + } + + if (!$ip) { + $remoteAddress = new RemoteAddress( + $this->httpRequest, + $headers + ); + + $ip = $remoteAddress->getRemoteAddress(); + } + + return $ip; + } + + /** + * Check if it is private IP + * + * @param string $ip + * @return bool + */ + private function isIpPrivate(string $ip): bool + { + if (!$ip) { + return false; + } + + $priAddrs = [ + '10.0.0.0|10.255.255.255', // single class A network + '172.16.0.0|172.31.255.255', // 16 contiguous class B network + '192.168.0.0|192.168.255.255', // 256 contiguous class C network + '169.254.0.0|169.254.255.255', // Link-local address also referred to as Automatic Private IP Addressing + '127.0.0.0|127.255.255.255' // localhost + ]; + + $longIp = ip2long($ip); + if ($longIp != -1) { + foreach ($priAddrs as $priAddr) { + list($start, $end) = explode('|', $priAddr); + + if ($longIp >= ip2long($start) && $longIp <= ip2long($end)) { + return true; + } + } + } + + return false; + } +} diff --git a/Gateway/Request/BasicParameter/CurrencyDataBuilder.php b/Gateway/Request/BasicParameter/CurrencyDataBuilder.php new file mode 100644 index 000000000..1d37d6a92 --- /dev/null +++ b/Gateway/Request/BasicParameter/CurrencyDataBuilder.php @@ -0,0 +1,153 @@ +configProviderMethodFactory = $configProviderMethodFactory; + } + + /** + * @inheritdoc + * + * @throws Exception|LocalizedException + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $order = $paymentDO->getOrder()->getOrder(); + $this->setAllowedCurrencies($paymentDO->getPayment()->getMethodInstance()); + + return [ + self::KEY_CURRENCY => $this->getCurrency($order) + ]; + } + + /** + * Set Allowed Currencies + * + * @param MethodInterface $methodInstance + * @return $this + * @throws Exception + */ + private function setAllowedCurrencies(MethodInterface $methodInstance): CurrencyDataBuilder + { + $method = $methodInstance->getCode(); + if (!$method) { + throw new Exception( + __("The payment method code it is not set.") + ); + } + $configProvider = $this->configProviderMethodFactory->get($method); + $this->allowedCurrencies = $configProvider->getAllowedCurrencies(); + + return $this; + } + + /** + * Get Allowed Currencies + * + * @param MethodInterface|null $methodInstance + * @return array + * @throws Exception + */ + public function getAllowedCurrencies(MethodInterface $methodInstance = null): array + { + if (empty($this->allowedCurrencies) && $methodInstance !== null) { + $this->setAllowedCurrencies($methodInstance); + } + + return $this->allowedCurrencies; + } + + /** + * Get Currency + * + * @param Order|null $order + * @return string + * @throws Exception + */ + public function getCurrency(Order $order = null): string + { + if (empty($this->currency)) { + $this->setCurrency($order); + } + + return $this->currency; + } + + /** + * Set Currency + * + * @param Order $order + * @return $this + * @throws Exception + */ + public function setCurrency(Order $order): CurrencyDataBuilder + { + $allowedCurrencies = $this->getAllowedCurrencies(); + if (in_array($order->getOrderCurrencyCode(), $allowedCurrencies)) { + $this->currency = $order->getOrderCurrencyCode(); + } elseif (in_array($order->getBaseCurrencyCode(), $allowedCurrencies)) { + $this->currency = $order->getBaseCurrencyCode(); + } else { + throw new Exception( + __("The selected payment method does not support the selected currency or the store's base currency.") + ); + } + + return $this; + } +} diff --git a/Gateway/Request/BasicParameter/CustomParametersDataBuilder.php b/Gateway/Request/BasicParameter/CustomParametersDataBuilder.php new file mode 100644 index 000000000..1db1e9268 --- /dev/null +++ b/Gateway/Request/BasicParameter/CustomParametersDataBuilder.php @@ -0,0 +1,303 @@ +configProviderAccount = $configProviderAccount; + $this->countryFactory = $countryFactory; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + + /** @var Order $order */ + $order = $paymentDO->getOrder()->getOrder(); + + $store = $order->getStore(); + + $customParametersKey = $this->configProviderAccount->getCustomerAdditionalInfo($store); + + if (!empty($customParametersKey)) { + $billingData = $order->getBillingAddress(); + $shippingData = $order->getShippingAddress(); + $customParameters = $this->getCustomInfo( + $customParametersKey, + $billingData, + $shippingData + ); + return [ + 'customParameters' => $customParameters + ]; + } + + return []; + } + + /** + * Get custom parameters from billing and shipping address + * + * @param string $customParametersKey + * @param OrderAddressInterface|null $billingData + * @param OrderAddressInterface|null $shippingData + * @return array + */ + private function getCustomInfo( + string $customParametersKey, + ?OrderAddressInterface $billingData, + ?OrderAddressInterface $shippingData + ): array { + $customParameters = $this->getCustomNeededFieldsList($customParametersKey); + + $customerBillingArray = $this->formatCustomData($customParameters, 'billing'); + $customerShippingArray = $this->formatCustomData($customParameters, 'shipping'); + + $customerBillingArray = $this->getCustomerDataFromAddress($customerBillingArray, $billingData, 'Billing'); + + if ($shippingData === null) { + $shippingData = $billingData; + } + + $customerShippingArray = $this->getCustomerDataFromAddress($customerShippingArray, $shippingData, 'Shipping'); + + return array_merge($customerBillingArray, $customerShippingArray); + } + + /** + * @param $customerParameters + * @param $addressData + * @param $type + * @return array + */ + private function getCustomerDataFromAddress($customerParameters, $addressData, $type): array + { + foreach ($customerParameters as $key => $value) { + if ($value != 'housenumber' && $value != 'houseadditionalnumber') { + $customerParameters[$key] = ''; + } + if (!empty($addressData->getData($value))) { + $customerParameters[$key] = $addressData->getData($value); + } + if ($value == 'country') { + $customerParameters[$key] = $this->getCountryName($addressData); + } + } + $customerParameters = $this->setStreetData( + 'Customer' . $type . 'Street', + $customerParameters + ); + return $this->getNotEmptyCustomData($customerParameters); + } + + /** + * Get Custom Needed Fields + * + * @param string $customParameters + * @return array + */ + private function getCustomNeededFieldsList(string $customParameters): array + { + $customParametersArray = explode(',', $customParameters); + $customBillingData = []; + $customShippingData = []; + foreach ($customParametersArray as $customParameter) { + if (strpos($customParameter, 'billing') !== false) { + $customBillingData[] = $customParameter; + } else { + $customShippingData[] = $customParameter; + } + } + $customParametersArray = null; + $customParametersArray['billing'] = $customBillingData; + $customParametersArray['shipping'] = $customShippingData; + + return $customParametersArray; + } + + /** + * Format custom parameters + * + * @param $customParameters + * @param $address + * @return array + */ + private function formatCustomData($customParameters, $address): array + { + $customDataList = []; + + foreach ($customParameters[$address] as $customParameter) { + $customParameterLabel = $this->getCustomParameterLabel($customParameter); + $customValue = $this->getCustomParameterValue($customParameter); + + $customDataList[$customParameterLabel] = $customValue; + } + + return $customDataList; + } + + /** + * Format Parameter Label + * + * @param $parameterKey + * @return array|string|string[] + */ + public function getCustomParameterLabel($parameterKey) + { + return str_replace(' ', '', ucwords(str_replace('_', ' ', $parameterKey))); + } + + /** + * Format Parameter Value + * + * @param $parameterKey + * @return array|string|string[]|null + */ + public function getCustomParameterValue($parameterKey) + { + return str_replace('_', '', preg_replace('/^customer_(billing|shipping)_/', '', $parameterKey)); + } + + /** + * Get country name from country id + * + * @param $data + * @return string + */ + private function getCountryName($data): string + { + $countryName = ''; + $country = $this->countryFactory->create()->loadByCode($data->getData('country_id')); + if ($country) { + $countryName = $country->getName(); + } + return $countryName; + } + + /** + * Set Street Data + * + * @param string $addressData + * @param array $customerData + * @return array + */ + private function setStreetData(string $addressData, array $customerData) + { + if (!empty($customerData[$addressData])) { + $street = preg_replace('[\s]', ' ', $customerData[$addressData]); + $streetFormat = $this->formatStreet($street); + $customerData[$addressData] = 'street'; + + foreach ($customerData as $customerDataKey => $value) { + if (in_array($value, ['street', 'housenumber', 'houseadditionalnumber'])) { + $customerData[$customerDataKey] = $streetFormat[$value] ?? ''; + } + } + } + + foreach ($customerData as $customerDataKey => $value) { + if ($value == 'housenumber' || $value == 'houseadditionalnumber') { + $customerData[$customerDataKey] = ''; + } + } + + return $customerData; + } + + /** + * Format street address + * + * @param $street + * @return array + */ + private function formatStreet($street): array + { + $format = [ + 'housenumber' => '', + 'houseadditionalnumber' => '', + 'street' => $street + ]; + + if (preg_match('#^(.*?)([0-9\-]+)(.*)#s', $street, $matches)) { + // Check if the number is at the beginning of streetname + if ('' == $matches[1]) { + $format['housenumber'] = trim($matches[2]); + $format['street'] = trim($matches[3]); + } else { + if (preg_match('#^(.*?)(\d+)(.*)#s', $street, $matches)) { + $format['street'] = trim($matches[1]); + $format['housenumber'] = trim($matches[2]); + $format['houseadditionalnumber'] = trim($matches[3]); + } + } + } + + return $format; + } + + /** + * Remove empty customer data + * + * @param array $customData + * @return array + */ + private function getNotEmptyCustomData(array $customData): array + { + foreach ($customData as $key => $value) { + if (empty($value)) { + unset($customData[$key]); + } + } + + return $customData; + } +} diff --git a/Gateway/Request/BasicParameter/DescriptionDataBuilder.php b/Gateway/Request/BasicParameter/DescriptionDataBuilder.php new file mode 100644 index 000000000..be58a8cc1 --- /dev/null +++ b/Gateway/Request/BasicParameter/DescriptionDataBuilder.php @@ -0,0 +1,60 @@ +configProviderAccount = $configProviderAccount; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $order = $paymentDO->getOrder()->getOrder(); + + $store = $order->getStore(); + + return [ + 'description' => $this->configProviderAccount->getParsedLabel($store, $order) + ]; + } +} diff --git a/Gateway/Request/BasicParameter/InvoiceDataBuilder.php b/Gateway/Request/BasicParameter/InvoiceDataBuilder.php new file mode 100644 index 000000000..b93727a69 --- /dev/null +++ b/Gateway/Request/BasicParameter/InvoiceDataBuilder.php @@ -0,0 +1,114 @@ +setOrder($paymentDO->getOrder()->getOrder()); + + return [ + 'invoice' => $this->getInvoiceId(), + 'order' => $this->getOrder()->getIncrementId() + ]; + } + + /** + * Get order + * + * @return Order + */ + public function getOrder(): Order + { + return $this->order; + } + + /** + * Set order + * + * @param Order $order + * @return $this + */ + public function setOrder(Order $order): InvoiceDataBuilder + { + $this->order = $order; + + return $this; + } + + /** + * Get invoice id + * + * @return string + */ + public function getInvoiceId(): string + { + $order = $this->getOrder(); + + if (empty($this->invoiceId) + || (!$this->isCustomInvoiceId && ($this->invoiceId != $order->getIncrementId())) + ) { + $this->setInvoiceId($order->getIncrementId(), false); + } + + return $this->invoiceId; + } + + /** + * Set invoice id + * + * @param string $invoiceId + * @param bool $isCustomInvoiceId + * @return $this + */ + public function setInvoiceId(string $invoiceId, bool $isCustomInvoiceId = true): InvoiceDataBuilder + { + $this->invoiceId = $invoiceId; + $this->isCustomInvoiceId = $isCustomInvoiceId; + + return $this; + } +} diff --git a/Gateway/Request/BasicParameter/OrderNumberDataBuilder.php b/Gateway/Request/BasicParameter/OrderNumberDataBuilder.php new file mode 100644 index 000000000..8189f4a31 --- /dev/null +++ b/Gateway/Request/BasicParameter/OrderNumberDataBuilder.php @@ -0,0 +1,38 @@ + $paymentDO->getOrder()->getOrder()->getIncrementId()]; + } +} diff --git a/Gateway/Request/BasicParameter/PaymentMethodDataBuilder.php b/Gateway/Request/BasicParameter/PaymentMethodDataBuilder.php new file mode 100644 index 000000000..d6134cc0d --- /dev/null +++ b/Gateway/Request/BasicParameter/PaymentMethodDataBuilder.php @@ -0,0 +1,44 @@ +getPayment()->getMethodInstance()->getCode() ?? 'buckaroo_magento2_ideal'; + $providerType = str_replace('buckaroo_magento2_', '', $method); + + return [ + 'payment_method' => $providerType, + ]; + } +} diff --git a/Gateway/Request/BasicParameter/PushUrlDataBuilder.php b/Gateway/Request/BasicParameter/PushUrlDataBuilder.php new file mode 100644 index 000000000..5a13c8d5f --- /dev/null +++ b/Gateway/Request/BasicParameter/PushUrlDataBuilder.php @@ -0,0 +1,57 @@ +urlBuilder = $urlBuilder; + } + + /** + * @inheritdoc + * + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + public function build(array $buildSubject): array + { + return [ + 'pushURL' => $this->urlBuilder->getDirectUrl('rest/V1/buckaroo/push'), + 'pushURLFailure' => $this->urlBuilder->getDirectUrl('rest/V1/buckaroo/push') + ]; + } +} diff --git a/Gateway/Request/BasicParameter/RefundDescriptionDataBuilder.php b/Gateway/Request/BasicParameter/RefundDescriptionDataBuilder.php new file mode 100644 index 000000000..1543fed1e --- /dev/null +++ b/Gateway/Request/BasicParameter/RefundDescriptionDataBuilder.php @@ -0,0 +1,60 @@ +configProviderAccount = $configProviderAccount; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $order = $paymentDO->getOrder()->getOrder(); + + $store = $order->getStore(); + + return [ + 'description' => $this->configProviderAccount->getParsedRefundLabel($store, $order) + ]; + } +} diff --git a/Gateway/Request/BasicParameter/ReturnUrlDataBuilder.php b/Gateway/Request/BasicParameter/ReturnUrlDataBuilder.php new file mode 100644 index 000000000..248f42bd0 --- /dev/null +++ b/Gateway/Request/BasicParameter/ReturnUrlDataBuilder.php @@ -0,0 +1,151 @@ +urlBuilder = $urlBuilder; + $this->formKey = $formKey; + } + + /** + * @inheritdoc + * @throws LocalizedException + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $order = $paymentDO->getOrder()->getOrder(); + $returnUrl = $this->getReturnUrl($order); + + return [ + 'returnURL' => $returnUrl, + 'returnURLError' => $returnUrl, + 'returnURLCancel' => $returnUrl, + 'returnURLReject' => $returnUrl, + 'pushURL' => $this->urlBuilder->getDirectUrl('rest/V1/buckaroo/push'), + 'pushURLFailure' => $this->urlBuilder->getDirectUrl('rest/V1/buckaroo/push') + ]; + } + + /** + * Get return url for payment engine + * + * @param Order $order + * @return string|null + * @throws LocalizedException + */ + public function getReturnUrl(Order $order): ?string + { + $returnUrl = $this->getReturnUrlFromPayment($order); + if($returnUrl !== null) { + $this->setReturnUrl($returnUrl); + return $this->returnUrl; + } + + if ($this->returnUrl === null) { + $url = $this->urlBuilder->setScope($order->getStoreId()); + $url = $url->getDirectUrl('buckaroo/redirect/process') . '?form_key=' . $this->getFormKey(); + + $this->setReturnUrl($url); + } + + return $this->returnUrl; + } + + /** + * Set return url + * + * @param string $url + * @return $this + */ + public function setReturnUrl(string $url): ReturnUrlDataBuilder + { + $this->returnUrl = $url; + + return $this; + } + + /** + * Get magento form key + * + * @return string + * @throws LocalizedException + */ + public function getFormKey(): string + { + return $this->formKey->getFormKey(); + } + + public function getReturnUrlFromPayment(Order $order): ?string + { + if ( + $order->getPayment() === null || + $order->getPayment()->getAdditionalInformation(self::ADDITIONAL_RETURN_URL) === null + ) { + return null; + } + $returnUrl = (string)$order->getPayment()->getAdditionalInformation(self::ADDITIONAL_RETURN_URL); + if ( + !filter_var($returnUrl, FILTER_VALIDATE_URL) === false && + in_array(parse_url($returnUrl, PHP_URL_SCHEME), ['http', 'https']) + ) { + return $returnUrl; + } + + return null; + } +} diff --git a/Gateway/Request/BasicParameter/SaveOrderBeforeDataBuilder.php b/Gateway/Request/BasicParameter/SaveOrderBeforeDataBuilder.php new file mode 100644 index 000000000..f468cc783 --- /dev/null +++ b/Gateway/Request/BasicParameter/SaveOrderBeforeDataBuilder.php @@ -0,0 +1,71 @@ +configProviderAccount = $configProviderAccount; + } + + /** + * Save Order Before Request + * + * @param array $buildSubject + * @return array + * @throws \Exception + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + /** @var Order $order */ + $order = $paymentDO->getOrder()->getOrder(); + $store = $order->getStoreId(); + + if ($this->configProviderAccount->getCreateOrderBeforeTransaction($store)) { + $newStatus = $this->configProviderAccount->getOrderStatusNew($store); + if (!$newStatus) { + $newStatus = $order->getConfig()->getStateDefaultStatus('new'); + } + + $order->setState(Order::STATE_NEW); + $order->setStatus($newStatus); + $order->save(); + } + + return []; + } +} diff --git a/Gateway/Request/BillingAddress/CountryDataBuilder.php b/Gateway/Request/BillingAddress/CountryDataBuilder.php new file mode 100644 index 000000000..2be83eaed --- /dev/null +++ b/Gateway/Request/BillingAddress/CountryDataBuilder.php @@ -0,0 +1,45 @@ +getOrder()->getBillingAddress(); + + return [ + 'country' => $billingAddress->getCountryId(), + ]; + } +} diff --git a/Gateway/Request/BillingAddress/CustomerDataBuilder.php b/Gateway/Request/BillingAddress/CustomerDataBuilder.php new file mode 100644 index 000000000..10f90cd51 --- /dev/null +++ b/Gateway/Request/BillingAddress/CustomerDataBuilder.php @@ -0,0 +1,76 @@ +getOrder()->getBillingAddress(); + + return [ + 'customer' => [ + 'firstName' => $billingAddress->getFirstname(), + 'lastName' => $billingAddress->getLastname(), + 'initials' => strtoupper(substr($billingAddress->getFirstname(), 0, 1)), + 'birthDate' => $this->getBirthDate() + ] + ]; + } + + /** + * Get customer birthdate + * + * @return false|string + */ + protected function getBirthDate() + { + $customerDoB = (string)$this->payment->getAdditionalInformation('customer_DoB'); + if (empty($customerDoB)) { + $customerDoB = $this->getOrder()->getCustomerDob() ?? '1990-01-01'; + } + + return date( + $this->getFormatDate(), + strtotime(str_replace('/', '-', $customerDoB)) + ); + } + + /** + * Format date + * + * @return string + */ + protected function getFormatDate(): string + { + return 'd-m-Y'; + } +} diff --git a/Gateway/Request/BillingAddress/CustomerNameDataBuilder.php b/Gateway/Request/BillingAddress/CustomerNameDataBuilder.php new file mode 100644 index 000000000..a007ea5e1 --- /dev/null +++ b/Gateway/Request/BillingAddress/CustomerNameDataBuilder.php @@ -0,0 +1,48 @@ +getOrder()->getBillingAddress(); + + return [ + 'customer' => [ + 'firstName' => $billingAddress->getFirstname(), + 'lastName' => $billingAddress->getLastname(), + ] + ]; + } +} diff --git a/Gateway/Request/BillingAddress/EmailDataBuilder.php b/Gateway/Request/BillingAddress/EmailDataBuilder.php new file mode 100644 index 000000000..5a8d55473 --- /dev/null +++ b/Gateway/Request/BillingAddress/EmailDataBuilder.php @@ -0,0 +1,42 @@ +getOrder()->getBillingAddress(); + return ['email' => $billingAddress->getEmail()]; + } +} diff --git a/Gateway/Request/BillingAddress/LocaleDataBuilder.php b/Gateway/Request/BillingAddress/LocaleDataBuilder.php new file mode 100644 index 000000000..d077733ec --- /dev/null +++ b/Gateway/Request/BillingAddress/LocaleDataBuilder.php @@ -0,0 +1,60 @@ +getOrder()->getOrder(); + + return ['locale' => $this->getLocaleCode($order)]; + } + + /** + * Get Locale Code By Country ID from Billing Address + * + * @param Order $order + * @return string + */ + private function getLocaleCode(Order $order): string + { + $country = $order->getBillingAddress()->getCountryId(); + + if ($country == 'CN') { + $localeCode = 'zh-CN'; + } elseif ($country == 'TW') { + $localeCode = 'zh-TW'; + } else { + $localeCode = 'en-US'; + } + return $localeCode; + } +} diff --git a/Gateway/Request/BillingAddress/NameDataBuilder.php b/Gateway/Request/BillingAddress/NameDataBuilder.php new file mode 100644 index 000000000..461472b3e --- /dev/null +++ b/Gateway/Request/BillingAddress/NameDataBuilder.php @@ -0,0 +1,45 @@ +getOrder()->getOrder(); + + /** + * @var OrderAddressInterface $billingAddress + */ + $billingAddress = $order->getBillingAddress(); + + return ['customer' => ['name' => $billingAddress->getFirstname() . ' ' . $billingAddress->getLastName()]]; + } +} diff --git a/Gateway/Request/BuckarooBuilderComposite.php b/Gateway/Request/BuckarooBuilderComposite.php new file mode 100644 index 000000000..8e0cecf6a --- /dev/null +++ b/Gateway/Request/BuckarooBuilderComposite.php @@ -0,0 +1,152 @@ +tmapFactory = $tmapFactory; + $this->buildersArray = $builders; + $this->usingId = $usingId; + $this->dataBuilderService = $dataBuilderService; + } + + /** + * Builds ENV request + * + * @param array $buildSubject + * @return array + */ + public function build(array $buildSubject): array + { + $this->dataBuilderService = new DataBuilderService(); + + $result = []; + if ($this->usingId) { + foreach ($this->getBuilders() as $key => $builder) { + $result = $this->addData($result, [$key => $builder->build($buildSubject)]); + } + } else { + foreach ($this->getBuilders() as $builder) { + $result = $this->addData($result, $builder->build($buildSubject)); + } + } + + return $result; + } + + /** + * Merge function for builders + * + * @param array $result + * @param array $builder + * @return array + */ + protected function merge(array $result, array $builder): array + { + return array_replace_recursive($result, $builder); + } + + /** + * Return builders + * + * @return BuilderInterface[] + */ + private function getBuilders() + { + if ($this->builders === null) { + $this->builders = $this->tmapFactory->create( + [ + 'array' => $this->buildersArray, + 'type' => BuilderInterface::class + ] + ); + } + + return $this->builders; + } + + /** + * Add Data to the Request + * + * @param array $result + * @param array $data + * @return array + */ + public function addData(array $result, array $data): array + { + $result = $this->merge($result, $data); + $this->dataBuilderService->addData($data); + return $result; + } + + /** + * Get Data to the Request + * + * @return array + */ + public function getData(): array + { + return $this->dataBuilderService->getData(); + } +} diff --git a/Gateway/Request/Capayable/ArticlesDataBuilder.php b/Gateway/Request/Capayable/ArticlesDataBuilder.php new file mode 100644 index 000000000..a4777de78 --- /dev/null +++ b/Gateway/Request/Capayable/ArticlesDataBuilder.php @@ -0,0 +1,56 @@ +getOrder()->getAllItems() as $item) { + + /** @var OrderItemInterface $item */ + if ($item->getParentItem() != null) { + continue; + } + + $articles[] = [ + 'identifier' => $item->getSku(), + 'description' => $item->getName(), + 'quantity' => $item->getQtyOrdered(), + 'price' => $item->getBasePriceInclTax() + ]; + } + return [ + 'articles' => array_slice($articles, 0, 99) + ]; + } +} diff --git a/Gateway/Request/Capayable/CustomerDataBuilder.php b/Gateway/Request/Capayable/CustomerDataBuilder.php new file mode 100644 index 000000000..b46ded0b6 --- /dev/null +++ b/Gateway/Request/Capayable/CustomerDataBuilder.php @@ -0,0 +1,82 @@ +getOrder()->getBillingAddress(); + return [ + 'customer' => [ + 'initials' => $this->getInitials($billingAddress->getFirstname()), + 'lastName' => $billingAddress->getLastname(), + 'email' => $billingAddress->getEmail(), + 'phone' => $billingAddress->getTelephone(), + 'culture' => 'nl-NL', + 'birthDate' => $this->getCustomerBirthDate() + ] + ]; + } + + /** + * Get initial from first name + * + * @param string $name + * @return string + */ + protected function getInitials(string $name): string + { + $initials = ''; + $nameParts = explode(' ', $name); + + if (!$nameParts) { + return $initials; + } + + foreach ($nameParts as $part) { + $initials .= strtoupper(substr($part, 0, 1)) . '.'; + } + + return $initials; + } + + /** + * Get customer birthdate + * + * @return string + */ + protected function getCustomerBirthDate() + { + return str_replace('/', '-', (string)$this->getPayment()->getAdditionalInformation('customer_DoB')); + } +} diff --git a/Gateway/Request/Capayable/CustomerTypeDataBuilder.php b/Gateway/Request/Capayable/CustomerTypeDataBuilder.php new file mode 100644 index 000000000..5d22343a7 --- /dev/null +++ b/Gateway/Request/Capayable/CustomerTypeDataBuilder.php @@ -0,0 +1,39 @@ + 'Debtor' + ]; + } +} diff --git a/Gateway/Request/Capayable/In3V3DataBuilder.php b/Gateway/Request/Capayable/In3V3DataBuilder.php new file mode 100644 index 000000000..7244e56b3 --- /dev/null +++ b/Gateway/Request/Capayable/In3V3DataBuilder.php @@ -0,0 +1,63 @@ +capayableIn3Config = $capayableIn3Config; + } + /** + * @inheritdoc + * + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $payment = $paymentDO->getPayment(); + + $data = []; + + if (!$this->capayableIn3Config->isV2()) { + $payment->setAdditionalInformation("buckaroo_in3_v3", true); + $data['payment_method'] = 'in3'; + } + + return $data; + } +} diff --git a/Gateway/Request/Capayable/InvoiceDateDataBuilder.php b/Gateway/Request/Capayable/InvoiceDateDataBuilder.php new file mode 100644 index 000000000..d96b7909a --- /dev/null +++ b/Gateway/Request/Capayable/InvoiceDateDataBuilder.php @@ -0,0 +1,39 @@ + (new \DateTime())->format('Y-m-d') + ]; + } +} diff --git a/Gateway/Request/Capayable/PhoneDataBuilder.php b/Gateway/Request/Capayable/PhoneDataBuilder.php new file mode 100644 index 000000000..579a6b348 --- /dev/null +++ b/Gateway/Request/Capayable/PhoneDataBuilder.php @@ -0,0 +1,73 @@ +phoneFormatter = $phoneFormatter; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + + return [ + 'phone' => [ + 'mobile' => $this->getCleanPhone( + $this->getOrder()->getBillingAddress() + ) + ] + ]; + } + + /** + * Format phone number + * + * @param OrderAddressInterface $billingAddress + * @return mixed + */ + protected function getCleanPhone(OrderAddressInterface $billingAddress) + { + $phoneData = $this->phoneFormatter->format( + $billingAddress->getTelephone(), + $billingAddress->getCountryId() + ); + return $phoneData['clean']; + } +} diff --git a/Gateway/Request/Capayable/SubTotalsDataBuilder.php b/Gateway/Request/Capayable/SubTotalsDataBuilder.php new file mode 100644 index 000000000..abbaa434e --- /dev/null +++ b/Gateway/Request/Capayable/SubTotalsDataBuilder.php @@ -0,0 +1,102 @@ +getDiscount(); + if ($discount < 0) { + $subTotals[] = [ + 'name' => 'Discount', + 'value' => $discount + ]; + } + + $fee = $this->getFee(); + if ($fee > 0) { + $subTotals[] = [ + 'name' => 'Payment Fee', + 'value' => $fee + ]; + } + + $shipping = $this->getShipping(); + if ($shipping > 0) { + $subTotals[] = [ + 'name' => 'Shipping Costs', + 'value' => $shipping + ]; + } + + return [ + 'subtotals' => $subTotals + ]; + } + + + /** + * Get discount + * + * @return float + */ + protected function getDiscount() + { + $discount = abs((float)$this->getOrder()->getDiscountAmount()); + return -1 * round($discount, 2); + } + + + /** + * Get buckaroo fee + * + * @return float + */ + protected function getFee(): float + { + return round( + (float)$this->getOrder()->getBuckarooFee() + + (float)$this->getOrder()->getBuckarooFeeTaxAmount(), + 2 + ); + } + + /** + * Get shipping amount + * + * @return float + */ + protected function getShipping(): float + { + return round((float)$this->getOrder()->getShippingInclTax(), 2); + } +} diff --git a/Gateway/Request/ContinueOnIncompleteDataBuilder.php b/Gateway/Request/ContinueOnIncompleteDataBuilder.php new file mode 100644 index 000000000..2452f5e48 --- /dev/null +++ b/Gateway/Request/ContinueOnIncompleteDataBuilder.php @@ -0,0 +1,56 @@ +continueOnIncompleteField = $continueOnIncompleteField; + } + + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + + $method = $paymentDO->getPayment()->getMethodInstance(); + if ($method->getConfigData($this->continueOnIncompleteField) === '0') { + return ['continueOnIncomplete' => '1']; + } + + return []; + } +} diff --git a/Gateway/Request/CreditManagement/AddressDataBuilder.php b/Gateway/Request/CreditManagement/AddressDataBuilder.php new file mode 100644 index 000000000..6ae017942 --- /dev/null +++ b/Gateway/Request/CreditManagement/AddressDataBuilder.php @@ -0,0 +1,113 @@ +getOrder()->getBillingAddress(); + if ($billingAddress === null) { + return []; + } + + $addressData = $this->getAddressData( + $billingAddress->getStreet() + ); + + return [ + 'street' => $addressData['street'], + 'houseNumber' => $addressData['house_number'], + 'houseNumberSuffix' => $addressData['number_addition'], + 'zipcode' => $billingAddress->getPostcode(), + 'city' => $billingAddress->getCity(), + 'country' => $billingAddress->getCountryId(), + ]; + } + + /** + * Get address data + * + * @param string[]|null $street + * @return array + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + private function getAddressData(?array $street) + { + if (is_array($street)) { + $street = implode(' ', $street); + } + + $addressRegexResult = preg_match( + '#\A(.*?)\s+(\d+[a-zA-Z]?\s?-\s?\d*[a-zA-Z]?|\d+[a-zA-Z-]?\d*[a-zA-Z]?)#', + $street, + $matches + ); + + if (!$addressRegexResult || !is_array($matches)) { + return [ + 'street' => $street, + 'house_number' => '', + 'number_addition' => '', + ]; + } + + $streetname = ''; + $housenumber = ''; + $housenumberExtension = ''; + if (isset($matches[1])) { + $streetname = $matches[1]; + } + + if (isset($matches[2])) { + $housenumber = $matches[2]; + } + + if (!empty($housenumber)) { + $housenumber = trim($housenumber); + $housenumberRegexResult = preg_match('#^([\d]+)(.*)#s', $housenumber, $matches); + if ($housenumberRegexResult && is_array($matches)) { + if (isset($matches[1])) { + $housenumber = $matches[1]; + } + + if (isset($matches[2])) { + $housenumberExtension = trim($matches[2]); + } + } + } + + return [ + 'street' => $streetname, + 'house_number' => $housenumber, + 'number_addition' => $housenumberExtension, + ]; + } +} diff --git a/Gateway/Request/CreditManagement/BuilderComposite.php b/Gateway/Request/CreditManagement/BuilderComposite.php new file mode 100644 index 000000000..10270b14a --- /dev/null +++ b/Gateway/Request/CreditManagement/BuilderComposite.php @@ -0,0 +1,134 @@ +builders = $tmapFactory->create( + [ + 'array' => $builders, + 'type' => BuilderInterface::class + ] + ); + $this->configProvider = $configProvider; + $this->type = $type; + } + + /** + * Builds ENV request + * + * @param array $buildSubject + * @return array + * @throws Exception + */ + public function build(array $buildSubject): array + { + $result = []; + + if ($this->isCreditManagementActive($buildSubject) + || $this->hasCreditManagementTransaction($buildSubject)) { + foreach ($this->builders as $builder) { + $result = $this->merge($result, [$this->type => $builder->build($buildSubject)]); + } + } + + return $result; + } + + /** + * Check if credit management is active + * + * @param array $buildSubject + * @return bool + * @throws Exception + */ + protected function isCreditManagementActive(array $buildSubject): bool + { + $payment = SubjectReader::readPayment($buildSubject)->getPayment(); + + return (bool)$this->configProvider->get($payment->getMethod())->getActiveStatusCm3(); + } + + /** + * Checks whether the payment has a credit management transaction associated with it. + * + * @param array $buildSubject + * @return bool + */ + protected function hasCreditManagementTransaction(array $buildSubject): bool + { + $payment = SubjectReader::readPayment($buildSubject)->getPayment(); + + return $payment->getAdditionalInformation(CreditManagementOrderHandler::INVOICE_KEY) != null; + } + + /** + * Merge function for builders + * + * @param array $result + * @param array $builder + * @return array + */ + protected function merge(array $result, array $builder): array + { + return array_replace_recursive($result, $builder); + } +} diff --git a/Gateway/Request/CreditManagement/CompanyDataBuilder.php b/Gateway/Request/CreditManagement/CompanyDataBuilder.php new file mode 100644 index 000000000..57da1509a --- /dev/null +++ b/Gateway/Request/CreditManagement/CompanyDataBuilder.php @@ -0,0 +1,47 @@ +getOrder()->getBillingAddress(); + $company = $billingAddress->getCompany(); + + if (empty($company) || strlen($company) <= 0) { + return []; + } + + return [ + 'culture' => strtolower($billingAddress->getCountryId()), + 'name' => $billingAddress->getCompany() ?? 'Person' + ]; + } +} diff --git a/Gateway/Request/CreditManagement/ConfigDataBuilder.php b/Gateway/Request/CreditManagement/ConfigDataBuilder.php new file mode 100644 index 000000000..fd0d366f4 --- /dev/null +++ b/Gateway/Request/CreditManagement/ConfigDataBuilder.php @@ -0,0 +1,97 @@ +configProvider = $configProvider; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + + $this->config = $this->configProvider->get( + $this->getPayment()->getMethod() + ); + + $data = [ + 'dueDate' => $this->getDueDate(), + 'schemeKey' => $this->config->getSchemeKey(), + 'maxStepIndex' => $this->config->getMaxStepIndex(), + ]; + + if ($this->config->getPaymentMethodAfterExpiry() != null) { + $data['allowedServicesAfterDueDate'] = $this->getPaymentMethodsAfterExpiry(); + } + return $data; + } + + /** + * Get payment methods + * + * @return string + */ + protected function getPaymentMethodsAfterExpiry(): string + { + $methods = $this->config->getPaymentMethodAfterExpiry(); + if (is_array($methods)) { + return implode(',', $methods); + } + return ""; + } + + /** + * Get transfer due date + * + * @return string + */ + protected function getDueDate(): string + { + $dueDays = abs((float)$this->config->getCm3DueDate()); + return (new \DateTime()) + ->modify("+{$dueDays} day") + ->format('Y-m-d'); + } +} diff --git a/Gateway/Request/CreditManagement/DebtorDataBuilder.php b/Gateway/Request/CreditManagement/DebtorDataBuilder.php new file mode 100644 index 000000000..53191672d --- /dev/null +++ b/Gateway/Request/CreditManagement/DebtorDataBuilder.php @@ -0,0 +1,44 @@ +getOrder()->getBillingAddress(); + if ($address === null) { + return []; + } + + return [ + 'code' => $address->getEmail(), + ]; + } +} diff --git a/Gateway/Request/CreditManagement/InvoiceDataBuilder.php b/Gateway/Request/CreditManagement/InvoiceDataBuilder.php new file mode 100644 index 000000000..f36a7604d --- /dev/null +++ b/Gateway/Request/CreditManagement/InvoiceDataBuilder.php @@ -0,0 +1,40 @@ + $this->getOrder()->getGrandTotal(), + 'invoiceAmountVAT' => $this->getOrder()->getTaxAmount(), + 'invoiceDate' => date('Y-m-d'), + ]; + } +} diff --git a/Gateway/Request/CreditManagement/InvoiceKeyDataBuilder.php b/Gateway/Request/CreditManagement/InvoiceKeyDataBuilder.php new file mode 100644 index 000000000..1345ec170 --- /dev/null +++ b/Gateway/Request/CreditManagement/InvoiceKeyDataBuilder.php @@ -0,0 +1,39 @@ + $this->getOrder()->getIncrementId(), + ]; + } +} diff --git a/Gateway/Request/CreditManagement/InvoiceNumberDataBuilder.php b/Gateway/Request/CreditManagement/InvoiceNumberDataBuilder.php new file mode 100644 index 000000000..924353963 --- /dev/null +++ b/Gateway/Request/CreditManagement/InvoiceNumberDataBuilder.php @@ -0,0 +1,38 @@ + $this->getOrder()->getIncrementId() . '-creditnote' + ]; + } +} diff --git a/Gateway/Request/CreditManagement/PersonDataBuilder.php b/Gateway/Request/CreditManagement/PersonDataBuilder.php new file mode 100644 index 000000000..58813971f --- /dev/null +++ b/Gateway/Request/CreditManagement/PersonDataBuilder.php @@ -0,0 +1,47 @@ +getOrder()->getBillingAddress(); + if ($address === null) { + return []; + } + + return [ + 'culture' => strtolower($address->getCountryId()), + 'name' => $address->getFirstname() . ' ' . $address->getLastname(), + 'firstName' => $address->getFirstname(), + 'lastName' => $address->getLastname() + ]; + } +} diff --git a/Gateway/Request/GatewaySettingDataBuilder.php b/Gateway/Request/GatewaySettingDataBuilder.php new file mode 100644 index 000000000..fccc550c6 --- /dev/null +++ b/Gateway/Request/GatewaySettingDataBuilder.php @@ -0,0 +1,71 @@ +configProviderMethodFactory = $configProviderMethodFactory; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + + $method = $paymentDO->getPayment()->getMethodInstance()->getCode(); + if (!$method) { + throw new Exception( + __("The payment method code it is not set.") + ); + } + $configProvider = $this->configProviderMethodFactory->get($method); + + if (method_exists($configProvider, 'getGatewaySettings')) { + $paymentMethod = [ + 'payment_method' => $configProvider->getGatewaySettings(), + ]; + } + + return $paymentMethod ?? []; + } +} diff --git a/Gateway/Request/GiftcardsDataBuilder.php b/Gateway/Request/GiftcardsDataBuilder.php new file mode 100644 index 000000000..9338b31d4 --- /dev/null +++ b/Gateway/Request/GiftcardsDataBuilder.php @@ -0,0 +1,62 @@ +giftcardsConfig = $giftcardsConfig; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $order = $paymentDO->getOrder()->getOrder(); + + $availableCards = $this->giftcardsConfig->getAllowedGiftcards($order->getStore()); + + $availableCards = $paymentDO->getPayment()->getAdditionalInformation('giftcard_method') + ? $paymentDO->getPayment()->getAdditionalInformation('giftcard_method') + : $availableCards . ',ideal'; + + return [ + 'servicesSelectableByClient' => $availableCards, + 'continueOnIncomplete' => 'RedirectToHTML', + ]; + } +} diff --git a/Gateway/Request/GroupTransactionDetails.php b/Gateway/Request/GroupTransactionDetails.php new file mode 100644 index 000000000..8f614ab98 --- /dev/null +++ b/Gateway/Request/GroupTransactionDetails.php @@ -0,0 +1,59 @@ + $giftcardTransaction->getRemainingAmount(), + self::GROUP_TRANSACTION_CURRENCY => $giftcardTransaction->getCurrency(), + self::GROUP_TRANSACTION_INVOICE => $giftcardTransaction->getOrderIncrementId(), + self::GROUP_TRANSACTION_ORDER => $giftcardTransaction->getOrderIncrementId(), + self::GROUP_TRANSACTION_TRANSACTION_KEY => $giftcardTransaction->getTransactionId(), + self::GROUP_TRANSACTION_SERVICE_CODE => 'giftcard', + self::GIFTCARD_NAME => $giftcardTransaction->getServicecode() + ]; + } + + return []; + } +} diff --git a/Gateway/Request/IdinDataBuilder.php b/Gateway/Request/IdinDataBuilder.php new file mode 100644 index 000000000..0c0f35ea5 --- /dev/null +++ b/Gateway/Request/IdinDataBuilder.php @@ -0,0 +1,155 @@ +customerSession = $customerSession; + $this->urlBuilder = $urlBuilder; + $this->formKey = $formKey; + $this->store = $storeManager->getStore(); + $this->configProviderAccount = $configProviderAccount; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $returnUrl = $this->getReturnUrl(); + + return [ + 'payment_method' => 'idin', + 'returnURL' => $returnUrl, + 'returnURLError' => $returnUrl, + 'returnURLCancel' => $returnUrl, + 'returnURLReject' => $returnUrl, + 'issuer' => $this->configProviderAccount->getIdin() === Enablemode::ENABLE_LIVE + ? $buildSubject['issuer'] + : 'BANKNL2Y', + 'additionalParameters' => [ + 'service_action_from_magento' => 'verify', + 'initiated_by_magento' => 1, + 'idin_cid' => $this->customerSession->getCustomerId() + ] + ]; + } + + /** + * Retrieves the return URL. + * + * @return string + * @throws LocalizedException + */ + public function getReturnUrl(): string + { + if ($this->returnUrl === null) { + $url = $this->urlBuilder->setScope($this->store->getId()); + $url = $url->getRouteUrl('buckaroo/redirect/idinProcess') . '?form_key=' . $this->getFormKey(); + + $this->setReturnUrl($url); + } + + return $this->returnUrl; + } + + /** + * Sets the return URL. + * + * @param string $url + * @return $this + */ + public function setReturnUrl(string $url): IdinDataBuilder + { + $routeUrl = $this->urlBuilder->getRouteUrl($url); + $this->returnUrl = $routeUrl; + + return $this; + } + + /** + * Retrieves the form key. + * + * @return string + * @throws LocalizedException + */ + public function getFormKey(): string + { + return $this->formKey->getFormKey(); + } +} diff --git a/Gateway/Request/Invoice/AbstractInvoiceDataBuilder.php b/Gateway/Request/Invoice/AbstractInvoiceDataBuilder.php new file mode 100644 index 000000000..43414c163 --- /dev/null +++ b/Gateway/Request/Invoice/AbstractInvoiceDataBuilder.php @@ -0,0 +1,91 @@ +buckarooHelper = $buckarooHelper; + } + + /** + * Initializes the payment information for a Buckaroo payment. + * + * @param array $buildSubject + * @return array + */ + public function initialize(array $buildSubject): array + { + $data = parent::initialize($buildSubject); + + $order = $this->getOrder(); + + $totalOrder = $order->getBaseGrandTotal(); + $this->numberOfInvoices = $order->getInvoiceCollection()->count(); + $this->currentInvoiceTotal = 0; + + // loop through invoices to get the last one (=current invoice) + if ($this->numberOfInvoices) { + $invoiceCollection = $order->getInvoiceCollection(); + $currentInvoice = $invoiceCollection->getLastItem(); + $this->currentInvoiceTotal = $currentInvoice->getGrandTotal(); + } + + if ($this->buckarooHelper->areEqualAmounts($totalOrder, $this->currentInvoiceTotal) + && $this->numberOfInvoices == 1) { + $this->capturePartial = false; //full capture + } + + $data['capturePartial'] = $this->capturePartial; + $data['currentInvoiceTotal'] = $this->currentInvoiceTotal; + $data['numberOfInvoices'] = $this->numberOfInvoices; + + return $data; + } +} diff --git a/Gateway/Request/Invoice/AmountInvoicedDataBuilder.php b/Gateway/Request/Invoice/AmountInvoicedDataBuilder.php new file mode 100644 index 000000000..7e6f6ff14 --- /dev/null +++ b/Gateway/Request/Invoice/AmountInvoicedDataBuilder.php @@ -0,0 +1,35 @@ + $this->currentInvoiceTotal ?? 0]; + } +} diff --git a/Gateway/Request/Invoice/InvoiceNumberDataBuilder.php b/Gateway/Request/Invoice/InvoiceNumberDataBuilder.php new file mode 100644 index 000000000..cf9cb2fcd --- /dev/null +++ b/Gateway/Request/Invoice/InvoiceNumberDataBuilder.php @@ -0,0 +1,42 @@ +getOrder()->getIncrementId(); + + // Partial Capture Settings + if ($this->capturePartial) { + $data['invoice'] = $this->getOrder()->getIncrementId() . '-' . $this->numberOfInvoices; + } + + return $data; + } +} diff --git a/Gateway/Request/Invoice/OriginalTransactionKeyDataBuilder.php b/Gateway/Request/Invoice/OriginalTransactionKeyDataBuilder.php new file mode 100644 index 000000000..0f412980f --- /dev/null +++ b/Gateway/Request/Invoice/OriginalTransactionKeyDataBuilder.php @@ -0,0 +1,46 @@ +getPayment()->getAdditionalInformation( + self::BUCKAROO_ORIGINAL_TRANSACTION_KEY_KEY + ); + + // Partial Capture Settings + if ($this->capturePartial) { + $data['originalTransactionKey'] = $this->getPayment()->getParentTransactionId(); + } + + return $data; + } +} diff --git a/Gateway/Request/LocaleDataBuilder.php b/Gateway/Request/LocaleDataBuilder.php new file mode 100644 index 000000000..6e0242e5c --- /dev/null +++ b/Gateway/Request/LocaleDataBuilder.php @@ -0,0 +1,52 @@ + $this->getLocaleCode()]; + } + + /** + * Retrieves the locale code based on the billing address country. + * + * @return string + */ + private function getLocaleCode(): string + { + $country = $this->getOrder()->getBillingAddress()->getCountryId(); + + $map = [ + 'CN' => 'zh-CN', + 'TW' => 'zh-TW' + ]; + + return $map[$country] ?? 'en-US'; + } +} diff --git a/Gateway/Request/PayLinkDataBuilder.php b/Gateway/Request/PayLinkDataBuilder.php new file mode 100644 index 000000000..73ba89a78 --- /dev/null +++ b/Gateway/Request/PayLinkDataBuilder.php @@ -0,0 +1,100 @@ +payLinkConfig = $payLinkConfig; + $this->giftcardsConfig = $giftcardsConfig; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $order = $paymentDO->getOrder()->getOrder(); + $storeId = $order->getStoreId(); + + return [ + 'merchantSendsEmail' => false, + 'email' => $order->getCustomerEmail(), + 'paymentMethodsAllowed' => $this->getPaymentMethodsAllowed($this->payLinkConfig, $storeId), + 'attachment' => '', + 'customer' => [ + 'gender' => $order->getCustomerGender() ?? 1, + 'firstName' => $order->getCustomerFirstname(), + 'lastName' => $order->getCustomerLastname() + ] + ]; + } + + /** + * Get Payment Methods Allowed + * + * @param PayLink $config + * @param string|int|null $storeId + * @return string + */ + private function getPaymentMethodsAllowed(PayLink $config, $storeId): string + { + if ($methods = $config->getPaymentMethod($storeId)) { + $methods = explode(',', (string)$methods); + $activeCards = ''; + foreach ($methods as $key => $value) { + if ($value === 'giftcard' + && $activeCards = $this->giftcardsConfig->getAllowedGiftcards($storeId)) { + unset($methods[$key]); + } + } + + if ($activeCards) { + $methods = array_merge($methods, explode(',', (string)$activeCards)); + } + $methods = join(',', $methods); + } + return $methods ?? ''; + } +} diff --git a/Gateway/Request/PayPerEmailDataBuilder.php b/Gateway/Request/PayPerEmailDataBuilder.php new file mode 100644 index 000000000..3ed4e4ddd --- /dev/null +++ b/Gateway/Request/PayPerEmailDataBuilder.php @@ -0,0 +1,107 @@ +payPerEmailConfig = $payPerEmailConfig; + $this->giftcardsConfig = $giftcardsConfig; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + $storeId = $this->getOrder()->getStoreId(); + $payment = $this->getPayment(); + + $data = [ + 'merchantSendsEmail' => !$this->payPerEmailConfig->hasSendMail($storeId), + 'email' => $payment->getAdditionalInformation('customer_email'), + 'paymentMethodsAllowed' => $this->getPaymentMethodsAllowed($this->payPerEmailConfig, $storeId), + 'attachment' => '', + 'customer' => [ + 'gender' => $payment->getAdditionalInformation('customer_gender') ?? Gender::UNKNOWN, + 'firstName' => $payment->getAdditionalInformation('customer_billingFirstName'), + 'lastName' => $payment->getAdditionalInformation('customer_billingMiddleName') + . ' ' . $payment->getAdditionalInformation('customer_billingLastName') + ] + ]; + + if ($this->payPerEmailConfig->getExpireDays()) { + $data['expirationDate'] = date('Y-m-d', time() + $this->payPerEmailConfig->getExpireDays() * 86400); + } + + return $data; + } + + /** + * Retrieves the allowed payment methods based on the PayPerEmail configuration and store ID. + * + * @param PayPerEmail $config + * @param int|null $storeId + * @return string + */ + private function getPaymentMethodsAllowed(PayPerEmail $config, ?int $storeId): string + { + if ($methods = $config->getPaymentMethod($storeId)) { + $methods = explode(',', (string)$methods); + $activeCards = ''; + foreach ($methods as $key => $value) { + if ($value === 'giftcard' + && $activeCards = $this->giftcardsConfig->getAllowedGiftcards($storeId)) { + unset($methods[$key]); + } + } + + if ($activeCards) { + $methods = array_merge($methods, explode(',', (string)$activeCards)); + } + $methods = join(',', $methods); + } + return $methods; + } +} diff --git a/Gateway/Request/PayReminder/AmountDataBuilder.php b/Gateway/Request/PayReminder/AmountDataBuilder.php new file mode 100644 index 000000000..fd65c1166 --- /dev/null +++ b/Gateway/Request/PayReminder/AmountDataBuilder.php @@ -0,0 +1,59 @@ +payReminderService = $payReminderService; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + + $serviceAction = $this->payReminderService->getServiceAction($this->getOrder()->getIncrementId()); + + if (in_array($serviceAction, TransactionType::getPayRemainderActions())) { + return ['amountDebit' => $this->payReminderService->getPayRemainder($this->getOrder())]; + } + + return []; + } +} diff --git a/Gateway/Request/PayReminder/OriginalTransactionKeyDataBuilder.php b/Gateway/Request/PayReminder/OriginalTransactionKeyDataBuilder.php new file mode 100644 index 000000000..33b169839 --- /dev/null +++ b/Gateway/Request/PayReminder/OriginalTransactionKeyDataBuilder.php @@ -0,0 +1,61 @@ +payReminderService = $payReminderService; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + + $serviceAction = $this->payReminderService->getServiceAction($this->getOrder()->getIncrementId()); + + if (in_array($serviceAction, TransactionType::getPayRemainderActions())) { + return [ + 'originalTransactionKey' => $this->payReminderService->getOriginalTransactionKey($this->getOrder()) + ]; + } + + return []; + } +} diff --git a/Gateway/Request/PaypalExtrainfoDataBuilder.php b/Gateway/Request/PaypalExtrainfoDataBuilder.php new file mode 100644 index 000000000..1b665a7f2 --- /dev/null +++ b/Gateway/Request/PaypalExtrainfoDataBuilder.php @@ -0,0 +1,137 @@ +configProviderPaypal = $configProviderPaypal; + $this->paypalStateCodes = $paypalStateCodes; + $this->payReminderService = $payReminderService; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + + $sellersProtectionActive = (bool)$this->configProviderPaypal->getSellersProtection(); + $order = $this->getOrder(); + $shippingAddress = $order->getShippingAddress(); + + if ($shippingAddress === null) { + $shippingAddress = $order->getBillingAddress(); + } + + if ($shippingAddress === null) { + return []; + } + + $isPaypalExpress = $this->getPayment()->getAdditionalInformation('express_order_id')!== null; + + if (!$sellersProtectionActive || !$shippingAddress || $isPaypalExpress) { + return []; + } + + $serviceAction = $this->payReminderService->getServiceAction($this->getOrder()->getIncrementId()); + if (!empty($serviceAction) && ($serviceAction == 'PayRemainder')) { + return []; + } + + $data = [ + 'customer' => [ + 'name' => mb_substr($shippingAddress->getName(), 0, 32) + ], + 'address' => [ + 'street' => mb_substr($shippingAddress->getStreetLine(1), 0, 100), + 'city' => mb_substr($shippingAddress->getCity(), 0, 40), + 'state' => $this->getStateOrProvince($shippingAddress), + 'zipcode' => mb_substr($shippingAddress->getPostcode(), 0, 20), + 'country' => $shippingAddress->getCountryId(), + ], + 'phone' => [ + 'mobile' => $shippingAddress->getTelephone() ?? '' + ], + 'addressOverride' => true + ]; + + if ($this->payReminderService->getServiceAction($this->getOrder()->getIncrementId()) !== 'payRemainder') { + $this->payReminderService->setServiceAction('ExtraInfo'); + } + + return $data; + } + + /** + * Get state or province code of the shipping address + * + * @param Address $shippingAddress + * @return string + */ + private function getStateOrProvince(Address $shippingAddress): string + { + $shippingRegion = $shippingAddress->getRegion(); + if (!empty($shippingRegion)) { + $twoCharacterShippingRegion = $this->paypalStateCodes->getCodeFromValue( + $shippingAddress->getCountryId(), + $shippingAddress->getRegion() + ); + + if ($twoCharacterShippingRegion) { + return $twoCharacterShippingRegion; + } + } + + return ''; + } +} diff --git a/Gateway/Request/Recipient/AbstractRecipientDataBuilder.php b/Gateway/Request/Recipient/AbstractRecipientDataBuilder.php new file mode 100644 index 000000000..c7ff5208d --- /dev/null +++ b/Gateway/Request/Recipient/AbstractRecipientDataBuilder.php @@ -0,0 +1,211 @@ +addressType = $addressType; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + + return ['recipient' => $this->buildData()]; + } + + /** + * Returns an array containing customer data + * + * @return array + */ + protected function buildData(): array + { + return + [ + 'category' => $this->getCategory(), + 'gender' => $this->getGender(), + 'firstName' => $this->getFirstname(), + 'lastName' => $this->getLastName(), + 'birthDate' => $this->getBirthDate() + ]; + } + + /** + * Returns the category of the customer. + * + * @return string + */ + protected function getCategory(): string + { + return 'B2C'; + } + + /** + * Returns the gender of the customer. + * + * @return string + */ + protected function getGender(): string + { + if ($this->payment->getAdditionalInformation('customer_gender') === '1') { + return 'male'; + } + return 'female'; + } + + /** + * Returns the first name of the customer. + * + * @return string + */ + protected function getFirstname(): string + { + return $this->getAddress()->getFirstname(); + } + + /** + * Returns the address associated with the order. + * + * @return OrderAddressInterface + */ + protected function getAddress(): OrderAddressInterface + { + if ($this->addressType == 'shipping') { + return $this->getOrder()->getShippingAddress() ?? $this->getOrder()->getBillingAddress(); + } else { + return $this->getOrder()->getBillingAddress(); + } + } + + /** + * Returns the last name of the customer. + * + * @return string + */ + protected function getLastName(): string + { + return $this->getAddress()->getLastName(); + } + + /** + * Returns the birthdate of the customer + * + * @return false|string + */ + protected function getBirthDate() + { + $customerDoB = (string)$this->payment->getAdditionalInformation('customer_DoB'); + if (empty($customerDoB)) { + $customerDoB = $this->getOrder()->getCustomerDob() ?? '1990-01-01'; + } + + return date( + $this->getFormatDate(), + strtotime(str_replace('/', '-', $customerDoB)) + ); + } + + /** + * Returns the date format used to format the customer's birthdate. + * + * @return string + */ + protected function getFormatDate(): string + { + return 'd-m-Y'; + } + + /** + * Returns whether the category of customer + * + * @return string + */ + protected function getCareOf(): string + { + if (empty($this->getOrder()->getBillingAddress()->getCompany())) { + return 'Person'; + } + + return 'Company'; + } + + /** + * Returns the Chamber of Commerce number of the customer. + * + * @return mixed + */ + protected function getChamberOfCommerce() + { + return $this->payment->getAdditionalInformation('customer_chamberOfCommerce'); + } + + /** + * Required if Billing country is NL or BE. Possible values: Mr, Mrs, Miss. + * + * @return string + */ + protected function getTitle(): string + { + if ($this->getGender() === 'male') { + return 'Mr'; + } + + return 'Mrs'; + } + + /** + * Returns the initials of the customer's first name. + * + * @return string + */ + protected function getInitials(): string + { + return strtoupper(substr($this->getFirstname(), 0, 1)); + } + + /** + * Get Company Name + * + * @return string + */ + protected function getCompanyName(): string + { + return $this->payment->getAdditionalInformation('CompanyName') ?: $this->getAddress()->getCompany() ?: ''; + } +} diff --git a/Gateway/Request/Recipient/AfterpayDataBuilder.php b/Gateway/Request/Recipient/AfterpayDataBuilder.php new file mode 100644 index 000000000..0bc1b153f --- /dev/null +++ b/Gateway/Request/Recipient/AfterpayDataBuilder.php @@ -0,0 +1,175 @@ +scopeConfig = $scopeConfig; + } + + /** + * @inheritdoc + */ + protected function buildData(): array + { + $data = [ + 'category' => $this->getCategory(), + 'careOf' => $this->getCareOf(), + 'firstName' => $this->getFirstname(), + 'lastName' => $this->getLastName(), + 'conversationLanguage' => $this->getConversationLanguage(), + 'customerNumber' => 'customerNumber12345' + ]; + + $category = $this->getCategory(); + $billingAddress = $this->getOrder()->getBillingAddress(); + if ($category === RecipientCategory::PERSON) { + if ($billingAddress->getCountryId() == 'NL' || $billingAddress->getCountryId() == 'BE') { + $data['title'] = $this->getTitle(); + $data['birthDate'] = $this->getBirthDate(); + } + if ($billingAddress->getCountryId() == 'FI') { + $data['identificationNumber'] = $this->getIdentificationNumber(); + } + } else { + $data['companyName'] = $billingAddress->getCompany(); + $data['identificationNumber'] = $this->getIdentificationNumber(); + } + + return $data; + } + + /** + * @inheritdoc + */ + protected function getCategory(): string + { + $category = RecipientCategory::PERSON; + $billingAddress = $this->getOrder()->getBillingAddress(); + + if ($this->isCustomerB2B($this->getOrder()->getStoreId()) && + $billingAddress->getCountryId() === 'NL' && + !$this->isCompanyEmpty($billingAddress->getCompany()) + ) { + $category = RecipientCategory::COMPANY; + } + + return $category; + } + + /** + * Determines whether the customer is a B2B customer based on the store configuration. + * + * @param int|null $storeId + * @return bool + * @throws LocalizedException + */ + private function isCustomerB2B(int $storeId = null): bool + { + return $this->getConfigData('customer_type', $storeId) !== AfterpayCustomerType::CUSTOMER_TYPE_B2C; + } + + /** + * Retrieve information from payment configuration + * + * @param string $field + * @param int|string|null|Store $storeId + * @return mixed + * @throws LocalizedException + */ + public function getConfigData(string $field, $storeId = null) + { + if (null === $storeId) { + $storeId = $this->getOrder()->getStoreId(); + } + $path = 'payment/' . $this->getPayment()->getMethodInstance()->getCode() . '/' . $field; + return $this->scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId); + } + + /** + * Check if company is empty + * + * @param string|null $company + * + * @return boolean + */ + private function isCompanyEmpty(string $company = null): bool + { + if (null === $company) { + return true; + } + + return strlen(trim($company)) === 0; + } + + /** + * @inheritdoc + */ + protected function getCareOf(): string + { + return $this->getFirstname() . ' ' . $this->getLastName(); + } + + /** + * Possible values: NL, FR, DE, FI. + * + * @return string + */ + private function getConversationLanguage(): string + { + $countryId = $this->getOrder()->getBillingAddress()->getCountryId(); + + if (in_array($countryId, ['NL', 'FR', 'DE', 'FI'])) { + return $countryId; + } else { + return 'NL'; + } + } + + /** + * Retrieves the customer identification number associated with the payment. + * + * @return mixed + */ + protected function getIdentificationNumber() + { + return $this->getPayment()->getAdditionalInformation('customer_identificationNumber'); + } +} diff --git a/Gateway/Request/Recipient/AfterpayOldDataBuilder.php b/Gateway/Request/Recipient/AfterpayOldDataBuilder.php new file mode 100644 index 000000000..edf9bd028 --- /dev/null +++ b/Gateway/Request/Recipient/AfterpayOldDataBuilder.php @@ -0,0 +1,164 @@ +scopeConfig = $scopeConfig; + } + + /** + * @inheritdoc + */ + protected function buildData(): array + { + $data = [ + 'title' => $this->getFirstname(), + 'initials' => $this->getInitials(), + 'lastName' => $this->getLastName(), + 'birthDate' => $this->getBirthDate(), + 'culture' => $this->getOrder()->getBillingAddress()->getCountryId() + ]; + + if ($this->getCategory() == RecipientCategory::COMPANY) { + $data['chamberOfCommerce'] = $this->getPayment()->getAdditionalInformation('COCNumber'); + $data['companyName'] = $this->getPayment()->getAdditionalInformation('CompanyName'); + } + + return $data; + } + + /** + * @inheritdoc + */ + public function getCategory($order = null, $payment = null): string + { + $category = RecipientCategory::PERSON; + + if ($order === null) { + $order = $this->getOrder(); + } else { + $this->setOrder($order); + } + + if ($payment === null) { + $payment = $this->getPayment(); + } else { + $this->setPayment($payment); + } + + $billingAddress = $order->getBillingAddress(); + if ($payment->getAdditionalInformation('selectedBusiness') == self::BUSINESS_METHOD_B2B) { + $category = RecipientCategory::COMPANY; + } else { + if ($this->isCustomerB2B($order->getStoreId()) && + !$this->isCompanyEmpty($billingAddress->getCompany()) + ) { + $category = RecipientCategory::COMPANY; + } + } + + return $category; + } + + /** + * Determines whether the customer is a B2B customer based on the store configuration. + * + * @param int|string|null $storeId + * @return bool + * @throws LocalizedException + */ + private function isCustomerB2B($storeId = null): bool + { + return $this->getConfigData('customer_type', $storeId) !== AfterpayCustomerType::CUSTOMER_TYPE_B2C; + } + + /** + * Retrieve information from payment configuration + * + * @param string $field + * @param int|string|null|Store $storeId + * @return mixed + * @throws LocalizedException + */ + public function getConfigData(string $field, $storeId = null) + { + if (null === $storeId) { + $storeId = $this->getOrder()->getStoreId(); + } + $path = 'payment/' . $this->getPayment()->getMethodInstance()->getCode() . '/' . $field; + return $this->scopeConfig->getValue($path, ScopeInterface::SCOPE_STORE, $storeId); + } + + /** + * Check if company is empty + * + * @param string|null $company + * + * @return boolean + */ + private function isCompanyEmpty(string $company = null): bool + { + if (null === $company) { + return true; + } + + return strlen(trim($company)) === 0; + } + + /** + * @inheritdoc + */ + protected function getGender(): string + { + if ($this->payment->getAdditionalInformation('customer_gender') === '1') { + return (string)Gender::MALE; + } + return (string)Gender::FEMALE; + } +} diff --git a/Gateway/Request/Recipient/BillinkDataBuilder.php b/Gateway/Request/Recipient/BillinkDataBuilder.php new file mode 100644 index 000000000..f5363b9fa --- /dev/null +++ b/Gateway/Request/Recipient/BillinkDataBuilder.php @@ -0,0 +1,136 @@ +helper = $helper; + } + + /** + * @inheritdoc + */ + protected function buildData(): array + { + $category = $this->getCategory(); + + $data = [ + 'category' => $category, + 'careOf' => $this->getCareOf(), + 'title' => $this->getGender(), + 'initials' => $this->getInitials(), + 'firstName' => $this->getFirstname(), + 'lastName' => $this->getLastName(), + 'birthDate' => $this->getBirthDate() + ]; + + if ($category == 'B2B') { + $data['chamberOfCommerce'] = $this->getChamberOfCommerce(); + } + + return $data; + } + + /** + * Returns the birthdate of the customer + * + * @return false|string + */ + protected function getBirthDate() + { + $customerDoB = (string)$this->payment->getAdditionalInformation('customer_DoB'); + if (empty($customerDoB)) { + $customerDoB = $this->getOrder()->getCustomerDob() ?? '1990-01-01'; + } + + if(!is_string($customerDoB) || strlen(trim($customerDoB)) === 0) { + return null; + } + + $birthDayStamp = date( + $this->getFormatDate(), + strtotime(str_replace('/', '-', $customerDoB)) + ); + + if($birthDayStamp === false) { + return null; + } + + return $birthDayStamp; + } + + /** + * @inheritdoc + */ + protected function getCategory(): string + { + try { + return $this->helper->checkCustomerGroup('buckaroo_magento2_billink') ? 'B2B' : 'B2C'; + } catch (Exception $e) { + return 'B2C'; + } + } + + /** + * @inheritdoc + */ + protected function getCareOf(): string + { + $company = $this->getAddress()->getCompany(); + + if ($company !== null && strlen(trim($company)) > 0) { + return $company; + } + + return $this->getFirstname() . ' ' . $this->getLastName(); + } + + /** + * @inheritdoc + */ + protected function getGender(): string + { + if ($this->payment->getAdditionalInformation('customer_gender') === '1') { + return 'Male'; + } elseif ($this->payment->getAdditionalInformation('customer_gender') === '2') { + return 'Female'; + } else { + return 'Unknown'; + } + } +} diff --git a/Gateway/Request/Recipient/CapayableDataBuilder.php b/Gateway/Request/Recipient/CapayableDataBuilder.php new file mode 100644 index 000000000..aa0ee409e --- /dev/null +++ b/Gateway/Request/Recipient/CapayableDataBuilder.php @@ -0,0 +1,124 @@ +addressFormatter = $addressFormatter; + } + + /** + * @inheritdoc + */ + protected function buildData(): array + { + $category = $this->getCategory(); + + $data = [ + 'customerNumber' => $this->getCustomerNumber(), + 'category' => $category, + 'initials' => $this->getInitials(), + 'firstName' => $this->getFirstname(), + 'lastName' => $this->getLastName(), + 'careOf' => $this->getCareOf(), + 'birthDate' => $this->getBirthDate(), + 'phone' => $this->getPhone(), + 'country' => $this->getAddress()->getCountryId() + ]; + + if ($category == 'B2B') { + $data['companyName'] = $this->getCompanyName(); + $data['chamberOfCommerce'] = $this->getChamberOfCommerce(); + } + + return $data; + } + + /** + * @inheritdoc + */ + protected function getCategory(): string + { + if (empty($this->getAddress()->getCompany())) { + return 'B2C'; + } + + return 'B2B'; + } + + protected function getCustomerNumber() + { + $customerNumber = "guest"; + + if (!empty($this->getOrder()->getCustomerId())) { + $customerNumber = $this->getOrder()->getCustomerId(); + } + + return $customerNumber; + } + + /** + * Get phone + * + * @return string + */ + protected function getPhone(): string + { + $phone = $this->getAddress()->getTelephone(); + + if ($this->payment->getAdditionalInformation('customer_telephone') !== null) { + $phone = $this->payment->getAdditionalInformation('customer_telephone'); + } + + $phoneData = $this->addressFormatter->formatTelephone($phone, $this->getAddress()->getCountryId()); + + return $phoneData['clean']; + } + + /** + * Returns the date format used to format the customer's birthdate. + * + * @return string + */ + protected function getFormatDate(): string + { + return 'Y-m-d'; + } +} diff --git a/Gateway/Request/Recipient/KlarnaDataBuilder.php b/Gateway/Request/Recipient/KlarnaDataBuilder.php new file mode 100644 index 000000000..d42c38311 --- /dev/null +++ b/Gateway/Request/Recipient/KlarnaDataBuilder.php @@ -0,0 +1,47 @@ + $this->getCategory(), + 'gender' => $this->getGender(), + 'firstName' => $this->getFirstname(), + 'lastName' => $this->getLastName(), + 'birthDate' => $this->getBirthDate() + ]; + } + + /** + * @inheritdoc + */ + protected function getFormatDate(): string + { + return 'Y-m-d'; + } +} diff --git a/Gateway/Request/Recipient/KlarnaKpDataBuilder.php b/Gateway/Request/Recipient/KlarnaKpDataBuilder.php new file mode 100644 index 000000000..4de04c3fb --- /dev/null +++ b/Gateway/Request/Recipient/KlarnaKpDataBuilder.php @@ -0,0 +1,36 @@ + $this->getFirstname(), + 'lastName' => $this->getLastName(), + ]; + } +} diff --git a/Gateway/Request/RefundOriginalTransactionKeyDataBuilder.php b/Gateway/Request/RefundOriginalTransactionKeyDataBuilder.php new file mode 100644 index 000000000..435e05b33 --- /dev/null +++ b/Gateway/Request/RefundOriginalTransactionKeyDataBuilder.php @@ -0,0 +1,64 @@ +getPayment(); + + $originalTransactionKey = $this->getRefundTransactionPartialSupport($payment); + + return ['originalTransactionKey' => $originalTransactionKey]; + } + + /** + * Get Refund Transaction Partial Support KEY + * + * @param InfoInterface $payment + * @return mixed + * @throws LocalizedException + */ + protected function getRefundTransactionPartialSupport(InfoInterface $payment) + { + $creditmemo = $payment->getCreditmemo(); + if ($payment->getMethodInstance()->canRefundPartialPerInvoice() && $creditmemo) { + return $payment->getParentTransactionId(); + } + + return $payment->getAdditionalInformation(self::BUCKAROO_ORIGINAL_TRANSACTION_KEY_KEY); + } +} diff --git a/Gateway/Request/RefundReasonDataBuilder.php b/Gateway/Request/RefundReasonDataBuilder.php new file mode 100644 index 000000000..a0a7b2a81 --- /dev/null +++ b/Gateway/Request/RefundReasonDataBuilder.php @@ -0,0 +1,39 @@ + 'RequestedByCustomer', + ]; + } +} diff --git a/Gateway/Request/ReservationNumberDataBuilder.php b/Gateway/Request/ReservationNumberDataBuilder.php new file mode 100644 index 000000000..361ab9a64 --- /dev/null +++ b/Gateway/Request/ReservationNumberDataBuilder.php @@ -0,0 +1,35 @@ + $this->getOrder()->getBuckarooReservationNumber()]; + } +} diff --git a/Gateway/Request/ReserveBillingDataBuilder.php b/Gateway/Request/ReserveBillingDataBuilder.php new file mode 100644 index 000000000..e9ccac0bd --- /dev/null +++ b/Gateway/Request/ReserveBillingDataBuilder.php @@ -0,0 +1,137 @@ +order->getBillingAddress(); + $streetFormat = $this->formatStreet($billingAddress->getStreet()); + + $birthDayStamp = str_replace('/', '-', (string)$this->payment->getAdditionalInformation('customer_DoB')); + $identificationNumber = $this->payment->getAdditionalInformation('customer_identificationNumber'); + $telephone = $this->payment->getAdditionalInformation('customer_telephone'); + $telephone = (empty($telephone) ? $billingAddress->getTelephone() : $telephone); + $category = 'B2C'; + + $gender = 'female'; + if ($this->payment->getAdditionalInformation('customer_gender') === '1') { + $gender = 'male'; + } + + if ($this->getPayment()->getMethodInstance()->getCode() == 'buckaroo_magento2_klarnakp') { + if (empty($billingAddress->getCompany())) { + $careOf = 'Person'; + } else { + $careOf = 'Company'; + } + $billingData['recipient'] = [ + 'careOf' => $careOf, + 'firstName' => $billingAddress->getFirstname(), + 'lastName' => $billingAddress->getLastName(), + ]; + } else { + $billingData['recipient'] = [ + 'category' => $category, + 'gender' => $gender, + 'firstName' => $billingAddress->getFirstname(), + 'lastName' => $billingAddress->getLastName(), + 'birthDate' => $birthDayStamp + ]; + } + + $billingData['address'] = [ + 'street' => $streetFormat['street'], + 'houseNumber' => '', + 'houseNumberAdditional' => '', + 'zipcode' => $billingAddress->getPostcode(), + 'city' => $billingAddress->getCity(), + 'country' => $billingAddress->getCountryId() + ]; + + if (!empty($telephone)) { + $billingData['phone'] = [ + 'mobile' => $telephone, + 'landline' => $telephone + ]; + } + + $billingData['email'] = $billingAddress->getEmail(); + + if (!empty($streetFormat['house_number'])) { + $billingData['address']['houseNumber'] = $streetFormat['house_number']; + } + + if (!empty($streetFormat['number_addition'])) { + $billingData['address']['houseNumberAdditional'] = $streetFormat['number_addition']; + } + + if ($billingAddress->getCountryId() == 'FI') { + $billingData['IdentificationNumber'] = $identificationNumber; + } + + return ['billing' => $billingData]; + } + + /** + * Get street fragments + * + * @param string[] $street + * @return array + */ + public function formatStreet(array $street): array + { + $street = implode(' ', $street); + + $format = [ + 'house_number' => '', + 'number_addition' => '', + 'street' => $street, + ]; + + if (preg_match('#^(.*?)([0-9\-]+)(.*)#s', $street, $matches)) { + // Check if the number is at the beginning of streetname + if ('' == $matches[1]) { + $format['house_number'] = trim($matches[2]); + $format['street'] = trim($matches[3]); + } else { + if (preg_match('#^(.*?)(\d+)(.*)#s', $street, $matches)) { + $format['street'] = trim($matches[1]); + $format['house_number'] = trim($matches[2]); + $format['number_addition'] = trim($matches[3]); + } + } + } + + return $format; + } +} diff --git a/Gateway/Request/ReserveDataBuilder.php b/Gateway/Request/ReserveDataBuilder.php new file mode 100644 index 000000000..fefdf01b3 --- /dev/null +++ b/Gateway/Request/ReserveDataBuilder.php @@ -0,0 +1,55 @@ +getOrder()->getOrder(); + $payment = $paymentDO->getPayment(); + /** + * @var OrderAddressInterface $billingAddress + */ + $billingAddress = $order->getBillingAddress(); + $country = $billingAddress->getCountryId(); + $birthDayStamp = str_replace('/', '', (string)$payment->getAdditionalInformation('customer_DoB')); + $gender = Gender::FEMALE; + if ($payment->getAdditionalInformation('customer_gender') === '1') { + $gender = Gender::MALE; + } + return [ + 'operatingCountry' => $country, + 'pno' => empty($birthDayStamp) ? '01011990' : $birthDayStamp, + 'gender' => $gender + ]; + } +} diff --git a/Gateway/Request/SaveIssuerDataBuilder.php b/Gateway/Request/SaveIssuerDataBuilder.php new file mode 100644 index 000000000..0866e6f88 --- /dev/null +++ b/Gateway/Request/SaveIssuerDataBuilder.php @@ -0,0 +1,80 @@ +customerAttributes = $customerAttributes; + } + + /** + * Save last used issuer, it will be used to select automatically the issuer in the checkout + * + * @param array $buildSubject + * @return array + */ + public function build(array $buildSubject): array + { + $this->saveLastUsedIssuer(SubjectReader::readPayment($buildSubject)->getPayment()); + return []; + } + + /** + * @param InfoInterface|OrderPaymentInterface $payment + * + * @return void + */ + public function saveLastUsedIssuer($payment): void + { + /** @var Order $order */ + $order = $payment->getOrder(); + $customerId = $order->getCustomerId(); + + if ($customerId !== null) { + $this->customerAttributes->setAttribute( + (int)$customerId, + self::EAV_LAST_USED_ISSUER_ID, + $payment->getAdditionalInformation('issuer') + ); + } + } +} diff --git a/Gateway/Request/SkipPushDataBuilder.php b/Gateway/Request/SkipPushDataBuilder.php new file mode 100644 index 000000000..db7e50fa3 --- /dev/null +++ b/Gateway/Request/SkipPushDataBuilder.php @@ -0,0 +1,64 @@ +payReminderService = $payReminderService; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $payment = $paymentDO->getPayment(); + $orderId = $paymentDO->getOrder()->getOrderIncrementId(); + + $serviceAction = $this->payReminderService->getServiceAction($orderId); + + if (!in_array($serviceAction, TransactionType::getPayRemainderActions())) { + $payment->setAdditionalInformation(self::BUCKAROO_SKIP_PUSH_KEY, 1); + $paymentDO->getOrder()->getOrder()->save(); + } + + return []; + } +} diff --git a/Gateway/Request/TerminalIdDataBuilder.php b/Gateway/Request/TerminalIdDataBuilder.php new file mode 100644 index 000000000..888f3ca4e --- /dev/null +++ b/Gateway/Request/TerminalIdDataBuilder.php @@ -0,0 +1,61 @@ +cookieManager = $cookieManager; + } + + /** + * @inheritdoc + * + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + public function build(array $buildSubject): array + { + return ['terminalID' => $this->getPosPaymentTerminalId()]; + } + + /** + * Get Pos Terminal ID Cookie + * + * @return null|string + */ + private function getPosPaymentTerminalId(): ?string + { + return $this->cookieManager->getCookie('Pos-Terminal-Id'); + } +} diff --git a/Gateway/Request/TokenEncryptedDataBuilder.php b/Gateway/Request/TokenEncryptedDataBuilder.php new file mode 100644 index 000000000..32c9e3395 --- /dev/null +++ b/Gateway/Request/TokenEncryptedDataBuilder.php @@ -0,0 +1,87 @@ +scopeConfig = $scopeConfig; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + parent::initialize($buildSubject); + + $useClientSide = $this->getConfigData('client_side'); + $additionalInformation = $this->getPayment()->getAdditionalInformation(); + + if ($useClientSide && isset($additionalInformation['client_side_mode']) + && ($additionalInformation['client_side_mode'] == 'cc') + ) { + if (!isset($additionalInformation['customer_encrypteddata'])) { + throw new Exception( + __('An error occured trying to send the encrypted bancontact data to Buckaroo.') + ); + } + return ['encryptedCardData' => $additionalInformation['customer_encrypteddata']]; + } else { + return ['saveToken' => true]; + } + } + + /** + * Retrieve information from payment configuration + * + * @param string $field + * @param int|string|null|Store $storeId + * @return mixed + * @throws LocalizedException + */ + public function getConfigData(string $field, $storeId = null) + { + if (null === $storeId) { + $storeId = $this->getOrder()->getStoreId(); + } + $path = 'payment/' . $this->getPayment()->getMethodInstance()->getCode() . '/' . $field; + return $this->scopeConfig->getValue($path, ScopeInterface::SCOPE_STORE, $storeId); + } +} diff --git a/Gateway/Request/TransferOrderDataBuilder.php b/Gateway/Request/TransferOrderDataBuilder.php new file mode 100644 index 000000000..213b15f44 --- /dev/null +++ b/Gateway/Request/TransferOrderDataBuilder.php @@ -0,0 +1,55 @@ +transferConfig = $transferConfig; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject): array + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $order = $paymentDO->getOrder()->getOrder(); + return [ + 'dateDue' => $this->transferConfig->getDueDateFormated($order->getStore()), + 'sendMail' => $this->transferConfig->hasOrderEmail($order->getStore()), + ]; + } +} diff --git a/Gateway/Request/UseMobileViewDataBuilder.php b/Gateway/Request/UseMobileViewDataBuilder.php new file mode 100644 index 000000000..16777ec46 --- /dev/null +++ b/Gateway/Request/UseMobileViewDataBuilder.php @@ -0,0 +1,54 @@ + $this->isMobile()]; + } + + /** + * Return if browser is in mobile mode + * + * @return bool + */ + public function isMobile(): bool + { + $useragent = $_SERVER['HTTP_USER_AGENT']; + return preg_match( + '/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i', + $useragent + ) || preg_match( + '/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', + substr($useragent, 0, 4) + ); + } +} diff --git a/Gateway/Request/VersionDataBuilder.php b/Gateway/Request/VersionDataBuilder.php new file mode 100644 index 000000000..ecff8c122 --- /dev/null +++ b/Gateway/Request/VersionDataBuilder.php @@ -0,0 +1,38 @@ +v1 = $v1; + $this->v2 = $v2; + } + + public function build(array $buildSubject) + { + $paymentDO = SubjectReader::readPayment($buildSubject); + $payment = $paymentDO->getPayment(); + + $apiVersion = $payment->getMethodInstance()->getConfigData('api_version'); + + if (!empty($apiVersion)) { + if (strtolower($apiVersion) == 'v2') { + return $this->v2->build($buildSubject); + } else { + return $this->v1->build($buildSubject); + } + } + + return []; + } +} diff --git a/Gateway/Response/AuthorizeTransactionIdHandler.php b/Gateway/Response/AuthorizeTransactionIdHandler.php new file mode 100644 index 000000000..f72827021 --- /dev/null +++ b/Gateway/Response/AuthorizeTransactionIdHandler.php @@ -0,0 +1,55 @@ +getInstance(); - $result = $instance->convert($randomData); - - $this->assertEquals($randomData, $result); + $payment = SubjectReader::readPayment($handlingSubject)->getPayment(); + $payment->setAdditionalInformation('voided_by_buckaroo', true); } } diff --git a/Gateway/Response/ConsumerMessageHandler.php b/Gateway/Response/ConsumerMessageHandler.php new file mode 100644 index 000000000..3110ce6d5 --- /dev/null +++ b/Gateway/Response/ConsumerMessageHandler.php @@ -0,0 +1,65 @@ +messageManager = $messageManager; + } + + /** + * @inheritdoc + */ + public function handle(array $handlingSubject, array $response) + { + $response = SubjectReader::readTransactionResponse($response); + $consumerMessageData = $response->get('ConsumerMessage'); + + if (!empty($consumerMessageData) && $consumerMessageData['MustRead'] == 1) { + $title = $consumerMessageData['Title'] ?? null; + $plainText = $consumerMessageData['PlainText'] ?? null; + + if ($title) { + $this->messageManager->addSuccessMessage(__($title)); + } + + if ($plainText) { + $this->messageManager->addSuccessMessage(__($plainText)); + } + } + } +} diff --git a/Gateway/Response/CreditManagementOrderHandler.php b/Gateway/Response/CreditManagementOrderHandler.php new file mode 100644 index 000000000..c9b6d5228 --- /dev/null +++ b/Gateway/Response/CreditManagementOrderHandler.php @@ -0,0 +1,104 @@ +response = SubjectReader::readTransactionResponse($response); + $payment = SubjectReader::readPayment($handlingSubject)->getPayment(); + + $invoiceKey = $this->getServiceInvoice(); + if ($invoiceKey !== null) { + $payment->setAdditionalInformation(self::INVOICE_KEY, $invoiceKey); + } + } + + /** + * Get invoice key from response + * + * @return string|null + */ + protected function getServiceInvoice(): ?string + { + $services = $this->response->data('Services'); + if (is_array($services) && count($services) > 0) { + $service = $this->getCreditManagementService($services); + if (is_array($service) && count($service) > 0) { + return $this->getInvoiceKey($service); + } + } + + return null; + } + + /** + * Get service for credit management + * + * @param array $services + * @return array|null + */ + private function getCreditManagementService(array $services): ?array + { + foreach ($services as $service) { + if (isset($service['Name']) && $service['Name'] === "CreditManagement3") { + return $service; + } + } + return null; + } + + /** + * Get invoice key from service + * + * @param array $service + * @return string + */ + private function getInvoiceKey(array $service): string + { + if (!isset($service['Parameters']) || !is_array($service['Parameters'])) { + return ''; + } + foreach ($service['Parameters'] as $parameter) { + if ($parameter['Name'] === "InvoiceKey") { + return $parameter['Value']; + } + } + + return ''; + } +} diff --git a/Gateway/Response/DispatchEventHandler.php b/Gateway/Response/DispatchEventHandler.php new file mode 100644 index 000000000..85200fff2 --- /dev/null +++ b/Gateway/Response/DispatchEventHandler.php @@ -0,0 +1,92 @@ +eventManager = $eventManager; + $this->command = $command; + } + + /** + * Handles response + * + * @param array $handlingSubject + * @param array $response + * @return void + * @throws \Exception + */ + public function handle(array $handlingSubject, array $response) + { + $paymentDO = SubjectReader::readPayment($handlingSubject); + /** @var OrderPaymentInterface $payment */ + $payment = $paymentDO->getPayment(); + $order = $payment->getOrder(); + + $this->eventManager->dispatch('buckaroo_' . $this->command . '_after', ['order' => $order]); + $this->dispatchAfterEvent('buckaroo_magento2_method_' . $this->command . '_after', $payment, $response); + } + + /** + * Dispatch After Event + * + * @param string $name + * @param InfoInterface $payment + * @param array $response + * + * @return $this + */ + protected function dispatchAfterEvent(string $name, InfoInterface $payment, array $response): DispatchEventHandler + { + $this->eventManager->dispatch( + $name, + [ + 'payment' => $payment, + 'response' => $response, + ] + ); + + return $this; + } +} diff --git a/Gateway/Response/GiftCardRemoveHandler.php b/Gateway/Response/GiftCardRemoveHandler.php new file mode 100644 index 000000000..2af09ed32 --- /dev/null +++ b/Gateway/Response/GiftCardRemoveHandler.php @@ -0,0 +1,98 @@ +messageManager = $messageManager; + $this->groupTransactionRepository = $groupTransactionRepository; + } + + /** + * @inheritdoc + * @throws RemoveException + * @throws CouldNotSaveException + */ + public function handle(array $handlingSubject, array $response): void + { + $transactionResponse = SubjectReader::readTransactionResponse($response); + + if (isset($handlingSubject['giftcardTransaction']) + && $handlingSubject['giftcardTransaction'] instanceof GroupTransaction + && $transactionResponse->getStatusCode() == 190) { + $this->updateGiftcardTransactionAmount( + $handlingSubject['giftcardTransaction'], + (float)$transactionResponse->getAmount() + ); + } + + if ($transactionResponse->getStatusCode() == 690) { + throw new RemoveException( + 'Giftcard was already removed' + ); + } + } + + /** + * Update gift card transaction with the refunded amount + * + * @param GroupTransaction $giftcardTransaction + * @param float $amount + * @return void + * @throws CouldNotSaveException + */ + protected function updateGiftcardTransactionAmount( + GroupTransaction $giftcardTransaction, + float $amount + ): void { + $giftcardTransaction->setRefundedAmount( + $giftcardTransaction->getRefundedAmount() + $amount + ); + $this->groupTransactionRepository->save($giftcardTransaction); + } +} diff --git a/Gateway/Response/PayLinkHandler.php b/Gateway/Response/PayLinkHandler.php new file mode 100644 index 000000000..7946abd85 --- /dev/null +++ b/Gateway/Response/PayLinkHandler.php @@ -0,0 +1,69 @@ +messageManager = $messageManager; + } + + /** + * @inheritdoc + */ + public function handle(array $handlingSubject, array $response) + { + $response = SubjectReader::readTransactionResponse($response); + $paylink = $response->getServiceParameters()['paylink'] ?? ''; + $paymentDO = SubjectReader::readPayment($handlingSubject); + /** @var Order $order */ + $order = $paymentDO->getOrder()->getOrder(); + + if (!empty($paylink)) { + $order->addCommentToStatusHistory('Paylink: ' . $paylink); + $this->messageManager->addSuccess( + __( + 'Your PayLink %1', + $paylink + ) + ); + } else { + $this->messageManager->addErrorMessage('Error creating PayLink'); + } + } +} diff --git a/Gateway/Response/PaymentDetailsHandler.php b/Gateway/Response/PaymentDetailsHandler.php new file mode 100644 index 000000000..8b485082b --- /dev/null +++ b/Gateway/Response/PaymentDetailsHandler.php @@ -0,0 +1,95 @@ +helper = $helper; + $this->buckarooResponseData = $buckarooResponseData; + } + + /** + * @inheritdoc + */ + public function handle(array $handlingSubject, array $response) + { + $paymentDO = SubjectReader::readPayment($handlingSubject); + /** @var OrderPaymentInterface $payment */ + $payment = $paymentDO->getPayment(); + + /** @var TransactionResponse $transaction */ + $transactionResponse = SubjectReader::readTransactionResponse($response); + $arrayResponse = $transactionResponse->toArray(); + + /** + * Save the transaction's response as additional info for the transaction. + */ + $rawInfo = $this->getTransactionAdditionalInfo($arrayResponse); + + $payment->setTransactionAdditionalInfo( + \Magento\Sales\Model\Order\Payment\Transaction::RAW_DETAILS, + \json_encode($rawInfo) + ); + + // SET BUCKAROO RESPONSE REDIRECT + $this->buckarooResponseData->setResponse($transactionResponse); + } + + /** + * Get array of transaction Additional Info + * + * @param array $array + * + * @return array + */ + public function getTransactionAdditionalInfo(array $array): array + { + return $this->helper->getTransactionAdditionalInfo($array); + } +} diff --git a/Gateway/Response/PaymentInTransitHandler.php b/Gateway/Response/PaymentInTransitHandler.php new file mode 100644 index 000000000..8de91e84d --- /dev/null +++ b/Gateway/Response/PaymentInTransitHandler.php @@ -0,0 +1,67 @@ +getPayment(); + + /** @var TransactionResponse $transaction */ + $transactionResponse = SubjectReader::readTransactionResponse($response); + + $this->setPaymentInTransit($payment); + + if (!$transactionResponse->hasRedirect()) { + $this->setPaymentInTransit($payment, false); + } + } + + /** + * Set flag if user is on the payment provider page + * + * @param OrderPaymentInterface $payment + * @param bool $inTransit + * @return void + */ + public function setPaymentInTransit(OrderPaymentInterface $payment, bool $inTransit = true): void + { + $payment->setAdditionalInformation(self::BUCKAROO_PAYMENT_IN_TRANSIT, $inTransit); + } +} diff --git a/Gateway/Response/RefundTransactionIdHandler.php b/Gateway/Response/RefundTransactionIdHandler.php new file mode 100644 index 000000000..26b71982a --- /dev/null +++ b/Gateway/Response/RefundTransactionIdHandler.php @@ -0,0 +1,55 @@ +getPayment(); + + /** @var TransactionResponse $transaction */ + $transactionResponse = SubjectReader::readTransactionResponse($response); + + if ($payment->getMethod() == 'buckaroo_magento2_klarnakp') { + $order = $payment->getOrder(); + + if ($order->getBuckarooReservationNumber()) { + return; + } + + $serviceParameters = $transactionResponse->getServiceParameters(); + if (isset($serviceParameters['klarnakp_reservationnumber'])) { + $order->setBuckarooReservationNumber($serviceParameters['klarnakp_reservationnumber']); + $order->save(); + } + } + } +} diff --git a/Gateway/Response/RestoreQuoteHandler.php b/Gateway/Response/RestoreQuoteHandler.php new file mode 100644 index 000000000..577b3549e --- /dev/null +++ b/Gateway/Response/RestoreQuoteHandler.php @@ -0,0 +1,63 @@ +checkoutSession = $checkoutSession; + } + + /** + * Handles response + * + * @param array $handlingSubject + * @param array $response + * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function handle(array $handlingSubject, array $response) + { + $paymentDO = SubjectReader::readPayment($handlingSubject); + + $orderId = $paymentDO->getOrder()->getId(); + + $this->checkoutSession->setRestoreQuoteLastOrder($orderId); + } +} diff --git a/Gateway/Response/SkipPushHandler.php b/Gateway/Response/SkipPushHandler.php new file mode 100644 index 000000000..b2ab451b2 --- /dev/null +++ b/Gateway/Response/SkipPushHandler.php @@ -0,0 +1,65 @@ +getPayment(); + + $skipFirstPush = $payment->getAdditionalInformation('skip_push'); + if (is_array($skipFirstPush)) { + $skipFirstPush = array_shift($skipFirstPush); + } + /** + * Buckaroo Push is send before Response, for correct flow we skip the first push + * for some payment methods + * + * @todo when buckaroo changes the push / response order this can be removed + */ + if ($skipFirstPush > 0) { + $payment->setAdditionalInformation('skip_push', $skipFirstPush - 1); + if (!empty($payment->getOrder()) && !empty($payment->getOrder()->getId())) { + // Only save payment if order is already saved, this to avoid foreign key constraint error + // on table sales_order_payment, column parent_id. + $payment->save(); + } + } + } +} diff --git a/Gateway/Response/TestNotificationHandler.php b/Gateway/Response/TestNotificationHandler.php new file mode 100644 index 000000000..865b57019 --- /dev/null +++ b/Gateway/Response/TestNotificationHandler.php @@ -0,0 +1,51 @@ +getPayment(); + + /** @var TransactionResponse $transaction */ + $transactionResponse = SubjectReader::readTransactionResponse($response); + + $isTest = $transactionResponse->get('IsTest'); + + if ($isTest) { + $payment->setAdditionalInformation( + AddInTestModeMessage::PAYMENT_IN_TEST_MODE, + $isTest === true + ); + } + } +} \ No newline at end of file diff --git a/Gateway/Response/TransactionIdHandler.php b/Gateway/Response/TransactionIdHandler.php new file mode 100644 index 000000000..4c233b292 --- /dev/null +++ b/Gateway/Response/TransactionIdHandler.php @@ -0,0 +1,94 @@ +getPayment(); + + /** @var TransactionResponse $transaction */ + $transactionResponse = SubjectReader::readTransactionResponse($response); + $transactionKey = $transactionResponse->getTransactionKey(); + + if (!empty($transactionKey)) { + $payment->setTransactionId($transactionKey); + /** + * Save the payment's transaction key. + */ + if ($this->shouldSaveTransactionKey()) { + $payment->setAdditionalInformation(self::BUCKAROO_ORIGINAL_TRANSACTION_KEY_KEY, $transactionKey); + } + + $payment->setIsTransactionClosed($this->shouldCloseTransaction()); + $closed = $this->shouldCloseParentTransaction(); + $payment->setShouldCloseParentTransaction($closed); + } + } + + /** + * Whether transaction key should be saved on additional information + * + * @return bool + */ + protected function shouldSaveTransactionKey(): bool + { + return true; + } + + /** + * Whether transaction should be closed + * + * @return bool + */ + protected function shouldCloseTransaction(): bool + { + return true; + } + + /** + * Whether parent transaction should be closed + * + * @return bool + */ + protected function shouldCloseParentTransaction(): bool + { + return true; + } +} diff --git a/Gateway/Response/TransferDetailsHandler.php b/Gateway/Response/TransferDetailsHandler.php new file mode 100644 index 000000000..85db73a40 --- /dev/null +++ b/Gateway/Response/TransferDetailsHandler.php @@ -0,0 +1,63 @@ +getPayment(); + + /** @var SDKTransactionResponse $transaction */ + $transactionResponse = SubjectReader::readTransactionResponse($response); + + $transferDetails = $this->getTransferDetails($transactionResponse); + $payment->setAdditionalInformation('transfer_details', $transferDetails); + } + + /** + * @param $transactionResponse + * @return array + */ + protected function getTransferDetails($transactionResponse): array + { + $serviceParameters = $transactionResponse->getServiceParameters(); + + return [ + 'transfer_amount' => $transactionResponse->getAmount(), + 'transfer_paymentreference' => $serviceParameters['paymentreference'] ?? '', + 'transfer_accountholdername' => $serviceParameters['accountholdername'] ?? '', + 'transfer_iban' => $serviceParameters['iban'] ?? '', + 'transfer_bic' => $serviceParameters['bic'] ?? '', + ]; + } +} diff --git a/Gateway/Skip/GiftcardOrderSkip.php b/Gateway/Skip/GiftcardOrderSkip.php new file mode 100644 index 000000000..39754883f --- /dev/null +++ b/Gateway/Skip/GiftcardOrderSkip.php @@ -0,0 +1,52 @@ +paymentGroupTransaction = $paymentGroupTransaction; + } + + /** + * @inheritdoc + */ + public function isSkip(array $commandSubject): bool + { + $paymentDO = SubjectReader::readPayment($commandSubject); + $orderIncrementId = $paymentDO->getPayment()->getOrder()->getIncrementId(); + return $this->paymentGroupTransaction->isAnyGroupTransaction($orderIncrementId); + } +} diff --git a/Gateway/Validator/ActiveAccountValidator.php b/Gateway/Validator/ActiveAccountValidator.php new file mode 100644 index 000000000..40778982c --- /dev/null +++ b/Gateway/Validator/ActiveAccountValidator.php @@ -0,0 +1,73 @@ +configProviderFactory = $configProviderFactory; + parent::__construct($resultFactory); + } + + /** + * Validates if Buckaroo Module is enabled + * + * @param array $validationSubject + * @return ResultInterface + * @throws Exception + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function validate(array $validationSubject): ResultInterface + { + $isValid = true; + + /** + * @var Account $accountConfig + */ + $accountConfig = $this->configProviderFactory->get('account'); + if ($accountConfig->getActive() == 0) { + $isValid = false; + } + + return $this->createResult($isValid); + } +} diff --git a/Gateway/Validator/AllowedGiftcardsValidator.php b/Gateway/Validator/AllowedGiftcardsValidator.php new file mode 100644 index 000000000..c42944786 --- /dev/null +++ b/Gateway/Validator/AllowedGiftcardsValidator.php @@ -0,0 +1,70 @@ +giftcardsConfig = $giftcardsConfig; + parent::__construct($resultFactory); + } + + /** + * Validates the payment information for Buckaroo gateway. + * + * @param array $validationSubject + * @return ResultInterface + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function validate(array $validationSubject): ResultInterface + { + $isValid = true; + + /** + * If there are no giftcards chosen, we can't be available + */ + $fails = []; + if (null === $this->giftcardsConfig->getAllowedGiftcards()) { + $fails[] = __('There are no allowed giftcards.'); + $isValid = false; + } + + return $this->createResult($isValid, $fails); + } +} diff --git a/Gateway/Validator/AreaCodeValidator.php b/Gateway/Validator/AreaCodeValidator.php new file mode 100644 index 000000000..387154f95 --- /dev/null +++ b/Gateway/Validator/AreaCodeValidator.php @@ -0,0 +1,77 @@ +state = $state; + parent::__construct($resultFactory); + } + + /** + * Validate Area Code Value + * + * @param array $validationSubject + * @return ResultInterface + * @throws Exception + * @throws LocalizedException + */ + public function validate(array $validationSubject): ResultInterface + { + $isValid = true; + + $paymentMethodInstance = SubjectReader::readPaymentMethodInstance($validationSubject); + + $isAvailableInBackend = $paymentMethodInstance->getConfigData('available_in_backend'); + $areaCode = $this->state->getAreaCode(); + if (Area::AREA_ADMINHTML === $areaCode + && $isAvailableInBackend !== null + && $isAvailableInBackend == 0 + ) { + $isValid = false; + } + + return $this->createResult($isValid); + } +} diff --git a/Gateway/Validator/AvailableBasedOnAmountValidator.php b/Gateway/Validator/AvailableBasedOnAmountValidator.php new file mode 100644 index 000000000..d8df0617a --- /dev/null +++ b/Gateway/Validator/AvailableBasedOnAmountValidator.php @@ -0,0 +1,68 @@ +getStoreId(); + + if (($quote->getShippingAddress()->getCompany() || $quote->getBillingAddress()->getCompany()) + && in_array($paymentMethodInstance->getCode(), [Afterpay20::CODE, Billink::CODE])) { + $maximum = $paymentMethodInstance->getConfigData('max_amount_b2b', $storeId); + $minimum = $paymentMethodInstance->getConfigData('min_amount_b2b', $storeId); + } else { + $maximum = $paymentMethodInstance->getConfigData('max_amount', $storeId); + $minimum = $paymentMethodInstance->getConfigData('min_amount', $storeId); + } + + $total = $quote->getGrandTotal(); + + if ($total < 0.01 + || $maximum !== null && $total > $maximum + || $minimum !== null && $total < $minimum + ) { + $isValid = false; + } + + return $this->createResult($isValid); + } +} diff --git a/Gateway/Validator/AvailableBasedOnCurrencyValidator.php b/Gateway/Validator/AvailableBasedOnCurrencyValidator.php new file mode 100644 index 000000000..93a2d5f6b --- /dev/null +++ b/Gateway/Validator/AvailableBasedOnCurrencyValidator.php @@ -0,0 +1,53 @@ +getConfigData('allowed_currencies'); + $allowedCurrencies = explode(',', (string)$allowedCurrenciesRaw); + + $currentCurrency = SubjectReader::readQuote($validationSubject)->getCurrency()->getQuoteCurrencyCode(); + + if ($allowedCurrenciesRaw === null || in_array($currentCurrency, $allowedCurrencies)) { + $isValid = true; + } + + return $this->createResult($isValid); + } +} diff --git a/Gateway/Validator/AvailableBasedOnCustomerGroupValidator.php b/Gateway/Validator/AvailableBasedOnCustomerGroupValidator.php new file mode 100644 index 000000000..350c3aaa3 --- /dev/null +++ b/Gateway/Validator/AvailableBasedOnCustomerGroupValidator.php @@ -0,0 +1,84 @@ +helper = $helper; + } + + /** + * Available Based on Costumer Group + * + * @param array $validationSubject + * @return ResultInterface + * @throws Exception + * @throws LocalizedException + */ + public function validate(array $validationSubject): ResultInterface + { + $isValid = true; + + if (!isset($validationSubject['paymentMethodInstance']) || !isset($validationSubject['quote'])) { + return $this->createResult( + false, + [__('Payment method instance does not exist')] + ); + } + + $paymentMethodInstance = SubjectReader::readPaymentMethodInstance($validationSubject); + $paymentMethodCode = $paymentMethodInstance->getCode(); + + $checkCustomerGroup = $this->helper->checkCustomerGroup($paymentMethodCode); + if ($paymentMethodCode === 'buckaroo_magento2_billink' && !$checkCustomerGroup) { + $checkCustomerGroup = $this->helper->checkCustomerGroup($paymentMethodCode, true); + } + + if (!$checkCustomerGroup) { + $isValid = false; + } + + return $this->createResult($isValid); + } +} diff --git a/Gateway/Validator/AvailableBasedOnPOSValidator.php b/Gateway/Validator/AvailableBasedOnPOSValidator.php new file mode 100644 index 000000000..619e08268 --- /dev/null +++ b/Gateway/Validator/AvailableBasedOnPOSValidator.php @@ -0,0 +1,124 @@ +pospaymentConfiguration = $pospaymentConfiguration; + $this->helper = $helper; + $this->paymentHelper = $paymentHelper; + } + + /** + * Available Based on Costumer Group + * + * @param array $validationSubject + * @return ResultInterface + * @throws Exception + * @throws LocalizedException + */ + public function validate(array $validationSubject): ResultInterface + { + $isValid = true; + + if (!isset($validationSubject['paymentMethodInstance']) || !isset($validationSubject['quote'])) { + return $this->createResult( + false, + [__('Payment method instance does not exist')] + ); + } + + $paymentMethodInstance = SubjectReader::readPaymentMethodInstance($validationSubject); + $paymentMethodCode = $paymentMethodInstance->getCode(); + + $quote = SubjectReader::readQuote($validationSubject); + + if ($paymentMethodCode !== Pospayment::CODE && $this->pospaymentConfiguration->getActive()) { + $posPaymentMethodInstance = $this->paymentHelper->getMethodInstance(Pospayment::CODE); + if ($posPaymentMethodInstance->isAvailable($quote)) { + $isValid = false; + if ($this->checkPosOtherPaymentMethods($paymentMethodCode)) { + $isValid = true; + } + } + } + + return $this->createResult($isValid); + } + + /** + * Check if payment method should be display with POS + * + * @param string $paymentMethodCode + * @return bool + */ + private function checkPosOtherPaymentMethods(string $paymentMethodCode): bool + { + $otherPaymentMethods = $this->pospaymentConfiguration->getOtherPaymentMethods(); + if ($otherPaymentMethods && in_array( + $this->helper->getBuckarooMethod($paymentMethodCode), + explode(',', $otherPaymentMethods) + )) { + return true; + } + + return false; + } +} diff --git a/Gateway/Validator/BankAccountValidator.php b/Gateway/Validator/BankAccountValidator.php new file mode 100644 index 000000000..c44e1fbe4 --- /dev/null +++ b/Gateway/Validator/BankAccountValidator.php @@ -0,0 +1,104 @@ +ibanValidator = $ibanValidator; + parent::__construct($resultFactory); + } + + /** + * Validates the payment information for Buckaroo gateway. + * + * @param array $validationSubject + * @return bool|ResultInterface + * @throws NotFoundException + * @throws \Exception + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function validate(array $validationSubject): ResultInterface + { + $paymentInfo = $validationSubject['payment']; + + $customerBic = $paymentInfo->getAdditionalInformation('customer_bic'); + $customerIban = $paymentInfo->getAdditionalInformation('customer_iban'); + $customerAccountName = $paymentInfo->getAdditionalInformation('customer_account_name'); + + $fails = []; + if (empty($customerAccountName) || str_word_count($customerAccountName) < 2) { + $fails[] = __('Please enter a valid bank account holder name'); + } + + if ($paymentInfo instanceof Payment) { + $billingCountry = $paymentInfo->getOrder()->getBillingAddress()->getCountryId(); + } else { + $billingCountry = $paymentInfo->getQuote()->getBillingAddress()->getCountryId(); + } + + if (empty($customerIban) || !$this->ibanValidator->isValid($customerIban)) { + $fails[] = __('Please enter a valid bank account number'); + } + + if ($billingCountry != 'NL' && !preg_match(self::BIC_NUMBER_REGEX, $customerBic)) { + $fails[] = __('Please enter a valid BIC number'); + } + + $isValid = false; + if (empty($fails)) { + $isValid = true; + } + + return $this->createResult($isValid, $fails); + } +} diff --git a/Gateway/Validator/CountryValidator.php b/Gateway/Validator/CountryValidator.php new file mode 100644 index 000000000..49ef18f44 --- /dev/null +++ b/Gateway/Validator/CountryValidator.php @@ -0,0 +1,59 @@ +getConfigData('allowspecific', $storeId) === 1 + ) { + $availableCountries = explode( + ',', + $methodInstance->getConfigData('specificcountry', $storeId) ?? '' + ); + + if (!in_array($validationSubject['country'], $availableCountries)) { + $isValid = false; + } + } + + return $this->createResult($isValid); + } +} diff --git a/Gateway/Validator/HouseNumberValidator.php b/Gateway/Validator/HouseNumberValidator.php new file mode 100644 index 000000000..68d65090a --- /dev/null +++ b/Gateway/Validator/HouseNumberValidator.php @@ -0,0 +1,100 @@ +streetFormatter = $streetFormatter; + parent::__construct($resultFactory); + } + + /** + * Validate country + * + * @param array $validationSubject + * @return ResultInterface + */ + public function validate(array $validationSubject): ResultInterface + { + /** @var QuotePayment|OrderPayment $paymentInfo */ + $paymentInfo = $validationSubject['payment']; + if ($paymentInfo instanceof QuotePayment) { + $quote = $paymentInfo->getQuote(); + + try { + $this->validateHouseNumber($quote->getBillingAddress()); + $this->validateHouseNumber($quote->getShippingAddress()); + } catch (Exception $exception) { + return $this->createResult(false, [$exception->getMessage()]); + } + } + + return $this->createResult(true); + } + + /** + * @param Address $address + * @return void + * @throws Exception + */ + private function validateHouseNumber(Address $address): void + { + $streetFormat = $this->streetFormatter->format($address->getStreet()); + + if ($address->getCountryId() !== "DE") { + return; + } + + if (empty(trim($streetFormat['house_number'])) + || !is_string($streetFormat['house_number']) + ) { + throw new Exception( + new Phrase( + 'A valid address is required, cannot find street number' + ) + ); + } + } +} diff --git a/Gateway/Validator/IssuerValidator.php b/Gateway/Validator/IssuerValidator.php new file mode 100644 index 000000000..fc7c620f0 --- /dev/null +++ b/Gateway/Validator/IssuerValidator.php @@ -0,0 +1,121 @@ +configProvider = $configProvider; + $this->request = $request; + $this->jsonSerializer = $jsonSerializer; + + parent::__construct($resultFactory); + } + + /** + * Validate issuer + * + * @param array $validationSubject + * @return ResultInterface + * @throws LocalizedException + */ + public function validate(array $validationSubject): ResultInterface + { + /** @var Payment $paymentInfo */ + $paymentInfo = $validationSubject['payment']; + $config = $this->getConfig($paymentInfo); + + if (method_exists($config, 'canShowIssuers') && !$config->canShowIssuers()) { + return $this->createResult(true); + } + + $chosenIssuer = $paymentInfo->getAdditionalInformation('issuer'); + + if (!$chosenIssuer && $content = $this->request->getContent()) { + $jsonDecode = $this->jsonSerializer->unserialize($content); + if (!empty($jsonDecode['paymentMethod']['additional_data']['issuer'])) { + $chosenIssuer = $jsonDecode['paymentMethod']['additional_data']['issuer']; + $paymentInfo->setAdditionalInformation('issuer', $chosenIssuer); + } + } + + foreach ($config->getIssuers() as $issuer) { + if ($issuer['code'] == $chosenIssuer) { + return $this->createResult(true); + } + } + + return $this->createResult(false, [__('Please select a issuer from the list')]); + } + + /** + * Get config provider for specific payment method + * + * @param InfoInterface $paymentInfo + * @return ConfigProviderInterface|false + */ + protected function getConfig(InfoInterface $paymentInfo) + { + try { + return $this->configProvider->get($paymentInfo->getMethodInstance()->getCode()); + } catch (\Exception $exception) { + return false; + } + } +} diff --git a/Gateway/Validator/PosPaymentValidator.php b/Gateway/Validator/PosPaymentValidator.php new file mode 100644 index 000000000..dc58cecf8 --- /dev/null +++ b/Gateway/Validator/PosPaymentValidator.php @@ -0,0 +1,150 @@ +header = $header; + $this->cookieManager = $cookieManager; + $this->buckarooLog = $buckarooLog; + parent::__construct($resultFactory); + } + + /** + * Validate POS payment method + * + * @param array $validationSubject + * @return ResultInterface + */ + public function validate(array $validationSubject): ResultInterface + { + $this->validatePayment($validationSubject); + $this->validateTerminalId(); + $this->validateUserAgent($validationSubject); + + if (empty($this->errorMessages)) { + return $this->createResult(true); + } else { + return $this->createResult( + false, + $this->errorMessages + ); + } + } + + /** + * Validate if payment instance exists + * + * @param array $validationSubject + * @return void + */ + private function validatePayment(array $validationSubject) + { + if (!isset($validationSubject['payment'])) { + $this->errorMessages[] = __('Payment method instance does not exist'); + } + } + + /** + * Validate if POS Terminal ID is set + * + * @return void + */ + private function validateTerminalId() + { + if (!$this->getPosPaymentTerminalId()) { + $this->errorMessages[] = __('POS Terminal Id it is not set.'); + } + } + + /** + * Get the POS Payment Terminal ID + * + * @return string|null + */ + private function getPosPaymentTerminalId(): ?string + { + $terminalId = $this->cookieManager->getCookie('Pos-Terminal-Id'); + $this->buckarooLog->addDebug(__METHOD__ . '|1|'); + $this->buckarooLog->addDebug(var_export($terminalId, true)); + return $terminalId; + } + + /** + * Validate if User Agent is set as expected + * + * @param array $validationSubject + * @return void + */ + private function validateUserAgent(array $validationSubject) + { + $paymentMethodInstance = $validationSubject['payment']; + + $userAgent = $this->header->getHttpUserAgent(); + $userAgentConfiguration = trim((string)$paymentMethodInstance->getPayment()->getConfigData('user_agent')); + + $this->buckarooLog->addDebug(var_export([$userAgent, $userAgentConfiguration], true)); + + if (strlen($userAgentConfiguration) > 0 && $userAgent != $userAgentConfiguration) { + $this->errorMessages[] = __('Wrong User Agent configuration'); + } + } +} diff --git a/Gateway/Validator/RefundPendingApprovalValidator.php b/Gateway/Validator/RefundPendingApprovalValidator.php new file mode 100644 index 000000000..cf638e01d --- /dev/null +++ b/Gateway/Validator/RefundPendingApprovalValidator.php @@ -0,0 +1,164 @@ +logger = $logger; + $this->refundConfigProvider = $refundConfigProvider; + $this->registry = $registry; + $this->resourceConnection = $resourceConnection; + } + + /** + * Performs validation of result code + * + * @param array $validationSubject + * @return ResultInterface + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @throws LocalizedException + */ + public function validate(array $validationSubject): ResultInterface + { + $paymentDO = SubjectReader::readPayment($validationSubject); + $payment = $paymentDO->getPayment(); + $order = $paymentDO->getOrder()->getOrder(); + $transactionResponse = SubjectReader::readTransactionResponse($validationSubject['response']); + $statusCode = $transactionResponse->getStatusCode(); + + if (!empty($statusCode) + && ($statusCode == Response::STATUSCODE_PENDING_APPROVAL) + && $payment + && !empty($transactionResponse->getRelatedTransactions()) + ) { + $this->logger->addDebug(sprintf( + '[REFUND] | [RESPONSE] | [%s:%s] - Pending Approval validator', + __METHOD__, + __LINE__, + )); + + $this->resourceConnection->getConnection()->rollBack(); + + $transactionKeysArray = $payment->getAdditionalInformation( + DefaultProcessor::BUCKAROO_RECEIVED_TRANSACTIONS_STATUSES + ); + foreach ($transactionResponse->getRelatedTransactions() as $relatedTransaction) { + $transactionKeysArray[$relatedTransaction['RelatedTransactionKey']] = + $statusCode; + } + $payment->setAdditionalInformation( + DefaultProcessor::BUCKAROO_RECEIVED_TRANSACTIONS_STATUSES, + $transactionKeysArray + ); + + if ($this->refundConfigProvider->getPendingApprovalSetting() == RefundConfigProvider::PENDING_REFUND_ON_APPROVE) { + $creditmemo = $this->getCreditmemo(); + $creditmemoItems = $creditmemo->getAllItems(); + + $orderItemsRefunded = []; + foreach ($creditmemoItems as $creditmemoItem) { + if($creditmemoItem->getPrice() > 0) { + $orderItemsRefunded[$creditmemoItem->getOrderItemId()] = ['qty' => (int)$creditmemoItem->getQty()]; + } + } + + $payment->setAdditionalInformation( + RefundConfigProvider::ADDITIONAL_INFO_PENDING_REFUND_ITEMS, + $orderItemsRefunded + ); + } + + $order->addStatusHistoryComment( + __("The refund has been initiated but it is waiting for a approval. Login to the Buckaroo Plaza to finalize the refund by approving it.") + )->setIsCustomerNotified(false)->save(); + + $payment->save(); + + return $this->createResult( + false, + [__('Refund has been initiated, but it needs to be approved, so you need to wait for an approval')], + [$statusCode] + ); + } + + return $this->createResult(true, [__('Transaction Success')], [$statusCode]); + } + + /** + * Retrieve creditmemo model instance + * + * @return Creditmemo + */ + public function getCreditmemo() + { + return $this->registry->registry('current_creditmemo'); + } +} diff --git a/Gateway/Validator/ResponseCodeSDKValidator.php b/Gateway/Validator/ResponseCodeSDKValidator.php new file mode 100644 index 000000000..2a0638399 --- /dev/null +++ b/Gateway/Validator/ResponseCodeSDKValidator.php @@ -0,0 +1,183 @@ +helper = $helper; + $this->request = $request; + } + + /** + * Performs validation of result code + * + * @param array $validationSubject + * @return ResultInterface + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @throws LocalizedException + */ + public function validate(array $validationSubject): ResultInterface + { + $response = $validationSubject['response']['object'] ?? null; + + if (!$response instanceof TransactionResponse) { + return $this->createResult(false, [__('Data must be an instance of "TransactionResponse"')]); + } + + $this->transaction = $response; + $statusCode = $this->getStatusCode(); + + if ($this->isSuccessStatusCode($statusCode)) { + return $this->createResult(true, [__('Transaction Success')], [$statusCode]); + } elseif ($this->isFailedStatusCode($statusCode)) { + return $this->handleFailureStatusCode($validationSubject, $statusCode); + } + + return $this->createResult(false, [__("Invalid Buckaroo status code received: %1.")], [$statusCode]); + } + + /** + * Get Buckaroo status code + * + * @return int|null + */ + public function getStatusCode(): ?int + { + $statusCode = $this->transaction->getStatusCode(); + + if ((!isset($statusCode) || $statusCode == null) && $this->transaction->isCanceled()) { + $statusCode = Response::STATUSCODE_SUCCESS; + } + + if ((!isset($statusCode) || $statusCode == null) + && $this->request->getParam('cancel') + ) { + $statusCode = Response::STATUSCODE_CANCELLED_BY_USER; + } + + return $statusCode; + } + + private function isSuccessStatusCode(int $statusCode): bool + { + return in_array($statusCode, [ + Response::STATUSCODE_SUCCESS, + Response::STATUSCODE_PENDING_PROCESSING, + Response::STATUSCODE_WAITING_ON_USER_INPUT, + Response::STATUSCODE_WAITING_ON_CONSUMER, + Response::STATUSCODE_PAYMENT_ON_HOLD, + ]); + } + + private function isFailedStatusCode(int $statusCode): bool + { + return in_array($statusCode, [ + Response::ORDER_FAILED, + Response::STATUSCODE_VALIDATION_FAILURE, + Response::STATUSCODE_TECHNICAL_ERROR, + Response::STATUSCODE_FAILED, + Response::STATUSCODE_REJECTED, + Response::STATUSCODE_CANCELLED_BY_USER, + Response::STATUSCODE_CANCELLED_BY_MERCHANT, + ]); + } + + /** + * @throws LocalizedException + */ + private function handleFailureStatusCode(array $validationSubject, ?int $statusCode): ResultInterface + { + $payment = SubjectReader::readPayment($validationSubject)->getPayment(); + $methodInstanceClass = $payment->getMethodInstance(); + + if ($methodInstanceClass->getCode() == 'buckaroo_magento2_klarnakp') { + $methodInstanceClass::$requestOnVoid = false; + } + + $message = !empty($this->transaction->getSomeError()) ? + $this->transaction->getSomeError() + : 'Gateway rejected the transaction.'; + + if ($statusCode === 690 + && strpos($message, "deliveryCustomer.address.countryCode") !== false + ) { + $message = "Pay rejected: It is not allowed to specify another country " . + "for the invoice and delivery address for Afterpay transactions."; + } + + $fraudMessage = $this->getFailureMessageOnFraud(); + if ($fraudMessage !== null) { + $message = $fraudMessage; + } + + return $this->createResult(false, [__($message)], [$statusCode]); + } + + /** + * @return string|null + */ + public function getFailureMessageOnFraud(): ?string + { + if ($this->transaction->getSubStatusCode() == 'S103') { + return 'An anti-fraud rule has blocked this transaction automatically. Please contact the webshop.'; + } + + return null; + } +} diff --git a/Gateway/Validator/SpamLimitValidator.php b/Gateway/Validator/SpamLimitValidator.php new file mode 100644 index 000000000..809f5e06f --- /dev/null +++ b/Gateway/Validator/SpamLimitValidator.php @@ -0,0 +1,70 @@ +spamLimitService = $spamLimitService; + } + + /** + * Check if this payment method is limited by IP. + * + * @param array $validationSubject + * @return ResultInterface + */ + public function validate(array $validationSubject): ResultInterface + { + $paymentMethodInstance = SubjectReader::readPaymentMethodInstance($validationSubject); + + $isValid = true; + if ($this->spamLimitService->isSpamLimitActive($paymentMethodInstance) + && $this->spamLimitService->isSpamLimitReached( + $paymentMethodInstance, + $this->spamLimitService->getPaymentAttemptsStorage() + )) { + $isValid = false; + } + + return $this->createResult($isValid); + } +} diff --git a/Helper/Data.php b/Helper/Data.php index 2e1948912..5f2aa33ca 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -20,28 +20,60 @@ namespace Buckaroo\Magento2\Helper; +use Buckaroo\Magento2\Exception as BuckarooException; +use Buckaroo\Magento2\Logging\BuckarooLoggerInterface; use Buckaroo\Magento2\Model\Config\Source\Business; +use Buckaroo\Magento2\Service\CheckPaymentType; +use Buckaroo\Magento2\Model\ConfigProvider\Account; +use Buckaroo\Magento2\Model\ConfigProvider\Method\AbstractConfigProvider; +use Buckaroo\Magento2\Model\ConfigProvider\Factory; +use Buckaroo\Magento2\Model\GroupTransaction; +use Magento\Checkout\Model\ConfigProviderInterface; +use Magento\Checkout\Model\Session as CheckoutSession; +use Magento\Config\Model\Config\ScopeDefiner; use Magento\Customer\Api\CustomerRepositoryInterface; -use \Magento\Framework\App\Helper\AbstractHelper; +use Magento\Customer\Model\Group; +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Framework\App\Area; +use Magento\Framework\App\Helper\AbstractHelper; use Magento\Framework\App\Helper\Context; -use Buckaroo\Magento2\Model\ConfigProvider\Account; -use Buckaroo\Magento2\Model\ConfigProvider\Method\Factory; -use Buckaroo\Magento2\Helper\PaymentGroupTransaction; +use Magento\Framework\App\State; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\HTTP\Header; +use Magento\Framework\Serialize\Serializer\Json; +use Magento\Quote\Api\Data\CartInterface; +use Magento\Quote\Model\Quote; +use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\ScopeInterface; -use Buckaroo\Magento2\Logging\Log; use Magento\Store\Model\StoreManagerInterface; -use Magento\Framework\App\State; -use Magento\Customer\Model\Session; -use Magento\Customer\Model\Group; -use Magento\Framework\App\Area; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) + */ class Data extends AbstractHelper { - const MODE_INACTIVE = 0; - const MODE_TEST = 1; - const MODE_LIVE = 2; + public const MODE_INACTIVE = 0; + public const MODE_TEST = 1; + public const MODE_LIVE = 2; - const M2_ORDER_STATE_PENDING = 'pending'; + public const M2_ORDER_STATE_PENDING = 'pending'; + + /** + * @var Account + */ + public $configProviderAccount; + + /** + * @var Factory + */ + public $configProviderMethodFactory; + + /** + * @var CheckPaymentType + */ + public $checkPaymentType; /** * Buckaroo_Magento2 status codes @@ -68,73 +100,101 @@ class Data extends AbstractHelper 'BUCKAROO_MAGENTO2_ORDER_FAILED' => 11014, ]; + /** + * @var array + */ protected $debugConfig = []; /** - * @var Account + * @var Header */ - public $configProviderAccount; + protected $httpHeader; /** - * @var Factory + * @var CheckoutSession */ - public $configProviderMethodFactory; + protected $checkoutSession; /** - * @var \Magento\Framework\HTTP\Header + * @var PaymentGroupTransaction */ - protected $httpHeader; - - protected $_checkoutSession; - protected $groupTransaction; - protected $logger; + /** + * @var BuckarooLoggerInterface + */ + protected BuckarooLoggerInterface $logger; + /** + * @var CustomerRepositoryInterface + */ protected $customerRepository; - private $staticCache = []; + /** + * @var Json + */ + protected $json; - /** @var StoreManagerInterface */ + /** + * @var StoreManagerInterface + */ private $storeManager; + /** + * @var ScopeDefiner + */ private $scopeDefiner; /** - * @var \Magento\Framework\Serialize\Serializer\Json + * @var State */ - protected $json; - private $state; + + /** + * @var CustomerSession + */ private $customerSession; /** * @param Context $context * @param Account $configProviderAccount * @param Factory $configProviderMethodFactory + * @param Header $httpHeader + * @param CheckoutSession $checkoutSession + * @param PaymentGroupTransaction $groupTransaction + * @param BuckarooLoggerInterface $logger + * @param CustomerRepositoryInterface $customerRepository + * @param StoreManagerInterface $storeManager + * @param ScopeDefiner $scopeDefiner + * @param Json $json + * @param State $state + * @param CustomerSession $customerSession + * @param CheckPaymentType $checkPaymentType + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( Context $context, Account $configProviderAccount, Factory $configProviderMethodFactory, - \Magento\Framework\HTTP\Header $httpHeader, - \Magento\Checkout\Model\Session $checkoutSession, + Header $httpHeader, + CheckoutSession $checkoutSession, PaymentGroupTransaction $groupTransaction, - Log $logger, + BuckarooLoggerInterface $logger, CustomerRepositoryInterface $customerRepository, StoreManagerInterface $storeManager, - \Magento\Config\Model\Config\ScopeDefiner $scopeDefiner, - \Magento\Framework\Serialize\Serializer\Json $json, + ScopeDefiner $scopeDefiner, + Json $json, State $state, - Session $customerSession + CustomerSession $customerSession, + CheckPaymentType $checkPaymentType ) { parent::__construct($context); $this->configProviderAccount = $configProviderAccount; $this->configProviderMethodFactory = $configProviderMethodFactory; $this->httpHeader = $httpHeader; - $this->_checkoutSession = $checkoutSession; - $this->groupTransaction = $groupTransaction; + $this->checkoutSession = $checkoutSession; + $this->groupTransaction = $groupTransaction; $this->logger = $logger; $this->customerRepository = $customerRepository; $this->storeManager = $storeManager; @@ -142,16 +202,16 @@ public function __construct( $this->json = $json; $this->state = $state; $this->customerSession = $customerSession; + $this->checkPaymentType = $checkPaymentType; } /** * Return the requested status $code, or null if not found * - * @param $code - * + * @param string $code * @return int|null */ - public function getStatusCode($code) + public function getStatusCode(string $code): ?int { if (isset($this->statusCodes[$code])) { return $this->statusCodes[$code]; @@ -162,9 +222,8 @@ public function getStatusCode($code) /** * Return the requested status key with the value, or null if not found * - * @param int $value - * - * @return mixed|null + * @param int|string $value + * @return false|int|string|null */ public function getStatusByValue($value) { @@ -180,19 +239,20 @@ public function getStatusByValue($value) * * @return array */ - public function getStatusCodes() + public function getStatusCodes(): array { return $this->statusCodes; } /** - * @param array $array - * @param array $rawInfo - * @param string $keyPrefix + * Returns the additional transaction information * + * @param array $array + * @param array $rawInfo + * @param string $keyPrefix * @return array */ - public function getTransactionAdditionalInfo(array $array, $rawInfo = [], $keyPrefix = '') + public function getTransactionAdditionalInfo(array $array, array $rawInfo = [], string $keyPrefix = ''): array { foreach ($array as $key => $value) { if (in_array($key, ['brq_websitekey', 'brq_signature', 'brq_payer_hash'])) { @@ -216,21 +276,24 @@ public function getTransactionAdditionalInfo(array $array, $rawInfo = [], $keyPr } /** - * @param null|string $paymentMethod + * Get the active mode for the given payment method and store. + * + * @param string|null $paymentMethod + * @param string|int|null $store + * @return mixed * - * @return int - * @throws \Buckaroo\Magento2\Exception + * @throws BuckarooException */ - public function getMode($paymentMethod = null, $store = null) + public function getMode(string $paymentMethod = null, $store = null): int { - $baseMode = $this->configProviderAccount->getActive(); + $baseMode = $this->configProviderAccount->getActive(); if (!$paymentMethod || !$baseMode) { return $baseMode; } /** - * @var \Buckaroo\Magento2\Model\ConfigProvider\Method\AbstractConfigProvider $configProvider + * @var AbstractConfigProvider $configProvider */ $configProvider = $this->configProviderMethodFactory->get($paymentMethod); if ($store === null) { @@ -245,141 +308,115 @@ public function getMode($paymentMethod = null, $store = null) /** * Return if browser is in mobile mode * - * @return array + * @return bool */ - public function isMobile() + public function isMobile(): bool { $userAgent = $this->httpHeader->getHttpUserAgent(); return preg_match( - '/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i',$userAgent)||preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', - substr($userAgent,0,4) + '/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i', + $userAgent + ) || preg_match( + '/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', + substr($userAgent, 0, 4) ); } - public function getOriginalTransactionKey($orderId) + /** + * Get original transaction key + * + * @param string|int $orderId + * @return string|null + */ + public function getOriginalTransactionKey($orderId): ?string { return $this->groupTransaction->getGroupTransactionOriginalTransactionKey($orderId); } + /** + * Check if the transaction is part of a group transaction + * + * @return bool + */ + public function isGroupTransaction(): bool + { + return $this->groupTransaction->isGroupTransaction($this->getOrderId()); + } + + /** + * Retrieve the reserved order ID for the current quote + * + * If the order ID is not yet reserved, reserve it now and save the quote. + * + * @return string + * + * @throws LocalizedException + * @throws NoSuchEntityException + */ public function getOrderId() { - $orderId = $this->_checkoutSession->getQuote()->getReservedOrderId(); + $orderId = $this->checkoutSession->getQuote()->getReservedOrderId(); if (!$orderId) { - $orderId = $this->_checkoutSession->getQuote()->reserveOrderId()->getReservedOrderId(); - $this->_checkoutSession->getQuote()->save(); + $orderId = $this->checkoutSession->getQuote()->reserveOrderId()->getReservedOrderId(); + $this->checkoutSession->getQuote()->save(); } return $orderId; } - public function isGroupTransaction() + /** + * Returns the current quote object. + * + * @return CartInterface|Quote + * @throws LocalizedException + * @throws NoSuchEntityException + */ + public function getQuote() { - if ($this->groupTransaction->isGroupTransaction($orderId = $this->getOrderId())) { - return true; - } - return false; + return $this->checkoutSession->getQuote(); } /** * Get current store * - * @return \Magento\Store\Api\Data\StoreInterface|null + * @return StoreInterface|null */ - public function getStore() + public function getStore(): ?StoreInterface { try { return $this->storeManager->getStore(); - } - catch (\Exception $e) { - $this->logger->addDebug(__METHOD__.(string)$e); + } catch (\Exception $e) { + $this->logger->addError( + '[Helper] | [Helper] | [' . __METHOD__ . ':' . __LINE__ . '] - Get Store | [ERROR]: ' . $e->getMessage() + ); return null; } } - public function getConfigCardSort() - { - $configValue = $this->scopeConfig->getValue( - 'payment/buckaroo_magento2_creditcard/sorted_issuers', - $this->scopeDefiner->getScope(), - ($this->scopeDefiner->getScope() == ScopeInterface::SCOPE_WEBSITES) ? $this->storeManager->getStore() : null - ); - - return $configValue; - } - + /** + * Retrieve the sort order for the available gift card types + * + * @return mixed + * @throws NoSuchEntityException + */ public function getConfigGiftCardsSort() { - $configValue = $this->scopeConfig->getValue( + return $this->scopeConfig->getValue( 'payment/buckaroo_magento2_giftcards/sorted_giftcards', $this->scopeDefiner->getScope(), - ($this->scopeDefiner->getScope() == ScopeInterface::SCOPE_WEBSITES) ? $this->storeManager->getStore() : null + ($this->scopeDefiner->getScope() == ScopeInterface::SCOPE_WEBSITES) ? + $this->storeManager->getStore() : + null ); - - return $configValue; } /** - * try to fetch customer details for PPE method in admin area + * Check if two amounts are equal within a reasonable margin of error. * - * @return array + * @param float $amount1 + * @param float $amount2 + * @return bool */ - //phpcs:ignore:Generic.Metrics.NestingLevel - public function getPPeCustomerDetails() - { - $this->logger->addDebug(__METHOD__ . '|1|' . var_export($this->_getRequest()->getParams(), true)); - if (($customerId = $this->_getRequest()->getParam('customer_id')) && ((int)$customerId > 0)) { - $this->logger->addDebug(__METHOD__ . '|5|'); - if (!isset($this->staticCache['getPPeCustomerDetails']) - && ($customer = $this->customerRepository->getById((int)$customerId)) - ) { - $this->logger->addDebug(__METHOD__ . '|15|'); - $billingAddress = null; - if ($addresses = $customer->getAddresses()) { - foreach ($addresses as $address) { - if ($address->isDefaultBilling()) { - $billingAddress = $address; - break; - } - } - } - $this->logger->addDebug(var_export([$customer->getEmail()], true)); - $this->staticCache['getPPeCustomerDetails'] = [ - 'email' => $customer->getEmail(), - 'firstName' => $billingAddress ? $billingAddress->getFirstName() : '', - 'lastName' => $billingAddress ? $billingAddress->getLastName() : '', - 'middleName' => $billingAddress ? $billingAddress->getMiddlename() : '', - ]; - } - } - - if ($order = $this->_getRequest()->getParam('order')) { - if (isset($order['billing_address'])) { - $this->logger->addDebug(__METHOD__ . '|30|'); - $this->staticCache['getPPeCustomerDetails'] = [ - 'email' => !empty($this->staticCache['getPPeCustomerDetails']['email']) ? - $this->staticCache['getPPeCustomerDetails']['email'] : '', - 'firstName' => $order['billing_address']['firstname'], - 'lastName' => $order['billing_address']['lastname'], - 'middleName' => $order['billing_address']['middlename'], - ]; - } - } - - if (($payment = $this->_getRequest()->getParam('payment')) - && ($payment['method'] == 'buckaroo_magento2_payperemail') - ) { - $this->logger->addDebug(__METHOD__ . '|40|'); - $this->staticCache['getPPeCustomerDetails'] = [ - 'email' => $payment['customer_email'], - 'firstName' => $payment['customer_billingFirstName'], - 'lastName' => $payment['customer_billingLastName'], - 'middleName' => $payment['customer_billingMiddleName'], - ]; - } - - return $this->staticCache['getPPeCustomerDetails'] ?? null; - } - - public function areEqualAmounts($amount1, $amount2) + public function areEqualAmounts($amount1, $amount2): bool { if ($amount2 == 0) { return $amount1 == $amount2; @@ -388,36 +425,31 @@ public function areEqualAmounts($amount1, $amount2) } } - public function getRestoreQuoteLastOrder() - { - return $this->_checkoutSession->getRestoreQuoteLastOrder(); - } - - public function setRestoreQuoteLastOrder($value) - { - return $this->_checkoutSession->setRestoreQuoteLastOrder($value); - } - - public function getQuote() - { - return $this->_checkoutSession->getQuote(); - } - - public function addDebug($messages) - { - $this->logger->addDebug($messages); - } - + /** + * Returns the current checkout session object. + * + * @return CheckoutSession + */ public function getCheckoutSession() { - return $this->_checkoutSession; + return $this->checkoutSession; } + /** + * Returns an instance of the JSON object. + * + * @return Json + */ public function getJson() { return $this->json; } + /** + * Get payment methods + * + * @return array[] + */ public function getPaymentMethodsList() { return [ @@ -430,17 +462,15 @@ public function getPaymentMethodsList() ['value' => 'capayablein3', 'label' => __('In3')], ['value' => 'creditcard', 'label' => __('Credit and debit cards')], ['value' => 'creditcards', 'label' => __('Credit and debit cards (Client sided)')], - ['value' => 'emandate', 'label' => __('Digital Debit Authorization')], ['value' => 'eps', 'label' => __('EPS')], ['value' => 'giftcards', 'label' => __('Giftcards')], ['value' => 'giropay', 'label' => __('Giropay')], ['value' => 'ideal', 'label' => __('iDEAL')], - ['value' => 'idealprocessing', 'label' => __('iDEAL Processing')], ['value' => 'kbc', 'label' => __('KBC')], ['value' => 'klarna', 'label' => __('Klarna Pay later (pay)')], ['value' => 'klarnain', 'label' => __('Klarna Slice it')], ['value' => 'klarnakp', 'label' => __('Klarna Pay later (authorize/capture)')], - ['value' => 'mrcash', 'label' => __('Bancontact / Mister Cash')], + ['value' => 'mrcash', 'label' => __('Bancontact')], ['value' => 'p24', 'label' => __('Przelewy24')], ['value' => 'payconiq', 'label' => __('Payconiq')], ['value' => 'paylink', 'label' => __('PayLink')], @@ -456,89 +486,119 @@ public function getPaymentMethodsList() ]; } + /** + * Check if customer group is allowed for the payment method + * + * @param string $paymentMethod + * @param bool $forceB2C + * @return bool + * @throws BuckarooException + * @throws LocalizedException + */ public function checkCustomerGroup(string $paymentMethod, bool $forceB2C = false): bool { - if ($this->isBuckarooMethod($paymentMethod)) { - $paymentMethodCode = $this->getBuckarooMethod($paymentMethod); - $configProvider = $this->configProviderMethodFactory->get($paymentMethodCode); - $configCustomerGroup = $configProvider->getSpecificCustomerGroup(); - - if (!$forceB2C - && ( - ($paymentMethodCode == 'billink') - || ( - (($paymentMethodCode == 'afterpay') || ($paymentMethodCode == 'afterpay2')) - && ($configProvider->getBusiness() == Business::BUSINESS_B2B) - ) - || ( - ($paymentMethodCode == 'payperemail') && ($configProvider->getEnabledB2B()) - ) - ) - ) { - $configCustomerGroup = $configProvider->getSpecificCustomerGroupB2B(); + if (!$this->checkPaymentType->isBuckarooMethod($paymentMethod)) { + return true; + } - } + $paymentMethodCode = $this->getBuckarooMethod($paymentMethod); + $configProvider = $this->configProviderMethodFactory->get($paymentMethodCode); - if ($configCustomerGroup === null) { - return true; - } + $configCustomerGroup = $this->determineCustomerGroup($paymentMethodCode, $configProvider, $forceB2C); - if ($configCustomerGroup == -1) { - return false; - } + if ($configCustomerGroup === null || $configCustomerGroup == Group::CUST_GROUP_ALL) { + return true; + } - if ($configCustomerGroup == Group::CUST_GROUP_ALL) { - return true; - } + if ($configCustomerGroup == -1) { + return false; + } - $configCustomerGroupArr = explode(',', $configCustomerGroup); + $configCustomerGroupArr = explode(',', $configCustomerGroup); - if ($this->state->getAreaCode() == Area::AREA_ADMINHTML) { - return $this->checkCustomerGroupAdminArea($configCustomerGroupArr); - } else { - return $this->checkCustomerGroupFrontArea($configCustomerGroupArr); - } + return $this->checkCustomerGroupArea($configCustomerGroupArr); + } + + /** + * Determine the appropriate customer group configuration. + * + * @param string $paymentMethodCode + * @param ConfigProviderInterface $configProvider + * @param bool $forceB2C + * @return int|null + */ + private function determineCustomerGroup( + string $paymentMethodCode, + ConfigProviderInterface $configProvider, + bool $forceB2C + ): ?int { + if (!$forceB2C && $this->isSpecialPaymentMethod($paymentMethodCode, $configProvider)) { + return $configProvider->getSpecificCustomerGroupB2B(); } - return true; + return $configProvider->getSpecificCustomerGroup(); } - private function checkCustomerGroupAdminArea(array $configCustomerGroupArr): bool + /** + * Check if the payment method is one of the special cases. + * + * @param string $paymentMethodCode + * @param ConfigProviderInterface $configProvider + * @return bool + */ + private function isSpecialPaymentMethod(string $paymentMethodCode, ConfigProviderInterface $configProvider): bool { - if (($customerId = $this->_getRequest()->getParam('customer_id')) && ($customerId > 0)) { - if ($customer = $this->customerRepository->getById($customerId)) { - if ($customerGroup = $customer->getGroupId()) { - return in_array($customerGroup, $configCustomerGroupArr); - } - } - } - return true; + return ($paymentMethodCode == 'billink') + || (($paymentMethodCode == 'afterpay' || $paymentMethodCode == 'afterpay2') + && $configProvider->getBusiness() == Business::BUSINESS_B2B) + || ($paymentMethodCode == 'payperemail' && $configProvider->isEnabledB2B()); } - private function checkCustomerGroupFrontArea(array $configCustomerGroupArr): bool + /** + * Check if the customer group is allowed based on the area (admin or front). + * + * @param array $configCustomerGroupArr + * @return bool + * @throws LocalizedException + */ + private function checkCustomerGroupArea(array $configCustomerGroupArr): bool { - if ($this->customerSession->isLoggedIn()) { - if ($customerGroup = $this->customerSession->getCustomer()->getGroupId()) { - return in_array($customerGroup, $configCustomerGroupArr); - } + if ($this->state->getAreaCode() == Area::AREA_ADMINHTML) { + return $this->checkCustomerGroupAdminArea($configCustomerGroupArr); } else { - if (!in_array(Group::NOT_LOGGED_IN_ID, $configCustomerGroupArr)) { - return false; - } + return $this->checkCustomerGroupFrontArea($configCustomerGroupArr); } - return true; } + /** + * Checks if a given payment method is a Buckaroo method + * + * @param string $paymentMethod + * @return bool + */ public function isBuckarooMethod(string $paymentMethod): bool { return strpos($paymentMethod, 'buckaroo_magento2_') !== false; } + /** + * Extracts the Buckaroo payment method code from the full payment method code. + * + * @param string $paymentMethod + * @return string + */ public function getBuckarooMethod(string $paymentMethod): string { return strtolower(str_replace('buckaroo_magento2_', '', $paymentMethod)); } + /** + * Get order status by state + * + * @param $order + * @param $orderState + * @return mixed + */ public function getOrderStatusByState($order, $orderState) { $orderStatus = $order->getPayment()->getMethodInstance()->getConfigData('order_status'); @@ -550,4 +610,43 @@ public function getOrderStatusByState($order, $orderState) return $orderStatus; } + + /** + * Checks if the customer group in the admin area is allowed to use the Buckaroo payment method. + * + * @param array $configCustomerGroupArr + * @return bool + * @throws LocalizedException + * @throws NoSuchEntityException + */ + private function checkCustomerGroupAdminArea(array $configCustomerGroupArr): bool + { + if (($customerId = $this->_getRequest()->getParam('customer_id')) && ($customerId > 0) + && ($customer = $this->customerRepository->getById($customerId)) + && $customerGroup = $customer->getGroupId()) { + return in_array($customerGroup, $configCustomerGroupArr); + } + + return true; + } + + /** + * Check if the current logged in customer's group matches with the allowed customer groups + * + * @param array $configCustomerGroupArr + * @return bool + */ + private function checkCustomerGroupFrontArea(array $configCustomerGroupArr): bool + { + if ($this->customerSession->isLoggedIn()) { + if ($customerGroup = $this->customerSession->getCustomer()->getGroupId()) { + return in_array($customerGroup, $configCustomerGroupArr); + } + } else { + if (!in_array(Group::NOT_LOGGED_IN_ID, $configCustomerGroupArr)) { + return false; + } + } + return true; + } } diff --git a/Helper/PaymentFee.php b/Helper/PaymentFee.php index b6e266ffa..5a18c946c 100644 --- a/Helper/PaymentFee.php +++ b/Helper/PaymentFee.php @@ -1,13 +1,12 @@ displaySalesBothPrices(); $displayIncludeTaxPrice = $this->displaySalesIncludeTaxPrice(); - } elseif ($dataObject instanceof \Magento\Quote\Model\Quote\Address\Total) { + } elseif ($dataObject instanceof Total) { $displayBothPrices = $this->displayCartBothPrices(); $displayIncludeTaxPrice = $this->displayCartIncludeTaxPrice(); } @@ -120,14 +149,14 @@ public function getTotals($dataObject) */ $this->addTotalToTotals( $totals, - ($dataObject instanceof \Magento\Sales\Model\Order\Creditmemo) ? 'buckaroo_fee' : 'buckaroo_fee_incl', + ($dataObject instanceof Creditmemo) ? 'buckaroo_fee' : 'buckaroo_fee_incl', $dataObject->getBuckarooFee() + $dataObject->getBuckarooFeeTaxAmount(), $dataObject->getBaseBuckarooFee() + $dataObject->getBuckarooFeeBaseTaxAmount(), $label . __(' (Incl. Tax)'), - ($dataObject instanceof \Magento\Sales\Model\Order\Creditmemo) ? 'buckaroo_fee' : false, + ($dataObject instanceof Creditmemo) ? 'buckaroo_fee' : false, false, [ - 'incl_tax' => true, + 'incl_tax' => true, 'fee_with_tax' => $dataObject->getBuckarooFee() + $dataObject->getBuckarooFeeTaxAmount() ] ); @@ -141,10 +170,10 @@ public function getTotals($dataObject) $dataObject->getBuckarooFee(), $dataObject->getBaseBuckarooFee(), $label, - ($dataObject instanceof \Magento\Sales\Model\Order\Creditmemo) ? 'buckaroo_fee' : false, + ($dataObject instanceof Creditmemo) ? 'buckaroo_fee' : false, false, [ - 'incl_tax' => false, + 'incl_tax' => false, 'fee_with_tax' => $dataObject->getBuckarooFee() + $dataObject->getBuckarooFeeTaxAmount() ] ); @@ -156,136 +185,86 @@ public function getTotals($dataObject) /** * @noinspection PhpUndefinedMethodInspection */ - $this->buckarooFee = $dataObject->getBuckarooFee(); + $this->buckarooFee = $dataObject->getBuckarooFee(); /** * @noinspection PhpUndefinedMethodInspection */ $this->buckarooFeeTax = $dataObject->getBuckarooFeeTaxAmount(); return $totals; } - public function addAlreadyPayedTotals($dataObject, &$totals) - { - $order_id = $this->getOrderIncrementId($dataObject); - $alreadyPayed = $this->groupTransaction->getAlreadyPaid($order_id); - - if (!$dataObject instanceof \Magento\Sales\Model\Order\Creditmemo && $alreadyPayed > 0) { - unset($totals['buckaroo_fee']); - $this->addTotalToTotals( - $totals, - 'buckaroo_already_paid', - $alreadyPayed, - $alreadyPayed, - __('Paid with Giftcard / Voucher') - ); - return; - } - - if ($order_id !== null && $alreadyPayed > 0) { - $requestParams = $this->_request->getParams(); - $items = $this->groupTransaction->getGroupTransactionItems($order_id); - $giftcards = []; - - if (isset($requestParams['creditmemo']['buckaroo_already_paid'])) { - foreach ($requestParams['creditmemo']['buckaroo_already_paid'] as $giftcardKey => $value) { - $transaction = explode('|', $giftcardKey); - $giftcards[$transaction[1]] = $value; - } - } - foreach ($items as $key => $giftcard) { - $foundGiftcard = $this->giftcardCollection->getItemByColumnValue( - 'servicecode', - $giftcard['servicecode'] - ); - - $label = __('Paid with Voucher'); - if ($foundGiftcard) { - $label = __('Paid with ' . $foundGiftcard['label']); - } - - $refundedAlreadyPaidSaved = $giftcard->getRefundedAmount() ?? 0; - $amountValue = $giftcard['amount']; - $amountBaseValue = $giftcard['amount']; - - if (!empty($foundGiftcard['is_partial_refundable'])) { - $residual = floatval($giftcard['amount']) - floatval($refundedAlreadyPaidSaved); - if ( - array_key_exists($foundGiftcard['servicecode'], $giftcards) - && floatval($giftcards[$foundGiftcard['servicecode']]) <= $residual - ) { - $amountValue = floatval($giftcards[$foundGiftcard['servicecode']]); - $amountBaseValue = floatval($giftcards[$foundGiftcard['servicecode']]); - } else { - $amountBaseValue = $residual; - $amountValue = $residual; - } - } else { - if ((!empty(floatval($refundedAlreadyPaidSaved)) - && floatval($refundedAlreadyPaidSaved) === floatval($amountValue))) { - $amountBaseValue = 0; - $amountValue = 0; - } elseif (is_array($foundGiftcard) && array_key_exists($foundGiftcard['servicecode'], $giftcards)) { - if (empty(floatval($giftcards[$foundGiftcard['servicecode']]))) { - $amountBaseValue = 0; - $amountValue = 0; - } - } - } + /** + * Check ability to display both prices for buckaroo fee in backend sales + * + * @param Store|int|null $store + * @return bool + */ + public function displaySalesBothPrices($store = null) + { + /** + * @noinspection PhpUndefinedMethodInspection + */ + $configValue = $this->configProviderBuckarooFee->getPriceDisplaySales($store); - $this->addTotalToTotals( - $totals, - 'buckaroo_already_paid', - -$amountValue, - -$amountBaseValue, - $label, - 'buckaroo_already_paid', - $giftcard['transaction_id'] . '|' . $giftcard['servicecode'] . '|' . $giftcard['amount'] - ); - } - } + return $configValue == DisplayType::DISPLAY_TYPE_BOTH; } /** - * Get order increment id from data object - * - * @param mixed $dataObject + * Check ability to display prices including tax for buckaroo fee in backend sales * - * @return string|null + * @param Store|int|null $store + * @return bool */ - public function getOrderIncrementId($dataObject) + public function displaySalesIncludeTaxPrice($store = null) { - if ($dataObject instanceof \Magento\Sales\Model\Order) { - return $dataObject->getIncrementId(); - } - if ( - $dataObject instanceof \Magento\Sales\Model\Order\Invoice - || $dataObject instanceof \Magento\Sales\Model\Order\Creditmemo - ) { - return $dataObject->getOrder()->getIncrementId(); - } + /** + * @noinspection PhpUndefinedMethodInspection + */ + $configValue = $this->configProviderBuckarooFee->getPriceDisplaySales($store); + + return $configValue == DisplayType::DISPLAY_TYPE_BOTH || + $configValue == DisplayType::DISPLAY_TYPE_INCLUDING_TAX; } + /** - * @return mixed + * Check ability to display both prices for buckaroo fee in shopping cart + * + * @param Store|int|null $store + * @return bool */ - public function getBuckarooFee() + public function displayCartBothPrices($store = null) { - return $this->buckarooFee; + /** + * @noinspection PhpUndefinedMethodInspection + */ + $configValue = $this->configProviderBuckarooFee->getPriceDisplayCart($store); + + return $configValue == DisplayType::DISPLAY_TYPE_BOTH; } /** - * @return mixed + * Check ability to display prices including tax for buckaroo fee in shopping cart + * + * @param Store|int|null $store + * @return bool */ - public function getBuckarooFeeTax() + public function displayCartIncludeTaxPrice($store = null) { - return $this->buckarooFeeTax; + /** + * @noinspection PhpUndefinedMethodInspection + */ + $configValue = $this->configProviderBuckarooFee->getPriceDisplayCart($store); + + return $configValue == DisplayType::DISPLAY_TYPE_BOTH || + $configValue == DisplayType::DISPLAY_TYPE_INCLUDING_TAX; } /** * Return the correct label for the payment method * - * @param $dataObject - * + * @param Order|Invoice|Creditmemo|Total|DataObject|string|bool $dataObject * @return string + * @throws Exception */ public function getBuckarooPaymentFeeLabel($dataObject) { @@ -295,11 +274,10 @@ public function getBuckarooPaymentFeeLabel($dataObject) /** * Parse data object for payment method */ - if ($dataObject instanceof \Magento\Sales\Model\Order) { + if ($dataObject instanceof Order) { $method = $dataObject->getPayment()->getMethod(); - } elseif ( - $dataObject instanceof \Magento\Sales\Model\Order\Invoice - || $dataObject instanceof \Magento\Sales\Model\Order\Creditmemo + } elseif ($dataObject instanceof Invoice + || $dataObject instanceof Creditmemo ) { $method = $dataObject->getOrder()->getPayment()->getMethod(); } elseif (is_string($dataObject)) { @@ -334,196 +312,310 @@ public function getBuckarooPaymentFeeLabel($dataObject) } /** - * @param \Magento\Framework\DataObject $dataObject + * Add total into array totals * - * @return array + * @param array $totals + * @param string $code + * @param float $value + * @param float $baseValue + * @param string $label + * @return void */ - public function getBuckarooPaymentFeeTotal($dataObject) + protected function addTotalToTotals( + &$totals, + $code, + $value, + $baseValue, + $label, + $blockName = false, + $transactionId = false, + $extraInfo = [] + ) { + if ($value == 0 && $baseValue == 0) { + return; + } + $total = [ + 'code' => $code, + 'value' => $value, + 'base_value' => $baseValue, + 'label' => $label, + 'extra_info' => $extraInfo + ]; + if ($blockName) { + $total['block_name'] = $blockName; + } + if ($transactionId) { + $total['transaction_id'] = $transactionId; + } + $totals[] = $total; + } + + /** + * Get Buckaroo fee + * + * @return mixed + */ + public function getBuckarooFee() { - $totals = []; + return $this->buckarooFee; + } - /** - * @noinspection PhpUndefinedMethodInspection - */ + /** + * Add already paid to totals + * + * @param DataObject $dataObject + * @param array $totals + * @return void + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + public function addAlreadyPayedTotals($dataObject, &$totals) + { + $orderId = $this->getOrderIncrementId($dataObject); + $alreadyPayed = $this->groupTransaction->getAlreadyPaid($orderId); + + if ($this->isAlreadyPayedNotCreditmemo($dataObject, $alreadyPayed)) { + $this->handleAlreadyPayedNotCreditmemo($totals, $alreadyPayed); + return; + } + + if ($orderId !== null && $alreadyPayed > 0) { + $this->processGiftcards($orderId, $totals); + } + } + + /** + * Determine if the function should return early. + */ + private function isAlreadyPayedNotCreditmemo($dataObject, $alreadyPayed): bool + { + return !$dataObject instanceof Creditmemo && $alreadyPayed > 0; + } + + /** + * Handle the early return logic. + */ + private function handleAlreadyPayedNotCreditmemo(&$totals, $alreadyPayed) + { + unset($totals['buckaroo_fee']); $this->addTotalToTotals( $totals, - 'buckaroo_fee', - $dataObject->getBuckarooFee() + $dataObject->getBuckarooFeeTaxAmount(), - $dataObject->getBaseBuckarooFee() + $dataObject->getBuckarooFeeBaseTaxAmount(), - $this->getBuckarooPaymentFeeLabel($dataObject) + 'buckaroo_already_paid', + $alreadyPayed, + $alreadyPayed, + __('Paid with Giftcard / Voucher') ); + } - return $totals; + /** + * Process giftcards and update totals. + */ + private function processGiftcards($orderId, &$totals) + { + $requestParams = $this->_request->getParams(); + $items = $this->groupTransaction->getGroupTransactionItems($orderId); + $giftcards = $this->extractGiftcardsFromRequest($requestParams); + + foreach ($items as $giftcard) { + $this->updateTotalsWithGiftcard($giftcard, $giftcards, $totals); + } } /** - * Check if the fee calculation has to be done with taxes - * - * @param \Magento\Store\Model\Store|int|null $store - * - * @return bool + * Extract giftcards from the request. */ - public function buckarooPaymentCalculationInclTax($store = null) + private function extractGiftcardsFromRequest($requestParams): array { - /** - * @noinspection PhpUndefinedMethodInspection - */ - $configValue = $this->configProviderBuckarooFee->getPaymentFeeTax($store); + $giftcards = []; - return $configValue == DisplayType::DISPLAY_TYPE_INCLUDING_TAX; + if (isset($requestParams['creditmemo']['buckaroo_already_paid'])) { + foreach ($requestParams['creditmemo']['buckaroo_already_paid'] as $giftcardKey => $value) { + $transaction = explode('|', $giftcardKey); + $giftcards[$transaction[1]] = $value; + } + } + + return $giftcards; } /** - * Check if the fee calculation has to be done without taxes - * - * @param \Magento\Store\Model\Store|int|null $store - * - * @return bool + * Update totals based on a single giftcard. */ - public function buckarooPaymentFeeCalculationExclTax($store = null) + private function updateTotalsWithGiftcard($giftcard, $giftcards, &$totals) { - /** - * @noinspection PhpUndefinedMethodInspection - */ - $configValue = $this->configProviderBuckarooFee->getPaymentFeeTax($store); + $foundGiftcard = $this->giftcardCollection->getItemByColumnValue('servicecode', $giftcard['servicecode']); - return $configValue == DisplayType::DISPLAY_TYPE_EXCLUDING_TAX; + $label = $this->getGiftcardLabel($foundGiftcard); + + list($amountValue, $amountBaseValue) = $this->calculateAmountValues($giftcard, $giftcards, $foundGiftcard); + + $this->addTotalToTotals( + $totals, + 'buckaroo_already_paid', + -$amountValue, + -$amountBaseValue, + $label, + 'buckaroo_already_paid', + $giftcard['transaction_id'] . '|' . $giftcard['servicecode'] . '|' . $giftcard['amount'] + ); + } + + private function getGiftcardLabel($foundGiftcard) { + if ($foundGiftcard) { + return __('Paid with ' . $foundGiftcard['label']); + } + return __('Paid with Voucher'); + } + + private function calculateAmountValues($giftcard, $giftcards, $foundGiftcard) + { + $refundedAlreadyPaidSaved = $giftcard->getRefundedAmount() ?? 0; + $amountValue = $giftcard['amount']; + $amountBaseValue = $giftcard['amount']; + + if (!empty($foundGiftcard['is_partial_refundable'])) { + $residual = floatval($giftcard['amount']) - floatval($refundedAlreadyPaidSaved); + if (array_key_exists($foundGiftcard['servicecode'], $giftcards) + && floatval($giftcards[$foundGiftcard['servicecode']]) <= $residual + ) { + $amountValue = floatval($giftcards[$foundGiftcard['servicecode']]); + $amountBaseValue = floatval($giftcards[$foundGiftcard['servicecode']]); + } else { + $amountBaseValue = $residual; + $amountValue = $residual; + } + } else { + if (!empty(floatval($refundedAlreadyPaidSaved)) + && floatval($refundedAlreadyPaidSaved) === floatval($amountValue) + ) { + $amountBaseValue = 0; + $amountValue = 0; + } elseif (is_array($foundGiftcard) && array_key_exists($foundGiftcard['servicecode'], $giftcards)) { + if (empty(floatval($giftcards[$foundGiftcard['servicecode']]))) { + $amountBaseValue = 0; + $amountValue = 0; + } + } + } + + return [$amountValue, $amountBaseValue]; } /** - * Check ability to display prices including tax for buckaroo fee in shopping cart + * Get order increment id from data object * - * @param \Magento\Store\Model\Store|int|null $store - * @return bool + * @param mixed $dataObject + * @return string|null */ - public function displayCartIncludeTaxPrice($store = null) + public function getOrderIncrementId($dataObject) { - /** - * @noinspection PhpUndefinedMethodInspection - */ - $configValue = $this->configProviderBuckarooFee->getPriceDisplayCart($store); + if ($dataObject instanceof Order) { + return $dataObject->getIncrementId(); + } + if ($dataObject instanceof Invoice + || $dataObject instanceof Creditmemo + ) { + return $dataObject->getOrder()->getIncrementId(); + } - return $configValue == DisplayType::DISPLAY_TYPE_BOTH || - $configValue == DisplayType::DISPLAY_TYPE_INCLUDING_TAX; + return null; } /** - * Check ability to display prices excluding tax for buckaroo fee in shopping cart + * Get buckaroo fee tax * - * @param \Magento\Store\Model\Store|int|null $store - * @return bool + * @return mixed */ - public function displayCartExcludeTaxPrice($store = null) + public function getBuckarooFeeTax() { + return $this->buckarooFeeTax; + } + + /** + * Add payment fee to total + * + * @param DataObject $dataObject + * @return array + */ + public function getBuckarooPaymentFeeTotal($dataObject) + { + $totals = []; + /** * @noinspection PhpUndefinedMethodInspection */ - $configValue = $this->configProviderBuckarooFee->getPriceDisplayCart($store); + $this->addTotalToTotals( + $totals, + 'buckaroo_fee', + $dataObject->getBuckarooFee() + $dataObject->getBuckarooFeeTaxAmount(), + $dataObject->getBaseBuckarooFee() + $dataObject->getBuckarooFeeBaseTaxAmount(), + $this->getBuckarooPaymentFeeLabel($dataObject) + ); - return $configValue == DisplayType::DISPLAY_TYPE_EXCLUDING_TAX; + return $totals; } /** - * Check ability to display both prices for buckaroo fee in shopping cart + * Check if the fee calculation has to be done with taxes * - * @param \Magento\Store\Model\Store|int|null $store + * @param Store|int|null $store * @return bool */ - public function displayCartBothPrices($store = null) + public function buckarooPaymentCalculationInclTax($store = null) { /** * @noinspection PhpUndefinedMethodInspection */ - $configValue = $this->configProviderBuckarooFee->getPriceDisplayCart($store); + $configValue = $this->configProviderBuckarooFee->getPaymentFeeTax($store); - return $configValue == DisplayType::DISPLAY_TYPE_BOTH; + return $configValue == DisplayType::DISPLAY_TYPE_INCLUDING_TAX; } /** - * Check ability to display prices including tax for buckaroo fee in backend sales + * Check if the fee calculation has to be done without taxes * - * @param \Magento\Store\Model\Store|int|null $store + * @param Store|int|null $store * @return bool */ - public function displaySalesIncludeTaxPrice($store = null) + public function buckarooPaymentFeeCalculationExclTax($store = null) { /** * @noinspection PhpUndefinedMethodInspection */ - $configValue = $this->configProviderBuckarooFee->getPriceDisplaySales($store); + $configValue = $this->configProviderBuckarooFee->getPaymentFeeTax($store); - return $configValue == DisplayType::DISPLAY_TYPE_BOTH || - $configValue == DisplayType::DISPLAY_TYPE_INCLUDING_TAX; + return $configValue == DisplayType::DISPLAY_TYPE_EXCLUDING_TAX; } /** - * Check ability to display prices excluding tax for buckaroo fee in backend sales + * Check ability to display prices excluding tax for buckaroo fee in shopping cart * - * @param \Magento\Store\Model\Store|int|null $store + * @param Store|int|null $store * @return bool */ - public function displaySalesExcludeTaxPrice($store = null) + public function displayCartExcludeTaxPrice($store = null) { /** * @noinspection PhpUndefinedMethodInspection */ - $configValue = $this->configProviderBuckarooFee->getPriceDisplaySales($store); + $configValue = $this->configProviderBuckarooFee->getPriceDisplayCart($store); return $configValue == DisplayType::DISPLAY_TYPE_EXCLUDING_TAX; } /** - * Check ability to display both prices for buckaroo fee in backend sales + * Check ability to display prices excluding tax for buckaroo fee in backend sales * - * @param \Magento\Store\Model\Store|int|null $store + * @param Store|int|null $store * @return bool */ - public function displaySalesBothPrices($store = null) + public function displaySalesExcludeTaxPrice($store = null) { /** * @noinspection PhpUndefinedMethodInspection */ $configValue = $this->configProviderBuckarooFee->getPriceDisplaySales($store); - return $configValue == DisplayType::DISPLAY_TYPE_BOTH; - } - - /** - * Add total into array totals - * - * @param array &$totals - * @param string $code - * @param float $value - * @param float $baseValue - * @param string $label - * @return void - */ - protected function addTotalToTotals( - &$totals, - $code, - $value, - $baseValue, - $label, - $block_name = false, - $transaction_id = false, - $extra_info = [] - ) { - if ($value == 0 && $baseValue == 0) { - return; - } - $total = [ - 'code' => $code, - 'value' => $value, - 'base_value' => $baseValue, - 'label' => $label, - 'extra_info' => $extra_info - ]; - if ($block_name) { - $total['block_name'] = $block_name; - } - if ($transaction_id) { - $total['transaction_id'] = $transaction_id; - } - $totals[] = $total; + return $configValue == DisplayType::DISPLAY_TYPE_EXCLUDING_TAX; } } diff --git a/Helper/PaymentGroupTransaction.php b/Helper/PaymentGroupTransaction.php index 4e2e1c21f..7a77ea0fe 100644 --- a/Helper/PaymentGroupTransaction.php +++ b/Helper/PaymentGroupTransaction.php @@ -1,13 +1,12 @@ groupTransactionFactory = $groupTransactionFactory; $this->dateTime = $dateTime; - $this->order = $order; - $this->transaction = $transaction; - $this->logging = $logging; + $this->logger = $logger; $this->grTrCollectionFactory = $grTrCollectionFactory; $this->resourceModel = $resourceModel; } + /** + * Saves a group transaction in the database. + * + * @param array $response + * @return mixed + */ public function saveGroupTransaction($response) { - $this->logging->addDebug(__METHOD__ . '|1|' . var_export($response, true)); - $groupTransaction = $this->groupTransactionFactory->create(); - $data['order_id'] = $response['Invoice']; - $data['transaction_id'] = $response['Key']; - $data['relatedtransaction'] = $response['RequiredAction']['PayRemainderDetails']['GroupTransaction'] ?? null; - $data['servicecode'] = $response['ServiceCode']; - $data['currency'] = $response['Currency']; - $data['amount'] = $response['AmountDebit']; - $data['type'] = $response['RelatedTransactions'][0]['RelationType'] ?? null; - $data['status'] = $response['Status']['Code']['Code']; - $data['created_at'] = $this->dateTime->gmtDate(); + $this->logger->addDebug(sprintf( + '[GROUP_TRANSACTION] | [Helper] | [%s:%s] - Save group transaction in database | response: %s', + __METHOD__, + __LINE__, + var_export($response, true) + )); + + $groupTransaction = $this->groupTransactionFactory->create(); + $data['order_id'] = $response['Invoice']; + $data['transaction_id'] = $response['Key']; + $data['relatedtransaction'] = $response['RequiredAction']['PayRemainderDetails']['GroupTransaction'] ?? + $response['RelatedTransactions'][0]['RelatedTransactionKey'] ?? null; + $data['servicecode'] = $response['ServiceCode']; + $data['currency'] = $response['Currency']; + $data['amount'] = $response['AmountDebit']; + $data['type'] = $response['RelatedTransactions'][0]['RelationType'] ?? null; + $data['status'] = $response['Status']['Code']['Code']; + $data['created_at'] = $this->dateTime->gmtDate(); $groupTransaction->setData($data); return $groupTransaction->save(); } + /** + * Updates a group transaction in the database. + * + * @param array $item + * @return mixed + * @throws \Exception + */ public function updateGroupTransaction($item) { $groupTransaction = $this->groupTransactionFactory->create(); @@ -105,18 +128,43 @@ public function updateGroupTransaction($item) return $groupTransaction->save(); } - public function isGroupTransaction($order_id) + /** + * Check if is group transaction the order + * + * @param string|int $orderId + * @return bool + */ + public function isGroupTransaction($orderId) + { + $groupTransactions = $this->getGroupTransactionItems($orderId); + return is_array($groupTransactions) && count($groupTransactions) > 0; + } + + /** + * Check if is group transaction the order + * + * @param string|int $orderId + * @return bool + */ + public function isAnyGroupTransaction($orderId) { - return $this->getGroupTransactionItems($order_id); + $groupTransactions = $this->getAnyGroupTransactionItems($orderId); + return is_array($groupTransactions) && count($groupTransactions) > 0; } - public function getGroupTransactionItems($order_id) + /** + * Retrieves the group transaction items for a given order ID. + * + * @param string|int $orderId + * @return array + */ + public function getGroupTransactionItems($orderId) { $collection = $this->groupTransactionFactory->create() ->getCollection() ->addFieldToFilter( 'order_id', - ['eq' => $order_id] + ['eq' => $orderId] ) ->addFieldToFilter( 'status', @@ -124,94 +172,146 @@ public function getGroupTransactionItems($order_id) ); $items = array_values($collection->getItems()); - return array_filter($items, function($item) { - return $item['amount'] - (float)$item['refunded_amount'] > 0; + return array_filter($items, function ($item) { + return (float)$item['amount'] - (float)$item['refunded_amount'] > 0; }); } /** - * Get already paid amount from db + * Retrieves the group transaction items for a given order ID. * - * @param string|null $order_id + * @param string|int $orderId + * @return array + */ + public function getAnyGroupTransactionItems($orderId) + { + $collection = $this->groupTransactionFactory->create() + ->getCollection() + ->addFieldToFilter( + 'order_id', + ['eq' => $orderId] + ); + $items = array_values($collection->getItems()); + + return array_filter($items, function ($item) { + return (float)$item['amount'] - (float)$item['refunded_amount'] > 0; + }); + } + + /** + * Get already paid amount from db * + * @param string|int|null $orderId * @return float */ - public function getAlreadyPaid($order_id) + public function getAlreadyPaid($orderId) { - if ($order_id === null) { + if ($orderId === null) { return 0; } - return $this->getGroupTransactionAmount($order_id); + return $this->getGroupTransactionAmount($orderId); } - public function getGroupTransactionAmount($order_id) + /** + * Calculates the total amount of group transactions for a given order ID. + * + * @param string|int $orderId + * @return float|int + */ + public function getGroupTransactionAmount($orderId) { $total = 0; - foreach ($this->getGroupTransactionItems($order_id) as $key => $value) { + foreach ($this->getGroupTransactionItems($orderId) as $value) { if ($value['status'] == '190') { - $total += $value['amount'] - (float)$value['refunded_amount']; + $total += (float)$value['amount'] - (float)$value['refunded_amount']; } } return $total; } - public function getGroupTransactionOriginalTransactionKey($order_id) + /** + * Get last transaction from group transaction filter by order + * + * @param string|int $orderId + * @return string|null + */ + public function getGroupTransactionOriginalTransactionKey($orderId): ?string { - if($order_id === null) { - return; + if ($orderId === null) { + return null; } $collection = $this->grTrCollectionFactory->create(); $groupTransaction = $collection ->addFieldToFilter( 'order_id', - ['eq' => $order_id] + ['eq' => $orderId] ) ->addFieldToFilter( 'status', ['eq' => '190'] - )->setOrder('entity_id','DESC') + )->setOrder('entity_id', 'DESC') ->getFirstItem(); - if (!$groupTransaction->isEmpty()) { - return $groupTransaction->getData('relatedtransaction'); - } - return; + if (!$groupTransaction->isEmpty()) { + return $groupTransaction->getData('relatedtransaction'); + } + + return null; } - public function getGroupTransactionItemsNotRefunded($order_id) + /** + * Retrieves the group transaction items that have not been refunded for a given order ID. + * + * @param string|int $orderId + * @return array + */ + public function getGroupTransactionItemsNotRefunded($orderId) { $collection = $this->groupTransactionFactory->create() ->getCollection() - ->addFieldToFilter('order_id', ['eq' => $order_id]) + ->addFieldToFilter('order_id', $orderId) + ->addFieldToFilter('status', '190') ->addFieldToFilter('refunded_amount', ['null' => true]); return array_values($collection->getItems()); } - - public function getGroupTransactionById($entity_id) + /** + * Retrieves the group transaction item for a given entity ID. + * + * @param int|string $entityId + * @return mixed + */ + public function getGroupTransactionById($entityId) { $collection = $this->groupTransactionFactory->create() ->getCollection() - ->addFieldToFilter('entity_id', ['eq' => $entity_id]); + ->addFieldToFilter('entity_id', ['eq' => $entityId]); return $collection->getItems(); } - public function getGroupTransactionByTrxId($trx_id) + /** + * Retrieves the group transaction item for a given transaction ID. + * + * @param int|string $trxId + * @return GroupTransaction + */ + public function getGroupTransactionByTrxId($trxId) { - return $this->groupTransactionFactory->create() + $collection = $this->groupTransactionFactory->create() ->getCollection() - ->addFieldToFilter('transaction_id', ['eq' => $trx_id])->getItems(); + ->addFieldToFilter('transaction_id', $trxId); + + return $collection->getFirstItem(); } + /** - * Get successful group transactions for orderId - * with giftcard label + * Get successful group transactions for orderId with giftcard label * * @param string|null $orderId - * - *@return \Buckaroo\Magento2\Model\GroupTransaction[] + * @return GroupTransaction[] */ public function getActiveItemsWithName($orderId) { - if($orderId === null) { + if ($orderId === null) { return []; } @@ -233,13 +333,12 @@ public function getActiveItemsWithName($orderId) ); return $collection->getItems(); } + /** - * Get successful group transaction dor transaction id - * with giftcard label + * Get successful group transaction dor transaction id with giftcard label * - * @param string $orderId - * - * @return \Buckaroo\Magento2\Model\GroupTransaction + * @param string $transactionId + * @return GroupTransaction */ public function getByTransactionIdWithName(string $transactionId) { @@ -257,26 +356,22 @@ public function getByTransactionIdWithName(string $transactionId) ); return $collection->getFirstItem(); } + /** * Set status to all transactions in a group * * @param string $groupTransactionId * @param string $status - * * @return void */ public function setGroupTransactionsStatus(string $groupTransactionId, string $status) { $this->resourceModel - ->getConnection() - ->update( - $this->resourceModel->getTable('buckaroo_magento2_group_transaction'), - [ - 'status' => $status - ], - [ - 'relatedtransaction = ?' => $groupTransactionId - ] - ); + ->getConnection() + ->update( + $this->resourceModel->getTable('buckaroo_magento2_group_transaction'), + ['status' => $status], + ['relatedtransaction = ?' => $groupTransactionId] + ); } } diff --git a/Model/Method/Klarna/PayLater.php b/Logging/BuckarooLoggerInterface.php similarity index 53% rename from Model/Method/Klarna/PayLater.php rename to Logging/BuckarooLoggerInterface.php index 0f099cea3..6d5b816dd 100644 --- a/Model/Method/Klarna/PayLater.php +++ b/Logging/BuckarooLoggerInterface.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,21 +17,19 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ -namespace Buckaroo\Magento2\Model\Method\Klarna; +declare(strict_types=1); -use Buckaroo\Magento2\Model\Method\Klarna; +namespace Buckaroo\Magento2\Logging; -class PayLater extends Klarna +interface BuckarooLoggerInterface { - /** Payment Code */ - const PAYMENT_METHOD_CODE = 'buckaroo_magento2_klarna'; + public function addDebug(string $message): bool; - const KLARNA_ORDER_SERVICE_ACTION = 'Pay'; + public function addError(string $message): bool; - /** @var string */ - public $buckarooPaymentMethodCode = 'klarna'; - - /** @var string */ - // @codingStandardsIgnoreLine - protected $_code = 'buckaroo_magento2_klarna'; + public function addWarning(string $message): bool; + + public function debug($message, array $context = []): void; + + public function setAction(string $action): BuckarooLoggerInterface; } diff --git a/Logging/CriticalHandler.php b/Logging/CriticalHandler.php index 5030aa9ec..257716d76 100644 --- a/Logging/CriticalHandler.php +++ b/Logging/CriticalHandler.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,10 +17,12 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ +declare(strict_types=1); + namespace Buckaroo\Magento2\Logging; -use Monolog\Logger; use Magento\Framework\Logger\Handler\Base; +use Monolog\Logger; class CriticalHandler extends Base { diff --git a/Logging/DbHandler.php b/Logging/DbHandler.php new file mode 100644 index 000000000..c2ddeebaa --- /dev/null +++ b/Logging/DbHandler.php @@ -0,0 +1,71 @@ +logFactory = $logFactory; + } + + /** + * @inheritdoc + */ + public function write(array $record): void + { + $now = new \DateTime(); + $logFactory = $this->logFactory->create(); + try { + $logData = json_decode($record['message'], true); + } catch (\Exception $e) { + $logData = []; + } + + $logFactory->setData([ + 'channel' => $record['channel'], + 'level' => $record['level'], + 'message' => $record['message'], + 'time' => $now->format('Y-m-d H:i:s'), + 'session_id' => ($logData['sid']) ?? '', + 'customer_id' => ($logData['cid']) ?? '', + 'quote_id' => ($logData['qid']) ?? '', + 'order_id' => ($logData['id']) ?? '' + ]); + $logFactory->save(); + } +} diff --git a/Logging/DebugHandler.php b/Logging/DebugHandler.php index c5bb10a05..14b84c930 100644 --- a/Logging/DebugHandler.php +++ b/Logging/DebugHandler.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,16 +17,47 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Logging; -use Monolog\Logger; +use Magento\Framework\Filesystem\DirectoryList; +use Magento\Framework\Filesystem\DriverInterface; use Magento\Framework\Logger\Handler\Base; +use Monolog\Logger; class DebugHandler extends Base { - // @codingStandardsIgnoreLine + /** + * @var int + */ protected $loggerType = Logger::DEBUG; - // @codingStandardsIgnoreLine - protected $fileName = '/var/log/Buckaroo/debug.log'; + /** + * @var string + */ + protected $fileName = ''; + + /** + * @var DriverInterface + */ + protected $filesystem; + + /** + * @var DirectoryList + */ + protected $dir; + + /** + * @param DriverInterface $filesystem + * @param DirectoryList $dir + */ + public function __construct( + DriverInterface $filesystem, + DirectoryList $dir + ) { + $this->dir = $dir; + $this->fileName = '/var/log/Buckaroo/' . date('Y-m-d') . '.log'; + + parent::__construct($filesystem); + } } diff --git a/Logging/InternalLogger.php b/Logging/InternalLogger.php index b9e5cf445..a8469abe8 100644 --- a/Logging/InternalLogger.php +++ b/Logging/InternalLogger.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,15 +17,15 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Logging; -use DateTimeZone; use Monolog\Logger; -class InternalLogger extends Logger { - +class InternalLogger extends Logger +{ public function __construct(string $name, array $handlers = [], array $processors = []) { parent::__construct($name, $handlers, $processors); } -} \ No newline at end of file +} diff --git a/Logging/Log.php b/Logging/Log.php index ee8953426..1ae94bb97 100644 --- a/Logging/Log.php +++ b/Logging/Log.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,64 +17,92 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Logging; -use Monolog\Logger; -use Monolog\Handler\HandlerInterface; -use Buckaroo\Magento2\Logging\InternalLogger; use Buckaroo\Magento2\Model\ConfigProvider\DebugConfiguration; +use Magento\Checkout\Model\Session; +use Magento\Framework\Session\SessionManager; +use Monolog\DateTimeImmutable; +use Monolog\Handler\HandlerInterface; +use Monolog\Logger; -class Log +class Log extends Logger implements BuckarooLoggerInterface { - /** @var DebugConfiguration */ - private $debugConfiguration; + public const BUCKAROO_LOG_TRACE_DEPTH_DEFAULT = 10; - /** @var Mail */ - private $mail; + /** + * @var DebugConfiguration + */ + private DebugConfiguration $debugConfiguration; - /** @var array */ - protected $message = []; + /** + * @var array + */ + protected array $message = []; + + /** + * @var string + */ + protected string $action = ''; + /** + * @var int + */ private static $processUid = 0; /** - * @var \Buckaroo\Magento2\Logging\InternalLogger + * @var Session + */ + protected Session $checkoutSession; + + /** + * @var SessionManager + */ + protected SessionManager $session; + + /** + * @var \Magento\Customer\Model\Session */ - private $logger; + protected \Magento\Customer\Model\Session $customerSession; /** * Log constructor. * - * @param string $name * @param DebugConfiguration $debugConfiguration - * @param Mail $mail + * @param Session $checkoutSession + * @param SessionManager $sessionManager + * @param \Magento\Customer\Model\Session $customerSession * @param HandlerInterface[] $handlers - * @param callable[] $processors + * @param callable[] $processors + * @param string $name */ public function __construct( DebugConfiguration $debugConfiguration, - Mail $mail, - InternalLogger $logger + Session $checkoutSession, + SessionManager $sessionManager, + \Magento\Customer\Model\Session $customerSession, + array $handlers = [], + array $processors = [], + string $name = 'buckaroo' ) { $this->debugConfiguration = $debugConfiguration; - $this->mail = $mail; - $this->logger = $logger; - - } + $this->checkoutSession = $checkoutSession; + $this->session = $sessionManager; + $this->customerSession = $customerSession; - /** - * Make sure the debug information is always send to the debug email - */ - public function __destruct() - { - $this->mail->mailMessage(); + parent::__construct($name, $handlers, $processors); } /** - * {@inheritdoc} + * @inheritdoc */ - public function addRecord(int $level, string $message, array $context = []): bool - { + public function addRecord( + int $level, + string $message, + array $context = [], + DateTimeImmutable $datetime = null + ): bool { if (!$this->debugConfiguration->canLog($level)) { return false; } @@ -83,15 +111,47 @@ public function addRecord(int $level, string $message, array $context = []): boo self::$processUid = uniqid(); } - $message = self::$processUid . '|' . microtime(true). '|' . $message; + $depth = $this->debugConfiguration->getDebugBacktraceDepth(); + if (empty($depth) || trim($depth) == '') { + $depth = self::BUCKAROO_LOG_TRACE_DEPTH_DEFAULT; + } - // Prepare the message to be send to the debug email - $this->mail->addToMessage($message); + $trace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, $depth); + $logTrace = []; + + for ($cnt = 1; $cnt < $depth; $cnt++) { + if (isset($trace[$cnt])) { + try { + /** @phpstan-ignore-next-line */ + $logTrace[] = str_replace(BP, '', $trace[$cnt]['file']) . ": " . $trace[$cnt]['line'] . " " . + $trace[$cnt]['class'] . '->' . + $trace[$cnt]['function'] . '()'; + } catch (\Exception $e) { + $logTrace[] = json_encode($trace[$cnt]); + } + } + } - return $this->logger->addRecord($level, $message, $context); + $flags = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; + $message = $this->action . $message; + + $message = json_encode([ + 'uid' => self::$processUid, + 'time' => microtime(true), + 'sid' => $this->session->getSessionId(), + 'cid' => $this->customerSession->getCustomer()->getId(), + 'qid' => $this->checkoutSession->getQuote()->getId(), + 'id' => $this->checkoutSession->getQuote()->getReservedOrderId(), + 'msg' => $message, + 'trace' => $logTrace + ], $flags); + + return parent::addRecord($level, $message, $context); } /** + * Logs a debug message. + * * @param string $message * @return bool */ @@ -100,15 +160,42 @@ public function addDebug(string $message): bool return $this->addRecord(Logger::DEBUG, $message); } + /** + * Logs an error message. + * + * @param string $message + * @return bool + */ public function addError(string $message): bool { return $this->addRecord(Logger::ERROR, $message); } + + /** + * Logs a warning message. + * + * @param string $message + * @return bool + */ + public function addWarning(string $message): bool + { + return $this->addRecord(Logger::WARNING, $message); + } + + /** + * @inheritdoc + */ + public function debug($message, array $context = []): void + { + $this->addRecord(Logger::DEBUG, (string) $message, $context); + } + /** - * {@inheritdoc} + * @inheritdoc */ - public function debug($message) + public function setAction(string $action): BuckarooLoggerInterface { - return $this->addRecord(Logger::DEBUG, $message); + $this->action = $action; + return $this; } } diff --git a/Logging/Mail.php b/Logging/Mail.php index 2831329b9..7221dc1b7 100644 --- a/Logging/Mail.php +++ b/Logging/Mail.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,22 +17,31 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Logging; use Buckaroo\Magento2\Model\ConfigProvider\DebugConfiguration; class Mail { - /** @var DebugConfiguration */ + /** + * @var DebugConfiguration + */ private $debugConfiguration; - /** @var array */ + /** + * @var array + */ private $message = []; - /** @var string */ + /** + * @var string + */ protected $mailSubject = 'Buckaroo_Magento2 log mail'; - /** @var string */ + /** + * @var string + */ protected $mailFrom = 'nobody@buckaroo.nl'; /** @@ -46,30 +55,8 @@ public function __construct(DebugConfiguration $debugConfiguration) } /** - * Mail the debug message to the debug recipients - */ - public function mailMessage() - { - $debugEmails = $this->debugConfiguration->getDebugEmails(); - $message = $this->getMessageAsString(); - - if (count($debugEmails) <= 0 || !$message) { - return; - } - - $headers = 'From: ' . $this->getMailFrom() . "\r\n" . - 'Reply-To: ' . $this->getMailFrom() . "\r\n" . - 'X-Mailer: PHP/' . phpversion(); - - foreach ($debugEmails as $mailTo) { - //@codingStandardsIgnoreLine - mail($mailTo, $this->getMailSubject(), $message, $headers); - } - - $this->resetMessage(); - } - - /** + * Reset the message + * * @return $this */ public function resetMessage() @@ -82,8 +69,7 @@ public function resetMessage() /** * Add $message to the message array, and cast to string if an array or object * - * @param $message - * + * @param mixed $message * @return $this */ public function addToMessage($message) @@ -99,6 +85,8 @@ public function addToMessage($message) } /** + * Get message + * * @return array */ public function getMessage() @@ -121,6 +109,8 @@ public function getMessageAsString() } /** + * Get mail subject + * * @return string */ public function getMailSubject() @@ -129,8 +119,9 @@ public function getMailSubject() } /** - * @param string $mailSubject + * Set mail subject * + * @param string $mailSubject * @return $this */ public function setMailSubject($mailSubject) @@ -141,6 +132,8 @@ public function setMailSubject($mailSubject) } /** + * Get mail from + * * @return string */ public function getMailFrom() @@ -149,8 +142,9 @@ public function getMailFrom() } /** - * @param string $mailFrom + * Set mail from * + * @param string $mailFrom * @return $this */ public function setMailFrom($mailFrom) diff --git a/Logging/SimplifiedLog.php b/Logging/SimplifiedLog.php new file mode 100644 index 000000000..907c8e562 --- /dev/null +++ b/Logging/SimplifiedLog.php @@ -0,0 +1,132 @@ +debugConfiguration = $debugConfiguration; + + parent::__construct($name, $handlers, $processors); + } + + /** + * @inheritdoc + */ + public function addRecord( + int $level, + string $message, + array $context = [], + DateTimeImmutable $datetime = null + ): bool { + if (!$this->debugConfiguration->canLog($level)) { + return false; + } + + $message = $this->action . $message; + + return parent::addRecord($level, $message, $context); + } + + /** + * Logs a debug message. + * + * @param string $message + * @return bool + */ + public function addDebug(string $message): bool + { + return $this->addRecord(Logger::DEBUG, $message); + } + + /** + * Logs an error message. + * + * @param string $message + * @return bool + */ + public function addError(string $message): bool + { + return $this->addRecord(Logger::ERROR, $message); + } + + /** + * Logs a warning message. + * + * @param string $message + * @return bool + */ + public function addWarning(string $message): bool + { + return $this->addRecord(Logger::WARNING, $message); + } + + /** + * @inheritdoc + */ + public function debug($message, array $context = []): void + { + $this->addRecord(Logger::DEBUG, (string) $message, $context); + } + + /** + * @inheritdoc + */ + public function setAction(string $action): BuckarooLoggerInterface + { + $this->action = $action; + return $this; + } +} diff --git a/Model/Adapter/BuckarooAdapter.php b/Model/Adapter/BuckarooAdapter.php new file mode 100644 index 000000000..613f2d235 --- /dev/null +++ b/Model/Adapter/BuckarooAdapter.php @@ -0,0 +1,319 @@ +mapPaymentMethods = $mapPaymentMethods; + $this->logger = $logger; + $this->configProviderFactory = $configProviderFactory; + $this->encryptor = $encryptor; + $this->productMetadata = $productMetadata; + $this->localeResolver = $localeResolver; + $this->storeManager = $storeManager; + } + + /** + * Execute request using Buckaroo SDK + * + * @param string $action + * @param string $method + * @param array $data + * @return TransactionResponse + * @throws \Throwable + */ + public function execute(string $action, string $method, array $data): TransactionResponse + { + $this->setClientSdk($method); + $payment = $this->buckaroo->method($this->getMethodName($method)); + + try { + if ($this->isCreditManagementOfType($data, BuilderComposite::TYPE_ORDER)) { + $payment = $payment->combine($this->getCreditManagementBody($data)); + } + + if ($this->isCreditManagementOfType($data, BuilderComposite::TYPE_REFUND)) { + $this->createCreditNote($data); + } + + if ($this->isCreditManagementOfType($data, BuilderComposite::TYPE_VOID)) { + return $this->createCreditNote($data, BuilderComposite::TYPE_VOID); + } + + if (isset($data['serviceVersion'])) { + $payment->setServiceVersion($data['serviceVersion']); + unset($data['serviceVersion']); + } + + return $payment->{$action}($data); + } catch (\Throwable $th) { + $this->logger->addError(sprintf( + '[SDK] | [Adapter] | [%s:%s] - Execute request using Buckaroo SDK | [ERROR]: %s', + __METHOD__, + __LINE__, + $th->getMessage() + )); + + throw $th; + } + } + + /** + * Set Client SDK base on account configuration and payment method configuration + * + * @throws \Exception + */ + private function setClientSdk($paymentMethod = ''): void + { + /** @var Account $configProviderAccount */ + $configProviderAccount = $this->configProviderFactory->get('account'); + $storeId = $this->storeManager->getStore()->getId(); + $accountMode = $configProviderAccount->getActive($storeId); + $clientMode = $this->getClientMode($accountMode, $storeId, $paymentMethod); + + $this->buckaroo = new BuckarooClient(new DefaultConfig( + $this->encryptor->decrypt($configProviderAccount->getMerchantKey()), + $this->encryptor->decrypt($configProviderAccount->getSecretKey()), + $clientMode, + null, + null, + null, + null, + $this->productMetadata->getName() . ' - ' . $this->productMetadata->getEdition(), + $this->productMetadata->getVersion(), + 'Buckaroo', + 'Magento2', + Data::BUCKAROO_VERSION, + str_replace('_', '-', $this->localeResolver->getLocale()) + )); + } + + /** + * Get client mode base on account mode and payment method mode + * + * @param int|string $accountMode + * @param int|string $storeId + * @param string $paymentMethod + * @return string + * @throws Exception + */ + private function getClientMode($accountMode, $storeId, string $paymentMethod = ''): string + { + $clientMode = Config::TEST_MODE; + + if ($accountMode == Enablemode::ENABLE_OFF) { + throw new Exception(__('The Buckaroo Module is OFF')); + } + + if ($accountMode == Enablemode::ENABLE_LIVE) { + $clientMode = Config::LIVE_MODE; + + if ($paymentMethod) { + /** @var AbstractConfigProvider $configProviderPaymentMethod */ + $configProviderPaymentMethod = $this->configProviderFactory->get($paymentMethod); + $isActivePaymentMethod = $configProviderPaymentMethod->getActive($storeId); + if ($isActivePaymentMethod == Enablemode::ENABLE_OFF) { + throw new Exception(__('Payment method: %s is not active', $paymentMethod)); + } + + if ($isActivePaymentMethod == Enablemode::ENABLE_TEST) { + $clientMode = Config::TEST_MODE; + } + } + } + + return $clientMode; + } + + /** + * Get the payment method name from SDK + * + * @param string $method + * @return string + */ + protected function getMethodName(string $method): string + { + return $this->mapPaymentMethods[$method] ?? $method; + } + + /** + * Check if we have credit management information of type + * + * @param array $data + * @param string $type + * + * @return boolean + */ + protected function isCreditManagementOfType(array $data, string $type): bool + { + return isset($data[$type]) && + is_array($data[$type]) && + count($data[$type]) > 0; + } + + /** + * Get credit management body + * + * @param array $data + * @return TransactionResponse|CreditManagement + */ + protected function getCreditManagementBody(array $data) + { + return $this->buckaroo->method('credit_management') + ->manually() + ->createCombinedInvoice( + $data[BuilderComposite::TYPE_ORDER] + ); + } + + /** + * Get credit note body + * + * @param array $data + * @param string $type + * @return TransactionResponse + */ + protected function createCreditNote(array $data, string $type = BuilderComposite::TYPE_REFUND): TransactionResponse + { + return $this->buckaroo->method('credit_management') + ->createCreditNote( + $data[$type] + ); + } + + /** + * Get ideal issuers + * + * @return array + * @throws \Throwable + */ + public function getIdealIssuers(): array + { + try { + $this->setClientSdk(); + return $this->buckaroo->method('ideal')->issuers(); + } catch (\Throwable $th) { + $this->logger->addError(sprintf( + '[SDK] | [Adapter] | [%s:%s] - Get ideal issuers | [ERROR]: %s', + __METHOD__, + __LINE__, + $th->getMessage() + )); + return []; + } + } + + /** + * Validate request + * + * @throws BuckarooException + * @throws \Exception + */ + public function validate($postData, $authHeader, $uri): bool + { + $this->setClientSdk(); + $replyHandler = new ReplyHandler($this->buckaroo->client()->config(), $postData, $authHeader, $uri); + $replyHandler->validate(); + return $replyHandler->isValid(); + } +} diff --git a/Model/Applepay.php b/Model/Applepay.php deleted file mode 100644 index 0640f665c..000000000 --- a/Model/Applepay.php +++ /dev/null @@ -1,34 +0,0 @@ - '', - 'firstname' => isset($wallet['givenName']) ? $wallet['givenName'] : '', - 'middlename' => '', - 'lastname' => isset($wallet['familyName']) ? $wallet['familyName'] : '', - 'street' => [ - '0' => isset($wallet['addressLines'][0]) ? $wallet['addressLines'][0] : '', - '1' => isset($wallet['addressLines'][1]) ? $wallet['addressLines'][1] : null - ], - 'city' => isset($wallet['locality']) ? $wallet['locality'] : '', - 'country_id' => isset($wallet['countryCode']) ? strtoupper($wallet['countryCode']) : '', - 'region' => isset($wallet['administrativeArea']) ? $wallet['administrativeArea'] : '', - 'region_id' => '', - 'postcode' => isset($wallet['postalCode']) ? $wallet['postalCode'] : '', - 'telephone' => isset($wallet['phoneNumber']) ? $wallet['phoneNumber'] : 'N/A', - 'fax' => '', - 'vat_id' => '' - ]; - //this fails with array to string coversion critical error; as a result the address is not saved - //made it one line - $address['street'] = implode("\n",$address['street']); - if ($type == 'shipping') { - $address['email'] = isset($wallet['emailAddress']) ? $wallet['emailAddress'] : ''; - } - - return $address; - } -} \ No newline at end of file diff --git a/Model/BuckarooRestOrderData.php b/Model/BuckarooRestOrderData.php index 58e64ebdd..9f1b79280 100644 --- a/Model/BuckarooRestOrderData.php +++ b/Model/BuckarooRestOrderData.php @@ -20,9 +20,9 @@ namespace Buckaroo\Magento2\Model; -use Buckaroo\Magento2\Helper\PaymentGroupTransaction; use Buckaroo\Magento2\Api\Data\BuckarooRestOrderDataInterface; use Buckaroo\Magento2\Api\Data\Giftcard\TransactionResponseInterfaceFactory; +use Buckaroo\Magento2\Helper\PaymentGroupTransaction; class BuckarooRestOrderData implements BuckarooRestOrderDataInterface { @@ -38,16 +38,18 @@ class BuckarooRestOrderData implements BuckarooRestOrderDataInterface public function __construct( string $orderIncrementId, PaymentGroupTransaction $groupTransaction, - TransactionResponseInterfaceFactory $trResponseFactory, - ) { + TransactionResponseInterfaceFactory $trResponseFactory + ) { $this->orderIncrementId = $orderIncrementId; $this->groupTransaction = $groupTransaction; $this->trResponseFactory = $trResponseFactory; } + /** * @return \Buckaroo\Magento2\Api\Data\Giftcard\TransactionResponseInterface[] */ - public function getGroupTransactions() { + public function getGroupTransactions() + { return $this->formatFound( $this->groupTransaction->getActiveItemsWithName( $this->orderIncrementId diff --git a/Model/BuckarooStatusCode.php b/Model/BuckarooStatusCode.php new file mode 100644 index 000000000..4d154249f --- /dev/null +++ b/Model/BuckarooStatusCode.php @@ -0,0 +1,133 @@ + 'Success', + 490 => 'Payment failure', + 491 => 'Validation error', + 492 => 'Technical error', + 690 => 'Payment rejected', + 790 => 'Waiting for user input', + 791 => 'Waiting for processor', + 792 => 'Waiting on consumer action', + 793 => 'Payment on hold', + 890 => 'Cancelled by consumer', + 891 => 'Cancelled by merchant' + ]; + + /** + * Buckaroo_Magento2 status codes + * + * @var array $statusCode + */ + private array $statusCodes = [ + 'BUCKAROO_MAGENTO2_STATUSCODE_SUCCESS' => 190, + 'BUCKAROO_MAGENTO2_STATUSCODE_FAILED' => 490, + 'BUCKAROO_MAGENTO2_STATUSCODE_VALIDATION_FAILURE' => 491, + 'BUCKAROO_MAGENTO2_STATUSCODE_TECHNICAL_ERROR' => 492, + 'BUCKAROO_MAGENTO2_STATUSCODE_REJECTED' => 690, + 'BUCKAROO_MAGENTO2_STATUSCODE_WAITING_ON_USER_INPUT' => 790, + 'BUCKAROO_MAGENTO2_STATUSCODE_PENDING_PROCESSING' => 791, + 'BUCKAROO_MAGENTO2_STATUSCODE_WAITING_ON_CONSUMER' => 792, + 'BUCKAROO_MAGENTO2_STATUSCODE_PAYMENT_ON_HOLD' => 793, + 'BUCKAROO_MAGENTO2_STATUSCODE_PENDING_APPROVAL' => 794, + 'BUCKAROO_MAGENTO2_STATUSCODE_CANCELLED_BY_USER' => 890, + 'BUCKAROO_MAGENTO2_STATUSCODE_CANCELLED_BY_MERCHANT' => 891, + + /** + * Codes below are created by dev, not by Buckaroo. + */ + 'BUCKAROO_MAGENTO2_ORDER_FAILED' => 11014, + ]; + + /** + * Get Response Message by Response Code + * + * @param int $responseCode + * @return string + */ + public function getResponseMessage(int $responseCode): string + { + return self::BPE_RESPONSE_MESSAGES[$responseCode] ?? 'Onbekende responsecode: ' . $responseCode; + } + + /** + * Return the requested status key with the value, or null if not found + * + * @param int $responseCode + * @return string + */ + public function getStatusKey(int $responseCode): string + { + $statusKey = array_search($responseCode, $this->statusCodes); + return $statusKey ?: 'BUCKAROO_MAGENTO2_STATUSCODE_NEUTRAL'; + } + + /** + * Get failed statuses + * + * @return string[] + */ + public function getFailedStatuses(): array + { + return [ + 'BUCKAROO_MAGENTO2_STATUSCODE_TECHNICAL_ERROR', + 'BUCKAROO_MAGENTO2_STATUSCODE_VALIDATION_FAILURE', + 'BUCKAROO_MAGENTO2_STATUSCODE_CANCELLED_BY_MERCHANT', + 'BUCKAROO_MAGENTO2_STATUSCODE_CANCELLED_BY_USER', + 'BUCKAROO_MAGENTO2_STATUSCODE_FAILED', + 'BUCKAROO_MAGENTO2_STATUSCODE_REJECTED' + ]; + } + + /** + * Get pending statuses + * + * @return string[] + */ + public function getPendingStatuses(): array + { + return [ + 'BUCKAROO_MAGENTO2_STATUSCODE_PAYMENT_ON_HOLD', + 'BUCKAROO_MAGENTO2_STATUSCODE_WAITING_ON_CONSUMER', + 'BUCKAROO_MAGENTO2_STATUSCODE_PENDING_PROCESSING', + 'BUCKAROO_MAGENTO2_STATUSCODE_WAITING_ON_USER_INPUT' + ]; + } +} diff --git a/Model/Cart/CartTotalRepository.php b/Model/Cart/CartTotalRepository.php deleted file mode 100644 index 6a9379eac..000000000 --- a/Model/Cart/CartTotalRepository.php +++ /dev/null @@ -1,174 +0,0 @@ -totalsFactory = $totalsFactory; - $this->quoteRepository = $quoteRepository; - $this->dataObjectHelper = $dataObjectHelper; - $this->couponService = $couponService; - $this->totalsConverter = $totalsConverter; - $this->itemConverter = $converter; - $this->productMetadata = $productMetadata; - } - - /** - * {@inheritDoc} - * - * @param int $cartId The cart ID. - * @return Totals Quote totals data. - */ - public function get($cartId): QuoteTotalsInterface - { - if (!$this->isCorrectMagentoVersion()) { - return parent::get($cartId); - } - - /** @var \Magento\Quote\Model\Quote $quote */ - $quote = $this->quoteRepository->getActive($cartId); - if ($quote->isVirtual()) { - $addressTotalsData = $quote->getBillingAddress()->getData(); - $addressTotals = $quote->getBillingAddress()->getTotals(); - } else { - $addressTotalsData = $quote->getShippingAddress()->getData(); - $addressTotals = $quote->getShippingAddress()->getTotals(); - } - - // Rewrite start - unset($addressTotalsData[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]); - // Rewrite end - - /** @var \Magento\Quote\Api\Data\TotalsInterface $quoteTotals */ - $quoteTotals = $this->totalsFactory->create(); - $this->dataObjectHelper->populateWithArray( - $quoteTotals, - $addressTotalsData, - \Magento\Quote\Api\Data\TotalsInterface::class - ); - $items = []; - foreach ($quote->getAllVisibleItems() as $index => $item) { - $items[$index] = $this->itemConverter->modelToDataObject($item); - } - $calculatedTotals = $this->totalsConverter->process($addressTotals); - $quoteTotals->setTotalSegments($calculatedTotals); - - $amount = $quoteTotals->getGrandTotal() - $quoteTotals->getTaxAmount(); - $amount = $amount > 0 ? $amount : 0; - $quoteTotals->setCouponCode($this->couponService->get($cartId)); - $quoteTotals->setGrandTotal($amount); - $quoteTotals->setItems($items); - $quoteTotals->setItemsQty($quote->getItemsQty()); - $quoteTotals->setBaseCurrencyCode($quote->getBaseCurrencyCode()); - $quoteTotals->setQuoteCurrencyCode($quote->getQuoteCurrencyCode()); - return $quoteTotals; - } - - /** - * Overwrite only version 2.2.2 - * - * @return bool - */ - private function isCorrectMagentoVersion() - { - $currentVersion = $this->productMetadata->getVersion(); - - if (in_array($currentVersion, ['2.2.2', '2.2.3'])) { - return true; - } - - return false; - } -} diff --git a/Model/Certificate.php b/Model/Certificate.php deleted file mode 100644 index 601a728f4..000000000 --- a/Model/Certificate.php +++ /dev/null @@ -1,120 +0,0 @@ -_init('Buckaroo\Magento2\Model\ResourceModel\Certificate'); - } - - /** - * {@inheritdoc} - */ - public function getCertificate() - { - return $this->getData('certificate'); - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return $this->getData('name'); - } - - /** - * {@inheritdoc} - */ - public function getCreatedAt() - { - return $this->getData('created_at'); - } - - /** - * {@inheritdoc} - */ - public function setCertificate($certificate) - { - return $this->setData('certificate', $certificate); - } - - /** - * {@inheritdoc} - */ - public function setName($name) - { - return $this->setData('name', $name); - } - - /** - * {@inheritdoc} - */ - public function setCreatedAt($createdAt) - { - return $this->setData('created_at', $createdAt); - } - - /** - * @param boolean $skipEncryptionOnSave - * - * @return $this - */ - public function setSkipEncryptionOnSave($skipEncryptionOnSave) - { - $this->skipEncryptionOnSave = $skipEncryptionOnSave; - - return $this; - } - - /** - * @return boolean - */ - public function isSkipEncryptionOnSave() - { - return $this->skipEncryptionOnSave; - } -} diff --git a/Model/CertificateRepository.php b/Model/CertificateRepository.php deleted file mode 100644 index dfc6d0c35..000000000 --- a/Model/CertificateRepository.php +++ /dev/null @@ -1,203 +0,0 @@ -resource = $resource; - $this->certificateCollectionFactory = $certificateCollectionFactory; - $this->certificateFactory = $certificateFactory; - $this->searchResultsFactory = $searchResultsFactory; - } - - /** - * {@inheritdoc} - */ - public function save(CertificateInterface $certificate) - { - try { - $this->resource->save($certificate); - } catch (\Exception $exception) { - throw new CouldNotSaveException(__($exception->getMessage())); - } - - return $certificate; - } - - /** - * {@inheritdoc} - */ - public function getById($certificateId) - { - $certificate = $this->certificateFactory->create(); - $certificate->load($certificateId); - - if (!$certificate->getId()) { - throw new NoSuchEntityException(__('Certificate with id "%1" does not exist.', $certificateId)); - } - - return $certificate; - } - - /** - * {@inheritdoc} - */ - public function getList(SearchCriteria $searchCriteria) - { - /** @var SearchResultsInterface $searchResults */ - $searchResults = $this->searchResultsFactory->create(); - $searchResults->setSearchCriteria($searchCriteria); - - /** @var CertificateCollection $collection */ - $collection = $this->certificateCollectionFactory->create(); - - foreach ($searchCriteria->getFilterGroups() as $filterGroup) { - $this->handleFilterGroups($filterGroup, $collection); - } - - $searchResults->setTotalCount($collection->getSize()); - $this->handleSortOrders($searchCriteria, $collection); - - $items = $this->getSearchResultItems($searchCriteria, $collection); - $searchResults->setItems($items); - - return $searchResults; - } - - /** - * @param \Magento\Framework\Api\Search\FilterGroup $filterGroup - * @param CertificateCollection $collection - */ - private function handleFilterGroups($filterGroup, $collection) - { - $fields = []; - $conditions = []; - foreach ($filterGroup->getFilters() as $filter) { - $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; - $fields[] = $filter->getField(); - $conditions[] = [$condition => $filter->getValue()]; - } - - if ($fields) { - $collection->addFieldToFilter($fields, $conditions); - } - } - - /** - * @param SearchCriteria $searchCriteria - * @param CertificateCollection $collection - */ - private function handleSortOrders($searchCriteria, $collection) - { - $sortOrders = $searchCriteria->getSortOrders(); - - if (!$sortOrders) { - return; - } - - /** @var SortOrder $sortOrder */ - foreach ($sortOrders as $sortOrder) { - $collection->addOrder( - $sortOrder->getField(), - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - } - - /** - * @param SearchCriteria $searchCriteria - * @param CertificateCollection $collection - * - * @return array - */ - private function getSearchResultItems($searchCriteria, $collection) - { - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); - $items = []; - - foreach ($collection as $testieModel) { - $items[] = $testieModel; - } - - return $items; - } - - /** - * {@inheritdoc} - */ - public function delete(CertificateInterface $certificate) - { - try { - $this->resource->delete($certificate); - } catch (\Exception $exception) { - throw new CouldNotDeleteException(__($exception->getMessage())); - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function deleteById($certificateId) - { - $certificate = $this->getById($certificateId); - - return $this->delete($certificate); - } -} diff --git a/Model/Config/Backend/AllowedCurrencies.php b/Model/Config/Backend/AllowedCurrencies.php index 4cd52f482..67ad4a95a 100644 --- a/Model/Config/Backend/AllowedCurrencies.php +++ b/Model/Config/Backend/AllowedCurrencies.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,50 +17,65 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Model\Config\Backend; +use Buckaroo\Magento2\Model\ConfigProvider\AllowedCurrencies as ConfigAllowedCurrencies; +use Magento\Framework\App\Cache\TypeListInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Config\Value; +use Magento\Framework\Data\Collection\AbstractDb; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Locale\Bundle\CurrencyBundle; +use Magento\Framework\Locale\ResolverInterface; +use Magento\Framework\Model\Context; +use Magento\Framework\Model\ResourceModel\AbstractResource; +use Magento\Framework\Registry; + /** * @method mixed getValue() */ -class AllowedCurrencies extends \Magento\Framework\App\Config\Value +class AllowedCurrencies extends Value { /** - * @var \Buckaroo\Magento2\Model\ConfigProvider\AllowedCurrencies + * @var ConfigAllowedCurrencies */ protected $configProvider; /** - * @var \Magento\Framework\Locale\ResolverInterface + * @var ResolverInterface */ protected $localeResolver; /** - * @var \Magento\Framework\Locale\Bundle\CurrencyBundle + * @var CurrencyBundle */ protected $currencyBundle; /** - * @param \Magento\Framework\Model\Context $context - * @param \Magento\Framework\Registry $registry - * @param \Magento\Framework\App\Config\ScopeConfigInterface $config - * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList - * @param \Buckaroo\Magento2\Model\ConfigProvider\AllowedCurrencies $configProvider - * @param \Magento\Framework\Locale\Bundle\CurrencyBundle $currencyBundle - * @param \Magento\Framework\Locale\ResolverInterface $localeResolver - * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource - * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection - * @param array $data + * @param Context $context + * @param Registry $registry + * @param ScopeConfigInterface $config + * @param TypeListInterface $cacheTypeList + * @param ConfigAllowedCurrencies $configProvider + * @param CurrencyBundle $currencyBundle + * @param ResolverInterface $localeResolver + * @param AbstractResource|null $resource + * @param AbstractDb|null $resourceCollection + * @param array $data + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( - \Magento\Framework\Model\Context $context, - \Magento\Framework\Registry $registry, - \Magento\Framework\App\Config\ScopeConfigInterface $config, - \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList, - \Buckaroo\Magento2\Model\ConfigProvider\AllowedCurrencies $configProvider, - \Magento\Framework\Locale\Bundle\CurrencyBundle $currencyBundle, - \Magento\Framework\Locale\ResolverInterface $localeResolver, - \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, - \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, + Context $context, + Registry $registry, + ScopeConfigInterface $config, + TypeListInterface $cacheTypeList, + ConfigAllowedCurrencies $configProvider, + CurrencyBundle $currencyBundle, + ResolverInterface $localeResolver, + AbstractResource $resource = null, + AbstractDb $resourceCollection = null, array $data = [] ) { parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); @@ -74,7 +89,7 @@ public function __construct( * Check that the value contains valid currencies. * * @return $this - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ public function save() { @@ -83,7 +98,7 @@ public function save() foreach ($value as $currency) { if (!in_array($currency, $allowedCurrencies)) { - throw new \Magento\Framework\Exception\LocalizedException( + throw new LocalizedException( __("Please enter a valid currency: '%1'.", $this->getCurrencyTranslation($currency)) ); } @@ -95,8 +110,7 @@ public function save() /** * Checks if there is a translation for this currency. If not, returns the original value to show it to the user. * - * @param $currency - * + * @param string $currency * @return mixed */ protected function getCurrencyTranslation($currency) diff --git a/Model/Config/Backend/Certificate.php b/Model/Config/Backend/Certificate.php deleted file mode 100644 index 9ffd91ca7..000000000 --- a/Model/Config/Backend/Certificate.php +++ /dev/null @@ -1,163 +0,0 @@ -readFactory = $readFactory; - $this->writer = $writer; - $this->certificateFactory = $certificateFactory; - $this->certificateRepository = $certificateRepository; - $this->file = $file; - } - - /** - * Save the certificate - * - * @return $this - * @throws \Exception - */ - public function save() - { - //type == application/x-x509-ca-cert - if (!empty($this->getFieldsetDataValue('certificate_upload')['name'])) { - $certFile = $this->getFieldsetDataValue('certificate_upload'); - $certLabel = $this->getFieldsetDataValue('certificate_label'); - - if (!$this->validExtension($certFile['name'])) { - throw new LocalizedException(__('Disallowed file type.')); - } - - if (strlen(trim($certLabel)) <= 0) { - throw new LocalizedException(__('Enter a name for the certificate.')); - } - - /** - * Read the configuration contents - */ - /** - * @var \Magento\Framework\Filesystem\File\Read $read - */ - $read = $this->readFactory->create($certFile['tmp_name'], \Magento\Framework\Filesystem\DriverPool::FILE); - - $certificate = $this->certificateFactory->create(); - $certificate->setCertificate($read->readAll()); - $certificate->setName($certLabel); - $this->certificateRepository->save($certificate); - - /** - * Only update the selected certificate when there is a new certificate uploaded, and the user did not - * change the selected value. - */ - $oldValue = $this->_config->getValue( - 'buckaroo_magento2/account/certificate_file', - $this->getScope(), - $this->getScopeId() - ); - $newValue = $this->getFieldsetDataValue('certificate_file'); - - if ($oldValue == $newValue) { - /** - * Set the current configuration value to this new uploaded certificate. - */ - $this->writer->save( - 'buckaroo_magento2/account/certificate_file', - $certificate->getId(), - $this->getScope() ? $this->getScope() : 'default', - $this->getScopeId() - ); - } - } - - return $this; - } - - /** - * Check if extension is valid - * - * @param String $filename Name of uplpaded file - * - * @return bool - */ - protected function validExtension($filename) - { - $allowedExtensions = ['pem']; - - $extensionData = $this->file->getPathInfo($filename, PATHINFO_EXTENSION); - $extension = $extensionData['extension']; - return in_array(strtolower($extension), $allowedExtensions); - } -} diff --git a/Model/Config/Backend/ExpireDays.php b/Model/Config/Backend/ExpireDays.php index 588de5678..2f7bac86d 100644 --- a/Model/Config/Backend/ExpireDays.php +++ b/Model/Config/Backend/ExpireDays.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,29 +17,33 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Model\Config\Backend; +use Magento\Framework\App\Config\Value; +use Magento\Framework\Exception\LocalizedException; + /** * @method mixed getValue */ -class ExpireDays extends \Magento\Framework\App\Config\Value +class ExpireDays extends Value { /** * Test that the value is a integer within 0 and 180 interval * * @return $this - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ public function save() { - $value = (int) $this->getValue(); + $value = (int)$this->getValue(); if (empty($value)) { return parent::save(); } if (!is_int($value) || $value < 0 || $value > 180) { - throw new \Magento\Framework\Exception\LocalizedException( + throw new LocalizedException( __("Please enter a valid integer within 0 and 180 interval") ); } diff --git a/Model/Config/Backend/Number.php b/Model/Config/Backend/Number.php index 4792f77ae..490afb26e 100644 --- a/Model/Config/Backend/Number.php +++ b/Model/Config/Backend/Number.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,18 +17,22 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Model\Config\Backend; +use Magento\Framework\App\Config\Value; +use Magento\Framework\Exception\LocalizedException; + /** * @method mixed getValue */ -class Number extends \Magento\Framework\App\Config\Value +class Number extends Value { /** * Test that the value is a number and is positive. * * @return $this - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ public function save() { @@ -39,7 +43,7 @@ public function save() } if (!ctype_digit($value) || $value < 0) { - throw new \Magento\Framework\Exception\LocalizedException(__("Please enter a valid number: '%1'.", $value)); + throw new LocalizedException(__("Please enter a valid number: '%1'.", $value)); } return parent::save(); diff --git a/Model/Config/Backend/PaymentFee.php b/Model/Config/Backend/PaymentFee.php index 8a398a940..b8044c835 100644 --- a/Model/Config/Backend/PaymentFee.php +++ b/Model/Config/Backend/PaymentFee.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,18 +17,22 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Model\Config\Backend; +use Magento\Framework\App\Config\Value; +use Magento\Framework\Exception\LocalizedException; + /** * @method mixed getValue */ -class PaymentFee extends \Magento\Framework\App\Config\Value +class PaymentFee extends Value { /** * Test that the value is a number and is positive. * * @return $this - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ public function save() { @@ -37,7 +41,7 @@ public function save() $withoutLastChar = substr($value, 0, -1); if (!empty($value) && !is_numeric(($onlyLastChar == '%' ? $withoutLastChar : $value))) { - throw new \Magento\Framework\Exception\LocalizedException(__("Please enter a valid number: '%1'.", $value)); + throw new LocalizedException(__("Please enter a valid number: '%1'.", $value)); } return parent::save(); diff --git a/Model/Config/Backend/PaypalExpressMerchantId.php b/Model/Config/Backend/PaypalExpressMerchantId.php index 28f880f1f..cdb5a6796 100644 --- a/Model/Config/Backend/PaypalExpressMerchantId.php +++ b/Model/Config/Backend/PaypalExpressMerchantId.php @@ -1,13 +1,12 @@ getFieldsetDataValue('available_buttons')) && + if (is_array($this->getFieldsetDataValue('available_buttons')) && strlen($this->getValue()) === 0 ) { throw new LocalizedException(__('Paypal express merchant id is required')); diff --git a/Model/Config/Backend/Price.php b/Model/Config/Backend/Price.php index 584360a1e..6913c5dc8 100644 --- a/Model/Config/Backend/Price.php +++ b/Model/Config/Backend/Price.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,15 +17,19 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Model\Config\Backend; -class Price extends \Magento\Framework\App\Config\Value +use Magento\Framework\App\Config\Value; +use Magento\Framework\Exception\LocalizedException; + +class Price extends Value { /** * Validate that the number is a valid price. * * @return $this - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ public function save() { @@ -34,7 +38,7 @@ public function save() */ $value = $this->getValue(); if (!empty($value) && !is_numeric($value)) { - throw new \Magento\Framework\Exception\LocalizedException(__("Please enter a valid number: '%1'.", $value)); + throw new LocalizedException(__("Please enter a valid number: '%1'.", $value)); } return parent::save(); diff --git a/Model/Config/Backend/TransactionLabel.php b/Model/Config/Backend/TransactionLabel.php index ea3041a7f..fcb0f1f03 100644 --- a/Model/Config/Backend/TransactionLabel.php +++ b/Model/Config/Backend/TransactionLabel.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,21 +17,65 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ + namespace Buckaroo\Magento2\Model\Config\Backend; -class TransactionLabel extends \Magento\Framework\App\Config\Value +use Magento\Framework\App\Cache\TypeListInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Config\Value; +use Magento\Framework\Data\Collection\AbstractDb; +use Magento\Framework\Model\Context; +use Magento\Framework\Model\ResourceModel\AbstractResource; +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface; + +class TransactionLabel extends Value { + /** + * @var StoreManagerInterface + */ + private StoreManagerInterface $storeManagerInterface; + + /** + * @param StoreManagerInterface $storeManagerInterface + * @param Context $context + * @param Registry $registry + * @param ScopeConfigInterface $config + * @param TypeListInterface $cacheTypeList + * @param AbstractResource|null $resource + * @param AbstractDb|null $resourceCollection + * @param array $data + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + public function __construct( + StoreManagerInterface $storeManagerInterface, + Context $context, + Registry $registry, + ScopeConfigInterface $config, + TypeListInterface $cacheTypeList, + AbstractResource $resource = null, + AbstractDb $resourceCollection = null, + array $data = [] + ) { + $this->storeManagerInterface = $storeManagerInterface; + parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); + } + + /** + * @inheritdoc + */ public function _afterLoad() { $value = $this->getValue(); if (!$value || $value == 'Magento Buckaroo') { - $storeName = \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Store\Model\StoreManagerInterface::class) - ->getStore() - ->getName(); + $storeName = $this->storeManagerInterface + ->getStore() + ->getName(); if ($storeName) { $this->setValue($storeName); } } + return $this; } } diff --git a/Model/Config/Source/Afterpay2PaymentMethods.php b/Model/Config/Source/Afterpay2PaymentMethods.php index f6cf914bc..26caa5b23 100644 --- a/Model/Config/Source/Afterpay2PaymentMethods.php +++ b/Model/Config/Source/Afterpay2PaymentMethods.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,24 +17,27 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ +declare(strict_types=1); namespace Buckaroo\Magento2\Model\Config\Source; -class Afterpay2PaymentMethods implements \Magento\Framework\Option\ArrayInterface +use Magento\Framework\Data\OptionSourceInterface; + +class Afterpay2PaymentMethods implements OptionSourceInterface { - const PAYMENT_METHOD_ACCEPTGIRO = 1; - const PAYMENT_METHOD_DIGIACCEPT = 2; + public const PAYMENT_METHOD_ACCEPTGIRO = 1; + public const PAYMENT_METHOD_DIGIACCEPT = 2; /** * Options getter * * @return array */ - public function toOptionArray() + public function toOptionArray(): array { $options = []; - // These are the paymethods available at Afterpay + // These are the payment methods available at Afterpay $options[] = ['value' => self::PAYMENT_METHOD_ACCEPTGIRO, 'label' => __('Acceptgiro')]; $options[] = ['value' => self::PAYMENT_METHOD_DIGIACCEPT, 'label' => __('Digiaccept')]; diff --git a/Model/Config/Source/AfterpayCustomerType.php b/Model/Config/Source/AfterpayCustomerType.php index 7141abc1e..d938667fe 100644 --- a/Model/Config/Source/AfterpayCustomerType.php +++ b/Model/Config/Source/AfterpayCustomerType.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,10 +17,13 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ +declare(strict_types=1); namespace Buckaroo\Magento2\Model\Config\Source; -class AfterpayCustomerType implements \Magento\Framework\Data\OptionSourceInterface +use Magento\Framework\Data\OptionSourceInterface; + +class AfterpayCustomerType implements OptionSourceInterface { public const CUSTOMER_TYPE_B2C = 'b2c'; public const CUSTOMER_TYPE_B2B = 'b2b'; @@ -31,12 +34,12 @@ class AfterpayCustomerType implements \Magento\Framework\Data\OptionSourceInterf * * @return array */ - public function toOptionArray() + public function toOptionArray(): array { return [ ['value' => self::CUSTOMER_TYPE_BOTH, 'label' => __('Both')], - ['value' => self::CUSTOMER_TYPE_B2C, 'label' => __('B2C (Business-to-consumer)')], - ['value' => self::CUSTOMER_TYPE_B2B, 'label' => __('B2B ((Business-to-Business)')] + ['value' => self::CUSTOMER_TYPE_B2C, 'label' => __('B2C (Business-to-Consumer)')], + ['value' => self::CUSTOMER_TYPE_B2B, 'label' => __('B2B (Business-to-Business)')] ]; } } diff --git a/Model/Config/Source/AfterpayPaymentMethods.php b/Model/Config/Source/AfterpayPaymentMethods.php index ff5df4835..bcf3b459f 100644 --- a/Model/Config/Source/AfterpayPaymentMethods.php +++ b/Model/Config/Source/AfterpayPaymentMethods.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,20 +17,23 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ +declare(strict_types=1); namespace Buckaroo\Magento2\Model\Config\Source; -class AfterpayPaymentMethods implements \Magento\Framework\Option\ArrayInterface +use Magento\Framework\Data\OptionSourceInterface; + +class AfterpayPaymentMethods implements OptionSourceInterface { - const PAYMENT_METHOD_ACCEPTGIRO = 1; - const PAYMENT_METHOD_DIGIACCEPT = 2; + public const PAYMENT_METHOD_ACCEPTGIRO = 1; + public const PAYMENT_METHOD_DIGIACCEPT = 2; /** * Options getter * * @return array */ - public function toOptionArray() + public function toOptionArray(): array { $options = []; diff --git a/Model/Config/Source/AllOrSpecificCountries.php b/Model/Config/Source/AllOrSpecificCountries.php index 507068ec9..3e25a165e 100644 --- a/Model/Config/Source/AllOrSpecificCountries.php +++ b/Model/Config/Source/AllOrSpecificCountries.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,16 +17,20 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ +declare(strict_types=1); + namespace Buckaroo\Magento2\Model\Config\Source; -class AllOrSpecificCountries implements \Magento\Framework\Option\ArrayInterface +use Magento\Framework\Data\OptionSourceInterface; + +class AllOrSpecificCountries implements OptionSourceInterface { /** * Options getter * * @return array */ - public function toOptionArray() + public function toOptionArray(): array { return [ ['value' => 0, 'label' => __('All Allowed Countries')], @@ -39,7 +43,7 @@ public function toOptionArray() * * @return array */ - public function toArray() + public function toArray(): array { return [ 0 => __('All Allowed Countries'), diff --git a/Model/Config/Source/AllowedCountries.php b/Model/Config/Source/AllowedCountries.php index e62c871b6..ff63a27b1 100644 --- a/Model/Config/Source/AllowedCountries.php +++ b/Model/Config/Source/AllowedCountries.php @@ -5,8 +5,8 @@ * This source file is subject to the MIT License * It is available through the world-wide-web at this URL: * https://tldrlegal.com/license/mit-license - * If you are unable to obtain it through the world-wide-web, please send an email - * to support@buckaroo.nl so we can send you a copy immediately. + * If you are unable to obtain it through the world-wide-web, please email + * to support@buckaroo.nl, so we can send you a copy immediately. * * DISCLAIMER * @@ -17,27 +17,38 @@ * @copyright Copyright (c) Buckaroo B.V. * @license https://tldrlegal.com/license/mit-license */ +declare(strict_types=1); + namespace Buckaroo\Magento2\Model\Config\Source; +use Buckaroo\Magento2\Exception as BuckarooException; use Magento\Framework\Data\OptionSourceInterface; use Magento\Framework\Locale\Bundle\RegionBundle; use Magento\Framework\Locale\ListsInterface; use Magento\Framework\Locale\ResolverInterface; -use Buckaroo\Magento2\Model\ConfigProvider\Method\Factory as ConfigProviderFactory; +use Buckaroo\Magento2\Model\ConfigProvider\Factory as ConfigProviderFactory; class AllowedCountries implements OptionSourceInterface { - /** @var ListsInterface */ - private $localeLists; + /** + * @var ListsInterface + */ + private ListsInterface $localeLists; - /** @var ConfigProviderFactory */ - private $configProviderMethodFactory; + /** + * @var ConfigProviderFactory + */ + private ConfigProviderFactory $configProviderMethodFactory; - /** @var ResolverInterface */ - protected $localeResolver; + /** + * @var ResolverInterface + */ + protected ResolverInterface $localeResolver; - /** @var RegionBundle */ - protected $regionBundle; + /** + * @var RegionBundle + */ + protected RegionBundle $regionBundle; /** * @param ListsInterface $localeLists @@ -60,12 +71,12 @@ public function __construct( /** * Return array of options as value-label pairs * - * @param null $method + * @param string|null $method * * @return array Format: array(array('value' => '', 'label' => '