From 07aed223667193f81384dd724ea67584d2005021 Mon Sep 17 00:00:00 2001 From: Teuber Date: Wed, 17 Jul 2024 09:29:58 +0200 Subject: [PATCH 1/2] version bump to 3110 --- Model/PayoneConfig.php | 2 +- composer.json | 2 +- etc/module.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Model/PayoneConfig.php b/Model/PayoneConfig.php index f6fa5198..6998ddba 100644 --- a/Model/PayoneConfig.php +++ b/Model/PayoneConfig.php @@ -32,7 +32,7 @@ abstract class PayoneConfig { /* Module version */ - const MODULE_VERSION = '3.10.2'; + const MODULE_VERSION = '3.11.0'; /* Authorization request types */ const REQUEST_TYPE_PREAUTHORIZATION = 'preauthorization'; diff --git a/composer.json b/composer.json index e82348f0..a7b0e8f0 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "payone-gmbh/magento-2", "description": "PAYONE payment gateway for all German online and offline payment methods including PayPal, all major Credit Cards and Maestro.", "type": "magento2-module", - "version": "3.10.2", + "version": "3.11.0", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/etc/module.xml b/etc/module.xml index 9ccc3862..efec9ec0 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -25,7 +25,7 @@ */ --> - + From bcf2c1b5d5a6a43a6dc4587653767ab286652be9 Mon Sep 17 00:00:00 2001 From: Teuber Date: Thu, 19 Sep 2024 13:20:05 +0200 Subject: [PATCH 2/2] version bump to 3120 --- Api/AmazonPayInterface.php | 16 ++ Api/Data/AmazonPayResponseInterface.php | 14 + Block/Amazon/Button.php | 22 ++ Block/Amazon/ButtonV2.php | 250 +++++++++++++++++ Block/RedirectReturn.php | 24 +- Controller/Amazon/Returned.php | 153 ++++++++++ Controller/Onepage/PlaceOrder.php | 3 + Controller/Onepage/Review.php | 36 ++- Helper/Environment.php | 4 +- Helper/Payment.php | 2 + Helper/Ratepay.php | 4 + .../CreateCheckoutSessionPayload.php | 71 +++++ .../Genericpayment/GetCheckoutSession.php | 63 +++++ .../Genericpayment/UpdateCheckoutSession.php | 65 +++++ Model/ConfigProvider.php | 18 +- Model/Methods/AmazonPayV2.php | 237 ++++++++++++++++ Model/Methods/BNPL/BNPLBase.php | 2 +- Model/Methods/Klarna/Debit.php | 2 +- Model/Methods/Klarna/Installment.php | 2 +- Model/Methods/OnlineBankTransfer/Ideal.php | 60 ---- Model/Methods/PayoneMethod.php | 9 + Model/Methods/Ratepay/RatepayBase.php | 2 +- Model/PayoneConfig.php | 3 +- Model/Plugins/MethodList.php | 3 +- Observer/AddAmazonPayButton.php | 26 +- Observer/OrderPaymentPlaceEnd.php | 5 +- Service/V1/AmazonPay.php | 113 ++++++-- Service/V1/Data/AmazonPayResponse.php | 20 ++ Test/Unit/Block/Amazon/ButtonTest.php | 10 + Test/Unit/Block/Amazon/ButtonV2Test.php | 265 ++++++++++++++++++ Test/Unit/Controller/Amazon/ReturnedTest.php | 160 +++++++++++ .../Controller/Onepage/PlaceOrderTest.php | 68 ++++- Test/Unit/Controller/Onepage/ReviewTest.php | 20 +- .../CreateCheckoutSessionPayloadTest.php | 86 ++++++ .../Genericpayment/GetCheckoutSessionTest.php | 86 ++++++ .../UpdateCheckoutSessionTest.php | 86 ++++++ Test/Unit/Model/ConfigProviderTest.php | 17 +- Test/Unit/Model/Methods/AmazonPayV2Test.php | 247 ++++++++++++++++ Test/Unit/Model/Methods/BNPL/DebitTest.php | 37 ++- .../Model/Methods/Klarna/InstallmentTest.php | 2 +- .../Methods/OnlineBankTransfer/IdealTest.php | 21 +- Test/Unit/Model/Methods/PayoneMethodTest.php | 8 + Test/Unit/Service/V1/AmazonPayTest.php | 57 +++- .../Service/V1/Data/AmazonPayResponseTest.php | 16 ++ composer.json | 4 +- etc/adminhtml/system.xml | 6 + etc/adminhtml/system/payone_amazonpayv2.xml | 146 ++++++++++ etc/config.xml | 15 + etc/csp_whitelist.xml | 3 + etc/module.xml | 2 +- etc/payment.xml | 3 + etc/webapi.xml | 34 +++ view/frontend/layout/checkout_index_index.xml | 3 + view/frontend/templates/amazon/buttonv2.phtml | 110 ++++++++ view/frontend/templates/redirect_return.phtml | 90 +++--- .../web/js/action/checkoutsessionpayload.js | 55 ++++ .../web/js/action/loadamazonpayapbsession.js | 55 ++++ .../method-renderer/amazonpayv2-method.js | 184 ++++++++++++ .../js/view/payment/method-renderer/base.js | 13 + .../method-renderer/obt_ideal-method.js | 23 +- .../web/js/view/payment/payone-payments.js | 4 + .../web/template/payment/amazonpayv2.html | 98 +++++++ .../web/template/payment/creditcard.html | 6 +- .../web/template/payment/obt_ideal.html | 22 -- 64 files changed, 3052 insertions(+), 239 deletions(-) create mode 100644 Block/Amazon/ButtonV2.php create mode 100644 Controller/Amazon/Returned.php create mode 100644 Model/Api/Request/Genericpayment/CreateCheckoutSessionPayload.php create mode 100644 Model/Api/Request/Genericpayment/GetCheckoutSession.php create mode 100644 Model/Api/Request/Genericpayment/UpdateCheckoutSession.php create mode 100644 Model/Methods/AmazonPayV2.php create mode 100644 Test/Unit/Block/Amazon/ButtonV2Test.php create mode 100644 Test/Unit/Controller/Amazon/ReturnedTest.php create mode 100644 Test/Unit/Model/Api/Request/Genericpayment/CreateCheckoutSessionPayloadTest.php create mode 100644 Test/Unit/Model/Api/Request/Genericpayment/GetCheckoutSessionTest.php create mode 100644 Test/Unit/Model/Api/Request/Genericpayment/UpdateCheckoutSessionTest.php create mode 100644 Test/Unit/Model/Methods/AmazonPayV2Test.php create mode 100644 etc/adminhtml/system/payone_amazonpayv2.xml create mode 100644 view/frontend/templates/amazon/buttonv2.phtml create mode 100644 view/frontend/web/js/action/checkoutsessionpayload.js create mode 100644 view/frontend/web/js/action/loadamazonpayapbsession.js create mode 100644 view/frontend/web/js/view/payment/method-renderer/amazonpayv2-method.js create mode 100644 view/frontend/web/template/payment/amazonpayv2.html diff --git a/Api/AmazonPayInterface.php b/Api/AmazonPayInterface.php index 3f271ab9..de976e31 100644 --- a/Api/AmazonPayInterface.php +++ b/Api/AmazonPayInterface.php @@ -38,4 +38,20 @@ interface AmazonPayInterface * @return \Payone\Core\Service\V1\Data\AmazonPayResponse */ public function getWorkorderId($amazonReferenceId, $amazonAddressToken); + + /** + * Returns Amazon Pay V2 checkout session payload + * + * @param string $cartId + * @return \Payone\Core\Service\V1\Data\AmazonPayResponse + */ + public function getCheckoutSessionPayload($cartId); + + /** + * Returns Amazon Pay V2 checkout session payload for APB + * + * @param string $orderId + * @return \Payone\Core\Service\V1\Data\AmazonPayResponse + */ + public function getAmazonPayApbSession($orderId); } diff --git a/Api/Data/AmazonPayResponseInterface.php b/Api/Data/AmazonPayResponseInterface.php index 8ead7dae..fc06cc56 100644 --- a/Api/Data/AmazonPayResponseInterface.php +++ b/Api/Data/AmazonPayResponseInterface.php @@ -55,4 +55,18 @@ public function getRedirectUrl(); * @return string */ public function getAmazonReviewHtml(); + + /** + * Returns error message + * + * @return string + */ + public function getPayload(); + + /** + * Returns error message + * + * @return string + */ + public function getSignature(); } diff --git a/Block/Amazon/Button.php b/Block/Amazon/Button.php index e322db09..cf642d43 100644 --- a/Block/Amazon/Button.php +++ b/Block/Amazon/Button.php @@ -46,6 +46,11 @@ class Button extends Template implements \Magento\Catalog\Block\ShortcutInterfac */ protected $baseHelper; + /** + * @var string + */ + protected $name; + /** * Constructor * @@ -73,6 +78,23 @@ public function getAlias() return $this->alias; } + /** + * @param string $name + * @return void + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + /** * Get Amazon client id from config * diff --git a/Block/Amazon/ButtonV2.php b/Block/Amazon/ButtonV2.php new file mode 100644 index 00000000..3016c41b --- /dev/null +++ b/Block/Amazon/ButtonV2.php @@ -0,0 +1,250 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2024 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Block\Amazon; + +use Magento\Framework\View\Element\Template; +use Payone\Core\Model\Methods\AmazonPayV2; +use Payone\Core\Model\PayoneConfig; + +/** + * Block class for the Amazon Pay V2 button + */ +class ButtonV2 extends Template implements \Magento\Catalog\Block\ShortcutInterface +{ + /** + * Shortcut alias + * + * @var string + */ + protected $alias = 'payone.block.amazon.buttonv2'; + + /** + * @var string + */ + protected $name; + + /** + * @var \Payone\Core\Helper\Api + */ + protected $apiHelper; + + /** + * @var \Magento\Checkout\Model\Session + */ + protected $checkoutSession; + + /** + * @var \Payone\Core\Model\Methods\AmazonPayV2 + */ + protected $amazonPayment; + + /** + * Constructor + * + * @param \Magento\Framework\View\Element\Template\Context $context + * @param \Payone\Core\Helper\Api $apiHelper + * @param \Magento\Checkout\Model\Session $checkoutSession + * @param \Payone\Core\Model\Methods\AmazonPayV2 $amazonPayment + * @param array $data + */ + public function __construct( + \Magento\Framework\View\Element\Template\Context $context, + \Payone\Core\Helper\Api $apiHelper, + \Magento\Checkout\Model\Session $checkoutSession, + \Payone\Core\Model\Methods\AmazonPayV2 $amazonPayment, + array $data = [] + ) { + parent::__construct($context, $data); + $this->apiHelper = $apiHelper; + $this->checkoutSession = $checkoutSession; + $this->amazonPayment = $amazonPayment; + $this->setTemplate('amazon/buttonv2.phtml'); + } + + /** + * Get shortcut alias + * + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @param string $name + * @return void + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @return int + */ + public function getQuoteId() + { + return $this->getQuote()->getId(); + } + + /** + * @return string + */ + public function getStoreCode() + { + return $this->getQuote()->getStore()->getCode(); + } + + /** + * @return string + */ + public function getButtonId() + { + $buttonId = "AmazonPayButton"; + if (strpos($this->getName() ?? '', "checkout.cart.shortcut.buttons") !== false) { + $buttonId = "AmazonPayButtonBasket"; + } elseif (strpos($this->getName() ?? '', "shortcutbuttons") !== false) { + $buttonId = "AmazonPayButtonMiniBasket"; + } + return $buttonId; + } + + /** + * @return mixed + */ + public function getQuote() + { + return $this->checkoutSession->getQuote(); + } + + /** + * @return string + */ + public function getPublicKeyId() + { + return AmazonPayV2::BUTTON_PUBLIC_KEY; + } + + /** + * Get Amazon merchant id from config + * + * @return string + */ + public function getMerchantId() + { + return $this->amazonPayment->getMerchantId(); + } + + /** + * @return bool + */ + public function isTestMode() + { + return $this->amazonPayment->useSandbox(); + } + + /** + * @return string + */ + public function getCurrency() + { + return $this->apiHelper->getCurrencyFromQuote($this->getQuote()); + } + + /** + * @return float + */ + public function getAmount() + { + return $this->apiHelper->getQuoteAmount($this->getQuote()); + } + + /** + * @return string + */ + public function getProductType() + { + $oQuote = $this->getQuote(); + if ($oQuote->isVirtual() === true) { + return "PayOnly"; + } + return "PayAndShip"; + /** + * 'PayAndShip' - Offer checkout using buyer's Amazon wallet and address book. Select this product type if you need the buyer's shipping details + * 'PayOnly' - Offer checkout using only the buyer's Amazon wallet. Select this product type if you do not need the buyer's shipping details + * 'SignIn' - Offer Amazon Sign-in. Select this product type if you need buyer details before the buyer starts Amazon Pay checkout. See Amazon Sign-in for more information. + * Default value: 'PayAndShip' + */ + } + + /** + * @return string + */ + public function getPlacement() + { + if ($this->getButtonId() == "AmazonPayButtonBasket") { + return "Cart"; + } + return "Home"; + /** + * 'Home' - Initial or main page + * 'Product' - Product details page + * 'Cart' - Cart review page before buyer starts checkout + * 'Checkout' - Any page after buyer starts checkout + * 'Other' - Any page that doesn't fit the previous descriptions + */ + } + + /** + * Get Amazon button color from config + * + * @return string + */ + public function getButtonColor() + { + return $this->amazonPayment->getButtonColor(); + } + + /** + * Get Amazon button language from config + * + * @return string + */ + public function getButtonLanguage() + { + return $this->amazonPayment->getButtonLanguage(); + } +} diff --git a/Block/RedirectReturn.php b/Block/RedirectReturn.php index 402ad2b6..9365518b 100644 --- a/Block/RedirectReturn.php +++ b/Block/RedirectReturn.php @@ -29,6 +29,7 @@ use Magento\Framework\View\Element\Template; use Magento\Quote\Model\Quote; use Magento\Checkout\Model\Session; +use Payone\Core\Helper\Script; /** * Block class for re-setting the guest checkout information @@ -42,17 +43,28 @@ class RedirectReturn extends Template */ protected $checkoutSession; + /** + * @var Script + */ + protected $scriptHelper; + /** * Constructor * * @param Template\Context $context * @param Session $checkoutSession + * @param Script $scriptHelper * @param array $data */ - public function __construct(Template\Context $context, Session $checkoutSession, array $data = []) - { + public function __construct( + Template\Context $context, + Session $checkoutSession, + Script $scriptHelper, + array $data = [] + ) { parent::__construct($context, $data); $this->checkoutSession = $checkoutSession; + $this->scriptHelper = $scriptHelper; } /** @@ -115,4 +127,12 @@ public function isGuest() { return $this->getQuote()->getCustomerIsGuest(); } + + /** + * @return Script + */ + public function getScriptHelper() + { + return $this->scriptHelper; + } } diff --git a/Controller/Amazon/Returned.php b/Controller/Amazon/Returned.php new file mode 100644 index 00000000..6933664d --- /dev/null +++ b/Controller/Amazon/Returned.php @@ -0,0 +1,153 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2016 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Controller\Amazon; + +use Magento\Framework\Controller\ResultFactory; +use Magento\Framework\Controller\Result\Redirect; +use Payone\Core\Model\PayoneConfig; +use Magento\Checkout\Model\Type\Onepage; +use Magento\Customer\Model\Group; + +class Returned extends \Magento\Framework\App\Action\Action +{ + /** + * Checkout session + * + * @var \Magento\Checkout\Model\Session + */ + protected $checkoutSession; + + /** + * PAYONE checkout helper + * + * @var \Payone\Core\Helper\Checkout + */ + protected $checkoutHelper; + + /** + * PAYONE order helper + * + * @var \Payone\Core\Helper\Order + */ + protected $orderHelper; + + /** + * Amazon Pay payment model + * + * @var \Payone\Core\Model\Methods\AmazonPayV2 + */ + protected $amazonPayment; + + /** + * PAYONE GetCheckoutSession request + * + * @var \Payone\Core\Model\Api\Request\Genericpayment\GetCheckoutSession + */ + protected $getCheckoutSession; + + /** + * Constructor + * + * @param \Magento\Framework\App\Action\Context $context + * @param \Magento\Checkout\Model\Session $checkoutSession + * @param \Payone\Core\Helper\Checkout $checkoutHelper + * @param \Payone\Core\Helper\Order $orderHelper + * @param \Payone\Core\Model\Methods\AmazonPayV2 $amazonPayment + * @param \Payone\Core\Model\Api\Request\Genericpayment\GetCheckoutSession $getCheckoutSession + */ + public function __construct( + \Magento\Framework\App\Action\Context $context, + \Magento\Checkout\Model\Session $checkoutSession, + \Payone\Core\Helper\Checkout $checkoutHelper, + \Payone\Core\Helper\Order $orderHelper, + \Payone\Core\Model\Methods\AmazonPayV2 $amazonPayment, + \Payone\Core\Model\Api\Request\Genericpayment\GetCheckoutSession $getCheckoutSession + ) { + parent::__construct($context); + $this->checkoutSession = $checkoutSession; + $this->checkoutHelper = $checkoutHelper; + $this->orderHelper = $orderHelper; + $this->amazonPayment = $amazonPayment; + $this->getCheckoutSession = $getCheckoutSession; + } + + /** + * @param string $sWorkorderId + * @return void + */ + protected function handleReturn($sWorkorderId) + { + $oQuote = $this->checkoutSession->getQuote(); + $aResponse = $this->getCheckoutSession->sendRequest($this->amazonPayment, $oQuote, $sWorkorderId); + if (!isset($aResponse['status']) || $aResponse['status'] != 'OK') { + throw new \Exception('Could not get Amazon Pay checkout session. Status: '.$aResponse['status']); + } + + $oQuote = $this->orderHelper->updateAddresses($oQuote, $aResponse, true); + + if ($this->checkoutHelper->getCurrentCheckoutMethod($oQuote) == Onepage::METHOD_GUEST) { + $oQuote->setCustomerId(null) + ->setCustomerEmail($oQuote->getBillingAddress()->getEmail()) + ->setCustomerIsGuest(true) + ->setCustomerGroupId(Group::NOT_LOGGED_IN_ID); + } + + $oPayment = $oQuote->getPayment(); + $oPayment->setMethod(PayoneConfig::METHOD_AMAZONPAYV2); + + $oQuote->setPayment($oPayment); + $oQuote->setInventoryProcessed(false); + $oQuote->collectTotals()->save(); + } + + /** + * Redirect to payment-provider or to success page + * + * @return Redirect + */ + public function execute() + { + $sWorkorderId = $this->checkoutSession->getPayoneWorkorderId(); + if ($sWorkorderId) { + try { + $this->handleReturn($sWorkorderId); + + /** @var Redirect $resultRedirect */ + $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); + return $resultRedirect->setPath('payone/onepage/review'); + } catch (\Exception $e) { + $this->messageManager->addExceptionMessage( + $e, + __('An error occured during the Amazon Pay transaction.') + ); + } + } + /** @var Redirect $resultRedirect */ + $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); + return $resultRedirect->setPath('checkout/cart'); + } +} diff --git a/Controller/Onepage/PlaceOrder.php b/Controller/Onepage/PlaceOrder.php index 7d2e0094..c26eee5b 100644 --- a/Controller/Onepage/PlaceOrder.php +++ b/Controller/Onepage/PlaceOrder.php @@ -149,6 +149,9 @@ protected function placeOrder($oQuote) if ($oQuote->getPayment()->getMethod() == PayoneConfig::METHOD_PAYPAL) { $this->checkoutSession->setIsPayonePayPalExpress(true); } + if ($oQuote->getPayment()->getMethod() == PayoneConfig::METHOD_AMAZONPAYV2) { + $this->checkoutSession->setIsPayoneAmazonPayAuth(true); + } if ($this->getRequest()->getParam('fingerprint')) { $this->checkoutSession->setPayoneDeviceFingerprint($this->getRequest()->getParam('fingerprint')); } diff --git a/Controller/Onepage/Review.php b/Controller/Onepage/Review.php index 7cfae152..d74e7ec7 100644 --- a/Controller/Onepage/Review.php +++ b/Controller/Onepage/Review.php @@ -30,6 +30,7 @@ use Magento\Quote\Model\Quote; use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Controller\Result\Redirect as CoreRedirect; +use Payone\Core\Model\Methods\AmazonPayV2; use Payone\Core\Model\PayoneConfig; /** @@ -56,6 +57,11 @@ class Review extends \Magento\Framework\App\Action\Action */ protected $quoteRepository; + /** + * @var \Payone\Core\Model\Api\Request\Genericpayment\UpdateCheckoutSession + */ + protected $updateCheckoutSession; + /** * List of all PAYONE payment methods available for this review step * @@ -64,25 +70,30 @@ class Review extends \Magento\Framework\App\Action\Action protected $availableReviewMethods = [ PayoneConfig::METHOD_PAYPAL, PayoneConfig::METHOD_PAYDIREKT, + PayoneConfig::METHOD_AMAZONPAYV2, ]; /** * Constructor * - * @param \Magento\Framework\App\Action\Context $context - * @param \Magento\Checkout\Model\Session $checkoutSession - * @param \Magento\Framework\View\Result\PageFactory $pageFactory + * @param \Magento\Framework\App\Action\Context $context + * @param \Magento\Checkout\Model\Session $checkoutSession + * @param \Magento\Framework\View\Result\PageFactory $pageFactory + * @param \Magento\Quote\Api\CartRepositoryInterface $quoteRepository + * @param \Payone\Core\Model\Api\Request\Genericpayment\UpdateCheckoutSession $updateCheckoutSession */ public function __construct( \Magento\Framework\App\Action\Context $context, \Magento\Checkout\Model\Session $checkoutSession, \Magento\Framework\View\Result\PageFactory $pageFactory, - \Magento\Quote\Api\CartRepositoryInterface $quoteRepository + \Magento\Quote\Api\CartRepositoryInterface $quoteRepository, + \Payone\Core\Model\Api\Request\Genericpayment\UpdateCheckoutSession $updateCheckoutSession ) { parent::__construct($context); $this->checkoutSession = $checkoutSession; $this->pageFactory = $pageFactory; $this->quoteRepository = $quoteRepository; + $this->updateCheckoutSession = $updateCheckoutSession; } /** @@ -116,16 +127,15 @@ public function execute() */ protected function canReviewBeShown() { - $sWorkorderId = $this->checkoutSession->getPayoneWorkorderId(); - if ($this->checkoutSession->getQuote()->getPayment()->getMethod() == PayoneConfig::METHOD_PAYPAL && empty($sWorkorderId)) { + if (!in_array($this->checkoutSession->getQuote()->getPayment()->getMethod(), $this->availableReviewMethods)) { return false; } - if (in_array($this->checkoutSession->getQuote()->getPayment()->getMethod(), $this->availableReviewMethods)) { - return true; + $sWorkorderId = $this->checkoutSession->getPayoneWorkorderId(); + if (empty($sWorkorderId)) { + return false; } - - return false; + return true; } /** @@ -148,6 +158,12 @@ protected function updateShippingMethod($sShippingMethod) } $oQuote->collectTotals(); $this->quoteRepository->save($oQuote); + + $oPayment = $oQuote->getPayment()->getMethodInstance(); + $sWorkorderId = $this->checkoutSession->getPayoneWorkorderId(); + if ($oPayment instanceof AmazonPayV2) { + $this->updateCheckoutSession->sendRequest($oPayment, $oQuote, $sWorkorderId); + } } } } diff --git a/Helper/Environment.php b/Helper/Environment.php index 10b559ae..e0ba70f9 100644 --- a/Helper/Environment.php +++ b/Helper/Environment.php @@ -74,7 +74,9 @@ public function getEncoding() public function getRemoteIp() { $blProxyMode = (bool)$this->getConfigParam('proxy_mode', 'processing', 'payone_misc'); - return $this->request->getClientIp($blProxyMode); + $sClientIp = $this->request->getClientIp($blProxyMode); // may return a comma separated ip list like ", , " + $aSplitIp = explode(",", $sClientIp); // split by comma + return trim(current($aSplitIp)); // return first array element } /** diff --git a/Helper/Payment.php b/Helper/Payment.php index 5fde9f1f..bec510df 100644 --- a/Helper/Payment.php +++ b/Helper/Payment.php @@ -62,6 +62,7 @@ class Payment extends \Payone\Core\Helper\Base PayoneConfig::METHOD_PAYOLUTION_INSTALLMENT, PayoneConfig::METHOD_ALIPAY, PayoneConfig::METHOD_AMAZONPAY, + PayoneConfig::METHOD_AMAZONPAYV2, PayoneConfig::METHOD_KLARNA_BASE, PayoneConfig::METHOD_KLARNA_DEBIT, PayoneConfig::METHOD_KLARNA_INVOICE, @@ -103,6 +104,7 @@ class Payment extends \Payone\Core\Helper\Base PayoneConfig::METHOD_PAYOLUTION_INSTALLMENT => 'fnc', PayoneConfig::METHOD_ALIPAY => 'wlt', PayoneConfig::METHOD_AMAZONPAY => 'wlt', + PayoneConfig::METHOD_AMAZONPAYV2 => 'wlt', PayoneConfig::METHOD_KLARNA_BASE => 'wlt', PayoneConfig::METHOD_KLARNA_DEBIT => 'wlt', PayoneConfig::METHOD_KLARNA_INVOICE => 'wlt', diff --git a/Helper/Ratepay.php b/Helper/Ratepay.php index edaf2146..843a7009 100644 --- a/Helper/Ratepay.php +++ b/Helper/Ratepay.php @@ -215,6 +215,10 @@ public function refreshProfiles($sMethodCode) $aShopIds = $this->getRatepayShopConfigByPaymentMethod($sMethodCode); foreach ($aShopIds as $aConfig) { $aResult = $this->profile->sendRequest($aConfig['shop_id'], $aConfig['currency'], $sMode); + if (!isset($aResult['status']) || $aResult['status'] != 'OK') { + throw new \Exception("An error occured".(!empty($aResult['errormessage']) ? ": ".$aResult['errormessage'] : "")); + } + $this->profileResource->updateProfileConfig($aConfig['shop_id'], $aResult); } } diff --git a/Model/Api/Request/Genericpayment/CreateCheckoutSessionPayload.php b/Model/Api/Request/Genericpayment/CreateCheckoutSessionPayload.php new file mode 100644 index 00000000..305f0f33 --- /dev/null +++ b/Model/Api/Request/Genericpayment/CreateCheckoutSessionPayload.php @@ -0,0 +1,71 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2024 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Model\Api\Request\Genericpayment; + +use Payone\Core\Model\Methods\PayoneMethod; +use Magento\Quote\Model\Quote; + +/** + * Class for the PAYONE Server API request genericpayment - "createCheckoutSessionPayload" + */ +class CreateCheckoutSessionPayload extends Base +{ + /** + * Send request to PAYONE Server-API with request-type "genericpayment" and action "createCheckoutSessionPayload" + * + * @param PayoneMethod $oPayment payment object + * @param Quote $oQuote + * @return array + */ + public function sendRequest(PayoneMethod $oPayment, Quote $oQuote) + { + $this->addParameter('request', 'genericpayment'); + $this->addParameter('add_paydata[action]', 'createCheckoutSessionPayload'); + + $this->addParameter('mode', $oPayment->getOperationMode()); + $this->addParameter('aid', $this->shopHelper->getConfigParam('aid')); // ID of PayOne Sub-Account + + $this->addParameter('clearingtype', 'wlt'); + $this->addParameter('wallettype', 'AMP'); + + $this->addParameter('amount', number_format($this->apiHelper->getQuoteAmount($oQuote), 2, '.', '') * 100); // add price to request + $this->addParameter('currency', $this->apiHelper->getCurrencyFromQuote($oQuote)); + + $oPayment->setNeedsReturnedUrl(true); + $this->addRedirectUrls($oPayment); + $oPayment->setNeedsReturnedUrl(false); + + // Optional and not yet implemented + #$this->addParameter('add_paydata[specialRestrictions]', ""); + #$this->addParameter('add_paydata[addressRestrictions_type]', ""); + #$this->addParameter('add_paydata[addressRestrictions_country_[n]]', ""); + #$this->addParameter('add_paydata[addressRestrictions_stateOrRegions_[n]]', ""); + #$this->addParameter('add_paydata[addressRestrictions_zipCodes_[n]]', ""); + + return $this->send($oPayment); + } +} diff --git a/Model/Api/Request/Genericpayment/GetCheckoutSession.php b/Model/Api/Request/Genericpayment/GetCheckoutSession.php new file mode 100644 index 00000000..b66d28ab --- /dev/null +++ b/Model/Api/Request/Genericpayment/GetCheckoutSession.php @@ -0,0 +1,63 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2024 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Model\Api\Request\Genericpayment; + +use Payone\Core\Model\Methods\PayoneMethod; +use Magento\Quote\Model\Quote; + +/** + * Class for the PAYONE Server API request genericpayment - "getCheckoutSession" + */ +class GetCheckoutSession extends Base +{ + /** + * Send request to PAYONE Server-API with request-type "genericpayment" and action "getCheckoutSession" + * + * @param PayoneMethod $oPayment payment object + * @param Quote $oQuote + * @param string $sWorkorderId + * @return array + */ + public function sendRequest(PayoneMethod $oPayment, Quote $oQuote, $sWorkorderId) + { + $this->addParameter('request', 'genericpayment'); + $this->addParameter('add_paydata[action]', 'getCheckoutSession'); + + $this->addParameter('mode', $oPayment->getOperationMode()); + $this->addParameter('aid', $this->shopHelper->getConfigParam('aid')); // ID of PayOne Sub-Account + + $this->addParameter('clearingtype', 'wlt'); + $this->addParameter('wallettype', 'AMP'); + + $this->addParameter('amount', number_format($this->apiHelper->getQuoteAmount($oQuote), 2, '.', '') * 100); // add price to request + $this->addParameter('currency', $this->apiHelper->getCurrencyFromQuote($oQuote)); + + $this->addParameter('workorderid', $sWorkorderId); + + return $this->send($oPayment); + } +} diff --git a/Model/Api/Request/Genericpayment/UpdateCheckoutSession.php b/Model/Api/Request/Genericpayment/UpdateCheckoutSession.php new file mode 100644 index 00000000..1cc55ab8 --- /dev/null +++ b/Model/Api/Request/Genericpayment/UpdateCheckoutSession.php @@ -0,0 +1,65 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2024 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Model\Api\Request\Genericpayment; + +use Payone\Core\Model\Methods\PayoneMethod; +use Magento\Quote\Model\Quote; + +/** + * Class for the PAYONE Server API request genericpayment - "updateCheckoutSession" + */ +class UpdateCheckoutSession extends Base +{ + /** + * Send request to PAYONE Server-API with request-type "genericpayment" and action "updateCheckoutSession" + * + * @param PayoneMethod $oPayment payment object + * @param Quote $oQuote + * @param string $sWorkorderId + * @return array + */ + public function sendRequest(PayoneMethod $oPayment, Quote $oQuote, $sWorkorderId) + { + $this->addParameter('request', 'genericpayment'); + $this->addParameter('add_paydata[action]', 'updateCheckoutSession'); + + $this->addParameter('mode', $oPayment->getOperationMode()); + $this->addParameter('aid', $this->shopHelper->getConfigParam('aid')); // ID of PayOne Sub-Account + + $this->addParameter('clearingtype', 'wlt'); + $this->addParameter('wallettype', 'AMP'); + + $this->addParameter('amount', number_format($this->apiHelper->getQuoteAmount($oQuote), 2, '.', '') * 100); // add price to request + $this->addParameter('currency', $this->apiHelper->getCurrencyFromQuote($oQuote)); + + $this->addParameter('workorderid', $sWorkorderId); + + $this->addRedirectUrls($oPayment); + + return $this->send($oPayment); + } +} diff --git a/Model/ConfigProvider.php b/Model/ConfigProvider.php index 76c3f0e1..aecc205c 100644 --- a/Model/ConfigProvider.php +++ b/Model/ConfigProvider.php @@ -27,6 +27,7 @@ namespace Payone\Core\Model; use Payone\Core\Model\Methods\BNPL\BNPLBase; +use Payone\Core\Model\Methods\PayoneMethod; use Payone\Core\Model\PayoneConfig; use Payone\Core\Model\Methods\OnlineBankTransfer\Eps; use Payone\Core\Model\Methods\OnlineBankTransfer\Ideal; @@ -209,16 +210,12 @@ public function __construct( /** * Get the payment description text * - * @param string $sCode + * @param PayoneMethod $sCode * @return string */ - protected function getInstructionByCode($sCode) + protected function getInstructionByMethod($oMethodInstance) { - $oMethodInstance = $this->dataHelper->getMethodInstance($sCode); - if ($oMethodInstance) { - return nl2br($this->escaper->escapeHtml($oMethodInstance->getInstructions())); - } - return ''; + return nl2br($this->escaper->escapeHtml($oMethodInstance->getInstructions())); } /** @@ -267,7 +264,6 @@ protected function getPayoneConfig() 'bankCodeValidatedAndValid' => false, 'blockedMessage' => $this->paymentHelper->getBankaccountCheckBlockedMessage(), 'epsBankGroups' => Eps::getBankGroups(), - 'idealBankGroups' => Ideal::getBankGroups(), 'customerBirthday' => $this->customerHelper->getCustomerBirthday(), 'addresscheckEnabled' => (int)$this->requestHelper->getConfigParam('enabled', 'address_check', 'payone_protect'), 'addresscheckBillingEnabled' => $this->requestHelper->getConfigParam('check_billing', 'address_check', 'payone_protect') == 'NO' ? 0 : 1, @@ -307,7 +303,11 @@ public function getConfig() ], ]); foreach ($this->paymentHelper->getAvailablePaymentTypes() as $sCode) { - $config['payment']['instructions'][$sCode] = $this->getInstructionByCode($sCode); + $oMethodInstance = $this->dataHelper->getMethodInstance($sCode); + if ($oMethodInstance instanceof PayoneMethod && $oMethodInstance->isAvailable()) { + $config['payment']['payone'][$sCode] = $oMethodInstance->getFrontendConfig(); + $config['payment']['instructions'][$sCode] = $this->getInstructionByMethod($oMethodInstance); + } } return $config; } diff --git a/Model/Methods/AmazonPayV2.php b/Model/Methods/AmazonPayV2.php new file mode 100644 index 00000000..ea1ac998 --- /dev/null +++ b/Model/Methods/AmazonPayV2.php @@ -0,0 +1,237 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2024 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Model\Methods; + +use Payone\Core\Model\PayoneConfig; +use Magento\Sales\Model\Order; +use Magento\Framework\DataObject; + +/** + * Model for Amazon Pay V2 payment method + */ +class AmazonPayV2 extends PayoneMethod +{ + const BUTTON_PUBLIC_KEY = 'AE5E5B7B2SAERURYEH6DKDAZ'; + + /** + * Payment method code + * + * @var string + */ + protected $_code = PayoneConfig::METHOD_AMAZONPAYV2; + + /** + * Clearingtype for PAYONE authorization request + * + * @var string + */ + protected $sClearingtype = 'wlt'; + + /** + * Determines if the redirect-parameters have to be added + * to the authorization-request + * + * @var bool + */ + protected $blNeedsRedirectUrls = true; + + /** + * @var bool + */ + protected $blNeedsReturnedUrl = false; + + /** + * Keys that need to be assigned to the additionalinformation fields + * + * @var array + */ + protected $aAssignKeys = [ + 'telephone', + ]; + + /** + * @return bool + */ + public function isAPBPayment() + { + if ($this->isAmazonPayExpress() === true) { + return false; + } + return true; + } + + /** + * @return bool + */ + public function isAmazonPayExpress() + { + if ($this->checkoutSession->getPayoneIsAmazonPayExpressPayment() === true) { + return true; + } + return false; + } + + /** + * @return string + */ + public function getMerchantId() + { + return $this->getCustomConfigParam('merchant_id'); + } + + /** + * @return string + */ + public function getButtonColor() + { + return $this->getCustomConfigParam('button_color'); + } + + /** + * @return string + */ + public function getButtonLanguage() + { + return str_replace("-", "_", $this->getCustomConfigParam('button_language')); + } + + /** + * @return bool + */ + public function useSandbox() + { + if ($this->getOperationMode() == 'test') { + return true; + } + return false; + } + + /** + * Return success url for redirect payment types + * + * @param Order $oOrder + * @return string + */ + public function getSuccessUrl(Order $oOrder = null) + { + if ($this->blNeedsReturnedUrl === true) { + return $this->url->getUrl('payone/amazon/returned'); + } + return parent::getSuccessUrl($oOrder); + } + + /** + * @param bool $blNeedsReturnedUrl + * @return void + */ + public function setNeedsReturnedUrl($blNeedsReturnedUrl) + { + $this->blNeedsReturnedUrl = $blNeedsReturnedUrl; + } + + /** + * Add the checkout-form-data to the checkout session + * + * @param DataObject $data + * @return $this + */ + public function assignData(DataObject $data) + { + parent::assignData($data); + + $oInfoInstance = $this->getInfoInstance(); + foreach ($this->aAssignKeys as $sKey) { + $sData = $this->toolkitHelper->getAdditionalDataEntry($data, $sKey); + if ($sData) { + $oInfoInstance->setAdditionalInformation($sKey, $sData); + } + } + + return $this; + } + + /** + * Return parameters specific to this payment type + * + * @param Order $oOrder + * @return array + */ + public function getPaymentSpecificParameters(Order $oOrder) + { + $aParams = ['wallettype' => 'AMP']; + + $sWorkorderId = $this->checkoutSession->getPayoneWorkorderId(); + if ($sWorkorderId) { + $aParams['workorderid'] = $sWorkorderId; + } + + if ($this->isAPBPayment() === true) { + $aParams['add_paydata[checkoutMode]'] = 'ProcessOrder'; + $aParams['add_paydata[productType]'] = $oOrder->getIsVirtual() ? 'PayOnly' : 'PayAndShip'; + + $sTelephone = $this->getInfoInstance()->getAdditionalInformation('telephone'); + if (!empty($sTelephone)) { + $aParams['telephonenumber'] = $sTelephone; + } + } + return $aParams; + } + + /** + * Perform certain actions with the response + * Extension hook for certain payment methods + * + * @param array $aResponse + * @param Order $oOrder + * @param float $amount + * @return array + */ + protected function handleResponse($aResponse, Order $oOrder, $amount) + { + $aResponse = parent::handleResponse($aResponse, $oOrder, $amount); + if ($this->isAPBPayment() === true && isset($aResponse['status'], $aResponse['add_paydata[signature]'], $aResponse['add_paydata[payload]']) && in_array($aResponse['status'], ['OK', 'REDIRECT'])) { + $this->checkoutSession->setPayoneAmazonPaySignature($aResponse['add_paydata[signature]']); + $this->checkoutSession->setPayoneAmazonPayPayload($aResponse['add_paydata[payload]']); + } + return $aResponse; + } + + + /** + * @return array + */ + public function getFrontendConfig() + { + return [ + 'buttonPublicKey' => self::BUTTON_PUBLIC_KEY, + 'merchantId' => $this->getMerchantId(), + 'buttonColor' => $this->getButtonColor(), + 'buttonLanguage' => $this->getButtonLanguage(), + 'useSandbox' => $this->useSandbox(), + ]; + } +} diff --git a/Model/Methods/BNPL/BNPLBase.php b/Model/Methods/BNPL/BNPLBase.php index 4dcf6241..5dd86447 100644 --- a/Model/Methods/BNPL/BNPLBase.php +++ b/Model/Methods/BNPL/BNPLBase.php @@ -169,7 +169,7 @@ public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null) $blParentReturn = parent::isAvailable($quote); // BNPL payment types are only available for payment in Euro - if ($this->apiHelper->getCurrencyFromQuote($quote) != "EUR") { + if ($quote !== null && $this->apiHelper->getCurrencyFromQuote($quote) != "EUR") { return false; } return $blParentReturn; diff --git a/Model/Methods/Klarna/Debit.php b/Model/Methods/Klarna/Debit.php index 9b522f5c..e73fceec 100644 --- a/Model/Methods/Klarna/Debit.php +++ b/Model/Methods/Klarna/Debit.php @@ -63,7 +63,7 @@ public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null) return false; } - if ($this->isB2BOrder($quote) === true) { + if ($quote !== null && $this->isB2BOrder($quote) === true) { return false; } diff --git a/Model/Methods/Klarna/Installment.php b/Model/Methods/Klarna/Installment.php index 560e8ff4..84fc3a2d 100644 --- a/Model/Methods/Klarna/Installment.php +++ b/Model/Methods/Klarna/Installment.php @@ -63,7 +63,7 @@ public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null) return false; } - if ($this->isB2BOrder($quote) === true) { + if ($quote !== null && $this->isB2BOrder($quote) === true) { return false; } diff --git a/Model/Methods/OnlineBankTransfer/Ideal.php b/Model/Methods/OnlineBankTransfer/Ideal.php index aa398275..1bcf1b4c 100644 --- a/Model/Methods/OnlineBankTransfer/Ideal.php +++ b/Model/Methods/OnlineBankTransfer/Ideal.php @@ -56,28 +56,6 @@ class Ideal extends OnlineBankTransferBase */ protected $sSubType = self::METHOD_OBT_SUBTYPE_IDEAL; - /** - * Array of all available bank groups - * - * @var array - */ - protected static $aBankGroups = [ - 'ABN_AMRO_BANK' => 'ABN Amro Bank', - 'ASN_BANK' => 'ASN Bank', - 'ING_BANK' => 'ING Bank', - 'RABOBANK' => 'Rabobank', - 'SNS_BANK' => 'SNS Bank', - 'SNS_REGIO_BANK' => 'SNS Regio Bank', - 'TRIODOS_BANK' => 'Triodos Bank', - 'VAN_LANSCHOT_BANKIERS' => 'Van Lanschot Kempen', - 'KNAB_BANK' => 'Knab Bank', - 'BUNQ_BANK' => 'Bunq Bank', - 'REVOLUT' => 'Revolut', - 'YOURSAFE' => 'Yoursafe', - 'NATIONALE_NEDERLANDEN' => 'Nationale-Nederlanden', - 'N26' => 'N26', - ]; - /** * Return parameters specific to this payment sub type * @@ -86,48 +64,10 @@ class Ideal extends OnlineBankTransferBase */ public function getSubTypeSpecificParameters(Order $oOrder) { - $oInfoInstance = $this->getInfoInstance(); - $aParams = [ 'bankcountry' => 'NL', - 'bankgrouptype' => $oInfoInstance->getAdditionalInformation('bank_group'), ]; return $aParams; } - - /** - * Add the checkout-form-data to the checkout session - * - * @param DataObject $data - * @return $this - */ - public function assignData(DataObject $data) - { - parent::assignData($data); - - $oInfoInstance = $this->getInfoInstance(); - $oInfoInstance->setAdditionalInformation('bank_group', $this->toolkitHelper->getAdditionalDataEntry($data, 'bank_group')); - - return $this; - } - - /** - * Return available bank groups - * - * @return array - */ - public static function getBankGroups() - { - $aReturn = []; - - foreach (self::$aBankGroups as $sKey => $sTitle) { - $aReturn[] = [ - 'id' => $sKey, - 'title' => mb_convert_encoding($sTitle, 'UTF-8'), - ]; - } - - return $aReturn; - } } diff --git a/Model/Methods/PayoneMethod.php b/Model/Methods/PayoneMethod.php index f82c80d8..3344b351 100644 --- a/Model/Methods/PayoneMethod.php +++ b/Model/Methods/PayoneMethod.php @@ -445,4 +445,13 @@ public function getNarrativeTextMaxLength() { return $this->iNarrativeTextMax; } + + /** + * @return array + */ + public function getFrontendConfig() + { + // Hook to be overloaded by child classes + return []; + } } diff --git a/Model/Methods/Ratepay/RatepayBase.php b/Model/Methods/Ratepay/RatepayBase.php index 405bf728..db3eda09 100644 --- a/Model/Methods/Ratepay/RatepayBase.php +++ b/Model/Methods/Ratepay/RatepayBase.php @@ -257,7 +257,7 @@ public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null) $quote = $this->checkoutSession->getQuote(); } - if ($this->ratepayHelper->getShopIdByQuote($this->getCode(), $quote) === false) { + if ($quote !== null && $this->ratepayHelper->getShopIdByQuote($this->getCode(), $quote) === false) { return false; } diff --git a/Model/PayoneConfig.php b/Model/PayoneConfig.php index 6998ddba..5687d4de 100644 --- a/Model/PayoneConfig.php +++ b/Model/PayoneConfig.php @@ -32,7 +32,7 @@ abstract class PayoneConfig { /* Module version */ - const MODULE_VERSION = '3.11.0'; + const MODULE_VERSION = '3.12.0'; /* Authorization request types */ const REQUEST_TYPE_PREAUTHORIZATION = 'preauthorization'; @@ -89,6 +89,7 @@ abstract class PayoneConfig const METHOD_ALIPAY = 'payone_alipay'; const METHOD_WECHATPAY = 'payone_wechatpay'; const METHOD_AMAZONPAY = 'payone_amazonpay'; + const METHOD_AMAZONPAYV2 = 'payone_amazonpayv2'; const METHOD_RATEPAY_INVOICE = 'payone_ratepay_invoice'; const METHOD_RATEPAY_INSTALLMENT = 'payone_ratepay_installment'; const METHOD_RATEPAY_DEBIT = 'payone_ratepay_debit'; diff --git a/Model/Plugins/MethodList.php b/Model/Plugins/MethodList.php index 01f9a8dc..8f044cfc 100644 --- a/Model/Plugins/MethodList.php +++ b/Model/Plugins/MethodList.php @@ -255,7 +255,8 @@ protected function removeNotWhitelistedPaymentMethods($aPaymentMethods) public function removeAmazonPay($aPaymentMethods) { foreach ($aPaymentMethods as $key => $aPaymentMethod) { - if ($aPaymentMethod->getCode() == PayoneConfig::METHOD_AMAZONPAY) { + if ($aPaymentMethod->getCode() == PayoneConfig::METHOD_AMAZONPAY || + ($aPaymentMethod->getCode() == PayoneConfig::METHOD_AMAZONPAYV2 && (bool)$this->customerHelper->getConfigParam('apb_active', PayoneConfig::METHOD_AMAZONPAYV2, 'payone_payment') === false)) { unset($aPaymentMethods[$key]); } } diff --git a/Observer/AddAmazonPayButton.php b/Observer/AddAmazonPayButton.php index 261b44f3..45cc1e17 100644 --- a/Observer/AddAmazonPayButton.php +++ b/Observer/AddAmazonPayButton.php @@ -63,6 +63,22 @@ public function __construct(Payment $paymentHelper, StoreManagerInterface $store $this->storeManager = $storeManager; } + /** + * @return bool + */ + protected function isAmazonV1Active() + { + return $this->paymentHelper->isPaymentMethodActive(PayoneConfig::METHOD_AMAZONPAY); + } + + /** + * @return bool + */ + protected function isAmazonV2Active() + { + return $this->paymentHelper->isPaymentMethodActive(PayoneConfig::METHOD_AMAZONPAYV2); + } + /** * Add PayPal shortcut buttons * @@ -71,7 +87,7 @@ public function __construct(Payment $paymentHelper, StoreManagerInterface $store */ public function execute(Observer $observer) { - if ($this->paymentHelper->isPaymentMethodActive(PayoneConfig::METHOD_AMAZONPAY) === false) { + if ($this->isAmazonV1Active() === false && $this->isAmazonV2Active() === false) { return; } @@ -83,12 +99,18 @@ public function execute(Observer $observer) return; } + $sBlock = 'Payone\Core\Block\Amazon\Button'; + if ($this->isAmazonV2Active()) { + $sBlock = 'Payone\Core\Block\Amazon\ButtonV2'; + } + /** @var Shortcut $shortcut */ $shortcut = $shortcutButtons->getLayout()->createBlock( - 'Payone\Core\Block\Amazon\Button', + $sBlock, '', ['data' => ['payoneLayoutName' => $shortcutButtons->getNameInLayout()]] ); + $shortcut->setName($shortcutButtons->getNameInLayout()); $shortcutButtons->addShortcut($shortcut); } diff --git a/Observer/OrderPaymentPlaceEnd.php b/Observer/OrderPaymentPlaceEnd.php index 9e93dabc..4a82e4ab 100644 --- a/Observer/OrderPaymentPlaceEnd.php +++ b/Observer/OrderPaymentPlaceEnd.php @@ -59,12 +59,15 @@ class OrderPaymentPlaceEnd implements ObserverInterface */ protected $aCheckoutSessionClearList = [ 'is_payone_redirect_cancellation', + 'is_payone_amazon_pay_auth', + 'payone_workorder_id', 'amazon_workorder_id', 'amazon_address_token', 'amazon_reference_id', 'order_reference_details_executed', 'trigger_invalid_payment', - 'payone_ratepay_device_fingerprint_token' + 'payone_ratepay_device_fingerprint_token', + 'payone_is_amazon_pay_express_payment', ]; /** diff --git a/Service/V1/AmazonPay.php b/Service/V1/AmazonPay.php index 8b3ac5a7..5e8b5a76 100644 --- a/Service/V1/AmazonPay.php +++ b/Service/V1/AmazonPay.php @@ -71,6 +71,11 @@ class AmazonPay implements AmazonPayInterface */ protected $setOrderReferenceDetails; + /** + * @var \Payone\Core\Model\Api\Request\Genericpayment\CreateCheckoutSessionPayload + */ + protected $createCheckoutSessionPayload; + /** * Amazon Pay payment object * @@ -78,6 +83,13 @@ class AmazonPay implements AmazonPayInterface */ protected $payment; + /** + * Amazon Pay payment object + * + * @var \Payone\Core\Model\Methods\AmazonPayV2 + */ + protected $paymentv2; + /** * Cart management interface * @@ -99,13 +111,6 @@ class AmazonPay implements AmazonPayInterface */ protected $checkoutHelper; - /** - * URL builder object - * - * @var \Magento\Framework\UrlInterface - */ - protected $urlBuilder; - /** * Block object of review page * @@ -121,17 +126,17 @@ class AmazonPay implements AmazonPayInterface /** * Constructor. * - * @param \Payone\Core\Api\Data\AmazonPayResponseInterfaceFactory $responseFactory - * @param \Magento\Checkout\Model\Session $checkoutSession - * @param \Payone\Core\Model\Api\Request\Genericpayment\GetConfiguration $getConfiguration - * @param \Payone\Core\Model\Api\Request\Genericpayment\GetOrderReferenceDetails $getOrderReferenceDetails - * @param \Payone\Core\Model\Methods\AmazonPay $payment - * @param \Magento\Quote\Api\CartManagementInterface $cartManagement - * @param \Payone\Core\Helper\Order $orderHelper - * @param \Payone\Core\Helper\Checkout $checkoutHelper - * @param \Magento\Framework\UrlInterface $urlBuilder - * @param \Payone\Core\Block\Onepage\Review $reviewBlock - * @param \Magento\Framework\App\ViewInterface $view + * @param \Payone\Core\Api\Data\AmazonPayResponseInterfaceFactory $responseFactory + * @param \Magento\Checkout\Model\Session $checkoutSession + * @param \Payone\Core\Model\Api\Request\Genericpayment\GetConfiguration $getConfiguration + * @param \Payone\Core\Model\Api\Request\Genericpayment\GetOrderReferenceDetails $getOrderReferenceDetails + * @param \Payone\Core\Model\Api\Request\Genericpayment\CreateCheckoutSessionPayload $createCheckoutSessionPayload + * @param \Payone\Core\Model\Methods\AmazonPay $payment + * @param \Magento\Quote\Api\CartManagementInterface $cartManagement + * @param \Payone\Core\Helper\Order $orderHelper + * @param \Payone\Core\Helper\Checkout $checkoutHelper + * @param \Payone\Core\Block\Onepage\Review $reviewBlock + * @param \Magento\Framework\App\ViewInterface $view */ public function __construct( \Payone\Core\Api\Data\AmazonPayResponseInterfaceFactory $responseFactory, @@ -139,11 +144,12 @@ public function __construct( \Payone\Core\Model\Api\Request\Genericpayment\GetConfiguration $getConfiguration, \Payone\Core\Model\Api\Request\Genericpayment\GetOrderReferenceDetails $getOrderReferenceDetails, \Payone\Core\Model\Api\Request\Genericpayment\SetOrderReferenceDetails $setOrderReferenceDetails, + \Payone\Core\Model\Api\Request\Genericpayment\CreateCheckoutSessionPayload $createCheckoutSessionPayload, \Payone\Core\Model\Methods\AmazonPay $payment, + \Payone\Core\Model\Methods\AmazonPayV2 $paymentv2, \Magento\Quote\Api\CartManagementInterface $cartManagement, \Payone\Core\Helper\Order $orderHelper, \Payone\Core\Helper\Checkout $checkoutHelper, - \Magento\Framework\UrlInterface $urlBuilder, \Payone\Core\Block\Onepage\Review $reviewBlock, \Magento\Framework\App\ViewInterface $view ) { @@ -152,11 +158,12 @@ public function __construct( $this->getConfiguration = $getConfiguration; $this->getOrderReferenceDetails = $getOrderReferenceDetails; $this->setOrderReferenceDetails = $setOrderReferenceDetails; + $this->createCheckoutSessionPayload = $createCheckoutSessionPayload; $this->payment = $payment; + $this->paymentv2 = $paymentv2; $this->cartManagement = $cartManagement; $this->orderHelper = $orderHelper; $this->checkoutHelper = $checkoutHelper; - $this->urlBuilder = $urlBuilder; $this->reviewBlock = $reviewBlock; $this->view = $view; } @@ -236,4 +243,70 @@ public function getWorkorderId($amazonReferenceId, $amazonAddressToken) { $oResponse->setData('amazonReviewHtml', $html); return $oResponse; } + + /** + * Returns Amazon Pay V2 checkout session payload + * + * @param string $cartId + * @return \Payone\Core\Service\V1\Data\AmazonPayResponse + */ + public function getCheckoutSessionPayload($cartId) + { + $blSuccess = false; + $oResponse = $this->responseFactory->create(); + + $oQuote = $this->checkoutSession->getQuote(); + + $oPayment = $oQuote->getPayment(); + $oPayment->setMethod(PayoneConfig::METHOD_AMAZONPAYV2); + + $oQuote->setPayment($oPayment); + $oQuote->save(); + + $this->checkoutSession->setPayoneIsAmazonPayExpressPayment(true); + + $aResponse = $this->createCheckoutSessionPayload->sendRequest($this->paymentv2, $oQuote); + if (isset($aResponse['status'], $aResponse['add_paydata[signature]'], $aResponse['add_paydata[payload]']) && $aResponse['status'] == 'OK') { + $blSuccess = true; + + $oResponse->setData('payload', $aResponse['add_paydata[payload]']); + $oResponse->setData('signature', $aResponse['add_paydata[signature]']); + + if (!empty($aResponse['workorderid'])) { + $this->checkoutSession->setPayoneWorkorderId($aResponse['workorderid']); + $this->checkoutSession->setPayoneQuoteComparisonString($this->checkoutHelper->getQuoteComparisonString($oQuote)); + } + } + + if (isset($aResponse['status'], $aResponse['customermessage']) && $aResponse['status'] == 'ERROR') { + $oResponse->setData('errormessage', $aResponse['customermessage']); + } + + $oResponse->setData('success', $blSuccess); + return $oResponse; + } + + /** + * Returns Amazon Pay V2 checkout session payload for APB + * + * @param string $cartId + * @return \Payone\Core\Service\V1\Data\AmazonPayResponse + */ + public function getAmazonPayApbSession($cartId) + { + $blSuccess = false; + $oResponse = $this->responseFactory->create(); + + $sPayload = $this->checkoutSession->getPayoneAmazonPayPayload(); + $sSignature = $this->checkoutSession->getPayoneAmazonPaySignature(); + if (!empty($sPayload) && !empty($sSignature)) { + $blSuccess = true; + + $oResponse->setData('payload', $sPayload); + $oResponse->setData('signature', $sSignature); + } + + $oResponse->setData('success', $blSuccess); + return $oResponse; + } } diff --git a/Service/V1/Data/AmazonPayResponse.php b/Service/V1/Data/AmazonPayResponse.php index 789aba6e..c88a7dac 100644 --- a/Service/V1/Data/AmazonPayResponse.php +++ b/Service/V1/Data/AmazonPayResponse.php @@ -72,4 +72,24 @@ public function getAmazonReviewHtml() { return $this->_get('amazonReviewHtml'); } + + /** + * Returns error message + * + * @return string + */ + public function getPayload() + { + return $this->_get('payload'); + } + + /** + * Returns error message + * + * @return string + */ + public function getSignature() + { + return $this->_get('signature'); + } } diff --git a/Test/Unit/Block/Amazon/ButtonTest.php b/Test/Unit/Block/Amazon/ButtonTest.php index 031d1a69..073da527 100644 --- a/Test/Unit/Block/Amazon/ButtonTest.php +++ b/Test/Unit/Block/Amazon/ButtonTest.php @@ -163,4 +163,14 @@ public function testGetCounterOther() $result = $this->classToTest->getCounter(); $this->assertEquals(3, $result); } + + public function testSetName() + { + $expected = "testName"; + + $this->classToTest->setName($expected); + $result = $this->classToTest->getName(); + + $this->assertEquals($expected, $result); + } } diff --git a/Test/Unit/Block/Amazon/ButtonV2Test.php b/Test/Unit/Block/Amazon/ButtonV2Test.php new file mode 100644 index 00000000..f7204932 --- /dev/null +++ b/Test/Unit/Block/Amazon/ButtonV2Test.php @@ -0,0 +1,265 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2024 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Test\Unit\Block\Amazon; + +use Payone\Core\Block\Amazon\ButtonV2 as ClassToTest; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Payone\Core\Helper\Api; +use Payone\Core\Model\Methods\AmazonPayV2; +use Magento\Checkout\Model\Session; +use Magento\Quote\Model\Quote; +use Magento\Store\Api\Data\StoreInterface; +use Payone\Core\Test\Unit\BaseTestCase; +use Payone\Core\Test\Unit\PayoneObjectManager; +use Payone\Core\Helper\Base; +use Magento\Framework\View\Element\Template\Context; +use Magento\Framework\UrlInterface; + +class ButtonV2Test extends BaseTestCase +{ + /** + * @var ClassToTest + */ + private $classToTest; + + /** + * @var ObjectManager|PayoneObjectManager + */ + private $objectManager; + + /** + * @var Base + */ + private $baseHelper; + + /** + * @var UrlInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $urlBuilder; + + /** + * @var Session|\PHPUnit\Framework\MockObject\MockObject + */ + private $checkoutSession; + + protected function setUp(): void + { + $this->objectManager = $this->getObjectManager(); + + $this->urlBuilder = $this->getMockBuilder(UrlInterface::class)->disableOriginalConstructor()->getMock(); + + $context = $this->getMockBuilder(Context::class)->disableOriginalConstructor()->getMock(); + $context->method('getUrlBuilder')->willReturn($this->urlBuilder); + + $this->checkoutSession = $this->getMockBuilder(Session::class) + ->disableOriginalConstructor() + ->setMethods(['getQuote']) + ->getMock(); + + $amazonPayment = $this->getMockBuilder(AmazonPayV2::class)->disableOriginalConstructor()->getMock(); + $amazonPayment->method('getMerchantId')->willReturn('test'); + $amazonPayment->method('useSandbox')->willReturn(false); + $amazonPayment->method('getButtonColor')->willReturn('test'); + $amazonPayment->method('getButtonLanguage')->willReturn('test'); + + $apiHelper = $this->getMockBuilder(Api::class)->disableOriginalConstructor()->getMock(); + $apiHelper->method('getCurrencyFromQuote')->willReturn('EUR'); + $apiHelper->method('getQuoteAmount')->willReturn('1000'); + + $this->baseHelper = $this->getMockBuilder(Base::class)->disableOriginalConstructor()->getMock(); + $this->classToTest = $this->objectManager->getObject(ClassToTest::class, [ + 'context' => $context, + 'baseHelper' => $this->baseHelper, + 'checkoutSession' => $this->checkoutSession, + 'amazonPayment' => $amazonPayment, + 'apiHelper' => $apiHelper, + ]); + } + + public function testGetAlias() + { + $expected = 'payone.block.amazon.buttonv2'; + + $result = $this->classToTest->getAlias(); + $this->assertEquals($expected, $result); + } + + public function testSetName() + { + $expected = "testName"; + + $this->classToTest->setName($expected); + $result = $this->classToTest->getName(); + + $this->assertEquals($expected, $result); + } + + public function testGetQuoteId() + { + $expected = 'test'; + + $oQuote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + $oQuote->method('getId')->willReturn($expected); + + $this->checkoutSession->method('getQuote')->willReturn($oQuote); + + $result = $this->classToTest->getQuoteId(); + + $this->assertEquals($expected, $result); + } + + public function testGetStoreCode() + { + $expected = 'test'; + + $store = $this->getMockBuilder(StoreInterface::class)->disableOriginalConstructor()->getMock(); + $store->method('getCode')->willReturn($expected); + + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + $quote->method('getStore')->willReturn($store); + + $this->checkoutSession->method('getQuote')->willReturn($quote); + + $result = $this->classToTest->getStoreCode(); + + $this->assertEquals($expected, $result); + } + + public function testGetButtonId() + { + $this->classToTest->setName('fallback'); + $result = $this->classToTest->getButtonId(); + $this->assertEquals('AmazonPayButton', $result); + + $this->classToTest->setName('checkout.cart.shortcut.buttons'); + $result = $this->classToTest->getButtonId(); + $this->assertEquals('AmazonPayButtonBasket', $result); + + $this->classToTest->setName('shortcutbuttons'); + $result = $this->classToTest->getButtonId(); + $this->assertEquals('AmazonPayButtonMiniBasket', $result); + } + + public function testGetQuote() + { + $oQuote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + + $this->checkoutSession->method('getQuote')->willReturn($oQuote); + + $result = $this->classToTest->getQuote(); + + $this->assertInstanceOf(Quote::class, $result); + } + + public function testGetPublicKeyId() + { + $result = $this->classToTest->getPublicKeyId(); + $this->assertEquals(AmazonPayV2::BUTTON_PUBLIC_KEY, $result); + } + + public function testGetMerchantId() + { + $result = $this->classToTest->getMerchantId(); + $this->assertEquals('test', $result); + } + + public function testIsTestMode() + { + $result = $this->classToTest->isTestMode(); + $this->assertFalse($result); + } + + public function testGetCurrency() + { + $oQuote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + + $this->checkoutSession->method('getQuote')->willReturn($oQuote); + + $result = $this->classToTest->getCurrency(); + $this->assertEquals('EUR', $result); + } + + public function testGetAmount() + { + $oQuote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + + $this->checkoutSession->method('getQuote')->willReturn($oQuote); + + $result = $this->classToTest->getAmount(); + $this->assertEquals('1000', $result); + } + + public function testGetProductType() + { + $oQuote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + $oQuote->method('isVirtual')->willReturn(false); + $this->checkoutSession->method('getQuote')->willReturn($oQuote); + + $result = $this->classToTest->getProductType(); + $this->assertEquals("PayAndShip", $result); + } + + public function testGetProductTypeVirtual() + { + $oQuote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + $oQuote->method('isVirtual')->willReturn(true); + $this->checkoutSession->method('getQuote')->willReturn($oQuote); + + $result = $this->classToTest->getProductType(); + $this->assertEquals("PayOnly", $result); + } + + public function testGetPlacement() + { + $result = $this->classToTest->getPlacement(); + $this->assertEquals("Home", $result); + + $this->classToTest->setName("checkout.cart.shortcut.buttons"); + $result = $this->classToTest->getPlacement(); + $this->assertEquals("Cart", $result); + } + + public function testGetButtonColor() + { + $expected = 'test'; + + $this->baseHelper->method('getConfigParam')->willReturn($expected); + + $result = $this->classToTest->getButtonColor(); + $this->assertEquals($expected, $result); + } + + public function testGetButtonLanguage() + { + $expected = 'test'; + + $this->baseHelper->method('getConfigParam')->willReturn($expected); + + $result = $this->classToTest->getButtonLanguage(); + $this->assertEquals($expected, $result); + } +} diff --git a/Test/Unit/Controller/Amazon/ReturnedTest.php b/Test/Unit/Controller/Amazon/ReturnedTest.php new file mode 100644 index 00000000..de766bff --- /dev/null +++ b/Test/Unit/Controller/Amazon/ReturnedTest.php @@ -0,0 +1,160 @@ +objectManager = $this->getObjectManager(); + + $resultRedirect = $this->getMockBuilder(Redirect::class)->disableOriginalConstructor()->getMock(); + $resultRedirect->method('setPath')->willReturn($resultRedirect); + + $resultFactory = $this->getMockBuilder(ResultFactory::class)->disableOriginalConstructor()->getMock(); + $resultFactory->method('create')->willReturn($resultRedirect); + + $messageManager = $this->getMockBuilder(ManagerInterface::class)->disableOriginalConstructor()->getMock(); + + $context = $this->getMockBuilder(Context::class)->disableOriginalConstructor()->getMock(); + $context->method('getResultFactory')->willReturn($resultFactory); + $context->method('getMessageManager')->willReturn($messageManager); + + $this->getCheckoutSession = $this->getMockBuilder(GetCheckoutSession::class)->disableOriginalConstructor()->getMock(); + + $address = $this->getMockBuilder(Address::class)->disableOriginalConstructor()->getMock(); + $address->method('getEmail')->willReturn('testing@payone.de'); + + $payment = $this->getMockBuilder(Payment::class)->disableOriginalConstructor()->getMock(); + + $quote = $this->getMockBuilder(Quote::class) + ->disableOriginalConstructor() + ->setMethods([ + 'getBillingAddress', + 'setCustomerId', + 'setCustomerEmail', + 'setCustomerIsGuest', + 'setCustomerGroupId', + 'getPayment', + 'setPayment', + 'setInventoryProcessed', + 'collectTotals', + 'save', + ]) + ->getMock(); + $quote->method('getBillingAddress')->willReturn($address); + $quote->method('setCustomerId')->willReturn($quote); + $quote->method('setCustomerEmail')->willReturn($quote); + $quote->method('setCustomerIsGuest')->willReturn($quote); + $quote->method('getPayment')->willReturn($payment); + $quote->method('collectTotals')->willReturn($quote); + + $orderHelper = $this->getMockBuilder(Order::class)->disableOriginalConstructor()->getMock(); + $orderHelper->method('updateAddresses')->willReturn($quote); + + $checkoutHelper = $this->getMockBuilder(Checkout::class)->disableOriginalConstructor()->getMock(); + $checkoutHelper->method('getCurrentCheckoutMethod')->willReturn(Onepage::METHOD_GUEST); + + $this->checkoutSession = $this->getMockBuilder(Session::class) + ->disableOriginalConstructor() + ->setMethods([ + 'getPayoneWorkorderId', + 'setIsPayonePayPalExpress', + 'getPayonePayPalExpressRetry', + 'unsPayonePayPalExpressRetry', + 'getQuote', + ]) + ->getMock(); + $this->checkoutSession->method('getQuote')->willReturn($quote); + + $this->returnHandler = $this->getMockBuilder(ReturnHandler::class)->disableOriginalConstructor()->getMock(); + + $this->classToTest = $this->objectManager->getObject(ClassToTest::class, [ + 'context' => $context, + 'checkoutSession' => $this->checkoutSession, + 'returnHandler' => $this->returnHandler, + 'getCheckoutSession' => $this->getCheckoutSession, + 'orderHelper' => $orderHelper, + 'checkoutHelper' => $checkoutHelper, + ]); + } + + public function testExecute() + { + $this->checkoutSession->method('getPayoneWorkorderId')->willReturn('12345'); + + $response = ['status' => 'OK']; + + $this->getCheckoutSession->method('sendRequest')->willReturn($response); + + $result = $this->classToTest->execute(); + $this->assertInstanceOf(Redirect::class, $result); + } + + public function testExecuteException() + { + $this->checkoutSession->method('getPayoneWorkorderId')->willReturn('12345'); + + $response = ['status' => 'ERROR']; + + $this->getCheckoutSession->method('sendRequest')->willReturn($response); + + #$exception = new \Exception; + #$this->returnHandler->expects($this->classToTest->method('handleReturn')->willThrowException($exception)); + + $result = $this->classToTest->execute(); + $this->assertInstanceOf(Redirect::class, $result); + } + + public function testExecutePayPal() + { + $this->checkoutSession->method('getPayoneWorkorderId')->willReturn(null); + + $result = $this->classToTest->execute(); + $this->assertInstanceOf(Redirect::class, $result); + } +} diff --git a/Test/Unit/Controller/Onepage/PlaceOrderTest.php b/Test/Unit/Controller/Onepage/PlaceOrderTest.php index a8eb8918..0884a5c7 100644 --- a/Test/Unit/Controller/Onepage/PlaceOrderTest.php +++ b/Test/Unit/Controller/Onepage/PlaceOrderTest.php @@ -39,6 +39,7 @@ use Magento\Framework\App\Request\Http; use Magento\Framework\Message\ManagerInterface; use Magento\Quote\Model\Quote\Address; +use Payone\Core\Model\PayoneConfig; use Payone\Core\Test\Unit\BaseTestCase; use Payone\Core\Test\Unit\PayoneObjectManager; use Magento\Quote\Model\Quote\Payment; @@ -81,6 +82,11 @@ class PlaceOrderTest extends BaseTestCase */ private $checkoutHelper; + /** + * @var Quote|\PHPUnit_Framework_MockObject_MockObject + */ + private $quote; + protected function setUp(): void { $this->objectManager = $this->getObjectManager(); @@ -120,9 +126,9 @@ protected function setUp(): void $address = $this->getMockBuilder(Address::class)->disableOriginalConstructor()->getMock(); $payment = $this->getMockBuilder(Payment::class)->disableOriginalConstructor()->getMock(); - $payment->method('getMethod')->willReturn('payone_paypal'); + $payment->method('getMethod')->willReturn(PayoneConfig::METHOD_PAYPAL); - $quote = $this->getMockBuilder(Quote::class) + $this->quote = $this->getMockBuilder(Quote::class) ->disableOriginalConstructor() ->setMethods([ 'getBillingAddress', @@ -135,13 +141,13 @@ protected function setUp(): void 'save' ]) ->getMock(); - $quote->method('getBillingAddress')->willReturn($address); - $quote->method('getShippingAddress')->willReturn($address); - $quote->method('getIsVirtual')->willReturn(false); - $quote->method('getId')->willReturn('12345'); - $quote->method('setIsActive')->willReturn($quote); - $quote->method('getSubtotal')->willReturn(100); - $quote->method('getPayment')->willReturn($payment); + $this->quote->method('getBillingAddress')->willReturn($address); + $this->quote->method('getShippingAddress')->willReturn($address); + $this->quote->method('getIsVirtual')->willReturn(false); + $this->quote->method('getId')->willReturn('12345'); + $this->quote->method('setIsActive')->willReturn($this->quote); + $this->quote->method('getSubtotal')->willReturn(100); + $this->quote->method('getPayment')->willReturn($payment); $this->checkoutSession = $this->getMockBuilder(Session::class) ->disableOriginalConstructor() @@ -161,9 +167,9 @@ protected function setUp(): void 'getPayoneRedirectUrl', 'setPayonePayPalExpressRetry', 'setPayoneCustomerIsRedirected', + 'setIsPayoneAmazonPayAuth', ]) ->getMock(); - $this->checkoutSession->method('getQuote')->willReturn($quote); $this->checkoutSession->method('setLastQuoteId')->willReturn($this->checkoutSession); $this->checkoutSession->method('setLastSuccessQuoteId')->willReturn($this->checkoutSession); $this->checkoutSession->method('unsPayoneWorkorderId')->willReturn($this->checkoutSession); @@ -190,6 +196,7 @@ protected function setUp(): void public function testExecute() { + $this->checkoutSession->method('getQuote')->willReturn($this->quote); $this->checkoutHelper->method('getQuoteComparisonString')->willReturn("QuoteString"); $this->checkoutSession->method('getPayoneQuoteComparisonString')->willReturn("QuoteString"); $this->request->method('getBeforeForwardInfo')->willReturn(false); @@ -199,6 +206,7 @@ public function testExecute() public function testExecuteValidation() { + $this->checkoutSession->method('getQuote')->willReturn($this->quote); $this->request->method('getBeforeForwardInfo')->willReturn([]); $result = $this->classToTest->execute(); $this->assertNull($result); @@ -206,6 +214,7 @@ public function testExecuteValidation() public function testExecuteException() { + $this->checkoutSession->method('getQuote')->willReturn($this->quote); $this->checkoutHelper->method('getQuoteComparisonString')->willReturn("QuoteString"); $this->checkoutSession->method('getPayoneQuoteComparisonString')->willReturn("QuoteString"); @@ -219,6 +228,7 @@ public function testExecuteException() public function testExecuteSubtotalMismatch() { + $this->checkoutSession->method('getQuote')->willReturn($this->quote); $this->checkoutHelper->method('getQuoteComparisonString')->willReturn("QuoteString"); $this->checkoutSession->method('getPayoneQuoteComparisonString')->willReturn("QuoteFalse"); $this->request->method('getBeforeForwardInfo')->willReturn(false); @@ -228,6 +238,7 @@ public function testExecuteSubtotalMismatch() public function testExecutePayPal() { + $this->checkoutSession->method('getQuote')->willReturn($this->quote); $this->checkoutHelper->method('getQuoteComparisonString')->willReturn("QuoteString"); $this->checkoutSession->method('getPayoneQuoteComparisonString')->willReturn("QuoteString"); $this->checkoutSession->method('getPayoneRedirectUrl')->willReturn("http://someurl.test"); @@ -235,4 +246,41 @@ public function testExecutePayPal() $result = $this->classToTest->execute(); $this->assertNull($result); } + + public function testExecuteAmazonPay() + { + $payment = $this->getMockBuilder(Payment::class)->disableOriginalConstructor()->getMock(); + $payment->method('getMethod')->willReturn(PayoneConfig::METHOD_AMAZONPAYV2); + + $address = $this->getMockBuilder(Address::class)->disableOriginalConstructor()->getMock(); + + $quote = $this->getMockBuilder(Quote::class) + ->disableOriginalConstructor() + ->setMethods([ + 'getBillingAddress', + 'getShippingAddress', + 'getIsVirtual', + 'getId', + 'setIsActive', + 'getSubtotal', + 'getPayment', + 'save' + ]) + ->getMock(); + $quote->method('getBillingAddress')->willReturn($address); + $quote->method('getShippingAddress')->willReturn($address); + $quote->method('getIsVirtual')->willReturn(false); + $quote->method('getId')->willReturn('12345'); + $quote->method('setIsActive')->willReturn($quote); + $quote->method('getSubtotal')->willReturn(100); + $quote->method('getPayment')->willReturn($payment); + + $this->checkoutHelper->method('getQuoteComparisonString')->willReturn("QuoteString"); + $this->checkoutSession->method('getPayoneQuoteComparisonString')->willReturn("QuoteString"); + $this->checkoutSession->method('getPayoneRedirectUrl')->willReturn("http://someurl.test"); + $this->checkoutSession->method('getQuote')->willReturn($quote); + $this->request->method('getBeforeForwardInfo')->willReturn(false); + $result = $this->classToTest->execute(); + $this->assertNull($result); + } } diff --git a/Test/Unit/Controller/Onepage/ReviewTest.php b/Test/Unit/Controller/Onepage/ReviewTest.php index e5cd0c7c..cc67e339 100644 --- a/Test/Unit/Controller/Onepage/ReviewTest.php +++ b/Test/Unit/Controller/Onepage/ReviewTest.php @@ -40,10 +40,12 @@ use Magento\Quote\Api\Data\CartExtension; use Magento\Quote\Model\ShippingAssignment; use Magento\Quote\Model\Shipping; +use Payone\Core\Model\Methods\AmazonPayV2; use Payone\Core\Model\PayoneConfig; use Payone\Core\Test\Unit\BaseTestCase; use Payone\Core\Test\Unit\PayoneObjectManager; use Magento\Quote\Model\Quote\Payment; +use Payone\Core\Model\Api\Request\Genericpayment\UpdateCheckoutSession; class ReviewTest extends BaseTestCase { @@ -127,10 +129,13 @@ protected function setUp(): void $pageFactory = $this->getMockBuilder(PageFactory::class)->disableOriginalConstructor()->getMock(); $pageFactory->method('create')->willReturn($page); + $updateCheckoutSession = $this->getMockBuilder(UpdateCheckoutSession::class)->disableOriginalConstructor()->getMock(); + $this->classToTest = $this->objectManager->getObject(ClassToTest::class, [ 'context' => $context, 'checkoutSession' => $this->checkoutSession, - 'pageFactory' => $pageFactory + 'pageFactory' => $pageFactory, + 'updateCheckoutSession' => $updateCheckoutSession, ]); } @@ -144,6 +149,19 @@ public function testExecute() $this->assertInstanceOf(Page::class, $result); } + public function testExecuteAmazonPay() + { + $amazonPay = $this->getMockBuilder(AmazonPayV2::class)->disableOriginalConstructor()->getMock(); + + $this->checkoutSession->method('getPayoneWorkorderId')->willReturn('12345'); + $this->payment->method('getMethod')->willReturn('payone_paypal'); + $this->payment->method('getMethodInstance')->willReturn($amazonPay); + + $this->request->method('getBeforeForwardInfo')->willReturn(false); + $result = $this->classToTest->execute(); + $this->assertInstanceOf(Page::class, $result); + } + public function testExecuteRedirect() { $this->payment->method('getMethod')->willReturn(null); diff --git a/Test/Unit/Model/Api/Request/Genericpayment/CreateCheckoutSessionPayloadTest.php b/Test/Unit/Model/Api/Request/Genericpayment/CreateCheckoutSessionPayloadTest.php new file mode 100644 index 00000000..e82b2bc2 --- /dev/null +++ b/Test/Unit/Model/Api/Request/Genericpayment/CreateCheckoutSessionPayloadTest.php @@ -0,0 +1,86 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2024 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Test\Unit\Model\Api\Request\Genericpayment; + +use Payone\Core\Model\Api\Request\Genericpayment\CreateCheckoutSessionPayload as ClassToTest; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Payone\Core\Helper\Api; +use Payone\Core\Helper\Shop; +use Payone\Core\Model\Methods\AmazonPayV2; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\Quote\Address; +use Payone\Core\Test\Unit\BaseTestCase; +use Payone\Core\Test\Unit\PayoneObjectManager; + +class CreateCheckoutSessionPayloadTest extends BaseTestCase +{ + /** + * @var ClassToTest + */ + private $classToTest; + + /** + * @var Api|\PHPUnit_Framework_MockObject_MockObject + */ + private $apiHelper; + + /** + * @var Shop|\PHPUnit_Framework_MockObject_MockObject + */ + private $shopHelper; + + protected function setUp(): void + { + $objectManager = $this->getObjectManager(); + + $this->apiHelper = $this->getMockBuilder(Api::class)->disableOriginalConstructor()->getMock(); + $this->shopHelper = $this->getMockBuilder(Shop::class)->disableOriginalConstructor()->getMock(); + + $this->classToTest = $objectManager->getObject(ClassToTest::class, [ + 'shopHelper' => $this->shopHelper, + 'apiHelper' => $this->apiHelper + ]); + } + + public function testSendRequest() + { + $payment = $this->getMockBuilder(AmazonPayV2::class)->disableOriginalConstructor()->getMock(); + $payment->method('getOperationMode')->willReturn('test'); + + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + + $this->shopHelper->method('getConfigParam')->willReturn('12345'); + + $response = ['status' => 'APPROVED']; + $this->apiHelper->method('sendApiRequest')->willReturn($response); + $this->apiHelper->method('getCurrencyFromQuote')->willReturn('EUR'); + $this->apiHelper->method('getQuoteAmount')->willReturn('10000'); + + $result = $this->classToTest->sendRequest($payment, $quote); + $this->assertEquals($response, $result); + } +} diff --git a/Test/Unit/Model/Api/Request/Genericpayment/GetCheckoutSessionTest.php b/Test/Unit/Model/Api/Request/Genericpayment/GetCheckoutSessionTest.php new file mode 100644 index 00000000..8fad977c --- /dev/null +++ b/Test/Unit/Model/Api/Request/Genericpayment/GetCheckoutSessionTest.php @@ -0,0 +1,86 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2024 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Test\Unit\Model\Api\Request\Genericpayment; + +use Payone\Core\Model\Api\Request\Genericpayment\GetCheckoutSession as ClassToTest; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Payone\Core\Helper\Api; +use Payone\Core\Helper\Shop; +use Payone\Core\Model\Methods\AmazonPayV2; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\Quote\Address; +use Payone\Core\Test\Unit\BaseTestCase; +use Payone\Core\Test\Unit\PayoneObjectManager; + +class GetCheckoutSessionTest extends BaseTestCase +{ + /** + * @var ClassToTest + */ + private $classToTest; + + /** + * @var Api|\PHPUnit_Framework_MockObject_MockObject + */ + private $apiHelper; + + /** + * @var Shop|\PHPUnit_Framework_MockObject_MockObject + */ + private $shopHelper; + + protected function setUp(): void + { + $objectManager = $this->getObjectManager(); + + $this->apiHelper = $this->getMockBuilder(Api::class)->disableOriginalConstructor()->getMock(); + $this->shopHelper = $this->getMockBuilder(Shop::class)->disableOriginalConstructor()->getMock(); + + $this->classToTest = $objectManager->getObject(ClassToTest::class, [ + 'shopHelper' => $this->shopHelper, + 'apiHelper' => $this->apiHelper + ]); + } + + public function testSendRequest() + { + $payment = $this->getMockBuilder(AmazonPayV2::class)->disableOriginalConstructor()->getMock(); + $payment->method('getOperationMode')->willReturn('test'); + + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + + $this->shopHelper->method('getConfigParam')->willReturn('12345'); + + $response = ['status' => 'APPROVED']; + $this->apiHelper->method('sendApiRequest')->willReturn($response); + $this->apiHelper->method('getCurrencyFromQuote')->willReturn('EUR'); + $this->apiHelper->method('getQuoteAmount')->willReturn('10000'); + + $result = $this->classToTest->sendRequest($payment, $quote, '1234567890'); + $this->assertEquals($response, $result); + } +} diff --git a/Test/Unit/Model/Api/Request/Genericpayment/UpdateCheckoutSessionTest.php b/Test/Unit/Model/Api/Request/Genericpayment/UpdateCheckoutSessionTest.php new file mode 100644 index 00000000..0859d20c --- /dev/null +++ b/Test/Unit/Model/Api/Request/Genericpayment/UpdateCheckoutSessionTest.php @@ -0,0 +1,86 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2024 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Test\Unit\Model\Api\Request\Genericpayment; + +use Payone\Core\Model\Api\Request\Genericpayment\UpdateCheckoutSession as ClassToTest; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Payone\Core\Helper\Api; +use Payone\Core\Helper\Shop; +use Payone\Core\Model\Methods\AmazonPayV2; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\Quote\Address; +use Payone\Core\Test\Unit\BaseTestCase; +use Payone\Core\Test\Unit\PayoneObjectManager; + +class UpdateCheckoutSessionTest extends BaseTestCase +{ + /** + * @var ClassToTest + */ + private $classToTest; + + /** + * @var Api|\PHPUnit_Framework_MockObject_MockObject + */ + private $apiHelper; + + /** + * @var Shop|\PHPUnit_Framework_MockObject_MockObject + */ + private $shopHelper; + + protected function setUp(): void + { + $objectManager = $this->getObjectManager(); + + $this->apiHelper = $this->getMockBuilder(Api::class)->disableOriginalConstructor()->getMock(); + $this->shopHelper = $this->getMockBuilder(Shop::class)->disableOriginalConstructor()->getMock(); + + $this->classToTest = $objectManager->getObject(ClassToTest::class, [ + 'shopHelper' => $this->shopHelper, + 'apiHelper' => $this->apiHelper + ]); + } + + public function testSendRequest() + { + $payment = $this->getMockBuilder(AmazonPayV2::class)->disableOriginalConstructor()->getMock(); + $payment->method('getOperationMode')->willReturn('test'); + + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + + $this->shopHelper->method('getConfigParam')->willReturn('12345'); + + $response = ['status' => 'APPROVED']; + $this->apiHelper->method('sendApiRequest')->willReturn($response); + $this->apiHelper->method('getCurrencyFromQuote')->willReturn('EUR'); + $this->apiHelper->method('getQuoteAmount')->willReturn('10000'); + + $result = $this->classToTest->sendRequest($payment, $quote, '1234567890'); + $this->assertEquals($response, $result); + } +} diff --git a/Test/Unit/Model/ConfigProviderTest.php b/Test/Unit/Model/ConfigProviderTest.php index 9ae63bb1..08079355 100644 --- a/Test/Unit/Model/ConfigProviderTest.php +++ b/Test/Unit/Model/ConfigProviderTest.php @@ -38,6 +38,7 @@ use Payone\Core\Helper\Request; use Magento\Framework\Escaper; use Payone\Core\Helper\Consumerscore; +use Payone\Core\Model\Methods\PayoneMethod; use Payone\Core\Model\PayoneConfig; use Magento\Payment\Model\Method\AbstractMethod; use Payone\Core\Test\Unit\BaseTestCase; @@ -46,6 +47,8 @@ use Magento\Customer\Model\Session as CustomerSession; use Payone\Core\Model\ResourceModel\SavedPaymentData; use Magento\Customer\Model\Customer as CustomerModel; +use Payone\Core\Helper\Ratepay; +use Payone\Core\Model\Methods\Ratepay\Installment; class ConfigProviderTest extends BaseTestCase { @@ -132,6 +135,12 @@ protected function setUp(): void $shopHelper = $this->getMockBuilder(Shop::class)->disableOriginalConstructor()->getMock(); $shopHelper->method('getMagentoVersion')->willReturn("2.4.4"); + $ratepayHelper = $this->getMockBuilder(Ratepay::class)->disableOriginalConstructor()->getMock(); + $ratepayHelper->method('getRatepayConfig')->willReturn([PayoneConfig::METHOD_RATEPAY_INSTALLMENT => []]); + + $ratepayInstallment = $this->getMockBuilder(Installment::class)->disableOriginalConstructor()->getMock(); + $ratepayInstallment->method('getAllowedMonths')->willReturn(['test']); + $this->classToTest = $this->objectManager->getObject(ClassToTest::class, [ 'dataHelper' => $this->dataHelper, 'countryHelper' => $countryHelper, @@ -144,17 +153,19 @@ protected function setUp(): void 'checkoutSession' => $this->checkoutSession, 'savedPaymentData' => $savedPaymentData, 'customerSession' => $this->customerSession, - 'shopHelper' => $shopHelper + 'shopHelper' => $shopHelper, + 'ratepayHelper' => $ratepayHelper, ]); } public function testGetConfig() { - $method = $this->getMockBuilder(AbstractMethod::class) + $method = $this->getMockBuilder(PayoneMethod::class) ->disableOriginalConstructor() - ->setMethods(['getInstructions']) + ->setMethods(['getInstructions', 'isAvailable']) ->getMock(); $method->method('getInstructions')->willReturn('Instruction'); + $method->method('isAvailable')->willReturn(true); $this->dataHelper->method('getMethodInstance')->willReturn($method); $this->customerSession->method('isLoggedIn')->willReturn(false); diff --git a/Test/Unit/Model/Methods/AmazonPayV2Test.php b/Test/Unit/Model/Methods/AmazonPayV2Test.php new file mode 100644 index 00000000..9c6af426 --- /dev/null +++ b/Test/Unit/Model/Methods/AmazonPayV2Test.php @@ -0,0 +1,247 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2024 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +namespace Payone\Core\Test\Unit\Model\Methods; + +use Magento\Store\Model\Store; +use Payone\Core\Model\Methods\AmazonPayV2 as ClassToTest; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Sales\Model\Order; +use Payone\Core\Test\Unit\BaseTestCase; +use Payone\Core\Test\Unit\PayoneObjectManager; +use Payone\Core\Helper\Shop; +use Magento\Checkout\Model\Session; +use Magento\Payment\Model\Info; +use Payone\Core\Model\Api\Request\Authorization; +use Magento\Framework\Exception\LocalizedException; +use Magento\Sales\Model\Order\Payment; +use Magento\Framework\Url; +use Magento\Framework\DataObject; +use Payone\Core\Helper\Toolkit; + +class AmazonPayV2Test extends BaseTestCase +{ + /** + * @var ClassToTest + */ + private $classToTest; + + /** + * @var ObjectManager|PayoneObjectManager + */ + private $objectManager; + + /** + * @var Shop + */ + private $shopHelper; + + /** + * @var Session + */ + private $checkoutSession; + + /** + * @var Authorization + */ + private $authorizationRequest; + + protected function setUp(): void + { + $this->objectManager = $this->getObjectManager(); + + $store = $this->getMockBuilder(Store::class)->disableOriginalConstructor()->getMock(); + $store->method('getCode')->willReturn('test'); + + $order = $this->getMockBuilder(Order::class)->disableOriginalConstructor()->getMock(); + $order->method('getStore')->willReturn($store); + + $info = $this->getMockBuilder(Info::class) + ->disableOriginalConstructor() + ->setMethods(['getAdditionalInformation', 'getOrder']) + ->getMock(); + $info->method('getAdditionalInformation')->willReturn('19010101'); + $info->method('getOrder')->willReturn($order); + + $toolkitHelper = $this->getMockBuilder(Toolkit::class)->disableOriginalConstructor()->getMock(); + $toolkitHelper->method('getAdditionalDataEntry')->willReturn('12'); + + $this->shopHelper = $this->getMockBuilder(Shop::class)->disableOriginalConstructor()->getMock(); + + $this->checkoutSession = $this->getMockBuilder(Session::class) + ->disableOriginalConstructor() + ->setMethods([ + 'unsPayoneRedirectUrl', + 'unsPayoneRedirectedPaymentMethod', + 'unsPayoneCanceledPaymentMethod', + 'unsPayoneIsError', + 'unsShowAmazonPendingNotice', + 'unsAmazonRetryAsync', + 'getPayoneIsAmazonPayExpressPayment', + 'getPayoneWorkorderId', + 'setPayoneAmazonPaySignature', + 'setPayoneAmazonPayPayload', + 'setPayoneRedirectUrl', + 'setPayoneRedirectedPaymentMethod', + ]) + ->getMock(); + + $this->authorizationRequest = $this->getMockBuilder(Authorization::class)->disableOriginalConstructor()->getMock(); + + $url = $this->getMockBuilder(Url::class)->disableOriginalConstructor()->getMock(); + $url->method('getUrl')->willReturn('payoneTest'); + + $this->classToTest = $this->objectManager->getObject(ClassToTest::class, [ + 'shopHelper' => $this->shopHelper, + 'toolkitHelper' => $toolkitHelper, + 'checkoutSession' => $this->checkoutSession, + 'authorizationRequest' => $this->authorizationRequest, + 'url' => $url, + ]); + $this->classToTest->setInfoInstance($info); + } + + public function testIsAPBPayment() + { + $this->checkoutSession->method('getPayoneIsAmazonPayExpressPayment')->willReturn(false); + + $this->assertTrue($this->classToTest->isAPBPayment()); + } + + public function testIsAPBPaymentFalse() + { + $this->checkoutSession->method('getPayoneIsAmazonPayExpressPayment')->willReturn(true); + + $this->assertFalse($this->classToTest->isAPBPayment()); + } + + public function testGetMerchantId() + { + $expected = "testMerchant"; + + $this->shopHelper->method('getConfigParam')->willReturn($expected); + + $result = $this->classToTest->getMerchantId(); + $this->assertEquals($expected, $result); + } + + public function testGetButtonColor() + { + $expected = "buttonColor"; + + $this->shopHelper->method('getConfigParam')->willReturn($expected); + + $result = $this->classToTest->getButtonColor(); + $this->assertEquals($expected, $result); + } + + public function testGetButtonLanguage() + { + $this->shopHelper->method('getConfigParam')->willReturn('de-DE'); + + $result = $this->classToTest->getButtonLanguage(); + $this->assertEquals('de_DE', $result); + } + + public function testUseSandbox() + { + $this->shopHelper->method('getConfigParam')->willReturn('test'); + + $result = $this->classToTest->useSandbox(); + $this->assertTrue($result); + } + + public function testUseSandboxFalse() + { + $this->shopHelper->method('getConfigParam')->willReturn('live'); + + $result = $this->classToTest->useSandbox(); + $this->assertFalse($result); + } + + public function testGetSuccessUrl() + { + $result = $this->classToTest->getSuccessUrl(); + $this->assertStringContainsString("payone", $result); + + $this->classToTest->setNeedsReturnedUrl(true); + + $result = $this->classToTest->getSuccessUrl(); + $this->assertStringContainsString("payone", $result); + } + + public function testAssignData() + { + $data = $this->getMockBuilder(DataObject::class)->disableOriginalConstructor()->getMock(); + + $result = $this->classToTest->assignData($data); + $this->assertInstanceOf(ClassToTest::class, $result); + } + + public function testGetPaymentSpecificParameters() + { + $order = $this->getMockBuilder(Order::class)->disableOriginalConstructor()->getMock(); + $order->method('getIsVirtual')->willReturn(false); + + $this->checkoutSession->method('getPayoneWorkorderId')->willReturn('12345'); + $this->checkoutSession->method('getPayoneIsAmazonPayExpressPayment')->willReturn(false); + + $result = $this->classToTest->getPaymentSpecificParameters($order); + $this->assertCount(5, $result); + } + + public function testGetFrontendConfig() + { + $this->shopHelper->method('getConfigParam')->willReturn('de-DE'); + + $result = $this->classToTest->getFrontendConfig(); + $this->assertCount(5, $result); + } + + public function testAuthorize() + { + $this->checkoutSession->method('getPayoneIsAmazonPayExpressPayment')->willReturn(false); + + $store = $this->getMockBuilder(Store::class)->disableOriginalConstructor()->getMock(); + $store->method('getCode')->willReturn('test'); + + $payment = $this->getMockBuilder(Payment::class)->disableOriginalConstructor()->getMock(); + $payment->method('getAdditionalInformation')->willReturn([]); + + $order = $this->getMockBuilder(Order::class)->disableOriginalConstructor()->getMock(); + $order->method('getStore')->willReturn($store); + $order->method('getPayment')->willReturn($payment); + + $paymentInfo = $this->getMockBuilder(Info::class)->disableOriginalConstructor()->setMethods(['getOrder'])->getMock(); + $paymentInfo->method('getOrder')->willReturn($order); + + $aResponse = ['status' => 'REDIRECT', 'txid' => '12345', 'redirecturl' => 'http://testdomain.com', 'add_paydata[signature]' => 'test', 'add_paydata[payload]' => 'test']; + $this->authorizationRequest->method('sendRequest')->willReturn($aResponse); + + $result = $this->classToTest->authorize($paymentInfo, 100); + $this->assertInstanceOf(ClassToTest::class, $result); + } +} diff --git a/Test/Unit/Model/Methods/BNPL/DebitTest.php b/Test/Unit/Model/Methods/BNPL/DebitTest.php index d7dbe5c4..16320c3a 100644 --- a/Test/Unit/Model/Methods/BNPL/DebitTest.php +++ b/Test/Unit/Model/Methods/BNPL/DebitTest.php @@ -26,9 +26,11 @@ namespace Payone\Core\Test\Unit\Model\Methods\BNPL; +use Payone\Core\Helper\Api; use Payone\Core\Model\Methods\BNPL\Debit as ClassToTest; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Sales\Model\Order; +use Magento\Quote\Model\Quote; use Magento\Quote\Model\Quote\Address; use Magento\Payment\Model\InfoInterface; use Magento\Payment\Model\Info; @@ -36,6 +38,8 @@ use Magento\Store\Model\Store; use Payone\Core\Test\Unit\BaseTestCase; use Payone\Core\Test\Unit\PayoneObjectManager; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Quote\Api\Data\CartInterface; class DebitTest extends BaseTestCase { @@ -49,14 +53,27 @@ class DebitTest extends BaseTestCase */ private $objectManager; + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + protected function setUp(): void { $this->objectManager = $this->getObjectManager(); + $this->scopeConfig = $this->getMockBuilder(ScopeConfigInterface::class)->disableOriginalConstructor()->getMock(); + $info = $this->getMockBuilder(Info::class)->disableOriginalConstructor()->setMethods(['getAdditionalInformation', 'getOrder'])->getMock(); $info->method('getAdditionalInformation')->willReturn('test'); - $this->classToTest = $this->objectManager->getObject(ClassToTest::class); + $apiHelper = $this->getMockBuilder(Api::class)->disableOriginalConstructor()->getMock(); + $apiHelper->method('getCurrencyFromOrder')->willReturn('GBP'); + + $this->classToTest = $this->objectManager->getObject(ClassToTest::class, [ + 'scopeConfig' => $this->scopeConfig, + 'apiHelper' => $apiHelper, + ]); $this->classToTest->setInfoInstance($info); } @@ -72,4 +89,22 @@ public function testGetSubTypeSpecificParameters() $result = $this->classToTest->getSubTypeSpecificParameters($order); $this->assertCount(2, $result); } + + public function testIsAvailable() + { + $this->scopeConfig->method('getValue')->willReturn(1); + + $result = $this->classToTest->isAvailable(); + $this->assertTrue($result); + } + + public function testIsAvailableNotEuro() + { + $this->scopeConfig->method('getValue')->willReturn(0); + + $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); + + $result = $this->classToTest->isAvailable($quote); + $this->assertFalse($result); + } } diff --git a/Test/Unit/Model/Methods/Klarna/InstallmentTest.php b/Test/Unit/Model/Methods/Klarna/InstallmentTest.php index a7ee1537..1a2199a5 100644 --- a/Test/Unit/Model/Methods/Klarna/InstallmentTest.php +++ b/Test/Unit/Model/Methods/Klarna/InstallmentTest.php @@ -110,7 +110,7 @@ public function testIsAvailableB2BSessionQuote() $quote = $this->getMockBuilder(Quote::class)->disableOriginalConstructor()->getMock(); $quote->method('getBillingAddress')->willReturn($address); - $result = $this->classToTest->isAvailable(); + $result = $this->classToTest->isAvailable($quote); $this->assertFalse($result); } diff --git a/Test/Unit/Model/Methods/OnlineBankTransfer/IdealTest.php b/Test/Unit/Model/Methods/OnlineBankTransfer/IdealTest.php index a3551f42..86516cfb 100644 --- a/Test/Unit/Model/Methods/OnlineBankTransfer/IdealTest.php +++ b/Test/Unit/Model/Methods/OnlineBankTransfer/IdealTest.php @@ -51,16 +51,7 @@ protected function setUp(): void { $this->objectManager = $this->getObjectManager(); - $info = $this->getMockBuilder(InfoInterface::class)->disableOriginalConstructor()->getMock(); - $info->method('getAdditionalInformation')->willReturn('info'); - - $toolkitHelper = $this->getMockBuilder(Toolkit::class)->disableOriginalConstructor()->getMock(); - $toolkitHelper->method('getAdditionalDataEntry')->willReturn('info'); - - $this->classToTest = $this->objectManager->getObject(ClassToTest::class, [ - 'toolkitHelper' => $toolkitHelper - ]); - $this->classToTest->setInfoInstance($info); + $this->classToTest = $this->objectManager->getObject(ClassToTest::class); } public function testGetSubTypeSpecificParameters() @@ -68,15 +59,7 @@ public function testGetSubTypeSpecificParameters() $order = $this->getMockBuilder(Order::class)->disableOriginalConstructor()->getMock(); $result = $this->classToTest->getSubTypeSpecificParameters($order); - $expected = ['bankcountry' => 'NL', 'bankgrouptype' => 'info']; + $expected = ['bankcountry' => 'NL']; $this->assertEquals($expected, $result); } - - public function testAssignData() - { - $data = $this->getMockBuilder(DataObject::class)->disableOriginalConstructor()->getMock(); - - $result = $this->classToTest->assignData($data); - $this->assertInstanceOf(ClassToTest::class, $result); - } } diff --git a/Test/Unit/Model/Methods/PayoneMethodTest.php b/Test/Unit/Model/Methods/PayoneMethodTest.php index 768ffc0d..72f846f1 100644 --- a/Test/Unit/Model/Methods/PayoneMethodTest.php +++ b/Test/Unit/Model/Methods/PayoneMethodTest.php @@ -154,4 +154,12 @@ public function testGetSuccessUrl() $result = $this->classToTest->getSuccessUrl(); $this->assertEquals($expected, $result); } + + public function testGetFrontendConfig() + { + $expected = []; + + $result = $this->classToTest->getFrontendConfig(); + $this->assertEquals($expected, $result); + } } diff --git a/Test/Unit/Service/V1/AmazonPayTest.php b/Test/Unit/Service/V1/AmazonPayTest.php index d1600bc9..caf7897d 100644 --- a/Test/Unit/Service/V1/AmazonPayTest.php +++ b/Test/Unit/Service/V1/AmazonPayTest.php @@ -43,6 +43,7 @@ use Payone\Core\Model\Api\Request\Genericpayment\GetConfiguration; use Payone\Core\Model\Api\Request\Genericpayment\GetOrderReferenceDetails; use Payone\Core\Model\Api\Request\Genericpayment\SetOrderReferenceDetails; +use Payone\Core\Model\Api\Request\Genericpayment\CreateCheckoutSessionPayload; use Payone\Core\Helper\Order; use Magento\Quote\Model\Quote\Payment; use Magento\Checkout\Model\Type\Onepage; @@ -63,6 +64,11 @@ class AmazonPayTest extends BaseTestCase */ private $response; + /** + * @var CreateCheckoutSessionPayload|\PHPUnit\Framework\MockObject\MockObject + */ + private $createCheckoutSessionPayload; + protected function setUp(): void { $objectManager = $this->getObjectManager(); @@ -112,10 +118,23 @@ protected function setUp(): void $checkoutSession = $this->getMockBuilder(Session::class) ->disableOriginalConstructor() - ->setMethods(['getAmazonWorkorderId', 'getQuote', 'setAmazonWorkorderId', 'setAmazonAddressToken', 'setAmazonReferenceId']) + ->setMethods([ + 'getAmazonWorkorderId', + 'getQuote', + 'setAmazonWorkorderId', + 'setAmazonAddressToken', + 'setAmazonReferenceId', + 'setPayoneIsAmazonPayExpressPayment', + 'setPayoneWorkorderId', + 'setPayoneQuoteComparisonString', + 'getPayoneAmazonPayPayload', + 'getPayoneAmazonPaySignature', + ]) ->getMock(); $checkoutSession->method('getAmazonWorkorderId')->willReturn(null); $checkoutSession->method('getQuote')->willReturn($quote); + $checkoutSession->method('getPayoneAmazonPayPayload')->willReturn('test'); + $checkoutSession->method('getPayoneAmazonPaySignature')->willReturn('test'); $aGetConfigurationResponse = [ 'status' => 'OK', @@ -138,6 +157,8 @@ protected function setUp(): void $setOrderReferenceDetails = $this->getMockBuilder(SetOrderReferenceDetails::class)->disableOriginalConstructor()->getMock(); $setOrderReferenceDetails->method('sendRequest')->willReturn($aSetOrderReferenceDetailsResponse); + $this->createCheckoutSessionPayload = $this->getMockBuilder(CreateCheckoutSessionPayload::class)->disableOriginalConstructor()->getMock(); + $checkoutHelper = $this->getMockBuilder(Checkout::class)->disableOriginalConstructor()->getMock(); $checkoutHelper->method('getCurrentCheckoutMethod')->willReturn(Onepage::METHOD_GUEST); @@ -157,6 +178,7 @@ protected function setUp(): void 'getConfiguration' => $getConfiguration, 'getOrderReferenceDetails' => $getOrderReferenceDetails, 'setOrderReferenceDetails' => $setOrderReferenceDetails, + 'createCheckoutSessionPayload' => $this->createCheckoutSessionPayload, 'orderHelper' => $orderHelper, 'checkoutHelper' => $checkoutHelper, 'view' => $view @@ -168,4 +190,37 @@ public function testGetWorkorderId() $result = $this->classToTest->getWorkorderId('123', '123'); $this->assertInstanceOf(AmazonPayResponse::class, $result); } + + public function testGetAmazonPayApbSession() + { + $result = $this->classToTest->getAmazonPayApbSession(4711); + $this->assertInstanceOf(AmazonPayResponse::class, $result); + $this->assertTrue($result->getSuccess()); + } + + public function testGetCheckoutSessionPayload() + { + $this->createCheckoutSessionPayload->method('sendRequest')->willReturn([ + 'status' => 'OK', + 'add_paydata[signature]' => 'test', + 'add_paydata[payload]' => 'test', + 'workorderid' => 'test', + ]); + + $result = $this->classToTest->getCheckoutSessionPayload(4711); + $this->assertInstanceOf(AmazonPayResponse::class, $result); + $this->assertTrue($result->getSuccess()); + } + + public function testGetCheckoutSessionPayloadError() + { + $this->createCheckoutSessionPayload->method('sendRequest')->willReturn([ + 'status' => 'ERROR', + 'customermessage' => 'ERROR', + ]); + + $result = $this->classToTest->getCheckoutSessionPayload(4711); + $this->assertInstanceOf(AmazonPayResponse::class, $result); + $this->assertFalse($result->getSuccess()); + } } diff --git a/Test/Unit/Service/V1/Data/AmazonPayResponseTest.php b/Test/Unit/Service/V1/Data/AmazonPayResponseTest.php index 51f2a73f..45231773 100644 --- a/Test/Unit/Service/V1/Data/AmazonPayResponseTest.php +++ b/Test/Unit/Service/V1/Data/AmazonPayResponseTest.php @@ -47,6 +47,8 @@ protected function setUp(): void 'success' => true, 'redirectUrl' => 'http://www.test.com', 'amazonReviewHtml' => 'test', + 'payload' => 'testPayload', + 'signature' => 'testSignature', ]; $this->classToTest = $objectManager->getObject(ClassToTest::class, [ @@ -80,4 +82,18 @@ public function testGetAmazonReviewHtml() $expected = 'test'; $this->assertEquals($expected, $result); } + + public function testGetPayload() + { + $result = $this->classToTest->getPayload(); + $expected = 'testPayload'; + $this->assertEquals($expected, $result); + } + + public function testGetSignature() + { + $result = $this->classToTest->getSignature(); + $expected = 'testSignature'; + $this->assertEquals($expected, $result); + } } diff --git a/composer.json b/composer.json index a7b0e8f0..b9f298a2 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "payone-gmbh/magento-2", "description": "PAYONE payment gateway for all German online and offline payment methods including PayPal, all major Credit Cards and Maestro.", "type": "magento2-module", - "version": "3.11.0", + "version": "3.12.0", "license": [ "OSL-3.0", "AFL-3.0" @@ -11,7 +11,7 @@ "email": "tech.support@payone.com" }, "require": { - "php": "~7.0.0|~7.1.0|~7.2.0|~7.3.0|~7.4.0|~8.0.0|~8.1.0|~8.2.0", + "php": "~7.0.0|~7.1.0|~7.2.0|~7.3.0|~7.4.0|~8.0.0|~8.1.0|~8.2.0|~8.3.0", "magento/framework": "^100.0.0|^101.0.0|^102.0.0|^103.0.0" }, "repositories": [ diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 593038fd..2dfe6f03 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -211,6 +211,11 @@ Payone\Core\Block\Adminhtml\Config\Form\Field\StatusMapping Magento\Config\Model\Config\Backend\Serialized\ArraySerialized + + + Payone\Core\Block\Adminhtml\Config\Form\Field\StatusMapping + Magento\Config\Model\Config\Backend\Serialized\ArraySerialized + @@ -320,6 +325,7 @@ + diff --git a/etc/adminhtml/system/payone_amazonpayv2.xml b/etc/adminhtml/system/payone_amazonpayv2.xml new file mode 100644 index 00000000..b0cb78fa --- /dev/null +++ b/etc/adminhtml/system/payone_amazonpayv2.xml @@ -0,0 +1,146 @@ + + + + + + + + Magento\Config\Model\Config\Source\Yesno + payment/payone_amazonpayv2/active + + + + payment/payone_amazonpayv2/title + + + + The authorization mode for payments with Amazon Pay is "preauthorization" by default. Amazon allows you to charge your buyer only when you fulfill the items in the order. Thus "authorization" can be used for custom made goods and articles that will be delivered immediately (e.g. electronically supplied services) + Payone\Core\Model\Source\RequestType + + + + + + + Payone\Core\Model\Source\AmazonButtonColor + + + + Payone\Core\Model\Source\AmazonButtonLanguage + + + + Amazon Pay V2 will also be shown in the payment list in the checkout with a special Amazon Pay buy button. + Magento\Config\Model\Config\Source\Yesno + + + + Magento\Sales\Model\Config\Source\Order\Status\NewStatus + payment/payone_amazonpayv2/order_status + + + + payment/payone_amazonpayv2/instructions + + + + payment/payone_amazonpayv2/min_order_total + + + + payment/payone_amazonpayv2/max_order_total + + + + payment/payone_amazonpayv2/sort_order + + + + Transmit the billing address as delivery address if delivery address is missing. + Magento\Config\Model\Config\Source\Yesno + + + + Maximum 81 digits. Placeholders: {order_increment_id} + + + + Payone\Core\Model\Source\Mode + + + + Magento\Config\Model\Config\Source\Yesno + + + + + 0 + + + + + + 0 + + + + + + 0 + + + + + + 0 + + + + + optional + A unique referencenumber has to be transferred to PAYONE with every request. This is a consecutive number, normally starting at 1. When operating multiple shops ( e.g. live- and test-shop ) with the same PAYONE account-data there will be problems when the current referencenumber was already used. This can be avoided by using different prefixes on different shops. + + 0 + + + + + Magento\Payment\Model\Config\Source\Allspecificcountries + + 0 + + + + + Magento\Directory\Model\Config\Source\Country + + 0 + 1 + + + + diff --git a/etc/config.xml b/etc/config.xml index 24b72e96..f2b7f235 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -219,6 +219,16 @@ 0 payone + + 1 + Authorization + Payone\Core\Model\Methods\AmazonPayV2 + pending + PAYONE Amazon Pay V2 + preauthorization + 0 + payone + 1 Authorization @@ -390,6 +400,7 @@ {"_payone_status_mapping9":{"txaction":"appointed","state_status":"processing"}} {"_payone_status_alipay":{"txaction":"appointed","state_status":"processing"}} {"_payone_status_amazon":{"txaction":"appointed","state_status":"processing"}} + {"_payone_status_amazonv2":{"txaction":"appointed","state_status":"processing"}} {"_payone_status_mapping10":{"txaction":"appointed","state_status":"processing"}} {"_payone_status_mapping11":{"txaction":"appointed","state_status":"processing"}} {"_payone_status_mapping12":{"txaction":"appointed","state_status":"processing"}} @@ -526,6 +537,10 @@ 1 + + 1 + 1 + 1 diff --git a/etc/csp_whitelist.xml b/etc/csp_whitelist.xml index 4fb2697f..088d204e 100644 --- a/etc/csp_whitelist.xml +++ b/etc/csp_whitelist.xml @@ -8,6 +8,8 @@ www.paypalobjects.com x.klarnacdn.net *.cloudfront.net + m.media-amazon.com + static-eu.payments-amazon.com @@ -40,6 +42,7 @@ payments.amazon.de + payments-eu.amazon.com d.ratepay.com jsctool.com eu.playground.klarnaevt.com diff --git a/etc/module.xml b/etc/module.xml index efec9ec0..61cf5951 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -25,7 +25,7 @@ */ --> - + diff --git a/etc/payment.xml b/etc/payment.xml index 92e2fa5e..29cd5fc8 100644 --- a/etc/payment.xml +++ b/etc/payment.xml @@ -94,6 +94,9 @@ 0 + + 0 + 0 diff --git a/etc/webapi.xml b/etc/webapi.xml index 0d315958..325413ba 100644 --- a/etc/webapi.xml +++ b/etc/webapi.xml @@ -177,4 +177,38 @@ %cart_id% + + + + + + + + + + + + + + + %cart_id% + + + + + + + + + + + + + + + + + %order_id% + + diff --git a/view/frontend/layout/checkout_index_index.xml b/view/frontend/layout/checkout_index_index.xml index afc52be7..39bdb08e 100644 --- a/view/frontend/layout/checkout_index_index.xml +++ b/view/frontend/layout/checkout_index_index.xml @@ -115,6 +115,9 @@ true + + true + true diff --git a/view/frontend/templates/amazon/buttonv2.phtml b/view/frontend/templates/amazon/buttonv2.phtml new file mode 100644 index 00000000..8efced88 --- /dev/null +++ b/view/frontend/templates/amazon/buttonv2.phtml @@ -0,0 +1,110 @@ +. + * + * PHP version 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2017 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ + +/** @var \Payone\Core\Block\Amazon\ButtonV2 $block */ +?> +
+ + diff --git a/view/frontend/templates/redirect_return.phtml b/view/frontend/templates/redirect_return.phtml index 8a1aaf46..a0fc2c63 100644 --- a/view/frontend/templates/redirect_return.phtml +++ b/view/frontend/templates/redirect_return.phtml @@ -22,55 +22,61 @@ * @license GNU Lesser General Public License * @link http://www.payone.de */ -?> - + });"; + echo $block->getScriptHelper()->insertScript($script); +} diff --git a/view/frontend/web/js/action/checkoutsessionpayload.js b/view/frontend/web/js/action/checkoutsessionpayload.js new file mode 100644 index 00000000..1d6121d0 --- /dev/null +++ b/view/frontend/web/js/action/checkoutsessionpayload.js @@ -0,0 +1,55 @@ +/** + * 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 - 2024 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_Customer/js/model/customer' +], function ($, urlBuilder, storage, fullScreenLoader, customer) { + 'use strict'; + return function (quoteId) { + var serviceUrl; + + var request = { + cartId: quoteId + }; + if (!customer.isLoggedIn()) { + serviceUrl = urlBuilder.createUrl('/guest-carts/:cartId/payone-getCheckoutSessionPayload', { + cartId: quoteId + }); + } else { + serviceUrl = urlBuilder.createUrl('/carts/mine/payone-getCheckoutSessionPayload', {}); + } + + fullScreenLoader.startLoader(); + + return storage.post( + serviceUrl, + JSON.stringify(request) + ); + }; +}); diff --git a/view/frontend/web/js/action/loadamazonpayapbsession.js b/view/frontend/web/js/action/loadamazonpayapbsession.js new file mode 100644 index 00000000..e5b227fc --- /dev/null +++ b/view/frontend/web/js/action/loadamazonpayapbsession.js @@ -0,0 +1,55 @@ +/** + * 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 - 2024 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_Customer/js/model/customer' +], function ($, urlBuilder, storage, fullScreenLoader, customer) { + 'use strict'; + return function (orderId) { + var serviceUrl; + + var request = { + orderId: orderId + }; + if (!customer.isLoggedIn()) { + serviceUrl = urlBuilder.createUrl('/guest-carts/:orderId/payone-getAmazonPayApbSession', { + orderId: orderId + }); + } else { + serviceUrl = urlBuilder.createUrl('/carts/mine/payone-getAmazonPayApbSession', {}); + } + + fullScreenLoader.startLoader(); + + return storage.post( + serviceUrl, + JSON.stringify(request) + ); + }; +}); diff --git a/view/frontend/web/js/view/payment/method-renderer/amazonpayv2-method.js b/view/frontend/web/js/view/payment/method-renderer/amazonpayv2-method.js new file mode 100644 index 00000000..9ee0fb04 --- /dev/null +++ b/view/frontend/web/js/view/payment/method-renderer/amazonpayv2-method.js @@ -0,0 +1,184 @@ +/** + * 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 5 + * + * @category Payone + * @package Payone_Magento2_Plugin + * @author FATCHIP GmbH + * @copyright 2003 - 2024 Payone GmbH + * @license GNU Lesser General Public License + * @link http://www.payone.de + */ +define( + [ + 'Payone_Core/js/view/payment/method-renderer/base', + 'jquery', + 'Magento_Checkout/js/model/quote', + 'Magento_Checkout/js/checkout-data', + 'Magento_Checkout/js/model/totals', + 'Magento_Checkout/js/model/full-screen-loader', + 'Payone_Core/js/action/loadamazonpayapbsession', + 'mage/translate' + ], + function (Component, $, quote, checkoutData, totals, fullScreenLoader, loadAmazonPayApbSession, $t) { + 'use strict'; + return Component.extend({ + defaults: { + template: 'Payone_Core/payment/amazonpayv2', + telephone: '', + buttonLoaded: false + }, + initObservable: function () { + this._super() + .observe([ + 'telephone', + 'buttonLoaded' + ]); + return this; + }, + validate: function () { + if (this.requestTelephone() === true && this.telephone() == '') { + this.messageContainer.addErrorMessage({'message': $t('Please enter your telephone number!')}); + return false; + } + return true; + }, + getData: function () { + var parentReturn = this._super(); + if (parentReturn.additional_data === null) { + parentReturn.additional_data = {}; + } + if (this.requestTelephone()) { + parentReturn.additional_data.telephone = this.telephone(); + } + return parentReturn; + }, + + getCurrency: function () { + if (window.checkoutConfig.payment.payone.currency === "display") { + return quote.totals().quote_currency_code; + } + return quote.totals().base_currency_code; + }, + + /** Returns payment method instructions */ + getInstructions: function () { + return window.checkoutConfig.payment.instructions[this.item.method]; + }, + initialize: function () { + let parentReturn = this._super(); + if (checkoutData.getSelectedPaymentMethod() === this.getCode()) { + this.initAmazonPayButton(); + } + return parentReturn; + }, + requestTelephone: function () { + if (quote.billingAddress() == null || (typeof quote.billingAddress().telephone != 'undefined' && quote.billingAddress().telephone != '')) { + return false; + } + return true; + }, + selectPaymentMethod: function () { + this.initAmazonPayButton(); + return this._super(); + }, + initAmazonPayButton: function () { + if (this.buttonLoaded() === false) { + var amazonPayMethod = this; + $.getScript("https://static-eu.payments-amazon.com/checkout.js", function () { + amazonPayMethod.renderAmazonPayButton(); + }); + this.buttonLoaded(true); + } + }, + getOrderTotal: function () { + if (window.checkoutConfig.payment.payone.currency === "display") { + return parseFloat(totals.getSegment('grand_total').value); + } + + var total = quote.getTotals(); + if (total) { + return parseFloat(total()['base_grand_total']); + } + return 0; + }, + getProductType: function () { + if (quote.isVirtual()) { + return 'PayOnly'; + } + return 'PayAndShip'; + }, + renderAmazonPayButton: function () { + var self = this; + + let buttonConfig = { + // set checkout environment + merchantId: this.getFrontendConfigParam('merchantId'), + publicKeyId: this.getFrontendConfigParam('buttonPublicKey'), + ledgerCurrency: this.getCurrency(), + productType: this.getProductType(), + placement: 'Checkout', + buttonColor: this.getFrontendConfigParam('buttonColor') + }; + if (this.getFrontendConfigParam('buttonLanguage') != 'none') { + buttonConfig.checkoutLanguage = this.getFrontendConfigParam('buttonLanguage'); + } + if (this.getFrontendConfigParam('useSandbox') == 1) { + buttonConfig.sandbox = true; + } + + let amazonPayButton = amazon.Pay.renderButton('#AmazonPayAPB', buttonConfig); + amazonPayButton.onClick(function(){ + self.isPlaceOrderActionAllowed(false); + self.getPlaceOrderDeferredObject() + .fail( + function () { + self.isPlaceOrderActionAllowed(true); + } + ).done( + function (orderId) { + self.afterPlaceOrder(); + + let ajaxCall = loadAmazonPayApbSession(orderId); + ajaxCall.done( + function (response) { + fullScreenLoader.stopLoader(); + if (response && response.success === true) { + amazonPayButton.initCheckout({ + estimatedOrderAmount: { "amount": self.getOrderTotal(), "currencyCode": self.getCurrency()}, + createCheckoutSessionConfig: { + payloadJSON: response.payload, + signature: response.signature, + publicKeyId: self.getFrontendConfigParam('buttonPublicKey') + } + }); + } else if (response && response.success === false) { + alert('An error occured.'); + } + } + ).fail( + function (response) { + fullScreenLoader.stopLoader(); + //errorProcessor.process(response, messageContainer); + alert('An error occured.'); + } + ); + } + ); + }); + } + }); + } +); diff --git a/view/frontend/web/js/view/payment/method-renderer/base.js b/view/frontend/web/js/view/payment/method-renderer/base.js index 6839bf54..9c349398 100644 --- a/view/frontend/web/js/view/payment/method-renderer/base.js +++ b/view/frontend/web/js/view/payment/method-renderer/base.js @@ -162,6 +162,19 @@ define( }, getAgreementMessage: function () { return window.checkoutConfig.payment.payone.agreementMessage; + }, + getFrontendConfig: function () { + if (window.checkoutConfig.payment.payone[this.getCode()] !== undefined) { + return window.checkoutConfig.payment.payone[this.getCode()]; + } + return []; + }, + getFrontendConfigParam: function (param, defaultReturn = '') { + let frontendConfig = this.getFrontendConfig(); + if (param in frontendConfig) { // check if key exists + return frontendConfig[param]; + } + return defaultReturn; } }); } diff --git a/view/frontend/web/js/view/payment/method-renderer/obt_ideal-method.js b/view/frontend/web/js/view/payment/method-renderer/obt_ideal-method.js index e3a241b9..ed052b3b 100644 --- a/view/frontend/web/js/view/payment/method-renderer/obt_ideal-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/obt_ideal-method.js @@ -29,33 +29,12 @@ define( 'use strict'; return Component.extend({ defaults: { - template: 'Payone_Core/payment/obt_ideal', - bankGroup: '' - }, - - initObservable: function () { - this._super() - .observe([ - 'bankGroup' - ]); - return this; - }, - - getData: function () { - var parentReturn = this._super(); - if (parentReturn.additional_data === null) { - parentReturn.additional_data = {}; - } - parentReturn.additional_data.bank_group = this.bankGroup(); - return parentReturn; + template: 'Payone_Core/payment/obt_ideal' }, /** Returns payment method instructions */ getInstructions: function () { return window.checkoutConfig.payment.instructions[this.item.method]; - }, - getBankGroups: function () { - return window.checkoutConfig.payment.payone.idealBankGroups; } }); } diff --git a/view/frontend/web/js/view/payment/payone-payments.js b/view/frontend/web/js/view/payment/payone-payments.js index fc9d93ff..1d7c0217 100644 --- a/view/frontend/web/js/view/payment/payone-payments.js +++ b/view/frontend/web/js/view/payment/payone-payments.js @@ -116,6 +116,10 @@ define( type: 'payone_amazonpay', component: 'Payone_Core/js/view/payment/method-renderer/amazonpay-method' }, + { + type: 'payone_amazonpayv2', + component: 'Payone_Core/js/view/payment/method-renderer/amazonpayv2-method' + }, { type: 'payone_klarna_base', component: 'Payone_Core/js/view/payment/method-renderer/klarna-method' diff --git a/view/frontend/web/template/payment/amazonpayv2.html b/view/frontend/web/template/payment/amazonpayv2.html new file mode 100644 index 00000000..e6b7e72d --- /dev/null +++ b/view/frontend/web/template/payment/amazonpayv2.html @@ -0,0 +1,98 @@ + +
+
+ + +
+ +
+ + + +
+ + + +
+ +
+
+ +
+ +
+
+
+ +

+
+ + + +
+
+
+ + +
+ +
+ + +
+ + +
+ + +
+
+
+
+
+
+
+
+
diff --git a/view/frontend/web/template/payment/creditcard.html b/view/frontend/web/template/payment/creditcard.html index 15393b3f..8a7e4376 100644 --- a/view/frontend/web/template/payment/creditcard.html +++ b/view/frontend/web/template/payment/creditcard.html @@ -110,7 +110,7 @@
-
-