diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9303fa46..cf2e0888 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,13 +23,13 @@ jobs: - 3306:3306 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install PHP uses: shivammathur/setup-php@master with: php-version: ${{ matrix.php-versions }} extensions: mbstring, gd, bcmath, ctype, curl, dom, hash, iconv, intl, openssl, simplexml, soap, xsl, zip - tools: composer:v1 + tools: composer:v2.1 - name: Validate composer.json and composer.lock run: composer validate diff --git a/.github/workflows/build_magento23.yml b/.github/workflows/build_magento23.yml index 45e3ca74..c880c97a 100644 --- a/.github/workflows/build_magento23.yml +++ b/.github/workflows/build_magento23.yml @@ -23,13 +23,13 @@ jobs: - 3306:3306 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install PHP uses: shivammathur/setup-php@master with: php-version: ${{ matrix.php-versions }} extensions: mbstring, gd, bcmath, ctype, curl, dom, hash, iconv, intl, openssl, simplexml, soap, xsl, zip - tools: composer:v1 + tools: composer:v1.8 - name: Validate composer.json and composer.lock run: composer validate diff --git a/.github/workflows/build_magento244php81.yml b/.github/workflows/build_magento244php81.yml index fe09ac6c..a8cf7d78 100644 --- a/.github/workflows/build_magento244php81.yml +++ b/.github/workflows/build_magento244php81.yml @@ -23,13 +23,13 @@ jobs: - 3306:3306 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install PHP uses: shivammathur/setup-php@master with: php-version: ${{ matrix.php-versions }} extensions: mbstring, gd, bcmath, ctype, curl, dom, hash, iconv, intl, openssl, simplexml, soap, xsl, zip - tools: composer:v1 + tools: composer:v2.1 - name: Validate composer.json and composer.lock run: composer validate diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml index a297598f..c49b3368 100644 --- a/.github/workflows/gitleaks.yml +++ b/.github/workflows/gitleaks.yml @@ -6,6 +6,6 @@ jobs: gitleaks: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: gitleaks-action - uses: gitleaks/gitleaks-action@v1.6.0 + uses: FatchipRobert/gitleaks-action@v1.6.1 diff --git a/Api/Data/RatepayConfigResponseInterface.php b/Api/Data/RatepayConfigResponseInterface.php new file mode 100644 index 00000000..39988b2f --- /dev/null +++ b/Api/Data/RatepayConfigResponseInterface.php @@ -0,0 +1,44 @@ +. + * + * PHP version 8 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2023 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Api\Data; + +interface RatepayConfigResponseInterface +{ + /** + * Returns if editing the address was a success + * + * @return bool + */ + public function getSuccess(); + + /** + * Returns config json array + * + * @return string + */ + public function getConfig(); +} diff --git a/Api/RatepayConfigInterface.php b/Api/RatepayConfigInterface.php new file mode 100644 index 00000000..a2036d8a --- /dev/null +++ b/Api/RatepayConfigInterface.php @@ -0,0 +1,40 @@ +. + * + * PHP version 8 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2023 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Api; + +interface RatepayConfigInterface +{ + /** + * PAYONE editAddress script + * The full class-paths must be given here otherwise the Magento 2 WebApi + * cant handle this with its fake type system! + * + * @param string $cartId + * @return \Payone\Core\Service\V1\Data\RatepayConfigResponse + */ + public function getConfig($cartId); +} diff --git a/Block/Adminhtml/Config/Form/Field/RefreshRatepayProfiles.php b/Block/Adminhtml/Config/Form/Field/RefreshRatepayProfiles.php index b0b07710..64ab6561 100644 --- a/Block/Adminhtml/Config/Form/Field/RefreshRatepayProfiles.php +++ b/Block/Adminhtml/Config/Form/Field/RefreshRatepayProfiles.php @@ -45,6 +45,19 @@ protected function _prepareLayout() return $this; } + /** + * Generates unique javascript function name for each payment method + * + * @param string $sPaymentMethod + * @return string + */ + protected function getJSFunctionName($sPaymentMethod) + { + $sPaymentMethod = ucwords($sPaymentMethod, "_"); + $sPaymentMethod = str_replace("_", "", $sPaymentMethod); + return "updateProfileConfigs".$sPaymentMethod; + } + /** * Unset some non-related element parameters * @@ -69,7 +82,8 @@ protected function _getElementHtml(\Magento\Framework\Data\Form\Element\Abstract $sPaymentMethod = str_replace('payone_payment/', '', $originalData['path']); $this->addData([ - 'ajax_url' => $this->_urlBuilder->getUrl('payone/config_ratepay/refresh', ['method' => $sPaymentMethod]) + 'ajax_url' => $this->_urlBuilder->getUrl('payone/config_ratepay/refresh', ['method' => $sPaymentMethod]), + 'javascript_function_name' => $this->getJSFunctionName($sPaymentMethod), ]); return $this->_toHtml(); diff --git a/Block/BNPL/InstallmentPlan.php b/Block/BNPL/InstallmentPlan.php index 961286fd..12e32e72 100644 --- a/Block/BNPL/InstallmentPlan.php +++ b/Block/BNPL/InstallmentPlan.php @@ -64,11 +64,11 @@ public function formatPrice($dPrice) */ public function getSelectLinkText($aInstallment) { - $sText = $this->formatPrice($aInstallment['monthly_amount_value']).' '; - $sText .= $aInstallment['monthly_amount_currency'].' '; - $sText .= __('per month').' - '; - $sText .= $aInstallment['number_of_payments'].' '; - $sText .= __('installments'); + $sText = __('Payment in'); + $sText .= ' '.$aInstallment['number_of_payments'].' '; + $sText .= __('installments of').' '; + $sText .= $this->formatPrice($aInstallment['monthly_amount_value']).' '; + $sText .= $aInstallment['monthly_amount_currency']; return $sText; } } diff --git a/Block/Form/RatepayInvoice.php b/Block/Form/RatepayInvoice.php new file mode 100644 index 00000000..23544a66 --- /dev/null +++ b/Block/Form/RatepayInvoice.php @@ -0,0 +1,188 @@ +orderCreate = $orderCreate; + $this->ratepayHelper = $ratepayHelper; + } + + /** + * Retrieve create order model object + * + * @return \Magento\Quote\Model\Quote + */ + public function getQuote() + { + return $this->orderCreate->getQuote(); + } + + /** + * Tries to determine a matching ratepay configuration + * + * @return array + */ + public function getRatepayConfig() + { + if ($this->ratepayConfig === null) { + $this->ratepayConfig = $this->ratepayHelper->getRatepaySingleConfig(PayoneConfig::METHOD_RATEPAY_INVOICE, $this->getQuote()); + } + return $this->ratepayConfig; + } + + /** + * Returns snippet id from config + * + * @return string + */ + public function getDevicefingerprintSnippetId() + { + return $this->ratepayHelper->getConfigParam('devicefingerprint_snippet_id', 'ratepay', 'payone_misc'); + } + + /** + * Returns token generated by Ratepay helper + * + * @return string + */ + public function getDevicefingerprintToken() + { + return $this->ratepayHelper->getRatepayDeviceFingerprintToken(); + } + + /** + * Returns if birthday has to be entered + * + * @return bool + */ + public function isBirthdayNeeded() + { + if ($this->isB2BMode() === true) { + return false; + } + return true; + } + + /** + * Return if customer has entered a company name in his billing address + * + * @return bool + */ + public function isB2BMode() + { + $billingAddress = $this->getQuote()->getBillingAddress(); + if ($billingAddress && !empty($billingAddress->getCompany())) { + return true; + } + return false; + } + + /** + * Return if ratepay config allows B2B mode + * + * @return bool + */ + public function isB2BModeAllowed() + { + $aConfig = $this->getRatepayConfig(); + if (isset($aConfig['b2bAllowed'])) { + return (bool)$aConfig['b2bAllowed']; + } + return false; + } + + /** + * Return if ratepay config allows differing delivery addresses + * + * @return bool + */ + public function isDifferingDeliveryAddressAllowed() + { + $aConfig = $this->getRatepayConfig(); + if (isset($aConfig['differentAddressAllowed'])) { + return (bool)$aConfig['differentAddressAllowed']; + } + return false; + } + + /** + * Returns if billing address is different as shipping address + * + * @return true + */ + public function hasDifferingDeliveryAddress() + { + return !$this->getQuote()->getShippingAddress()->getSameAsBilling(); + } + + /** + * Returns the customers birthday if known + * + * @return string + */ + public function getBirthday() + { + return $this->getQuote()->getCustomer()->getDob(); + } + + /** + * Returns a part of the birthday (day, month or year) + * + * @param string $sPart + * @return string + */ + public function getBirthdayPart($sPart) + { + $sBirthday = $this->getBirthday(); + if (!empty($sBirthday)) { + $timestamp = strtotime($sBirthday); + return date($sPart, $timestamp); + } + return ''; + } + + /** + * Returns if the telephone number has to be entered + * + * @return bool + */ + public function isTelephoneNeeded() + { + $billingAddress = $this->getQuote()->getBillingAddress(); + if ($billingAddress && !empty($billingAddress->getTelephone())) { + return false; + } + return true; + } +} diff --git a/Block/Onepage/Totals.php b/Block/Onepage/Totals.php index 5430bd5d..05b7f846 100644 --- a/Block/Onepage/Totals.php +++ b/Block/Onepage/Totals.php @@ -61,7 +61,6 @@ public function __construct( ) { $this->_salesConfig = $salesConfig; parent::__construct($context, $customerSession, $checkoutSession, $salesConfig, $layoutProcessors, $data); - $this->_isScopePrivate = true; $this->layoutProcessors = $layoutProcessors; $this->baseHelper = $baseHelper; } diff --git a/Block/RatepayDeviceFingerprint.php b/Block/RatepayDeviceFingerprint.php index a5132181..821434c1 100644 --- a/Block/RatepayDeviceFingerprint.php +++ b/Block/RatepayDeviceFingerprint.php @@ -87,9 +87,9 @@ public function getDevicefingerprintToken() */ protected function isRatepayMethodActive() { - if ($this->paymentHelper->isPaymentMethodActive(PayoneConfig::METHOD_RATEPAY_INVOICE) === false || - $this->paymentHelper->isPaymentMethodActive(PayoneConfig::METHOD_RATEPAY_DEBIT) === false || - $this->paymentHelper->isPaymentMethodActive(PayoneConfig::METHOD_RATEPAY_INSTALLMENT) === false + if ($this->paymentHelper->isPaymentMethodActive(PayoneConfig::METHOD_RATEPAY_INVOICE) === true || + $this->paymentHelper->isPaymentMethodActive(PayoneConfig::METHOD_RATEPAY_DEBIT) === true || + $this->paymentHelper->isPaymentMethodActive(PayoneConfig::METHOD_RATEPAY_INSTALLMENT) === true ) { return true; } diff --git a/Controller/Onepage/PlaceOrder.php b/Controller/Onepage/PlaceOrder.php index d6048aa7..a7485e0f 100644 --- a/Controller/Onepage/PlaceOrder.php +++ b/Controller/Onepage/PlaceOrder.php @@ -88,6 +88,22 @@ public function execute() try { $this->placeOrder(); + $sPayoneRedirectUrl = $this->checkoutSession->getPayoneRedirectUrl(); + if (!empty($sPayoneRedirectUrl)) { + $this->checkoutSession->setPayoneCustomerIsRedirected(true); + $this->checkoutSession->setPayonePayPalExpressRetry(true); + $this->_redirect($sPayoneRedirectUrl); + return; + } + + $oQuote = $this->checkoutSession->getQuote(); + + // "last successful quote" + $sQuoteId = $oQuote->getId(); + $this->checkoutSession->setLastQuoteId($sQuoteId)->setLastSuccessQuoteId($sQuoteId)->unsPayoneWorkorderId()->unsIsPayonePayPalExpress()->unsPayoneUserAgent()->unsPayoneDeviceFingerprint(); + + $oQuote->setIsActive(false)->save(); + $this->_redirect('checkout/onepage/success'); } catch (\Exception $e) { $this->messageManager->addExceptionMessage( @@ -129,12 +145,6 @@ protected function placeOrder() } $this->cartManagement->placeOrder($oQuote->getId()); - - // "last successful quote" - $sQuoteId = $oQuote->getId(); - $this->checkoutSession->setLastQuoteId($sQuoteId)->setLastSuccessQuoteId($sQuoteId)->unsPayoneWorkorderId()->unsIsPayonePayPalExpress()->unsPayoneUserAgent()->unsPayoneDeviceFingerprint(); - - $oQuote->setIsActive(false)->save(); } /** diff --git a/Controller/Paypal/Returned.php b/Controller/Paypal/Returned.php index 9eeedbff..f46279b6 100644 --- a/Controller/Paypal/Returned.php +++ b/Controller/Paypal/Returned.php @@ -73,6 +73,14 @@ public function __construct( */ public function execute() { + if ($this->checkoutSession->getPayonePayPalExpressRetry() === true) { // Is double redirect PayPal Express scenario? + $this->checkoutSession->unsPayonePayPalExpressRetry(); + + /** @var Redirect $resultRedirect */ + $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); + return $resultRedirect->setPath('checkout/onepage/success'); + } + $this->checkoutSession->setIsPayonePayPalExpress(true); $sWorkorderId = $this->checkoutSession->getPayoneWorkorderId(); if ($sWorkorderId) { diff --git a/Helper/Payment.php b/Helper/Payment.php index fbb5c8df..f47e5a5d 100644 --- a/Helper/Payment.php +++ b/Helper/Payment.php @@ -73,7 +73,7 @@ class Payment extends \Payone\Core\Helper\Base PayoneConfig::METHOD_BANCONTACT, PayoneConfig::METHOD_BNPL_INVOICE, PayoneConfig::METHOD_BNPL_INSTALLMENT, - //BNPL_DEBIT_DEACTIVATED PayoneConfig::METHOD_BNPL_DEBIT, + PayoneConfig::METHOD_BNPL_DEBIT, ]; /** diff --git a/Helper/Ratepay.php b/Helper/Ratepay.php index 47c7f5e8..a56b8dfd 100644 --- a/Helper/Ratepay.php +++ b/Helper/Ratepay.php @@ -26,11 +26,24 @@ namespace Payone\Core\Helper; +use Payone\Core\Model\PayoneConfig; + /** * Helper class for ratepay payment */ class Ratepay extends \Payone\Core\Helper\Base { + /** + * Map for methodCode to short payment method identifier for database columns + * + * @var array + */ + protected $aMethodIdentifierMap = [ + PayoneConfig::METHOD_RATEPAY_INVOICE => 'invoice', + PayoneConfig::METHOD_RATEPAY_DEBIT => 'elv', + PayoneConfig::METHOD_RATEPAY_INSTALLMENT => 'installment', + ]; + /** * Object of profile request * @@ -59,6 +72,13 @@ class Ratepay extends \Payone\Core\Helper\Base */ protected $apiHelper; + /** + * Payone Payment helper + * + * @var \Payone\Core\Helper\Payment + */ + protected $paymentHelper; + /** * Constructor * @@ -70,6 +90,7 @@ class Ratepay extends \Payone\Core\Helper\Base * @param \Payone\Core\Model\ResourceModel\RatepayProfileConfig $profileResource * @param \Magento\Checkout\Model\Session $checkoutSession * @param \Payone\Core\Helper\Api $apiHelper + * @param \Payone\Core\Helper\Payment $paymentHelper */ public function __construct( \Magento\Framework\App\Helper\Context $context, @@ -79,13 +100,15 @@ public function __construct( \Payone\Core\Model\Api\Request\Genericpayment\Profile $profile, \Payone\Core\Model\ResourceModel\RatepayProfileConfig $profileResource, \Magento\Checkout\Model\Session $checkoutSession, - \Payone\Core\Helper\Api $apiHelper + \Payone\Core\Helper\Api $apiHelper, + \Payone\Core\Helper\Payment $paymentHelper ) { parent::__construct($context, $storeManager, $shopHelper, $state); $this->profile = $profile; $this->profileResource = $profileResource; $this->checkoutSession = $checkoutSession; $this->apiHelper = $apiHelper; + $this->paymentHelper = $paymentHelper; } /** @@ -221,6 +244,20 @@ public function getRatepayDeviceFingerprintToken() return $sTokenFromSession; } + /** + * Returns ratepay method identifier + * + * @param string $sMethodCode + * @return string|false + */ + protected function getRatepayMethodIdentifierByMethodCode($sMethodCode) + { + if (isset($this->aMethodIdentifierMap[$sMethodCode])) { + return $this->aMethodIdentifierMap[$sMethodCode]; + } + return false; + } + /** * Get matching Ratepay shop id for current transaction * @@ -228,14 +265,75 @@ public function getRatepayDeviceFingerprintToken() * @param string $sCountryCode * @param string $sCurrency * @param double $dGrandTotal - * @return string + * @param bool $blGetConfigWithoutTotals + * @return string|false */ - public function getRatepayShopId($sMethodCode, $sCountryCode, $sCurrency, $dGrandTotal) + public function getRatepayShopId($sMethodCode, $sCountryCode, $sCurrency, $dGrandTotal, $blGetConfigWithoutTotals = false) { + $sRatepayMethodIdentifier = $this->getRatepayMethodIdentifierByMethodCode($sMethodCode); + $aShopIds = $this->getRatepayShopConfigIdsByPaymentMethod($sMethodCode); - $sShopId = $this->profileResource->getMatchingShopId($sMethodCode, $aShopIds, $sCountryCode, $sCurrency, $dGrandTotal); + return $this->profileResource->getMatchingShopId($sRatepayMethodIdentifier, $aShopIds, $sCountryCode, $sCurrency, $dGrandTotal, $blGetConfigWithoutTotals); + } + + /** + * Returns matching Ratepay shop id by given quote + * + * @param string $sMethodCode + * @param \Magento\Quote\Api\Data\CartInterface $quote + * @param bool $blGetConfigWithoutTotals + * @return string + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function getShopIdByQuote($sMethodCode, \Magento\Quote\Api\Data\CartInterface $quote, $blGetConfigWithoutTotals = false) + { + $sCountryCode = $quote->getShippingAddress()->getCountryId(); + if (empty($sCountryCode)) { + $sCountryCode = $quote->getBillingAddress()->getCountryId(); + } + $sCurrency = $this->apiHelper->getCurrencyFromQuote($quote); + $dGrandTotal = $this->apiHelper->getQuoteAmount($quote); - return $sShopId; + return $this->getRatepayShopId($sMethodCode, $sCountryCode, $sCurrency, $dGrandTotal, $blGetConfigWithoutTotals); + } + + /** + * Returns matching Ratepay shop config by quote + * + * @param string $sMethodCode + * @param \Magento\Quote\Api\Data\CartInterface|null $quote + * @param bool $blGetConfigWithoutTotals + * @return array + */ + public function getShopConfigByQuote($sMethodCode, \Magento\Quote\Api\Data\CartInterface $quote = null, $blGetConfigWithoutTotals = false) + { + if ($quote === null) { + $quote = $this->checkoutSession->getQuote(); + } + + $sShopId = $this->getShopIdByQuote($sMethodCode, $quote, $blGetConfigWithoutTotals); + if (empty($sShopId)) { + return []; + } + return $this->getRatepayShopConfigById($sShopId); + } + + /** + * Returns a certain property from the given shop config array + * + * @param array $aShopConfig + * @param string $sMethodCode + * @param string $sProperty + * @return string|false + */ + public function getShopConfigProperty($aShopConfig, $sMethodCode, $sProperty) + { + $sRatepayMethodIdentifier = $this->getRatepayMethodIdentifierByMethodCode($sMethodCode); + + if (isset($aShopConfig[$sProperty.'_'.$sRatepayMethodIdentifier])) { + return $aShopConfig[$sProperty.'_'.$sRatepayMethodIdentifier]; + } + return false; } /** @@ -252,4 +350,44 @@ public function getRatepayShopConfigById($sShopId) } return false; } + + /** + * Return Ratepay config for config provider + * + * @return array + */ + public function getRatepayConfig() + { + $aReturn = []; + + foreach (PayoneConfig::METHODS_RATEPAY as $sRatepayMethod) { + if ($this->paymentHelper->isPaymentMethodActive($sRatepayMethod) === true) { + $aReturn[$sRatepayMethod] = $this->getRatepaySingleConfig($sRatepayMethod); + } + } + return $aReturn; + } + + /** + * Return Ratepay configuration for given method code + * + * @param string $sRatepayMethodCode + * @param \Magento\Quote\Api\Data\CartInterface|null $quote + * @return array|bool[] + */ + public function getRatepaySingleConfig($sRatepayMethodCode, \Magento\Quote\Api\Data\CartInterface $quote = null) + { + $aShopConfig = $this->getShopConfigByQuote($sRatepayMethodCode, $quote); + if (empty($aShopConfig)) { + $aShopConfig = $this->getShopConfigByQuote($sRatepayMethodCode, $quote, true); + if (empty($aShopConfig)) { + return []; + } + } + + return [ + 'b2bAllowed' => (bool)$this->getShopConfigProperty($aShopConfig, $sRatepayMethodCode, 'b2b'), + 'differentAddressAllowed' => (bool)$this->getShopConfigProperty($aShopConfig, $sRatepayMethodCode, 'delivery_address'), + ]; + } } diff --git a/Helper/Toolkit.php b/Helper/Toolkit.php index 16c00fcd..f44963c5 100644 --- a/Helper/Toolkit.php +++ b/Helper/Toolkit.php @@ -213,7 +213,7 @@ public function maskIban($sUnmasked) */ public function isUTF8($sString) { - return $sString === mb_convert_encoding(mb_convert_encoding($sString, "UTF-32", "UTF-8"), "UTF-8", "UTF-32"); + return $sString === mb_convert_encoding(mb_convert_encoding($sString ?? '', "UTF-32", "UTF-8"), "UTF-8", "UTF-32"); } /** diff --git a/Model/ConfigProvider.php b/Model/ConfigProvider.php index 26ddaabc..6d92ef73 100644 --- a/Model/ConfigProvider.php +++ b/Model/ConfigProvider.php @@ -140,6 +140,13 @@ class ConfigProvider extends \Magento\Payment\Model\CcGenericConfigProvider */ protected $toolkitHelper; + /** + * PAYONE ratepay helper + * + * @var \Payone\Core\Helper\Ratepay + */ + protected $ratepayHelper; + /** * Constructor * @@ -159,6 +166,7 @@ class ConfigProvider extends \Magento\Payment\Model\CcGenericConfigProvider * @param \Payone\Core\Model\ResourceModel\SavedPaymentData $savedPaymentData * @param \Payone\Core\Model\Methods\Ratepay\Installment\Proxy $ratepayInstallment * @param \Payone\Core\Helper\Toolkit $toolkitHelper + * @param \Payone\Core\Helper\Ratepay $ratepayHelper */ public function __construct( \Magento\Payment\Model\CcConfig $ccConfig, @@ -176,7 +184,8 @@ public function __construct( \Payone\Core\Helper\Shop $shopHelper, \Payone\Core\Model\ResourceModel\SavedPaymentData $savedPaymentData, \Payone\Core\Model\Methods\Ratepay\Installment\Proxy $ratepayInstallment, - \Payone\Core\Helper\Toolkit $toolkitHelper + \Payone\Core\Helper\Toolkit $toolkitHelper, + \Payone\Core\Helper\Ratepay $ratepayHelper ) { parent::__construct($ccConfig, $dataHelper); $this->dataHelper = $dataHelper; @@ -194,6 +203,7 @@ public function __construct( $this->savedPaymentData = $savedPaymentData; $this->ratepayInstallment = $ratepayInstallment; $this->toolkitHelper = $toolkitHelper; + $this->ratepayHelper = $ratepayHelper; } /** @@ -278,7 +288,8 @@ protected function getPayoneConfig() 'currency' => $this->requestHelper->getConfigParam('currency'), 'klarnaTitles' => $this->paymentHelper->getKlarnaMethodTitles(), 'storeName' => $this->shopHelper->getStoreName(), - 'ratepayAllowedMonths' => $this->getRatepayAllowedMonths(), + 'ratepay' => $this->getRatepayConfig(), + 'ratepayRefreshed' => false, 'bnpl' => $this->getBNPLConfig(), ]; } @@ -330,12 +341,19 @@ protected function isPaydirektOneKlickDisplayable() return false; } - protected function getRatepayAllowedMonths() + /** + * Return ratepay config for all ratepay payment methods + * + * @return array + */ + protected function getRatepayConfig() { - if ($this->paymentHelper->isPaymentMethodActive(PayoneConfig::METHOD_RATEPAY_INSTALLMENT) === true) { - return $this->ratepayInstallment->getAllowedMonths(); + $aReturn = $this->ratepayHelper->getRatepayConfig(); + + if (isset($aReturn[PayoneConfig::METHOD_RATEPAY_INSTALLMENT])) { + $aReturn[PayoneConfig::METHOD_RATEPAY_INSTALLMENT]['allowedMonths'] = $this->ratepayInstallment->getAllowedMonths(); } - return []; + return $aReturn; } /** @@ -383,14 +401,17 @@ protected function getBNPLConfig() 'environment' => [ // "t" for TEST, "p" for PROD PayoneConfig::METHOD_BNPL_INVOICE => $this->requestHelper->getConfigParam('mode', PayoneConfig::METHOD_BNPL_INVOICE, 'payone_payment') == 'live' ? 'p' : 't', PayoneConfig::METHOD_BNPL_INSTALLMENT => $this->requestHelper->getConfigParam('mode', PayoneConfig::METHOD_BNPL_INSTALLMENT, 'payone_payment') == 'live' ? 'p' : 't', + PayoneConfig::METHOD_BNPL_DEBIT => $this->requestHelper->getConfigParam('mode', PayoneConfig::METHOD_BNPL_DEBIT, 'payone_payment') == 'live' ? 'p' : 't', ], 'mid' => [ PayoneConfig::METHOD_BNPL_INVOICE => $this->paymentHelper->getCustomConfigParam('mid', PayoneConfig::METHOD_BNPL_INVOICE), PayoneConfig::METHOD_BNPL_INSTALLMENT => $this->paymentHelper->getCustomConfigParam('mid', PayoneConfig::METHOD_BNPL_INSTALLMENT), + PayoneConfig::METHOD_BNPL_DEBIT => $this->paymentHelper->getCustomConfigParam('mid', PayoneConfig::METHOD_BNPL_DEBIT), ], 'differentAddressAllowed' => [ PayoneConfig::METHOD_BNPL_INVOICE => (bool)$this->requestHelper->getConfigParam('different_address_allowed', PayoneConfig::METHOD_BNPL_INVOICE, 'payment'), PayoneConfig::METHOD_BNPL_INSTALLMENT => (bool)$this->requestHelper->getConfigParam('different_address_allowed', PayoneConfig::METHOD_BNPL_INSTALLMENT, 'payment'), + PayoneConfig::METHOD_BNPL_DEBIT => (bool)$this->requestHelper->getConfigParam('different_address_allowed', PayoneConfig::METHOD_BNPL_DEBIT, 'payment'), ], 'payla_partner_id' => BNPLBase::BNPL_PARTNER_ID, 'uuid' => $this->getUUID(), diff --git a/Model/Entities/ApiLog.php b/Model/Entities/ApiLog.php index 7ecc03e8..d4123ad1 100644 --- a/Model/Entities/ApiLog.php +++ b/Model/Entities/ApiLog.php @@ -83,7 +83,7 @@ protected function formatArray($aArray) { foreach ($aArray as $sKey => $mValue) { if (!$this->toolkitHelper->isUTF8($mValue)) { - $aArray[$sKey] = utf8_encode($mValue); + $aArray[$sKey] = utf8_encode($mValue ?? ''); } } return $aArray; @@ -105,7 +105,7 @@ protected function getUnserializedArray($sKey, $blSort = false) $aRequest = unserialize($sRequest); } catch(\Exception $exc) { if ($this->toolkitHelper->isUTF8($sRequest)) { - $aRequest = unserialize(utf8_decode($sRequest)); + $aRequest = unserialize(utf8_decode($sRequest ?? '')); } } if (is_array($aRequest)) { diff --git a/Model/Methods/BNPL/BNPLBase.php b/Model/Methods/BNPL/BNPLBase.php index 5ce8ac8c..503c83c7 100644 --- a/Model/Methods/BNPL/BNPLBase.php +++ b/Model/Methods/BNPL/BNPLBase.php @@ -19,7 +19,7 @@ * @category Payone * @package Payone_Magento2_Plugin * @author FATCHIP GmbH - * @copyright 2003 - 2020 Payone GmbH + * @copyright 2003 - 2023 Payone GmbH * @license GNU Lesser General Public License * @link http://www.payone.de */ @@ -83,7 +83,6 @@ class BNPLBase extends PayoneMethod 'dateofbirth', 'telephone', 'iban', - 'bankaccountholder', 'installmentOption', 'optionid', ]; @@ -254,4 +253,29 @@ public function assignData(DataObject $data) return $this; } + + /** + * Perform certain actions with the response + * + * @param array $aResponse + * @param Order $oOrder + * @param float $amount + * @return array + */ + protected function handleResponse($aResponse, Order $oOrder, $amount) + { + if (isset($aResponse['status']) && $aResponse['status'] == 'ERROR' && isset($aResponse['errorcode']) && $aResponse['errorcode'] == '307') { + $aBans = $this->checkoutSession->getPayonePaymentBans(); + if (empty($aBans)) { + $aBans = []; + } + + $sBannedUntil = date('Y-m-d H:i:s', (time() + (60 * 60 * 8))); + $aBans[PayoneConfig::METHOD_BNPL_DEBIT] = $sBannedUntil; + $aBans[PayoneConfig::METHOD_BNPL_INSTALLMENT] = $sBannedUntil; + $aBans[PayoneConfig::METHOD_BNPL_INVOICE] = $sBannedUntil; + $this->checkoutSession->setPayonePaymentBans($aBans); + } + return $aResponse; + } } diff --git a/Model/Methods/BNPL/Debit.php b/Model/Methods/BNPL/Debit.php index 5ef338ee..d661b6d6 100644 --- a/Model/Methods/BNPL/Debit.php +++ b/Model/Methods/BNPL/Debit.php @@ -55,9 +55,10 @@ class Debit extends BNPLBase public function getSubTypeSpecificParameters(Order $oOrder) { $oInfoInstance = $this->getInfoInstance(); + $oBilling = $oOrder->getBillingAddress(); $aParams = [ - 'bankaccountholder' => $oInfoInstance->getAdditionalInformation('bankaccountholder'), + 'bankaccountholder' => $oBilling->getFirstname().' '.$oBilling->getLastname(), 'iban' => $oInfoInstance->getAdditionalInformation('iban'), ]; diff --git a/Model/Methods/BNPL/Installment.php b/Model/Methods/BNPL/Installment.php index e8799c22..dc665d5a 100644 --- a/Model/Methods/BNPL/Installment.php +++ b/Model/Methods/BNPL/Installment.php @@ -55,9 +55,10 @@ class Installment extends BNPLBase public function getSubTypeSpecificParameters(Order $oOrder) { $oInfoInstance = $this->getInfoInstance(); + $oBilling = $oOrder->getBillingAddress(); $aParams = [ - 'bankaccountholder' => $oInfoInstance->getAdditionalInformation('bankaccountholder'), + 'bankaccountholder' => $oBilling->getFirstname().' '.$oBilling->getLastname(), 'iban' => $oInfoInstance->getAdditionalInformation('iban'), 'add_paydata[installment_option_id]' => $oInfoInstance->getAdditionalInformation('optionid'), 'workorderid' => $this->checkoutSession->getInstallmentWorkorderId(), diff --git a/Model/Methods/OnlineBankTransfer/Ideal.php b/Model/Methods/OnlineBankTransfer/Ideal.php index 84a8362f..d4eb1552 100644 --- a/Model/Methods/OnlineBankTransfer/Ideal.php +++ b/Model/Methods/OnlineBankTransfer/Ideal.php @@ -63,18 +63,17 @@ class Ideal extends OnlineBankTransferBase */ protected static $aBankGroups = [ 'ABN_AMRO_BANK' => 'ABN Amro', + 'ASN_BANK' => 'ASN Bank', 'BUNQ_BANK' => 'Bunq', + 'ING_BANK' => 'ING Bank', + 'KNAB_BANK' => 'Knab', 'RABOBANK' => 'Rabobank', - 'ASN_BANK' => 'ASN Bank', + 'REVOLUT' => 'Revolut', 'SNS_BANK' => 'SNS Bank', - 'TRIODOS_BANK' => 'Triodos Bank', 'SNS_REGIO_BANK' => 'Regio Bank', - 'ING_BANK' => 'ING Bank', - 'KNAB_BANK' => 'Knab', + 'TRIODOS_BANK' => 'Triodos Bank', 'VAN_LANSCHOT_BANKIERS' => 'van Lanschot', - 'HANDELSBANKEN' => 'Handelsbanken', - 'FRIESLAND_BANK' => 'Friesland Bank', - 'REVOLUT' => 'Revolut', + 'YOURSAFE' => 'Yoursafe B.V', ]; /** diff --git a/Model/Methods/Ratepay/Installment.php b/Model/Methods/Ratepay/Installment.php index b2c13715..3c5f48bd 100644 --- a/Model/Methods/Ratepay/Installment.php +++ b/Model/Methods/Ratepay/Installment.php @@ -144,12 +144,7 @@ public function getAllowedMonths(\Magento\Quote\Api\Data\CartInterface $quote = $quote = $this->checkoutSession->getQuote(); } - $sShopId = $this->getShopIdByQuote($quote); - if (empty($sShopId)) { - return []; - } - - $aConfig = $this->ratepayHelper->getRatepayShopConfigById($sShopId); + $aConfig = $this->ratepayHelper->getShopConfigByQuote($this->getCode(), $quote); if (!$aConfig) { return []; } diff --git a/Model/Methods/Ratepay/Invoice.php b/Model/Methods/Ratepay/Invoice.php index e6844cbe..4ac054a7 100644 --- a/Model/Methods/Ratepay/Invoice.php +++ b/Model/Methods/Ratepay/Invoice.php @@ -46,4 +46,11 @@ class Invoice extends RatepayBase * @var string */ protected $sSubType = self::METHOD_RATEPAY_SUBTYPE_INVOICE; + + /** + * Info instructions block path + * + * @var string + */ + protected $_formBlockType = 'Payone\Core\Block\Form\RatepayInvoice'; } diff --git a/Model/Methods/Ratepay/RatepayBase.php b/Model/Methods/Ratepay/RatepayBase.php index 09ee3605..1fc3b932 100644 --- a/Model/Methods/Ratepay/RatepayBase.php +++ b/Model/Methods/Ratepay/RatepayBase.php @@ -92,8 +92,12 @@ class RatepayBase extends PayoneMethod protected $aAssignKeys = [ 'telephone', 'dateofbirth', + 'birthday', + 'birthmonth', + 'birthyear', 'iban', - 'bic' + 'bic', + 'company_uid', ]; /** @@ -195,9 +199,19 @@ public function getPaymentSpecificParameters(Order $oOrder) 'add_paydata[shop_id]' => $this->getShopIdByOrder($oOrder), ]; + $sCompanyUid = $this->getInfoInstance()->getAdditionalInformation('company_uid'); + if (!empty($sCompanyUid)) { + $aBaseParams['add_paydata[vat_id]'] = $sCompanyUid; + } + $sBirthday = $this->getInfoInstance()->getAdditionalInformation('dateofbirth'); if ($sBirthday) { $aBaseParams['birthday'] = $sBirthday; + } elseif (!empty($this->getInfoInstance()->getAdditionalInformation('birthday'))) { + $sDayOfBirth = $this->getInfoInstance()->getAdditionalInformation('birthday'); + $sMonthOfBirth = $this->getInfoInstance()->getAdditionalInformation('birthmonth'); + $sYearOfBirth = $this->getInfoInstance()->getAdditionalInformation('birthyear'); + $aBaseParams['birthday'] = $sYearOfBirth.$sMonthOfBirth.$sDayOfBirth; } $sTelephone = $this->getInfoInstance()->getAdditionalInformation('telephone'); @@ -210,25 +224,6 @@ public function getPaymentSpecificParameters(Order $oOrder) return $aParams; } - /** - * Returns matching Ratepay shop id by given quote - * - * @param \Magento\Quote\Api\Data\CartInterface $quote - * @return string - * @throws \Magento\Framework\Exception\LocalizedException - */ - protected function getShopIdByQuote(\Magento\Quote\Api\Data\CartInterface $quote) - { - $sCountryCode = $quote->getShippingAddress()->getCountryId(); - if (empty($sCountryCode)) { - $sCountryCode = $quote->getBillingAddress()->getCountryId(); - } - $sCurrency = $this->apiHelper->getCurrencyFromQuote($quote); - $dGrandTotal = $this->apiHelper->getQuoteAmount($quote); - - return $this->ratepayHelper->getRatepayShopId($this->getCode(), $sCountryCode, $sCurrency, $dGrandTotal); - } - /** * Returns matching Ratepay shop id by given quote * @@ -262,7 +257,7 @@ public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null) $quote = $this->checkoutSession->getQuote(); } - if ($this->getShopIdByQuote($quote) === false) { + if ($this->ratepayHelper->getShopIdByQuote($this->getCode(), $quote) === false) { return false; } @@ -279,6 +274,7 @@ public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null) */ protected function handleResponse($aResponse, Order $oOrder, $amount) { + $this->checkoutSession->unsPayoneRatepayDeviceFingerprintToken(); if (isset($aResponse['status']) && $aResponse['status'] == 'ERROR' && isset($aResponse['errorcode']) && $aResponse['errorcode'] == '307' ) { diff --git a/Model/PayoneConfig.php b/Model/PayoneConfig.php index 97e7db4d..a311eed8 100644 --- a/Model/PayoneConfig.php +++ b/Model/PayoneConfig.php @@ -105,4 +105,10 @@ abstract class PayoneConfig const METHOD_GROUP_KLARNA = 'payone_klarna'; const METHOD_GROUP_RATEPAY = 'payone_ratepay'; const METHOD_GROUP_BNPL = 'payone_bnpl'; + + const METHODS_RATEPAY = [ + self::METHOD_RATEPAY_INVOICE, + self::METHOD_RATEPAY_DEBIT, + self::METHOD_RATEPAY_INSTALLMENT, + ]; } diff --git a/Model/Plugins/MethodList.php b/Model/Plugins/MethodList.php index 6d1862bd..01f9a8dc 100644 --- a/Model/Plugins/MethodList.php +++ b/Model/Plugins/MethodList.php @@ -196,11 +196,11 @@ protected function getBannedPaymentMethods(Quote $oQuote) $aBans = []; if (!empty($oQuote->getCustomerId())) { $aBans = $this->paymentBan->getPaymentBans($oQuote->getCustomerId()); - } else { // guest checkout - $aSessionBans = $this->checkoutSession->getPayonePaymentBans(); - if (!empty($aSessionBans)) { - $aBans = $aSessionBans; - } + } + + $aSessionBans = $this->checkoutSession->getPayonePaymentBans(); + if (!empty($aSessionBans)) { + $aBans = array_merge($aBans, $aSessionBans); } return $aBans; } @@ -214,11 +214,11 @@ protected function getBannedPaymentMethods(Quote $oQuote) */ protected function removeBannedPaymentMethods($aPaymentMethods, Quote $oQuote) { - $aBannedMethos = $this->getBannedPaymentMethods($oQuote); + $aBannedMethods = $this->getBannedPaymentMethods($oQuote); foreach ($aPaymentMethods as $key => $aPaymentMethod) { $sCode = $aPaymentMethod->getCode(); - if (array_key_exists($sCode, $aBannedMethos) !== false) { - $iBannedUntil = strtotime($aBannedMethos[$sCode]); + if (array_key_exists($sCode, $aBannedMethods) !== false) { + $iBannedUntil = strtotime($aBannedMethods[$sCode]); if ($iBannedUntil > time()) { unset($aPaymentMethods[$key]); } diff --git a/Model/ResourceModel/RatepayProfileConfig.php b/Model/ResourceModel/RatepayProfileConfig.php index d4487fb3..f0931473 100644 --- a/Model/ResourceModel/RatepayProfileConfig.php +++ b/Model/ResourceModel/RatepayProfileConfig.php @@ -33,17 +33,6 @@ */ class RatepayProfileConfig extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { - /** - * Map for methodCode to short payment method identifier for database columns - * - * @var array - */ - protected $aMethodIdentifierMap = [ - PayoneConfig::METHOD_RATEPAY_INVOICE => 'invoice', - PayoneConfig::METHOD_RATEPAY_DEBIT => 'elv', - PayoneConfig::METHOD_RATEPAY_INSTALLMENT => 'installment', - ]; - /** * Initialize connection and table * @@ -99,6 +88,24 @@ public function profileExists($sShopId) return false; } + /** + * Convert strange Ratepay yes/no values to int-style bool values for the database + * + * @param string $sValue + * @return int + */ + protected function convertYesNoToBool($sValue) + { + if (strtolower($sValue) == "yes") { + return 1; + } + + if (strtolower($sValue) == "no") { + return 0; + } + return $sValue; + } + /** * Fills data array for insert and update queries * @@ -108,10 +115,10 @@ public function profileExists($sShopId) protected function getDataArray($aProfileResponse) { $aData = [ - 'profile_id' => $aProfileResponse['add_paydata[profile-id]'], - 'merchant_name' => $aProfileResponse['add_paydata[merchant-name]'], - 'merchant_status' => $aProfileResponse['add_paydata[merchant-status]'], - 'shop_name' => $aProfileResponse['add_paydata[shop-name]'], + 'profile_id' => isset($aProfileResponse['add_paydata[profile-id]']) ? $aProfileResponse['add_paydata[profile-id]'] : '', + 'merchant_name' => isset($aProfileResponse['add_paydata[merchant-name]']) ? $aProfileResponse['add_paydata[merchant-name]'] : '', + 'merchant_status' => isset($aProfileResponse['add_paydata[merchant-status]']) ? $aProfileResponse['add_paydata[merchant-status]'] : 0, + 'shop_name' => isset($aProfileResponse['add_paydata[shop-name]']) ? $aProfileResponse['add_paydata[shop-name]'] : '', 'name' => $aProfileResponse['add_paydata[name]'], 'currency' => $aProfileResponse['add_paydata[currency]'], 'type' => $aProfileResponse['add_paydata[type]'], @@ -120,28 +127,28 @@ protected function getDataArray($aProfileResponse) 'activation_status_invoice' => $aProfileResponse['add_paydata[activation-status-invoice]'], 'activation_status_prepayment' => $aProfileResponse['add_paydata[activation-status-prepayment]'], 'amount_min_longrun' => $aProfileResponse['add_paydata[amount-min-longrun]'], - 'b2b_pq_full' => $aProfileResponse['add_paydata[b2b-PQ-full]'], - 'b2b_pq_light' => isset($aProfileResponse['add_paydata[b2b-PQ-light]']) ? $aProfileResponse['add_paydata[b2b-PQ-light]'] : '', - 'b2b_elv' => $aProfileResponse['add_paydata[b2b-elv]'], - 'b2b_installment' => $aProfileResponse['add_paydata[b2b-installment]'], - 'b2b_invoice' => $aProfileResponse['add_paydata[b2b-invoice]'], - 'b2b_prepayment' => $aProfileResponse['add_paydata[b2b-prepayment]'], + 'b2b_pq_full' => $this->convertYesNoToBool($aProfileResponse['add_paydata[b2b-PQ-full]']), + 'b2b_pq_light' => isset($aProfileResponse['add_paydata[b2b-PQ-light]']) ? $this->convertYesNoToBool($aProfileResponse['add_paydata[b2b-PQ-light]']) : 0, + 'b2b_elv' => $this->convertYesNoToBool($aProfileResponse['add_paydata[b2b-elv]']), + 'b2b_installment' => $this->convertYesNoToBool($aProfileResponse['add_paydata[b2b-installment]']), + 'b2b_invoice' => $this->convertYesNoToBool($aProfileResponse['add_paydata[b2b-invoice]']), + 'b2b_prepayment' => $this->convertYesNoToBool($aProfileResponse['add_paydata[b2b-prepayment]']), 'country_code_billing' => $aProfileResponse['add_paydata[country-code-billing]'], 'country_code_delivery' => $aProfileResponse['add_paydata[country-code-delivery]'], - 'delivery_address_pq_full' => $aProfileResponse['add_paydata[delivery-address-PQ-full]'], - 'delivery_address_pq_light' => isset($aProfileResponse['add_paydata[delivery-address-PQ-light]']) ? $aProfileResponse['add_paydata[delivery-address-PQ-light]'] : '', - 'delivery_address_elv' => $aProfileResponse['add_paydata[delivery-address-elv]'], - 'delivery_address_installment' => $aProfileResponse['add_paydata[delivery-address-installment]'], - 'delivery_address_invoice' => $aProfileResponse['add_paydata[delivery-address-invoice]'], - 'delivery_address_prepayment' => $aProfileResponse['add_paydata[delivery-address-prepayment]'], + 'delivery_address_pq_full' => $this->convertYesNoToBool($aProfileResponse['add_paydata[delivery-address-PQ-full]']), + 'delivery_address_pq_light' => isset($aProfileResponse['add_paydata[delivery-address-PQ-light]']) ? $this->convertYesNoToBool($aProfileResponse['add_paydata[delivery-address-PQ-light]']) : 0, + 'delivery_address_elv' => $this->convertYesNoToBool($aProfileResponse['add_paydata[delivery-address-elv]']), + 'delivery_address_installment' => $this->convertYesNoToBool($aProfileResponse['add_paydata[delivery-address-installment]']), + 'delivery_address_invoice' => $this->convertYesNoToBool($aProfileResponse['add_paydata[delivery-address-invoice]']), + 'delivery_address_prepayment' => $this->convertYesNoToBool($aProfileResponse['add_paydata[delivery-address-prepayment]']), 'device_fingerprint_snippet_id' => isset($aProfileResponse['add_paydata[device-fingerprint-snippet-id]']) ? $aProfileResponse['add_paydata[device-fingerprint-snippet-id]'] : NULL, 'eligibility_device_fingerprint' => isset($aProfileResponse['add_paydata[eligibility-device-fingerprint]']) ? $aProfileResponse['add_paydata[eligibility-device-fingerprint]'] : NULL, - 'eligibility_ratepay_elv' => isset($aProfileResponse['add_paydata[eligibility-ratepay-elv]']) ? $aProfileResponse['add_paydata[eligibility-ratepay-elv]'] : 'no', - 'eligibility_ratepay_installment' => isset($aProfileResponse['add_paydata[eligibility-ratepay-installment]']) ? $aProfileResponse['add_paydata[eligibility-ratepay-installment]'] : 'no', - 'eligibility_ratepay_invoice' => isset($aProfileResponse['add_paydata[eligibility-ratepay-invoice]']) ? $aProfileResponse['add_paydata[eligibility-ratepay-invoice]'] : 'no', - 'eligibility_ratepay_pq_full' => isset($aProfileResponse['add_paydata[eligibility-ratepay-pq-full]']) ? $aProfileResponse['add_paydata[eligibility-ratepay-pq-full]'] : 'no', - 'eligibility_ratepay_pq_light' => isset($aProfileResponse['add_paydata[eligibility-ratepay-pq-light]']) ? $aProfileResponse['add_paydata[eligibility-ratepay-pq-light]'] : 'no', - 'eligibility_ratepay_prepayment' => $aProfileResponse['add_paydata[eligibility-ratepay-prepayment]'], + 'eligibility_ratepay_elv' => isset($aProfileResponse['add_paydata[eligibility-ratepay-elv]']) ? $this->convertYesNoToBool($aProfileResponse['add_paydata[eligibility-ratepay-elv]']) : 0, + 'eligibility_ratepay_installment' => isset($aProfileResponse['add_paydata[eligibility-ratepay-installment]']) ? $this->convertYesNoToBool($aProfileResponse['add_paydata[eligibility-ratepay-installment]']) : 0, + 'eligibility_ratepay_invoice' => isset($aProfileResponse['add_paydata[eligibility-ratepay-invoice]']) ? $this->convertYesNoToBool($aProfileResponse['add_paydata[eligibility-ratepay-invoice]']) : 0, + 'eligibility_ratepay_pq_full' => isset($aProfileResponse['add_paydata[eligibility-ratepay-pq-full]']) ? $this->convertYesNoToBool($aProfileResponse['add_paydata[eligibility-ratepay-pq-full]']) : 0, + 'eligibility_ratepay_pq_light' => isset($aProfileResponse['add_paydata[eligibility-ratepay-pq-light]']) ? $this->convertYesNoToBool($aProfileResponse['add_paydata[eligibility-ratepay-pq-light]']) : 0, + 'eligibility_ratepay_prepayment' => $this->convertYesNoToBool($aProfileResponse['add_paydata[eligibility-ratepay-prepayment]']), 'interest_rate_merchant_towards_bank' => $aProfileResponse['add_paydata[interest-rate-merchant-towards-bank]'], 'interestrate_default' => $aProfileResponse['add_paydata[interestrate-default]'], 'interestrate_max' => $aProfileResponse['add_paydata[interestrate-max]'], @@ -198,20 +205,6 @@ public function insertProfileConfig($sShopId, $aProfileResponse) $this->getConnection()->insert($this->getMainTable(), $data); } - /** - * Returns ratepay method identifier - * - * @param string $sMethodCode - * @return string|false - */ - protected function getRatepayMethodIdentifierByMethodCode($sMethodCode) - { - if (isset($this->aMethodIdentifierMap[$sMethodCode])) { - return $this->aMethodIdentifierMap[$sMethodCode]; - } - return false; - } - /** * Get matching shop id for current quote parameters * @@ -220,28 +213,33 @@ protected function getRatepayMethodIdentifierByMethodCode($sMethodCode) * @param string $sCountryCode * @param string $sCurrency * @param double $dGrandTotal - * @return string|bool + * @param bool $blGetConfigWithoutTotals + * @return string|false */ - public function getMatchingShopId($sMethodCode, $aShopIds, $sCountryCode, $sCurrency, $dGrandTotal) + public function getMatchingShopId($sRatepayMethodIdentifier, $aShopIds, $sCountryCode, $sCurrency, $dGrandTotal, $blGetConfigWithoutTotals = false) { - $sRatepayMethodIdentifier = $this->getRatepayMethodIdentifierByMethodCode($sMethodCode); - $oSelect = $this->getConnection()->select() ->from($this->getMainTable(), ['shop_id']) ->where("shop_id IN ('".implode("','", $aShopIds)."')") - ->where("tx_limit_".$sRatepayMethodIdentifier."_min <= :grandTotal") - ->where("tx_limit_".$sRatepayMethodIdentifier."_max >= :grandTotal") ->where("country_code_billing = :countryCode") ->where("currency = :currency") ->order('shop_id ASC') ->limit(1); $aParams = [ - 'grandTotal' => $dGrandTotal, 'countryCode' => $sCountryCode, 'currency' => $sCurrency, ]; + // $blGetConfigWithoutTotals = true mode is used to get a configuration without the totals being concidered. + // This is needed in checkout when basket total is a little unter the min_limit but with shipping costs it's over the limit + // CheckoutConfig javascript array is generated before shipping costs are added, but available payment methods are determined after shipping costs were added + if ($blGetConfigWithoutTotals === false) { + $oSelect = $oSelect->where("tx_limit_".$sRatepayMethodIdentifier."_min <= :grandTotal") + ->where("tx_limit_".$sRatepayMethodIdentifier."_max >= :grandTotal"); + $aParams['grandTotal'] = $dGrandTotal; + } + $sShopId = $this->getConnection()->fetchOne($oSelect, $aParams); if (empty($sShopId)) { return false; diff --git a/README.md b/README.md index 2a8866a8..d7a6a70b 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,6 @@ magento@payone.com
## License See our License Agreement at: https://www.payone.de/fileadmin/downloads/sonstiges/PAYONE_Haftungs_und_Lizenzvereinbarung_Extensions.pdf -## About BS PAYONE -Since the end of August 2017, the two payment specialist companies PAYONE and B+S Card Service merged to become BS PAYONE GmbH. All current partnerships will be maintained the way they are. APIs, interfaces, and other technical parameters will stay the same. Your current contact persons will continue to gladly be at your service.
-BS PAYONE GmbH is headquartered in Frankfurt am Main and is one of the leading omnichannel payment providers in Europe. In addition to providing customer support to numerous Sparkasse banks, the full-service payment service provider also provides cashless payment transactions services to more than 255,000 customers from various branches – whether that be in stationary retail or when completing e-commerce and mobile payment transactions. +## About PAYONE +Since the end of August 2017, the two payment specialist companies PAYONE and B+S Card Service merged to become PAYONE GmbH. All current partnerships will be maintained the way they are. APIs, interfaces, and other technical parameters will stay the same. Your current contact persons will continue to gladly be at your service.
+PAYONE GmbH is headquartered in Frankfurt am Main and is one of the leading omnichannel payment providers in Europe. In addition to providing customer support to numerous Sparkasse banks, the full-service payment service provider also provides cashless payment transactions services to more than 255,000 customers from various branches – whether that be in stationary retail or when completing e-commerce and mobile payment transactions. diff --git a/Service/V1/Data/RatepayConfigResponse.php b/Service/V1/Data/RatepayConfigResponse.php new file mode 100644 index 00000000..8e62130e --- /dev/null +++ b/Service/V1/Data/RatepayConfigResponse.php @@ -0,0 +1,55 @@ +. + * + * PHP version 8 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2023 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Service\V1\Data; + +use Payone\Core\Api\Data\RatepayConfigResponseInterface; + +/** + * Object for addresscheck WebApi response + */ +class RatepayConfigResponse extends \Magento\Framework\Api\AbstractExtensibleObject implements RatepayConfigResponseInterface +{ + /** + * Returns if editing the address was a success + * + * @return bool + */ + public function getSuccess() + { + return $this->_get('success'); + } + + /** + * Returns config json array + * + * @return string + */ + public function getConfig() + { + return $this->_get('config'); + } +} diff --git a/Service/V1/RatepayConfig.php b/Service/V1/RatepayConfig.php new file mode 100644 index 00000000..bc7a0083 --- /dev/null +++ b/Service/V1/RatepayConfig.php @@ -0,0 +1,89 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2018 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Service\V1; + +use Payone\Core\Api\RatepayConfigInterface; + +/** + * Web API model for the PAYONE RatepayConfig + */ +class RatepayConfig implements RatepayConfigInterface +{ + /** + * Factory for the response object + * + * @var \Payone\Core\Service\V1\Data\RatepayConfigResponseFactory + */ + protected $responseFactory; + + /** + * Address repository + * + * @var \Magento\Checkout\Model\Session + */ + protected $checkoutSession; + + /** + * PAYONE ratepay helper + * + * @var \Payone\Core\Helper\Ratepay + */ + protected $ratepayHelper; + + /** + * Constructor + * + * @param \Payone\Core\Service\V1\Data\RatepayConfigResponseFactory $responseFactory + * @param \Magento\Checkout\Model\Session $checkoutSession + * @param \Payone\Core\Helper\Ratepay $ratepayHelper + */ + public function __construct( + \Payone\Core\Service\V1\Data\RatepayConfigResponseFactory $responseFactory, + \Magento\Checkout\Model\Session $checkoutSession, + \Payone\Core\Helper\Ratepay $ratepayHelper + ) { + $this->responseFactory = $responseFactory; + $this->checkoutSession = $checkoutSession; + $this->ratepayHelper = $ratepayHelper; + } + + /** + * PAYONE editAddress script + * The full class-paths must be given here otherwise the Magento 2 WebApi + * cant handle this with its fake type system! + * + * @param string $cartId + * @return \Payone\Core\Service\V1\Data\RatepayConfigResponse + */ + public function getConfig($cartId) + { + $oResponse = $this->responseFactory->create(); + $oResponse->setData('config', json_encode($this->ratepayHelper->getRatepayConfig())); + $oResponse->setData('success', true); + return $oResponse; + } +} diff --git a/Test/Unit/Block/BNPL/InstallmentPlanTest.php b/Test/Unit/Block/BNPL/InstallmentPlanTest.php index a93b6f68..b557d7b0 100644 --- a/Test/Unit/Block/BNPL/InstallmentPlanTest.php +++ b/Test/Unit/Block/BNPL/InstallmentPlanTest.php @@ -86,7 +86,7 @@ public function testGetSelectLinkText() 'number_of_payments' => '12', 'monthly_amount_value' => '500', ]; - $expected = '5,00 EUR per month - 12 installments'; + $expected = 'Payment in 12 installments of 5,00 EUR'; $result = $this->classToTest->getSelectLinkText($aInstallment); $this->assertEquals($expected, $result); } diff --git a/Test/Unit/Block/Form/RatepayInvoiceTest.php b/Test/Unit/Block/Form/RatepayInvoiceTest.php new file mode 100644 index 00000000..fe58cd73 --- /dev/null +++ b/Test/Unit/Block/Form/RatepayInvoiceTest.php @@ -0,0 +1,241 @@ +. + * + * PHP version 8 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2023 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Test\Unit\Block\Form; + +use Payone\Core\Block\Form\RatepayInvoice as ClassToTest; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Payone\Core\Test\Unit\BaseTestCase; +use Payone\Core\Test\Unit\PayoneObjectManager; +use Payone\Core\Helper\Ratepay; +use Magento\Sales\Model\AdminOrder\Create; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\Quote\Address; +use Magento\Customer\Model\Data\Customer; + +class RatepayInvoiceTest extends BaseTestCase +{ + /** + * @var ClassToTest + */ + private $classToTest; + + /** + * @var ObjectManager|PayoneObjectManager + */ + private $objectManager; + + /** + * @var Ratepay + */ + private $ratepayHelper; + + /** + * @var Create + */ + private $orderCreate; + + protected function setUp(): void + { + $this->objectManager = $this->getObjectManager(); + + $this->ratepayHelper = $this->getMockBuilder(Ratepay::class)->disableOriginalConstructor()->getMock(); + $this->orderCreate = $this->getMockBuilder(Create::class)->disableOriginalConstructor()->getMock(); + $this->classToTest = $this->objectManager->getObject(ClassToTest::class, [ + 'ratepayHelper' => $this->ratepayHelper, + 'orderCreate' => $this->orderCreate, + ]); + } + + public function testGetQuote() + { + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + $this->orderCreate->method('getQuote')->willReturn($quote); + + $result = $this->classToTest->getQuote(); + $this->assertInstanceOf(Quote::class, $result); + } + + public function testGetRatepayConfig() + { + $config = [ + 'b2bAllowed' => '1', + 'differentAddressAllowed' => '1', + ]; + $this->ratepayHelper->method('getRatepaySingleConfig')->willReturn($config); + + $result = $this->classToTest->getRatepayConfig(); + $this->assertEquals($config, $result); + + $result = $this->classToTest->isB2BModeAllowed(); + $this->assertTrue($result); + + $result = $this->classToTest->isDifferingDeliveryAddressAllowed(); + $this->assertTrue($result); + } + + public function testGetRatepayConfigFalse() + { + $config = []; + $this->ratepayHelper->method('getRatepaySingleConfig')->willReturn($config); + + $result = $this->classToTest->getRatepayConfig(); + $this->assertEquals($config, $result); + + $result = $this->classToTest->isB2BModeAllowed(); + $this->assertFalse($result); + + $result = $this->classToTest->isDifferingDeliveryAddressAllowed(); + $this->assertFalse($result); + } + + public function testGetDevicefingerprintSnippetId() + { + $expected = "DeviceFingerprint"; + $this->ratepayHelper->method('getConfigParam')->willReturn($expected); + + $result = $this->classToTest->getDevicefingerprintSnippetId(); + $this->assertEquals($expected, $result); + } + + public function testGetDevicefingerprintToken() + { + $expected = "DeviceFingerprintToken"; + $this->ratepayHelper->method('getRatepayDeviceFingerprintToken')->willReturn($expected); + + $result = $this->classToTest->getDevicefingerprintToken(); + $this->assertEquals($expected, $result); + } + + public function testIsB2BModeTrue() + { + $address = $this->getMockBuilder(Address::class)->disableOriginalConstructor()->getMock(); + $address->method('getCompany')->willReturn("Company"); + + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + $quote->method('getBillingAddress')->willReturn($address); + + $this->orderCreate->method('getQuote')->willReturn($quote); + + $result = $this->classToTest->isB2BMode(); + $this->assertTrue($result); + + $result = $this->classToTest->isBirthdayNeeded(); + $this->assertFalse($result); + } + + public function testIsB2BModeFalse() + { + $address = $this->getMockBuilder(Address::class)->disableOriginalConstructor()->getMock(); + $address->method('getCompany')->willReturn(false); + + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + $quote->method('getBillingAddress')->willReturn($address); + + $this->orderCreate->method('getQuote')->willReturn($quote); + + $result = $this->classToTest->isB2BMode(); + $this->assertFalse($result); + + $result = $this->classToTest->isBirthdayNeeded(); + $this->assertTrue($result); + } + + public function testHasDifferingDeliveryAddress() + { + $address = $this->getMockBuilder(Address::class)->disableOriginalConstructor()->getMock(); + $address->method('getSameAsBilling')->willReturn(false); + + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + $quote->method('getShippingAddress')->willReturn($address); + + $this->orderCreate->method('getQuote')->willReturn($quote); + + $result = $this->classToTest->hasDifferingDeliveryAddress(); + $this->assertTrue($result); + } + + public function testGetBirthday() + { + $expected = "19550505"; + + $customer = $this->getMockBuilder(Customer::class)->disableOriginalConstructor()->getMock(); + $customer->method('getDob')->willReturn($expected); + + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + $quote->method('getCustomer')->willReturn($customer); + + $this->orderCreate->method('getQuote')->willReturn($quote); + + $result = $this->classToTest->getBirthday(); + $this->assertEquals($expected, $result); + + $result = $this->classToTest->getBirthdayPart("Y"); + $this->assertEquals("1955", $result); + } + + public function testGetBirthdayPartEmpty() + { + $customer = $this->getMockBuilder(Customer::class)->disableOriginalConstructor()->getMock(); + $customer->method('getDob')->willReturn(false); + + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + $quote->method('getCustomer')->willReturn($customer); + + $this->orderCreate->method('getQuote')->willReturn($quote); + + $result = $this->classToTest->getBirthdayPart("Y"); + $this->assertEquals('', $result); + } + + public function testIsTelephoneNeeded() + { + $address = $this->getMockBuilder(Address::class)->disableOriginalConstructor()->getMock(); + $address->method('getTelephone')->willReturn("0123456789"); + + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + $quote->method('getBillingAddress')->willReturn($address); + + $this->orderCreate->method('getQuote')->willReturn($quote); + + $result = $this->classToTest->isTelephoneNeeded(); + $this->assertFalse($result); + } + + public function testIsTelephoneNeededFalse() + { + $address = $this->getMockBuilder(Address::class)->disableOriginalConstructor()->getMock(); + $address->method('getTelephone')->willReturn(false); + + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + $quote->method('getBillingAddress')->willReturn($address); + + $this->orderCreate->method('getQuote')->willReturn($quote); + + $result = $this->classToTest->isTelephoneNeeded(); + $this->assertTrue($result); + } +} diff --git a/Test/Unit/Controller/Onepage/PlaceOrderTest.php b/Test/Unit/Controller/Onepage/PlaceOrderTest.php index 1583119c..d451510f 100644 --- a/Test/Unit/Controller/Onepage/PlaceOrderTest.php +++ b/Test/Unit/Controller/Onepage/PlaceOrderTest.php @@ -152,6 +152,9 @@ protected function setUp(): void 'unsPayoneUserAgent', 'setPayoneExpressType', 'setIsPayonePayPalExpress', + 'getPayoneRedirectUrl', + 'setPayonePayPalExpressRetry', + 'setPayoneCustomerIsRedirected', ]) ->getMock(); $this->checkoutSession->method('getQuote')->willReturn($quote); @@ -161,6 +164,7 @@ protected function setUp(): void $this->checkoutSession->method('unsIsPayonePayPalExpress')->willReturn($this->checkoutSession); $this->checkoutSession->method('unsPayoneUserAgent')->willReturn($this->checkoutSession); $this->checkoutSession->method('setIsPayonePayPalExpress')->willReturn(true); + $this->checkoutSession->method('setPayonePayPalExpressRetry')->willReturn($this->checkoutSession); $this->agreementValidator = $this->getMockBuilder(AgreementsValidatorInterface::class)->disableOriginalConstructor()->getMock(); $this->agreementValidator->method('isValid')->willReturn(false); @@ -209,4 +213,13 @@ public function testExecuteSubtotalMismatch() $result = $this->classToTest->execute(); $this->assertNull($result); } + + public function testExecutePayPal() + { + $this->checkoutSession->method('getPayoneGenericpaymentSubtotal')->willReturn(100); + $this->checkoutSession->method('getPayoneRedirectUrl')->willReturn("http://someurl.test"); + $this->request->method('getBeforeForwardInfo')->willReturn(false); + $result = $this->classToTest->execute(); + $this->assertNull($result); + } } diff --git a/Test/Unit/Controller/Paypal/ReturnedTest.php b/Test/Unit/Controller/Paypal/ReturnedTest.php index a96ad410..1a33628d 100644 --- a/Test/Unit/Controller/Paypal/ReturnedTest.php +++ b/Test/Unit/Controller/Paypal/ReturnedTest.php @@ -55,6 +55,11 @@ class ReturnedTest extends BaseTestCase */ private $returnHandler; + /** + * @var Session + */ + private $checkoutSession; + protected function setUp(): void { $this->objectManager = $this->getObjectManager(); @@ -71,33 +76,50 @@ protected function setUp(): void $context->method('getResultFactory')->willReturn($resultFactory); $context->method('getMessageManager')->willReturn($messageManager); - $checkoutSession = $this->getMockBuilder(Session::class) + $this->checkoutSession = $this->getMockBuilder(Session::class) ->disableOriginalConstructor() - ->setMethods(['getPayoneWorkorderId', 'setIsPayonePayPalExpress']) + ->setMethods([ + 'getPayoneWorkorderId', + 'setIsPayonePayPalExpress', + 'getPayonePayPalExpressRetry', + 'unsPayonePayPalExpressRetry', + ]) ->getMock(); - $checkoutSession->method('getPayoneWorkorderId')->willReturn('12345'); + $this->checkoutSession->method('getPayoneWorkorderId')->willReturn('12345'); $this->returnHandler = $this->getMockBuilder(ReturnHandler::class)->disableOriginalConstructor()->getMock(); $this->classToTest = $this->objectManager->getObject(ClassToTest::class, [ 'context' => $context, - 'checkoutSession' => $checkoutSession, + 'checkoutSession' => $this->checkoutSession, 'returnHandler' => $this->returnHandler ]); } public function testExecute() { + $this->checkoutSession->method('getPayonePayPalExpressRetry')->willReturn(false); + $result = $this->classToTest->execute(); $this->assertInstanceOf(Redirect::class, $result); } public function testExecuteException() { + $this->checkoutSession->method('getPayonePayPalExpressRetry')->willReturn(false); + $exception = new \Exception; $this->returnHandler->expects($this->once())->method('handlePayPalReturn')->willThrowException($exception); $result = $this->classToTest->execute(); $this->assertInstanceOf(Redirect::class, $result); } + + public function testExecutePayPal() + { + $this->checkoutSession->method('getPayonePayPalExpressRetry')->willReturn(true); + + $result = $this->classToTest->execute(); + $this->assertInstanceOf(Redirect::class, $result); + } } diff --git a/Test/Unit/Model/Methods/BNPL/DebitTest.php b/Test/Unit/Model/Methods/BNPL/DebitTest.php index 42766932..d7dbe5c4 100644 --- a/Test/Unit/Model/Methods/BNPL/DebitTest.php +++ b/Test/Unit/Model/Methods/BNPL/DebitTest.php @@ -62,7 +62,12 @@ protected function setUp(): void public function testGetSubTypeSpecificParameters() { + $address = $this->getMockBuilder(Address::class)->disableOriginalConstructor()->getMock(); + $address->method('getFirstname')->willReturn('Max'); + $address->method('getLastname')->willReturn('Mustermann'); + $order = $this->getMockBuilder(Order::class)->disableOriginalConstructor()->getMock(); + $order->method('getBillingAddress')->willReturn($address); $result = $this->classToTest->getSubTypeSpecificParameters($order); $this->assertCount(2, $result); diff --git a/Test/Unit/Model/Methods/BNPL/InstallmentTest.php b/Test/Unit/Model/Methods/BNPL/InstallmentTest.php index e900885b..68b66f16 100644 --- a/Test/Unit/Model/Methods/BNPL/InstallmentTest.php +++ b/Test/Unit/Model/Methods/BNPL/InstallmentTest.php @@ -63,8 +63,13 @@ protected function setUp(): void $store = $this->getMockBuilder(Store::class)->disableOriginalConstructor()->getMock(); $store->method('getCode')->willReturn('test'); + $address = $this->getMockBuilder(Address::class)->disableOriginalConstructor()->getMock(); + $address->method('getFirstname')->willReturn('Max'); + $address->method('getLastname')->willReturn('Mustermann'); + $this->order = $this->getMockBuilder(Order::class)->disableOriginalConstructor()->getMock(); $this->order->method('getStore')->willReturn($store); + $this->order->method('getBillingAddress')->willReturn($address); $toolkitHelper = $this->getMockBuilder(Toolkit::class)->disableOriginalConstructor()->getMock(); $toolkitHelper->method('getAdditionalDataEntry')->willReturn("value"); diff --git a/Test/Unit/Model/Methods/Ratepay/InstallmentTest.php b/Test/Unit/Model/Methods/Ratepay/InstallmentTest.php index 23d7a48d..01b63693 100644 --- a/Test/Unit/Model/Methods/Ratepay/InstallmentTest.php +++ b/Test/Unit/Model/Methods/Ratepay/InstallmentTest.php @@ -106,8 +106,7 @@ public function testGetAllowedMonths() 'interestrate_default' => '9', ]; - $this->ratepayHelper->method('getRatepayShopId')->willReturn("test"); - $this->ratepayHelper->method('getRatepayShopConfigById')->willReturn($config); + $this->ratepayHelper->method('getShopConfigByQuote')->willReturn($config); $result = $this->classToTest->getAllowedMonths(); $this->assertCount(3, $result); @@ -121,8 +120,7 @@ public function testGetAllowedMonthsZero() 'interestrate_default' => '0', ]; - $this->ratepayHelper->method('getRatepayShopId')->willReturn("test"); - $this->ratepayHelper->method('getRatepayShopConfigById')->willReturn($config); + $this->ratepayHelper->method('getShopConfigByQuote')->willReturn($config); $result = $this->classToTest->getAllowedMonths(); $this->assertCount(3, $result); diff --git a/Test/Unit/Model/Methods/Ratepay/InvoiceTest.php b/Test/Unit/Model/Methods/Ratepay/InvoiceTest.php index d665afa1..f15d7ae0 100644 --- a/Test/Unit/Model/Methods/Ratepay/InvoiceTest.php +++ b/Test/Unit/Model/Methods/Ratepay/InvoiceTest.php @@ -110,7 +110,8 @@ protected function setUp(): void 'unsPayoneCanceledPaymentMethod', 'unsPayoneIsError', 'unsShowAmazonPendingNotice', - 'unsAmazonRetryAsync' + 'unsAmazonRetryAsync', + 'unsPayoneRatepayDeviceFingerprintToken', ]) ->getMock(); $checkoutSession->method('getQuote')->willReturn($quote); @@ -171,6 +172,7 @@ public function testGetPaymentSpecificParameters() 'add_paydata[device_token]' => '12345', 'add_paydata[merchant_consumer_id]' => '123', 'add_paydata[shop_id]' => '54321', + 'add_paydata[vat_id]' => '1', 'birthday' => '1', 'telephonenumber' => '1', ]; @@ -264,7 +266,7 @@ public function testIsAvailableFalse() { $this->scopeConfig->method('getValue')->willReturn(1); - $this->ratepayHelper->method('getRatepayShopId')->willReturn(false); + $this->ratepayHelper->method('getShopIdByQuote')->willReturn(false); $result = $this->classToTest->isAvailable(); $this->assertFalse($result); diff --git a/Test/Unit/Model/Plugins/MethodListTest.php b/Test/Unit/Model/Plugins/MethodListTest.php index f193c270..53297179 100644 --- a/Test/Unit/Model/Plugins/MethodListTest.php +++ b/Test/Unit/Model/Plugins/MethodListTest.php @@ -134,15 +134,18 @@ public function testAfterGetAvailableMethodsPreviousCheck() $subject = $this->getMockBuilder(MethodList::class)->disableOriginalConstructor()->getMock(); + $paymentBanned = $this->getMockBuilder(MethodInterface::class)->disableOriginalConstructor()->getMock(); + $paymentBanned->method('getCode')->willReturn(PayoneConfig::METHOD_DEBIT); + $payment = $this->getMockBuilder(MethodInterface::class)->disableOriginalConstructor()->getMock(); - $payment->method('getCode')->willReturn(PayoneConfig::METHOD_DEBIT); - $paymentMethods = [$payment]; + $payment->method('getCode')->willReturn(PayoneConfig::METHOD_CASH_ON_DELIVERY); + $paymentMethods = [$paymentBanned, $payment]; $this->quote->method('getCustomerId')->willReturn('5'); $this->paymentBan->method('getPaymentBans')->willReturn([]); $result = $this->classToTest->afterGetAvailableMethods($subject, $paymentMethods, $this->quote); - $this->assertInstanceOf(MethodInterface::class, $result[0]); + $this->assertInstanceOf(MethodInterface::class, array_shift($result)); } public function testAfterGetAvailableMethods() diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index ce96a8a3..9b6e986c 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -267,11 +267,11 @@ Payone\Core\Block\Adminhtml\Config\Form\Field\StatusMapping Payone\Core\Model\Config\Backend\SerializedOrJson - + Payone\Core\Block\Adminhtml\Config\Form\Field\StatusMapping @@ -332,7 +332,7 @@ - +
diff --git a/etc/config.xml b/etc/config.xml index 5b3859f9..81521eb5 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -330,16 +330,18 @@ 0 payone - + 1 Authorization diff --git a/etc/csp_whitelist.xml b/etc/csp_whitelist.xml index 4fe96246..03b36e6c 100644 --- a/etc/csp_whitelist.xml +++ b/etc/csp_whitelist.xml @@ -33,6 +33,7 @@ secure.pay1.de payments.amazon.de jsctool.com + www.jsctool.com diff --git a/etc/di.xml b/etc/di.xml index 8bc39b27..0f2c60b3 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -31,6 +31,8 @@ + + diff --git a/etc/payment.xml b/etc/payment.xml index 22c21773..aa2916d7 100644 --- a/etc/payment.xml +++ b/etc/payment.xml @@ -130,9 +130,9 @@ 0 - + 0 diff --git a/etc/webapi.xml b/etc/webapi.xml index 06499a16..0d315958 100644 --- a/etc/webapi.xml +++ b/etc/webapi.xml @@ -160,4 +160,21 @@ %cart_id% + + + + + + + + + + + + + + + %cart_id% + + diff --git a/i18n/de_DE.csv b/i18n/de_DE.csv index 9f06ca1f..7a4ff3d2 100644 --- a/i18n/de_DE.csv +++ b/i18n/de_DE.csv @@ -553,12 +553,12 @@ "Enable this if differing billing address and shipping address are allowed. This is disabled by default because this has to be enabled by Payone for your merchant account.","Aktivierbar um abweichende Rechnungs- und Lieferadresse zu erlauben. Dies ist standardmäßig deaktiviert, da dies erst von Payone in ihrem Merchant Account aktiviert werden muss." "B2B orders are not supported for this payment method","B2B Bestellungen sind nicht verfügbar für diese Zahlart" -"bnpl_legal_text_snippet_1","Mit dieser Bestellung erkläre ich mich mit den" -"bnpl_legal_text_snippet_2","zusätzlichen Zahlungsbedingungen" -"bnpl_legal_text_snippet_3","und der Risikobewertung für die gewählte Zahlungsart einverstanden." -"bnpl_legal_text_snippet_4","Ich habe den" -"bnpl_legal_text_snippet_5","zusätzlichen Datenschutzhinweis" -"bnpl_legal_text_snippet_6","zur Kenntnis genommen." +"bnpl_legal_text_snippet_1","Mit Abschluss dieser Bestellung erkläre ich mich mit den" +"bnpl_legal_text_snippet_2","ergänzenden Zahlungsbedingungen" +"bnpl_legal_text_snippet_3","und der Durchführung einer Risikoprüfung für die ausgewählte Zahlungsart einverstanden." +"bnpl_legal_text_snippet_4","Den" +"bnpl_legal_text_snippet_5","ergänzenden Datenschutzhinweis" +"bnpl_legal_text_snippet_6","habe ich zur Kenntnis genommen." "bnpl_payment_terms_url","https://legal.paylater.payone.com/de/terms-of-payment.html" "bnpl_data_protection_url","https://legal.paylater.payone.com/de/data-protection-payments.html" @@ -1084,19 +1084,24 @@ "Accountholder","Kontoinhaber" "Check installment availability","Ratenkauf Verfügbarkeit prüfen" "Please select your desired number of installments","Bitte wählen Sie Ihre gewünschte Anzahl von Raten" +"Select the number of installments","Wählen Sie die Anzahl der Raten" "Overview","Übersicht" -"No. of installments:","Anzahl von Raten:" +"No. of installments:","Ratenanzahl:" "Financingamount:","Finanzierungsbetrag:" "Total:","Gesamt:" "Interest rate:","Zinssatz:" "Effective interest rate:","Effektivzinssatz:" "Monthly installment:","Monatliche Rate:" "Download Installment-Contract-Draft","Ratenkauf Mustervertrag herunterladen" +"Download installment information","Ratenkauf Informationen herunterladen" "per month","pro Monat" "installments","Raten" "Installment","Rate" "due","fällig" +"Payment in","Bezahlung in" +"installments of","Raten je" + "Use Klarna","Klarna verwenden" "Installment Draft Username","Ratenkauf Muster Benutzername" @@ -1175,5 +1180,5 @@ "PAYONE Credit Card", "PAYONE Kreditkarte" "Safe installment is not available for your current basket. Please choose another payment method.","Gesicherter Ratenkauf wird für Ihren aktuellen Warenkorb nicht unterstützt. Bitte wählen Sie eine andere Zahlart." -"Ratepay payment with differing billing- and shipping-address is not supported","Die Zahlung mit Ratepay bei abweichender Rechnungs- und Lieferadressen wird nicht unterstützt" +"Payment with differing billing- and shipping-address is not supported for this payment type","Die Zahlung bei abweichender Rechnungs- und Lieferadressen wird für diese Zahlart nicht unterstützt" "Place Order","Jetzt kaufen" diff --git a/i18n/en_GB.csv b/i18n/en_GB.csv new file mode 100644 index 00000000..9adf92c6 --- /dev/null +++ b/i18n/en_GB.csv @@ -0,0 +1,57 @@ +"VISA", "Visa" +"MASTERCARD", "Mastercard" +"AMEX", "Amex" +"DINERS", "Diners" +"JCB", "JCB" +"MAESTRO_INTERNATIONAL", "Maestro International" +"MAESTRO_UK", "Maestro UK" +"DISCOVER", "Discover" +"CARTE_BLEUE", "Carte Bleue" + +"PPE", "Paypal Express" + +"PNT", "SOFORT Überweisung" +"GPY", "Giropay" +"EPS", "EPS Österreich" +"PFF", "PostFinance E-Finance Schweiz" +"PFC", "PostFinance Card Schweiz" +"IDL", "IDEAL" +"P24", "Przelewy24" + +"CFR","Commerz Finanz" +"BSV","BillSAFE" +"KLV","Klarna" +"KLS","Klarna" + +"FCPO_CC_ROW_CC_Number","Creditcardnumber" +"FCPO_CC_ROW_CC_CVC","CVC security code" +"FCPO_CC_ROW_CC_Month","Validity-month" +"FCPO_CC_ROW_CC_Year","Validity-year" + +"NONE","No verification of personal data carried out (NONE)" +"PPB","First- & lastname is known (PPB)" +"PHB","Lastname is known (PHB)" +"PAB","First name & surname unknown (PAB)" +"PKI","Ambiguity in name and address (PKI)" +"PNZ","Cannot be delivered (any longer) (PNZ)" +"PPV","Person deceased (PPV)" +"PPF","Postal address details incorrect (PPF)" +"PUG","Postal address details correct but building unknown (PUG)" +"PUZ","Person has moved, address not corrected (PUZ)" +"UKN","Unknown return values are mapped to UKN (UKN)" + +"bnpl_legal_text_snippet_1","By placing this order, I agree to the" +"bnpl_legal_text_snippet_2","supplementary payment terms" +"bnpl_legal_text_snippet_3","and the performance of a risk assessment for the selected payment method." +"bnpl_legal_text_snippet_4","I am aware of the" +"bnpl_legal_text_snippet_5","supplementary data protection notice" +"bnpl_legal_text_snippet_6","." +"bnpl_payment_terms_url","https://legal.paylater.payone.com/en/terms-of-payment.html" +"bnpl_data_protection_url","https://legal.paylater.payone.com/en/data-protection-payments.html" + +"ratepay_legal_text_snippet_1","With clicking on" +"ratepay_legal_text_snippet_2","you agree to the" +"ratepay_legal_text_snippet_3","Ratepay Terms of Payment" +"ratepay_legal_text_snippet_4","as well as to the performance of a" +"ratepay_legal_text_snippet_5","risk check by Ratepay" +"ratepay_legal_text_snippet_6","." diff --git a/i18n/en_US.csv b/i18n/en_US.csv index 7555f53b..9adf92c6 100644 --- a/i18n/en_US.csv +++ b/i18n/en_US.csv @@ -42,9 +42,9 @@ "bnpl_legal_text_snippet_1","By placing this order, I agree to the" "bnpl_legal_text_snippet_2","supplementary payment terms" -"bnpl_legal_text_snippet_3","and the risk assessment for the selected payment method." +"bnpl_legal_text_snippet_3","and the performance of a risk assessment for the selected payment method." "bnpl_legal_text_snippet_4","I am aware of the" -"bnpl_legal_text_snippet_5","additional data protection notice" +"bnpl_legal_text_snippet_5","supplementary data protection notice" "bnpl_legal_text_snippet_6","." "bnpl_payment_terms_url","https://legal.paylater.payone.com/en/terms-of-payment.html" "bnpl_data_protection_url","https://legal.paylater.payone.com/en/data-protection-payments.html" diff --git a/view/adminhtml/layout/sales_order_create_index.xml b/view/adminhtml/layout/sales_order_create_index.xml index a1cbc44c..f61bbd2b 100644 --- a/view/adminhtml/layout/sales_order_create_index.xml +++ b/view/adminhtml/layout/sales_order_create_index.xml @@ -32,5 +32,11 @@ Payone_Core::payment/debit.phtml + + + payone_ratepay_invoice + Payone_Core::payment/ratepay_invoice.phtml + + diff --git a/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml b/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml index 5ff76985..89f7ed42 100644 --- a/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml +++ b/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml @@ -32,5 +32,11 @@ Payone_Core::payment/debit.phtml + + + payone_ratepay_invoice + Payone_Core::payment/ratepay_invoice.phtml + + \ No newline at end of file diff --git a/view/adminhtml/templates/payment/ratepay_invoice.phtml b/view/adminhtml/templates/payment/ratepay_invoice.phtml new file mode 100644 index 00000000..65ba897c --- /dev/null +++ b/view/adminhtml/templates/payment/ratepay_invoice.phtml @@ -0,0 +1,156 @@ +. + * + * PHP version 8 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2023 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +// @codingStandardsIgnoreFile + +/** @var Payone\Core\Block\Form\RatepayInvoice $block */ + +$code = $block->escapeHtml($block->getMethodCode()); + +$deviceIdentToken = $block->getDevicefingerprintToken(); +$deviceIdentSId = $block->getDevicefingerprintSnippetId(); + +?> + + + + + + diff --git a/view/adminhtml/templates/system/config/form/field/refresh_ratepay_profiles.phtml b/view/adminhtml/templates/system/config/form/field/refresh_ratepay_profiles.phtml index b4e22040..3734d70d 100644 --- a/view/adminhtml/templates/system/config/form/field/refresh_ratepay_profiles.phtml +++ b/view/adminhtml/templates/system/config/form/field/refresh_ratepay_profiles.phtml @@ -25,14 +25,14 @@ */ /** - * @see \Payone\Core\Block\Adminhtml\Config\Form\Field\AmazonConfiguration + * @see \Payone\Core\Block\Adminhtml\Config\Form\Field\RefreshRatepayProfiles */ ?>
-
diff --git a/view/frontend/layout/checkout_index_index.xml b/view/frontend/layout/checkout_index_index.xml index 10a2b506..fa56efdb 100644 --- a/view/frontend/layout/checkout_index_index.xml +++ b/view/frontend/layout/checkout_index_index.xml @@ -151,9 +151,9 @@ true - + true diff --git a/view/frontend/layout/payone_amazon_loadreview.xml b/view/frontend/layout/payone_amazon_loadreview.xml index a8e8384a..ec678a05 100644 --- a/view/frontend/layout/payone_amazon_loadreview.xml +++ b/view/frontend/layout/payone_amazon_loadreview.xml @@ -41,7 +41,7 @@ - + diff --git a/view/frontend/layout/payone_onepage_review.xml b/view/frontend/layout/payone_onepage_review.xml index 53431978..d97e1b4b 100644 --- a/view/frontend/layout/payone_onepage_review.xml +++ b/view/frontend/layout/payone_onepage_review.xml @@ -42,6 +42,6 @@ - + diff --git a/view/frontend/web/css/payolution.css b/view/frontend/web/css/payolution.css index 20da0c0b..0ed35dc8 100644 --- a/view/frontend/web/css/payolution.css +++ b/view/frontend/web/css/payolution.css @@ -63,7 +63,7 @@ list-style: circle outside none; } -.payolution_installment_overview TABLE TR TD.value, .bnpl_installment_overview TABLE TR TD.value { +.payolution_installment_overview TABLE TR TD.value{ text-align: right; padding-left: 60px; } diff --git a/view/frontend/web/css/payone.css b/view/frontend/web/css/payone.css index 319396b9..68681141 100644 --- a/view/frontend/web/css/payone.css +++ b/view/frontend/web/css/payone.css @@ -36,3 +36,7 @@ .payoneClear { clear:both; } + +.payoneBNPLselector { + margin-bottom:0.7em; +} diff --git a/view/frontend/web/js/action/ratepayconfig.js b/view/frontend/web/js/action/ratepayconfig.js new file mode 100644 index 00000000..c1e73a28 --- /dev/null +++ b/view/frontend/web/js/action/ratepayconfig.js @@ -0,0 +1,72 @@ +/** + * PAYONE Magento 2 Connector is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PAYONE Magento 2 Connector is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with PAYONE Magento 2 Connector. If not, see . + * + * PHP version 8 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2023 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ +/*jshint browser:true jquery:true*/ +/*global alert*/ +define([ + 'jquery', + 'Magento_Checkout/js/model/url-builder', + 'mage/storage', + 'Magento_Checkout/js/model/full-screen-loader', + 'Magento_Checkout/js/model/quote', + 'Magento_Customer/js/model/customer' +], function ($, urlBuilder, storage, fullScreenLoader, quote, customer) { + 'use strict'; + + /** Override default place order action and add agreement_ids to request */ + return function () { + var serviceUrl; + + var request = { + cartId: quote.getQuoteId() + }; + if (!customer.isLoggedIn()) { + serviceUrl = urlBuilder.createUrl('/guest-carts/:quoteId/payone-ratepayGetConfig', { + quoteId: quote.getQuoteId() + }); + } else { + serviceUrl = urlBuilder.createUrl('/carts/mine/payone-ratepayGetConfig', {}); + } + + fullScreenLoader.startLoader(); + + return storage.post( + serviceUrl, + JSON.stringify(request) + ).done( + function (response) { + if (response.success === true && response.config !== undefined) { + window.checkoutConfig.payment.payone.ratepayReloaded = JSON.parse(response.config); + window.checkoutConfig.payment.payone.ratepayRefreshed = true; + } + fullScreenLoader.stopLoader(); + } + ).fail( + function (response) { + //errorProcessor.process(response, messageContainer); + alert('An error occured.'); + fullScreenLoader.stopLoader(); + } + ); + }; +}); diff --git a/view/frontend/web/js/model/error-processor-mixin.js b/view/frontend/web/js/model/error-processor-mixin.js index b0af607b..ee0da8bf 100644 --- a/view/frontend/web/js/model/error-processor-mixin.js +++ b/view/frontend/web/js/model/error-processor-mixin.js @@ -41,7 +41,7 @@ define( ], function(methodList, quote) { targetModule.disablePaymentType = function (sPaymentType) { $('INPUT#' + sPaymentType).parents('.payment-method').find('.action.checkout').prop( "disabled", true ); - $('INPUT#' + sPaymentType).parents('.payment-method').delay(5000).fadeOut(2000, function() { + $('INPUT#' + sPaymentType).parents('.payment-method').delay(3000).fadeOut(2000, function() { $('INPUT#' + sPaymentType).parents('.payment-method').remove(); }); }; @@ -60,6 +60,12 @@ define( if(response.responseJSON.message.indexOf('307 -') !== -1 && quote.paymentMethod().method.indexOf('payone_ratepay') !== -1) { targetModule.disablePaymentType(quote.paymentMethod().method); } + if(response.responseJSON.message.indexOf('307 -') !== -1 && quote.paymentMethod().method.indexOf('payone_bnpl_') !== -1) { + // Hide all BNPL methods + targetModule.disablePaymentType('payone_bnpl_invoice'); + targetModule.disablePaymentType('payone_bnpl_installment'); + targetModule.disablePaymentType('payone_bnpl_debit'); + } } return origReturn; }); diff --git a/view/frontend/web/js/view/payment/method-renderer/bnpl_debit-method.js b/view/frontend/web/js/view/payment/method-renderer/bnpl_debit-method.js index c618ba61..ee951b32 100644 --- a/view/frontend/web/js/view/payment/method-renderer/bnpl_debit-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/bnpl_debit-method.js @@ -36,7 +36,6 @@ define( birthmonth: '', birthyear: '', telephone: '', - bankaccountholder: '', iban: '' }, initObservable: function () { @@ -46,11 +45,26 @@ define( 'birthmonth', 'birthyear', 'telephone', - 'bankaccountholder', 'iban' ]); return this; - } + }, + getData: function () { + var parentReturn = this._super(); + parentReturn.additional_data.iban = this.getCleanedNumber(this.iban()); + return parentReturn; + }, + validate: function () { + var parentReturn = this._super(); + if (parentReturn === false) { + return parentReturn; + } + if (this.iban() == '') { + this.messageContainer.addErrorMessage({'message': $t('Please enter a valid IBAN.')}); + return false; + } + return parentReturn; + }, }); } ); diff --git a/view/frontend/web/js/view/payment/method-renderer/bnpl_installment-method.js b/view/frontend/web/js/view/payment/method-renderer/bnpl_installment-method.js index c6008bf8..3ed5bb40 100644 --- a/view/frontend/web/js/view/payment/method-renderer/bnpl_installment-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/bnpl_installment-method.js @@ -39,7 +39,6 @@ define( birthmonth: '', birthyear: '', telephone: '', - bankaccountholder: '', iban: '', optionid: '' }, @@ -51,7 +50,6 @@ define( 'birthyear', 'telephone', 'telephone', - 'bankaccountholder', 'iban', 'optionid' ]); @@ -87,7 +85,6 @@ define( getData: function () { var parentReturn = this._super(); parentReturn.additional_data.optionid = this.optionid(); - parentReturn.additional_data.bankaccountholder = this.bankaccountholder(); parentReturn.additional_data.iban = this.getCleanedNumber(this.iban()); return parentReturn; }, @@ -96,10 +93,6 @@ define( if (parentReturn === false) { return parentReturn; } - if (this.bankaccountholder() == '') { - this.messageContainer.addErrorMessage({'message': $t('Please enter your bank account holder information.')}); - return false; - } if (this.iban() == '') { this.messageContainer.addErrorMessage({'message': $t('Please enter a valid IBAN.')}); return false; diff --git a/view/frontend/web/js/view/payment/method-renderer/ratepay_base.js b/view/frontend/web/js/view/payment/method-renderer/ratepay_base.js index 19499007..a81e8427 100644 --- a/view/frontend/web/js/view/payment/method-renderer/ratepay_base.js +++ b/view/frontend/web/js/view/payment/method-renderer/ratepay_base.js @@ -26,13 +26,58 @@ define( 'Payone_Core/js/view/payment/method-renderer/base', 'Magento_Checkout/js/model/quote', 'Magento_Customer/js/model/customer', + 'Payone_Core/js/action/ratepayconfig', 'mage/translate' ], - function (Component, quote, customer, $t) { + function (Component, quote, customer, ratepayconfig, $t) { 'use strict'; return Component.extend({ + initialize: function () { + let parentReturn = this._super(); + if (!customer.isLoggedIn() && window.checkoutConfig.payment.payone.ratepayRefreshed === false) { + ratepayconfig(); + window.checkoutConfig.payment.payone.ratepayRefreshed = true; + } + return parentReturn; + }, isPlaceOrderActionAllowedRatePay: function () { - return (quote.billingAddress() != null && quote.billingAddress().getCacheKey() == quote.shippingAddress().getCacheKey()); + return this.isDifferentAddressNotAllowed() === false && this.isB2BNotAllowed() === false; + }, + isDifferentAddressNotAllowed: function () { + if (this.getConfigValue('differentAddressAllowed') === true) { + return false; + } + return (quote.billingAddress() === null || quote.billingAddress().getCacheKey() !== quote.shippingAddress().getCacheKey()); + }, + isB2BNotAllowed: function () { + if (this.getConfigValue('b2bAllowed') === true) { + return false; + } + return (quote.billingAddress() !== null && typeof quote.billingAddress().company !== undefined && quote.billingAddress().company !== null && quote.billingAddress().company != ""); + }, + getConfigValue: function (sConfigKey) { + if (!customer.isLoggedIn() && window.checkoutConfig.payment.payone.ratepayRefreshed === true && window.checkoutConfig.payment.payone.ratepayReloaded !== undefined) { + let config = window.checkoutConfig.payment.payone.ratepayReloaded; + if (config[this.getCode()] !== undefined && config[this.getCode()][sConfigKey] !== undefined) { + return config[this.getCode()][sConfigKey]; + } + } + if (window.checkoutConfig.payment.payone.ratepay[this.getCode()][sConfigKey] !== undefined && window.checkoutConfig.payment.payone.ratepay[this.getCode()][sConfigKey] === true) { + return window.checkoutConfig.payment.payone.ratepay[this.getCode()][sConfigKey]; + } + return null; + }, + isB2bMode: function () { + if (quote.billingAddress() != null && + typeof quote.billingAddress().company !== undefined && + quote.billingAddress().company !== null && + quote.billingAddress().company != "" && + window.checkoutConfig.payment.payone.ratepay[this.getCode()].b2bAllowed !== undefined && + window.checkoutConfig.payment.payone.ratepay[this.getCode()].b2bAllowed === true + ) { + return true; + } + return false; }, getData: function () { var parentReturn = this._super(); @@ -45,6 +90,9 @@ define( if (this.requestTelephone()) { parentReturn.additional_data.telephone = this.telephone(); } + if (this.isB2bMode()) { + parentReturn.additional_data.company_uid = this.companyUid(); + } return parentReturn; }, @@ -53,6 +101,9 @@ define( return window.checkoutConfig.payment.instructions[this.item.method]; }, requestBirthday: function () { + if (quote.billingAddress() == null || this.isB2bMode() === true) { + return false; + } if (customer.customerData.dob == undefined || customer.customerData.dob === null) { return true; } diff --git a/view/frontend/web/js/view/payment/method-renderer/ratepay_debit-method.js b/view/frontend/web/js/view/payment/method-renderer/ratepay_debit-method.js index 96722bba..02a9007e 100644 --- a/view/frontend/web/js/view/payment/method-renderer/ratepay_debit-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/ratepay_debit-method.js @@ -37,7 +37,8 @@ define( birthyear: '', telephone: '', iban: '', - bic: '' + bic: '', + companyUid: '' }, initObservable: function () { this._super() @@ -47,7 +48,8 @@ define( 'birthyear', 'telephone', 'iban', - 'bic' + 'bic', + 'companyUid' ]); return this; }, diff --git a/view/frontend/web/js/view/payment/method-renderer/ratepay_installment-method.js b/view/frontend/web/js/view/payment/method-renderer/ratepay_installment-method.js index ca47f13c..763f5e3c 100644 --- a/view/frontend/web/js/view/payment/method-renderer/ratepay_installment-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/ratepay_installment-method.js @@ -49,8 +49,9 @@ define( installmentTotalAmount: null, interestRate: null, useDirectDebit: true, - allowedMonths: window.checkoutConfig.payment.payone.ratepayAllowedMonths, - allowedMonthsReloaded: false + allowedMonths: [], + allowedMonthsReloaded: false, + companyUid: '' }, initObservable: function () { this._super() @@ -69,10 +70,16 @@ define( 'interestRate', 'useDirectDebit', 'allowedMonths', - 'allowedMonthsReloaded' + 'allowedMonthsReloaded', + 'companyUid' ]); return this; }, + initialize: function () { + let parentReturn = this._super(); + this.allowedMonths(window.checkoutConfig.payment.payone.ratepay[this.getCode()].allowedMonths); + return parentReturn; + }, getData: function () { var parentReturn = this._super(); @@ -154,7 +161,7 @@ define( this.useDirectDebit(!this.useDirectDebit()); }, getAllowedMonths: function () { - if ((window.checkoutConfig.payment.payone.ratepayAllowedMonths === undefined || window.checkoutConfig.payment.payone.ratepayAllowedMonths.length == 0) && this.allowedMonthsReloaded() === false) { + if ((window.checkoutConfig.payment.payone.ratepay[this.getCode()].allowedMonths === undefined || window.checkoutConfig.payment.payone.ratepay[this.getCode()].allowedMonths.length == 0) && this.allowedMonthsReloaded() === false) { updateAllowedMonths(this); this.allowedMonthsReloaded(true); } diff --git a/view/frontend/web/js/view/payment/method-renderer/ratepay_invoice-method.js b/view/frontend/web/js/view/payment/method-renderer/ratepay_invoice-method.js index 16f49e2e..fe7e819f 100644 --- a/view/frontend/web/js/view/payment/method-renderer/ratepay_invoice-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/ratepay_invoice-method.js @@ -35,7 +35,8 @@ define( birthday: '', birthmonth: '', birthyear: '', - telephone: '' + telephone: '', + companyUid: '', }, initObservable: function () { this._super() @@ -43,7 +44,8 @@ define( 'birthday', 'birthmonth', 'birthyear', - 'telephone' + 'telephone', + 'companyUid' ]); return this; } diff --git a/view/frontend/web/js/view/payment/payone-payments.js b/view/frontend/web/js/view/payment/payone-payments.js index cb140283..ee500b09 100644 --- a/view/frontend/web/js/view/payment/payone-payments.js +++ b/view/frontend/web/js/view/payment/payone-payments.js @@ -164,10 +164,10 @@ define( type: 'payone_bnpl_invoice', component: 'Payone_Core/js/view/payment/method-renderer/bnpl_invoice-method' }, - /*BNPL_DEBIT_DEACTIVATED{ + { type: 'payone_bnpl_debit', component: 'Payone_Core/js/view/payment/method-renderer/bnpl_debit-method' - },*/ + }, { type: 'payone_bnpl_installment', component: 'Payone_Core/js/view/payment/method-renderer/bnpl_installment-method' diff --git a/view/frontend/web/template/payment/bnpl_debit.html b/view/frontend/web/template/payment/bnpl_debit.html index 9f2ff30e..991bdd7f 100644 --- a/view/frontend/web/template/payment/bnpl_debit.html +++ b/view/frontend/web/template/payment/bnpl_debit.html @@ -99,21 +99,6 @@ -
- -
- -
-

- +

diff --git a/view/frontend/web/template/payment/bnpl_installment.html b/view/frontend/web/template/payment/bnpl_installment.html index ca87d1da..7cd6cb99 100644 --- a/view/frontend/web/template/payment/bnpl_installment.html +++ b/view/frontend/web/template/payment/bnpl_installment.html @@ -99,22 +99,6 @@
- -
- -
- -
-

- +

diff --git a/view/frontend/web/template/payment/bnpl_invoice.html b/view/frontend/web/template/payment/bnpl_invoice.html index c5d2e556..65fd3092 100644 --- a/view/frontend/web/template/payment/bnpl_invoice.html +++ b/view/frontend/web/template/payment/bnpl_invoice.html @@ -105,7 +105,7 @@

- +

diff --git a/view/frontend/web/template/payment/ratepay_debit.html b/view/frontend/web/template/payment/ratepay_debit.html index 3b87547c..49e3d4ef 100644 --- a/view/frontend/web/template/payment/ratepay_debit.html +++ b/view/frontend/web/template/payment/ratepay_debit.html @@ -43,6 +43,23 @@
+ +
+ +
+ +
+
+
-

- +

+ +
+

+
diff --git a/view/frontend/web/template/payment/ratepay_installment.html b/view/frontend/web/template/payment/ratepay_installment.html index 689d4081..ce9bb6d2 100644 --- a/view/frontend/web/template/payment/ratepay_installment.html +++ b/view/frontend/web/template/payment/ratepay_installment.html @@ -139,6 +139,23 @@

+ +
+ +
+ +
+
+
-

- +

+ +
+

+

diff --git a/view/frontend/web/template/payment/ratepay_invoice.html b/view/frontend/web/template/payment/ratepay_invoice.html index 80a23d94..966815a2 100644 --- a/view/frontend/web/template/payment/ratepay_invoice.html +++ b/view/frontend/web/template/payment/ratepay_invoice.html @@ -43,6 +43,23 @@
+ +
+ +
+ +
+
+
-

- +

+ +
+

+
diff --git a/view/webapi_rest/templates/bnpl/installment_plan.phtml b/view/webapi_rest/templates/bnpl/installment_plan.phtml index 8791d03e..6774c28e 100644 --- a/view/webapi_rest/templates/bnpl/installment_plan.phtml +++ b/view/webapi_rest/templates/bnpl/installment_plan.phtml @@ -34,11 +34,11 @@ $aInstallmentData = $aInstallmentResponse['runtimes'];