diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 876bac399..ef9e0c45d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -5,6 +5,6 @@ **Tested scenarios** - + **Fixed issue**: \ No newline at end of file diff --git a/AdminMessage/VersionMessage.php b/AdminMessage/VersionMessage.php new file mode 100644 index 000000000..d95efe934 --- /dev/null +++ b/AdminMessage/VersionMessage.php @@ -0,0 +1,155 @@ + + */ + +namespace Adyen\Payment\AdminMessage; + +class VersionMessage implements \Magento\Framework\Notification\MessageInterface +{ + protected $_authSession; + protected $_adyenHelper; + protected $_inboxFactory; + + public function __construct( + \Magento\Backend\Model\Auth\Session $authSession, + \Adyen\Payment\Helper\Data $adyenHelper, + \Magento\AdminNotification\Model\InboxFactory $inboxFactory + ) { + $this->_authSession = $authSession; + $this->_adyenHelper = $adyenHelper; + $this->_inboxFactory = $inboxFactory; + } + + /** + * Message identity + */ + const MESSAGE_IDENTITY = 'Adyen Version Control message'; + + /** + * Retrieve unique system message identity + * + * @return string + */ + public function getIdentity() + { + return self::MESSAGE_IDENTITY; + } + + /** + * Check whether the system message should be shown + * + * @return bool + */ + public function isDisplayed() + { + // Only execute the query the first time you access the Admin page + if ($this->_authSession->isFirstPageAfterLogin()) { + + try { + $githubContent = $this->getDecodedContentFromGithub(); + $this->setSessionData("AdyenGithubVersion", $githubContent); + $title = "Adyen extension version " . $githubContent['tag_name'] . " available!"; + $versionData[] = array( + 'severity' => self::SEVERITY_NOTICE, + 'date_added' => $githubContent['published_at'], + 'title' => $title, + 'description' => $githubContent['body'], + 'url' => $githubContent['html_url'], + ); + + /* + * The parse function checks if the $versionData message exists in the inbox, + * otherwise it will create it and add it to the inbox. + */ + $this->_inboxFactory->create()->parse(array_reverse($versionData)); + + /* + * This will compare the currently installed version with the latest available one. + * A message will appear after the login if the two are not matching. + */ + if ($this->_adyenHelper->getModuleVersion() != $githubContent['tag_name']) { + return true; + } + } catch (\Exception $e) { + return false; + } + } + return false; + + } + + /** + * Retrieve system message text + * + * @return \Magento\Framework\Phrase + */ + public function getText() + { + $githubContent = $this->getSessionData("AdyenGithubVersion"); + $message = __("A new Adyen extension version is now available: "); + $message .= __(" " . $githubContent['tag_name'] . "!"); + $message .= __(" You are running the " . $this->_adyenHelper->getModuleVersion() . " version. We advise to update your extension."); + return __($message); + } + + /** + * Retrieve system message severity + * + * @return int + */ + public function getSeverity() + { + return self::SEVERITY_MAJOR; + } + + public function getDecodedContentFromGithub() + { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, 'https://api.github.com/repos/adyen/adyen-magento2/releases/latest'); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); + curl_setopt($ch, CURLOPT_USERAGENT, 'magento'); + $content = curl_exec($ch); + curl_close($ch); + $json = json_decode($content, true); + return $json; + } + + /** + * Set the current value for the backend session + */ + public function setSessionData($key, $value) + { + return $this->_authSession->setData($key, $value); + } + + /** + * Retrieve the session value + */ + public function getSessionData($key, $remove = false) + { + return $this->_authSession->getData($key, $remove); + } + +} + diff --git a/Api/AdyenPaymentMethodManagementInterface.php b/Api/AdyenPaymentMethodManagementInterface.php index a0e5c6f6c..ce21885cd 100644 --- a/Api/AdyenPaymentMethodManagementInterface.php +++ b/Api/AdyenPaymentMethodManagementInterface.php @@ -35,9 +35,10 @@ interface AdyenPaymentMethodManagementInterface /** * Get payment information * - * @param string $cartId + * @param string $cartId + * @param null|\Magento\Quote\Api\Data\AddressInterface * @return \Magento\Checkout\Api\Data\PaymentDetailsInterface */ - public function getPaymentMethods($cartId, \Magento\Quote\Api\Data\AddressInterface $shippingAddress); + public function getPaymentMethods($cartId, \Magento\Quote\Api\Data\AddressInterface $shippingAddress = null); } diff --git a/Api/Data/InvoiceInterface.php b/Api/Data/InvoiceInterface.php new file mode 100644 index 000000000..fb6079492 --- /dev/null +++ b/Api/Data/InvoiceInterface.php @@ -0,0 +1,125 @@ + + */ + +namespace Adyen\Payment\Api\Data; + +interface InvoiceInterface +{ + /** + * Constants for keys of data array. Identical to the name of the getter in snake case. + */ + + /* + * Entity ID. + */ + const ENTITY_ID = 'entity_id'; + /* + * Pspreference of the capture. + */ + const PSPREFERENCE = 'pspreference'; + /* + * Original Pspreference of the payment. + */ + const ORIGINAL_REFERENCE = 'original_reference'; + /* + * Acquirer reference. + */ + const ACQUIRER_REFERENCE = 'acquirer_reference'; + /* + * Invoice ID. + */ + const INVOICE_ID = 'invoice_id'; + + /** + * Gets the ID for the invoice. + * + * @return int|null Entity ID. + */ + public function getEntityId(); + + /** + * Sets entity ID. + * + * @param int $entityId + * @return $this + */ + public function setEntityId($entityId); + + /** + * Gets the Pspreference for the invoice(capture). + * + * @return int|null Pspreference. + */ + public function getPspreference(); + + /** + * Sets Pspreference. + * + * @param string $pspreference + * @return $this + */ + public function setPspreference($pspreference); + + /** + * @return mixed + */ + public function getOriginalReference(); + + /** + * @param $originalReference + * @return mixed + */ + public function setOriginalReference($originalReference); + + /** + * Gets the AcquirerReference for the invoice. + * + * @return int|null Acquirerreference. + */ + public function getAcquirerReference(); + + /** + * Sets AcquirerReference. + * + * @param string $acquirerReference + * @return $this + */ + public function setAcquirerReference($acquirerReference); + + /** + * Gets the InvoiceID for the invoice. + * + * @return int|null Invoice ID. + */ + public function getInvoiceId(); + + /** + * Sets InvoiceID. + * + * @param int $invoiceId + * @return $this + */ + public function setInvoiceId($invoiceId); + +} \ No newline at end of file diff --git a/Api/GuestAdyenPaymentMethodManagementInterface.php b/Api/GuestAdyenPaymentMethodManagementInterface.php index 890ab642e..b2727221a 100644 --- a/Api/GuestAdyenPaymentMethodManagementInterface.php +++ b/Api/GuestAdyenPaymentMethodManagementInterface.php @@ -35,9 +35,10 @@ interface GuestAdyenPaymentMethodManagementInterface /** * Get payment information * - * @param string $cartId + * @param string $cartId + * @param null|\Magento\Quote\Api\Data\AddressInterface * @return \Magento\Checkout\Api\Data\PaymentDetailsInterface */ - public function getPaymentMethods($cartId, \Magento\Quote\Api\Data\AddressInterface $shippingAddress); + public function getPaymentMethods($cartId, \Magento\Quote\Api\Data\AddressInterface $shippingAddress = null); } diff --git a/Block/Info/AbstractInfo.php b/Block/Info/AbstractInfo.php index 9358b609a..ab3a93958 100755 --- a/Block/Info/AbstractInfo.php +++ b/Block/Info/AbstractInfo.php @@ -34,7 +34,7 @@ class AbstractInfo extends \Magento\Payment\Block\Info protected $_adyenHelper; /** - * @var \Adyen\Payment\Model\Resource\Order\Payment\CollectionFactory + * @var \Adyen\Payment\Model\ResourceModel\Order\Payment\CollectionFactory */ protected $_adyenOrderPaymentCollectionFactory; @@ -42,13 +42,13 @@ class AbstractInfo extends \Magento\Payment\Block\Info * AbstractInfo constructor. * * @param \Adyen\Payment\Helper\Data $adyenHelper - * @param \Adyen\Payment\Model\Resource\Order\Payment\CollectionFactory $adyenOrderPaymentCollectionFactory + * @param \Adyen\Payment\Model\ResourceModel\Order\Payment\CollectionFactory $adyenOrderPaymentCollectionFactory * @param Template\Context $context * @param array $data */ public function __construct( \Adyen\Payment\Helper\Data $adyenHelper, - \Adyen\Payment\Model\Resource\Order\Payment\CollectionFactory $adyenOrderPaymentCollectionFactory, + \Adyen\Payment\Model\ResourceModel\Order\Payment\CollectionFactory $adyenOrderPaymentCollectionFactory, Template\Context $context, array $data = [] ) diff --git a/Block/Info/Oneclick.php b/Block/Info/Oneclick.php index 212d0e390..5eb080022 100755 --- a/Block/Info/Oneclick.php +++ b/Block/Info/Oneclick.php @@ -29,5 +29,5 @@ class Oneclick extends Cc /** * @var string */ - protected $_template = 'Adyen_Payment::info/adyen_oneclick.phtml'; + protected $_template = 'Adyen_Payment::info/adyen_cc.phtml'; } diff --git a/Block/Info/PaymentLink.php b/Block/Info/PaymentLink.php new file mode 100644 index 000000000..076b16a9d --- /dev/null +++ b/Block/Info/PaymentLink.php @@ -0,0 +1,96 @@ + + */ + +namespace Adyen\Payment\Block\Info; + +use Magento\Framework\View\Element\Template; + +class PaymentLink extends AbstractInfo +{ + /** + * @var \Magento\Framework\Registry + */ + private $registry; + + /** + * @var \Adyen\Payment\Gateway\Command\PayByMailCommand + */ + private $payByMail; + + public function __construct( + \Adyen\Payment\Helper\Data $adyenHelper, + \Adyen\Payment\Model\ResourceModel\Order\Payment\CollectionFactory $adyenOrderPaymentCollectionFactory, + Template\Context $context, + array $data = [], + \Magento\Framework\Registry $registry, + \Adyen\Payment\Gateway\Command\PayByMailCommand $payByMailCommand + ) { + $this->registry = $registry; + $this->payByMail = $payByMailCommand; + + parent::__construct($adyenHelper, $adyenOrderPaymentCollectionFactory, $context, $data); + } + + /** + * @return \Magento\Sales\Model\Order + */ + public function getOrder() + { + return $this->registry->registry('current_order'); + } + + /** + * @return \Magento\Sales\Model\Order\Payment + */ + public function getPayment() + { + $order = $this->getOrder(); + + return $order->getPayment(); + } + + /** + * @return string + */ + public function getPaymentLinkUrl() + { + return $this->payByMail->generatePaymentUrl($this->getPayment(), $this->getOrder()->getTotalDue()); + } + + /** + * Check if order was placed using Adyen payment method + * and if total due is greater than zero while one or more payments have been made + * + * @return string + */ + public function _toHtml() + { + return strpos($this->getPayment()->getMethod(), 'adyen_') === 0 + && $this->_scopeConfig->getValue('payment/adyen_hpp/active') + && $this->_scopeConfig->getValue('payment/adyen_pay_by_mail/active') + && $this->getOrder()->getTotalInvoiced() > 0 + && $this->getOrder()->getTotalDue() > 0 + ? parent::_toHtml() + : ''; + } +} diff --git a/Block/Redirect/Redirect.php b/Block/Redirect/Redirect.php index b08d74db3..269c769ab 100755 --- a/Block/Redirect/Redirect.php +++ b/Block/Redirect/Redirect.php @@ -445,31 +445,22 @@ protected function setOpenInvoiceData($formFields) foreach ($this->_order->getAllVisibleItems() as $item) { ++$count; - - - $description = str_replace("\n", '', trim($item->getName())); - $itemAmount = $this->_adyenHelper->formatAmount($item->getPrice(), $currency); - $itemVatAmount = - ($item->getTaxAmount() > 0 && $item->getPriceInclTax() > 0) ? - $this->_adyenHelper->formatAmount( - $item->getPriceInclTax(), - $currency - ) - $this->_adyenHelper->formatAmount( - $item->getPrice(), - $currency - ) : $this->_adyenHelper->formatAmount($item->getTaxAmount(), $currency); - - - // Calculate vat percentage - $itemVatPercentage = $this->_adyenHelper->getMinorUnitTaxPercent($item->getTaxPercent()); - $numberOfItems = (int)$item->getQtyOrdered(); - $formFields = $this->setOpenInvoiceLineData($formFields, $count, $currency, $description, $itemAmount, - $itemVatAmount, $itemVatPercentage, $numberOfItems); + $formFields = $this->_adyenHelper->createOpenInvoiceLineItem( + $formFields, + $count, + $item->getName(), + $item->getPrice(), + $currency, + $item->getTaxAmount(), + $item->getPriceInclTax(), + $item->getTaxPercent(), + $numberOfItems, + $this->_order->getPayment() + ); } - // Discount cost if ($this->_order->getDiscountAmount() > 0 || $this->_order->getDiscountAmount() < 0) { ++$count; @@ -480,35 +471,23 @@ protected function setOpenInvoiceData($formFields) $itemVatPercentage = "0"; $numberOfItems = 1; - $formFields = $this->setOpenInvoiceLineData($formFields, $count, $currency, $description, $itemAmount, - $itemVatAmount, $itemVatPercentage, $numberOfItems); + $formFields = $this->_adyenHelper->getOpenInvoiceLineData($formFields, $count, $currency, $description, $itemAmount, + $itemVatAmount, $itemVatPercentage, $numberOfItems, $this->_order->getPayment()); } // Shipping cost if ($this->_order->getShippingAmount() > 0 || $this->_order->getShippingTaxAmount() > 0) { ++$count; - $description = $this->_order->getShippingDescription(); - $itemAmount = $this->_adyenHelper->formatAmount($this->_order->getShippingAmount(), $currency); - $itemVatAmount = $this->_adyenHelper->formatAmount($this->_order->getShippingTaxAmount(), $currency); - - // Create RateRequest to calculate the Tax class rate for the shipping method - $rateRequest = $this->_taxCalculation->getRateRequest( - $this->_order->getShippingAddress(), - $this->_order->getBillingAddress(), - null, - $this->_order->getStoreId(), $this->_order->getCustomerId() + $formFields = $this->_adyenHelper->createOpenInvoiceLineShipping( + $formFields, + $count, + $this->_order, + $this->_order->getShippingAmount(), + $this->_order->getShippingTaxAmount(), + $currency, + $this->_order->getPayment() ); - - $taxClassId = $this->_taxConfig->getShippingTaxClass($this->_order->getStoreId()); - $rateRequest->setProductClassId($taxClassId); - $rate = $this->_taxCalculation->getRate($rateRequest); - - $itemVatPercentage = $this->_adyenHelper->getMinorUnitTaxPercent($rate); - $numberOfItems = 1; - - $formFields = $this->setOpenInvoiceLineData($formFields, $count, $currency, $description, $itemAmount, - $itemVatAmount, $itemVatPercentage, $numberOfItems); } $formFields['openinvoicedata.refundDescription'] = "Refund / Correction for " . $formFields['merchantReference']; @@ -517,40 +496,6 @@ protected function setOpenInvoiceData($formFields) return $formFields; } - - /** - * Set the openinvoice line - * - * @param $count - * @param $currencyCode - * @param $description - * @param $itemAmount - * @param $itemVatAmount - * @param $itemVatPercentage - * @param $numberOfItems - */ - protected function setOpenInvoiceLineData($formFields, $count, $currencyCode, $description, $itemAmount, - $itemVatAmount, $itemVatPercentage, $numberOfItems - ) - { - $linename = "line" . $count; - $formFields['openinvoicedata.' . $linename . '.currencyCode'] = $currencyCode; - $formFields['openinvoicedata.' . $linename . '.description'] = $description; - $formFields['openinvoicedata.' . $linename . '.itemAmount'] = $itemAmount; - $formFields['openinvoicedata.' . $linename . '.itemVatAmount'] = $itemVatAmount; - $formFields['openinvoicedata.' . $linename . '.itemVatPercentage'] = $itemVatPercentage; - $formFields['openinvoicedata.' . $linename . '.numberOfItems'] = $numberOfItems; - - if ($this->_adyenHelper->isVatCategoryHigh($this->_order->getPayment()->getAdditionalInformation( - \Adyen\Payment\Observer\AdyenHppDataAssignObserver::BRAND_CODE)) - ) { - $formFields['openinvoicedata.' . $linename . '.vatCategory'] = "High"; - } else { - $formFields['openinvoicedata.' . $linename . '.vatCategory'] = "None"; - } - return $formFields; - } - /** * @param $genderId * @return string diff --git a/Controller/Process/Cron.php b/Controller/Process/Cron.php deleted file mode 100644 index 2f213d059..000000000 --- a/Controller/Process/Cron.php +++ /dev/null @@ -1,62 +0,0 @@ - - */ -namespace Adyen\Payment\Controller\Process; -use Symfony\Component\Config\Definition\Exception\Exception; -/** - * Class Json - * @package Adyen\Payment\Controller\Process - */ -class Cron extends \Magento\Framework\App\Action\Action -{ - /** - * @var \Magento\Framework\ObjectManagerInterface - */ - protected $_objectManager; - /** - * @var \Magento\Framework\Controller\Result\RawFactory - */ - protected $_resultFactory; - - /** - * Cron constructor. - * - * @param \Magento\Framework\App\Action\Context $context - */ - public function __construct( - \Magento\Framework\App\Action\Context $context - ) { - parent::__construct($context); - $this->_objectManager = $context->getObjectManager(); - $this->_resultFactory = $context->getResultFactory(); - } - - /** - * Process Notification from Cron - */ - public function execute() - { - $cron = $this->_objectManager->create('Adyen\Payment\Model\Cron'); - $cron->processNotification(); - die(); - } -} \ No newline at end of file diff --git a/Controller/Process/Json.php b/Controller/Process/Json.php index 06af7dc0e..687eeea14 100755 --- a/Controller/Process/Json.php +++ b/Controller/Process/Json.php @@ -62,7 +62,8 @@ public function __construct( \Magento\Framework\App\Action\Context $context, \Adyen\Payment\Helper\Data $adyenHelper, \Adyen\Payment\Logger\AdyenLogger $adyenLogger - ) { + ) + { parent::__construct($context); $this->_objectManager = $context->getObjectManager(); $this->_resultFactory = $context->getResultFactory(); @@ -100,6 +101,8 @@ public function execute() if ($notificationMode != "" && $this->_validateNotificationMode($notificationMode)) { foreach ($notificationItems['notificationItems'] as $notificationItem) { + + $status = $this->_processNotification( $notificationItem['NotificationRequestItem'], $notificationMode ); @@ -108,9 +111,10 @@ public function execute() $this->_return401(); return; } - } - $acceptedMessage = "[accepted]"; + $acceptedMessage = "[accepted]"; + + } $cronCheckTest = $notificationItems['notificationItems'][0]['NotificationRequestItem']['pspReference']; // Run the query for checking unprocessed notifications, do this only for test notifications coming from the Adyen Customer Area @@ -247,8 +251,7 @@ protected function authorised($response) if (empty($submitedMerchantAccount) && empty($internalMerchantAccount)) { if ($this->_isTestNotification($response['pspReference'])) { - echo 'merchantAccountCode is empty in magento settings'; - exit(); + $this->_returnResult('merchantAccountCode is empty in magento settings'); } return false; } @@ -256,8 +259,9 @@ protected function authorised($response) // validate username and password if ((!isset($_SERVER['PHP_AUTH_USER']) && !isset($_SERVER['PHP_AUTH_PW']))) { if ($this->_isTestNotification($response['pspReference'])) { - echo 'Authentication failed: PHP_AUTH_USER and PHP_AUTH_PW are empty. See Adyen Magento manual CGI mode'; - exit(); + $this->_returnResult( + 'Authentication failed: PHP_AUTH_USER and PHP_AUTH_PW are empty. See Adyen Magento manual CGI mode' + ); } return false; } @@ -275,11 +279,11 @@ protected function authorised($response) // If notification is test check if fields are correct if not return error if ($this->_isTestNotification($response['pspReference'])) { if ($accountCmp != 0) { - echo 'MerchantAccount in notification is not the same as in Magento settings'; - exit(); + $this->_returnResult('MerchantAccount in notification is not the same as in Magento settings'); } elseif ($usernameCmp != 0 || $passwordCmp != 0) { - echo 'username (PHP_AUTH_USER) and\or password (PHP_AUTH_PW) are not the same as Magento settings'; - exit(); + $this->_returnResult( + 'username (PHP_AUTH_USER) and\or password (PHP_AUTH_PW) are not the same as Magento settings' + ); } } return false; @@ -356,4 +360,18 @@ protected function _isTestNotification($pspReference) return false; } } + + /** + * Returns the message to the browser + * + * @param $message + */ + protected function _returnResult($message) + { + $this->getResponse() + ->clearHeader('Content-Type') + ->setHeader('Content-Type', 'text/html') + ->setBody($message); + return; + } } \ No newline at end of file diff --git a/Controller/Process/Result.php b/Controller/Process/Result.php index 43eb1ea43..769c825d1 100755 --- a/Controller/Process/Result.php +++ b/Controller/Process/Result.php @@ -91,6 +91,8 @@ public function execute() $response = $this->getRequest()->getParams(); $this->_adyenLogger->addAdyenResult(print_r($response, true)); + $failReturnPath = $this->_adyenHelper->getAdyenAbstractConfigData('return_path'); + if ($response) { $result = $this->validateResponse($response); @@ -100,11 +102,11 @@ public function execute() $this->_redirect('checkout/onepage/success', ['_query' => ['utm_nooverride' => '1']]); } else { $this->_cancel($response); - $this->_redirect('checkout/cart'); + $this->_redirect($failReturnPath); } } else { // redirect to checkout page - $this->_redirect('checkout/cart'); + $this->_redirect($failReturnPath); } } diff --git a/Controller/Process/ResultPos.php b/Controller/Process/ResultPos.php index 4c5906dd5..3f0d7ed75 100644 --- a/Controller/Process/ResultPos.php +++ b/Controller/Process/ResultPos.php @@ -98,7 +98,7 @@ public function execute() $this->_redirect('checkout/onepage/success', ['_query' => ['utm_nooverride' => '1']]); } else { $this->_cancel($response); - $this->_redirect('checkout/cart'); + $this->_redirect($this->_adyenHelper->getAdyenAbstractConfigData('return_path')); } } diff --git a/Controller/Process/Validate3d.php b/Controller/Process/Validate3d.php index 7a0888fd4..a57806556 100755 --- a/Controller/Process/Validate3d.php +++ b/Controller/Process/Validate3d.php @@ -150,7 +150,7 @@ public function execute() // restore the quote $session->restoreQuote(); - $this->_redirect('checkout/cart'); + $this->_redirect($this->_adyenHelper->getAdyenAbstractConfigData('return_path')); } } } else { diff --git a/Gateway/Command/PayByMailCommand.php b/Gateway/Command/PayByMailCommand.php index faae9fdba..4aaf72b3c 100644 --- a/Gateway/Command/PayByMailCommand.php +++ b/Gateway/Command/PayByMailCommand.php @@ -54,6 +54,7 @@ public function __construct( $this->_adyenHelper = $adyenHelper; $this->_adyenLogger = $adyenLogger; } + /** * @param array $commandSubject * @return $this @@ -68,7 +69,7 @@ public function execute(array $commandSubject) $payment->setIsTransactionPending(true); // generateUrl - $payment->setAdditionalInformation('payment_url', $this->_generatePaymentUrl($payment)); + $payment->setAdditionalInformation('payment_url', $this->generatePaymentUrl($payment)); // update status and state $stateObject->setState(\Magento\Sales\Model\Order::STATE_NEW); @@ -79,13 +80,14 @@ public function execute(array $commandSubject) } /** - * @param $payment + * @param \Magento\Sales\Model\Order\Payment $payment + * @param float|bool $paymentAmount * @return string */ - protected function _generatePaymentUrl($payment) + public function generatePaymentUrl($payment, $paymentAmount = false) { $url = $this->getFormUrl(); - $fields = $this->getFormFields($payment); + $fields = $this->getFormFields($payment, $paymentAmount); $count = 1; $size = count($fields); @@ -119,10 +121,11 @@ public function getFormUrl() /** - * @param $payment + * @param \Magento\Sales\Model\Order\Payment $payment + * @param float|bool $paymentAmount * @return array */ - protected function getFormFields($payment) + protected function getFormFields($payment, $paymentAmount = false) { $order = $payment->getOrder(); @@ -143,7 +146,7 @@ protected function getFormFields($payment) $hmacKey = $this->_adyenHelper->getHmacPayByMail(); } - $amount = $this->_adyenHelper->formatAmount($order->getGrandTotal(), $orderCurrencyCode); + $amount = $this->_adyenHelper->formatAmount($paymentAmount ?: $order->getGrandTotal(), $orderCurrencyCode); $merchantAccount = trim($this->_adyenHelper->getAdyenAbstractConfigData('merchant_account', $storeId)); $shopperEmail = $order->getCustomerEmail(); $customerId = $order->getCustomerId(); diff --git a/Gateway/Request/BoletoAuthorizationDataBuilder.php b/Gateway/Request/BoletoAuthorizationDataBuilder.php index 53c4ae76e..cb55badbe 100644 --- a/Gateway/Request/BoletoAuthorizationDataBuilder.php +++ b/Gateway/Request/BoletoAuthorizationDataBuilder.php @@ -38,11 +38,12 @@ class BoletoAuthorizationDataBuilder implements BuilderInterface * * @param \Adyen\Payment\Helper\Data $adyenHelper */ - public function __construct(\Adyen\Payment\Helper\Data $adyenHelper) - { + public function __construct( + \Adyen\Payment\Helper\Data $adyenHelper + ) { $this->adyenHelper = $adyenHelper; } - + /** * @param array $buildSubject * @return mixed @@ -59,7 +60,15 @@ public function build(array $buildSubject) $request = []; $request['socialSecurityNumber'] = $payment->getAdditionalInformation("social_security_number"); - $request['selectedBrand'] = $payment->getAdditionalInformation("boleto_type"); + + $boletoTypes = $this->adyenHelper->getAdyenBoletoConfigData('boletotypes'); + $boletoTypes = explode(',', $boletoTypes); + + if (count($boletoTypes) == 1) { + $request['selectedBrand'] = $boletoTypes[0]; + } else { + $request['selectedBrand'] = $payment->getAdditionalInformation("boleto_type"); + } $shopperName = [ 'firstName' => $payment->getAdditionalInformation("firstname"), @@ -68,7 +77,7 @@ public function build(array $buildSubject) $request['shopperName'] = $shopperName; - $deliveryDays = (int) $this->adyenHelper->getAdyenBoletoConfigData("delivery_days", $storeId); + $deliveryDays = (int)$this->adyenHelper->getAdyenBoletoConfigData("delivery_days", $storeId); $deliveryDays = (!empty($deliveryDays)) ? $deliveryDays : 5; $deliveryDate = date( "Y-m-d\TH:i:s ", @@ -81,7 +90,7 @@ public function build(array $buildSubject) ); $request['deliveryDate'] = $deliveryDate; - + return $request; } } \ No newline at end of file diff --git a/Gateway/Request/CaptureDataBuilder.php b/Gateway/Request/CaptureDataBuilder.php index ec65aedb8..9c5b83dae 100644 --- a/Gateway/Request/CaptureDataBuilder.php +++ b/Gateway/Request/CaptureDataBuilder.php @@ -48,7 +48,7 @@ public function __construct(\Adyen\Payment\Helper\Data $adyenHelper) /** * Create capture request - * + * * @param array $buildSubject * @return array */ @@ -57,21 +57,84 @@ public function build(array $buildSubject) /** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */ $paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject); - $amount = \Magento\Payment\Gateway\Helper\SubjectReader::readAmount($buildSubject); + $amount = \Magento\Payment\Gateway\Helper\SubjectReader::readAmount($buildSubject); $payment = $paymentDataObject->getPayment(); + $pspReference = $payment->getCcTransId(); $currency = $payment->getOrder()->getOrderCurrencyCode(); - //format the amount to minor units $amount = $this->adyenHelper->formatAmount($amount, $currency); $modificationAmount = ['currency' => $currency, 'value' => $amount]; - - return [ + $request = [ "modificationAmount" => $modificationAmount, "reference" => $payment->getOrder()->getIncrementId(), "originalReference" => $pspReference ]; + + $brandCode = $payment->getAdditionalInformation( + \Adyen\Payment\Observer\AdyenHppDataAssignObserver::BRAND_CODE + ); + + if ($this->adyenHelper->isPaymentMethodOpenInvoiceMethod($brandCode)) { + $openInvoiceFields = $this->getOpenInvoiceData($payment); + $request["additionalData"] = $openInvoiceFields; + } + + return $request; + } + + + /** + * @param $payment + * @return mixed + * @internal param $formFields + */ + protected function getOpenInvoiceData($payment) + { + $formFields = []; + $count = 0; + $currency = $payment->getOrder()->getOrderCurrencyCode(); + + $invoices = $payment->getOrder()->getInvoiceCollection(); + + // The latest invoice will contain only the selected items(and quantities) for the (partial) capture + $latestInvoice = $invoices->getLastItem(); + + foreach ($latestInvoice->getItemsCollection() as $invoiceItem) { + ++$count; + $numberOfItems = (int)$invoiceItem->getQty(); + $formFields = $this->adyenHelper->createOpenInvoiceLineItem( + $formFields, + $count, + $invoiceItem->getName(), + $invoiceItem->getPrice(), + $currency, + $invoiceItem->getTaxAmount(), + $invoiceItem->getPriceInclTax(), + $invoiceItem->getTaxPercent(), + $numberOfItems, + $payment + ); + } + + // Shipping cost + if ($latestInvoice->getShippingAmount() > 0) { + ++$count; + $formFields = $this->adyenHelper->createOpenInvoiceLineShipping( + $formFields, + $count, + $payment->getOrder(), + $latestInvoice->getShippingAmount(), + $latestInvoice->getShippingTaxAmount(), + $currency, + $payment + ); + } + + $formFields['openinvoicedata.numberOfLines'] = $count; + + return $formFields; } } \ No newline at end of file diff --git a/Gateway/Request/RefundDataBuilder.php b/Gateway/Request/RefundDataBuilder.php index d238b88f8..4893343f6 100644 --- a/Gateway/Request/RefundDataBuilder.php +++ b/Gateway/Request/RefundDataBuilder.php @@ -37,22 +37,28 @@ class RefundDataBuilder implements BuilderInterface private $adyenHelper; /** - * @var \Adyen\Payment\Model\Resource\Order\Payment\CollectionFactory + * @var \Adyen\Payment\Model\ResourceModel\Order\Payment\CollectionFactory */ private $orderPaymentCollectionFactory; + /** + * @var \Adyen\Payment\Model\ResourceModel\Invoice\CollectionFactory + */ + protected $adyenInvoiceCollectionFactory; + /** * RefundDataBuilder constructor. * @param \Adyen\Payment\Helper\Data $adyenHelper - * @param \Adyen\Payment\Model\Resource\Order\Payment\CollectionFactory $orderPaymentCollectionFactory + * @param \Adyen\Payment\Model\ResourceModel\Order\Payment\CollectionFactory $orderPaymentCollectionFactory */ public function __construct( \Adyen\Payment\Helper\Data $adyenHelper, - \Adyen\Payment\Model\Resource\Order\Payment\CollectionFactory $orderPaymentCollectionFactory - ) - { + \Adyen\Payment\Model\ResourceModel\Order\Payment\CollectionFactory $orderPaymentCollectionFactory, + \Adyen\Payment\Model\ResourceModel\Invoice\CollectionFactory $adyenInvoiceCollectionFactory + ) { $this->adyenHelper = $adyenHelper; $this->orderPaymentCollectionFactory = $orderPaymentCollectionFactory; + $this->adyenInvoiceCollectionFactory = $adyenInvoiceCollectionFactory; } /** @@ -63,7 +69,7 @@ public function build(array $buildSubject) { /** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */ $paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject); - $amount = \Magento\Payment\Gateway\Helper\SubjectReader::readAmount($buildSubject); + $amount = \Magento\Payment\Gateway\Helper\SubjectReader::readAmount($buildSubject); $order = $paymentDataObject->getOrder(); $payment = $paymentDataObject->getPayment(); @@ -96,7 +102,7 @@ public function build(array $buildSubject) $orderPaymentCollection->addPaymentFilterDescending($payment->getId()); } elseif ($refundStrategy == "3") { // refund based on ratio - $ratio = $amount / $grandTotal; + $ratio = $amount / $grandTotal; $orderPaymentCollection->addPaymentFilterAscending($payment->getId()); } @@ -109,7 +115,7 @@ public function build(array $buildSubject) // refund based on ratio calculate refund amount $modificationAmount = $ratio * ( $splitPayment->getAmount() - $splitPayment->getTotalRefunded() - ); + ); } else { // total authorised amount of the split payment $splitPaymentAmount = $splitPayment->getAmount() - $splitPayment->getTotalRefunded(); @@ -119,7 +125,7 @@ public function build(array $buildSubject) continue; } - // if refunded amount is greather then split payment amount do a full refund + // if refunded amount is greater than split payment amount do a full refund if ($amount >= $splitPaymentAmount) { $modificationAmount = $splitPaymentAmount; } else { @@ -155,8 +161,81 @@ public function build(array $buildSubject) "merchantAccount" => $merchantAccount ] ]; + + $brandCode = $payment->getAdditionalInformation( + \Adyen\Payment\Observer\AdyenHppDataAssignObserver::BRAND_CODE + ); + + if ($this->adyenHelper->isPaymentMethodOpenInvoiceMethod($brandCode)) { + $openInvoiceFields = $this->getOpenInvoiceData($payment); + + //There is only one payment, so we add the fields to the first(and only) result + $result[0]["additionalData"] = $openInvoiceFields; + } + } - + return $result; } + + + protected function getOpenInvoiceData($payment) + { + $formFields = []; + $count = 0; + $currency = $payment->getOrder()->getOrderCurrencyCode(); + + /** + * Magento\Sales\Model\Order\Creditmemo + */ + $creditMemo = $payment->getCreditMemo(); + + foreach ($creditMemo->getAllItems() as $refundItem) { + ++$count; + $numberOfItems = $refundItem->getQty(); + + $formFields = $this->adyenHelper->createOpenInvoiceLineItem( + $formFields, + $count, + $refundItem->getName(), + $refundItem->getPrice(), + $currency, + $refundItem->getTaxAmount(), + $refundItem->getPriceInclTax(), + $refundItem->getTaxPercent(), + $numberOfItems, + $payment + ); + + } + + // Shipping cost + if ($creditMemo->getShippingAmount() > 0) { + ++$count; + $formFields = $this->adyenHelper->createOpenInvoiceLineShipping( + $formFields, + $count, + $payment->getOrder(), + $creditMemo->getShippingAmount(), + $creditMemo->getShippingTaxAmount(), + $currency, + $payment + ); + } + + $formFields['openinvoicedata.numberOfLines'] = $count; + + //Retrieve acquirerReference from the adyen_invoice + $invoiceId = $creditMemo->getInvoice()->getId(); + $invoices = $this->adyenInvoiceCollectionFactory->create() + ->addFieldToFilter('invoice_id', $invoiceId); + + $invoice = $invoices->getFirstItem(); + + if($invoice) { + $formFields['acquirerReference'] = $invoice->getAcquirerReference(); + } + + return $formFields; + } } \ No newline at end of file diff --git a/Helper/Data.php b/Helper/Data.php index 295dda367..11d072cb7 100755 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -55,7 +55,7 @@ class Data extends AbstractHelper protected $_moduleList; /** - * @var \Adyen\Payment\Model\Resource\Billing\Agreement\CollectionFactory + * @var \Adyen\Payment\Model\ResourceModel\Billing\Agreement\CollectionFactory */ protected $_billingAgreementCollectionFactory; @@ -69,6 +69,21 @@ class Data extends AbstractHelper */ protected $_assetSource; + /** + * @var \Adyen\Payment\Model\ResourceModel\Notification\CollectionFactory + */ + protected $_notificationFactory; + + /** + * @var \Magento\Tax\Model\Config + */ + protected $_taxConfig; + + /** + * @var \Magento\Tax\Model\Calculation + */ + protected $_taxCalculation; + /** * Data constructor. * @@ -77,7 +92,7 @@ class Data extends AbstractHelper * @param \Magento\Framework\Config\DataInterface $dataStorage * @param \Magento\Directory\Model\Config\Source\Country $country * @param \Magento\Framework\Module\ModuleListInterface $moduleList - * @param \Adyen\Payment\Model\Resource\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory + * @param \Adyen\Payment\Model\ResourceModel\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory * @param \Magento\Framework\View\Asset\Repository $assetRepo * @param \Magento\Framework\View\Asset\Source $assetSource */ @@ -87,12 +102,13 @@ public function __construct( \Magento\Framework\Config\DataInterface $dataStorage, \Magento\Directory\Model\Config\Source\Country $country, \Magento\Framework\Module\ModuleListInterface $moduleList, - \Adyen\Payment\Model\Resource\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory, + \Adyen\Payment\Model\ResourceModel\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory, \Magento\Framework\View\Asset\Repository $assetRepo, \Magento\Framework\View\Asset\Source $assetSource, - \Adyen\Payment\Model\Resource\Notification\CollectionFactory $notificationFactory - ) - { + \Adyen\Payment\Model\ResourceModel\Notification\CollectionFactory $notificationFactory, + \Magento\Tax\Model\Config $taxConfig, + \Magento\Tax\Model\Calculation $taxCalculation + ) { parent::__construct($context); $this->_encryptor = $encryptor; $this->_dataStorage = $dataStorage; @@ -102,6 +118,8 @@ public function __construct( $this->_assetRepo = $assetRepo; $this->_assetSource = $assetSource; $this->_notificationFactory = $notificationFactory; + $this->_taxConfig = $taxConfig; + $this->_taxCalculation = $taxCalculation; } /** @@ -464,7 +482,7 @@ public function getAdyenApplePayConfigData($field, $storeId = null) { return $this->getConfigData($field, 'adyen_apple_pay', $storeId); } - + /** * @param null $storeId * @return mixed @@ -847,15 +865,15 @@ public function getOneClickPaymentMethods($customerId, $storeId, $grandTotal, $r */ public function isPaymentMethodOpenInvoiceMethod($paymentMethod) { - if (strlen($paymentMethod) >= 9 && substr($paymentMethod, 0, 9) == 'afterpay_') { + if (strpos($paymentMethod, 'afterpay') !== false) { + return true; + } elseif (strpos($paymentMethod, 'klarna') !== false) { + return true; + } elseif (strpos($paymentMethod, 'ratepay') !== false) { return true; - } else { - if ($paymentMethod == 'klarna' || $paymentMethod == 'ratepay') { - return true; - } else { - return false; - } } + + return false; } public function getRatePayId() @@ -968,4 +986,149 @@ public function getLibrarySource($storeId = null) return "https://" . $environment . ".adyen.com/hpp/cse/js/" . $this->getLibraryToken($storeId) . ".shtml"; } + + /** + * @param $formFields + * @param $count + * @param $name + * @param $price + * @param $currency + * @param $taxAmount + * @param $priceInclTax + * @param $taxPercent + * @param $numberOfItems + * @param $payment + * @return mixed + */ + public function createOpenInvoiceLineItem( + $formFields, + $count, + $name, + $price, + $currency, + $taxAmount, + $priceInclTax, + $taxPercent, + $numberOfItems, + $payment + ) { + $description = str_replace("\n", '', trim($name)); + $itemAmount = $this->formatAmount($price, $currency); + + $itemVatAmount = $this->getItemVatAmount($taxAmount, + $priceInclTax, $price, $currency); + + // Calculate vat percentage + $itemVatPercentage = $this->getMinorUnitTaxPercent($taxPercent); + + return $this->getOpenInvoiceLineData($formFields, $count, $currency, $description, + $itemAmount, + $itemVatAmount, $itemVatPercentage, $numberOfItems, $payment); + } + + /** + * @param $formFields + * @param $count + * @param $order + * @param $shippingAmount + * @param $shippingTaxAmount + * @param $currency + * @param $payment + * @return mixed + */ + public function createOpenInvoiceLineShipping( + $formFields, + $count, + $order, + $shippingAmount, + $shippingTaxAmount, + $currency, + $payment + ) { + $description = $order->getShippingDescription(); + $itemAmount = $this->formatAmount($shippingAmount, $currency); + $itemVatAmount = $this->formatAmount($shippingTaxAmount, $currency); + + // Create RateRequest to calculate the Tax class rate for the shipping method + $rateRequest = $this->_taxCalculation->getRateRequest( + $order->getShippingAddress(), + $order->getBillingAddress(), + null, + $order->getStoreId(), + $order->getCustomerId() + ); + + $taxClassId = $this->_taxConfig->getShippingTaxClass($order->getStoreId()); + $rateRequest->setProductClassId($taxClassId); + $rate = $this->_taxCalculation->getRate($rateRequest); + + $itemVatPercentage = $this->getMinorUnitTaxPercent($rate); + $numberOfItems = 1; + + return $this->getOpenInvoiceLineData($formFields, $count, $currency, $description, + $itemAmount, + $itemVatAmount, $itemVatPercentage, $numberOfItems, $payment); + } + + /** + * @param $taxAmount + * @param $priceInclTax + * @param $price + * @param $currency + * @return string + */ + public function getItemVatAmount( + $taxAmount, + $priceInclTax, + $price, + $currency + ) { + if ($taxAmount > 0 && $priceInclTax > 0) { + return $this->formatAmount($priceInclTax, $currency) - $this->formatAmount($price, $currency); + } + return $this->formatAmount($taxAmount, $currency); + } + + /** + * Set the openinvoice line + * + * @param $formFields + * @param $count + * @param $currencyCode + * @param $description + * @param $itemAmount + * @param $itemVatAmount + * @param $itemVatPercentage + * @param $numberOfItems + * @param $payment + * @return + */ + public function getOpenInvoiceLineData( + $formFields, + $count, + $currencyCode, + $description, + $itemAmount, + $itemVatAmount, + $itemVatPercentage, + $numberOfItems, + $payment + ) { + $linename = "line" . $count; + $formFields['openinvoicedata.' . $linename . '.currencyCode'] = $currencyCode; + $formFields['openinvoicedata.' . $linename . '.description'] = $description; + $formFields['openinvoicedata.' . $linename . '.itemAmount'] = $itemAmount; + $formFields['openinvoicedata.' . $linename . '.itemVatAmount'] = $itemVatAmount; + $formFields['openinvoicedata.' . $linename . '.itemVatPercentage'] = $itemVatPercentage; + $formFields['openinvoicedata.' . $linename . '.numberOfItems'] = $numberOfItems; + + if ($this->isVatCategoryHigh($payment->getAdditionalInformation( + \Adyen\Payment\Observer\AdyenHppDataAssignObserver::BRAND_CODE)) + ) { + $formFields['openinvoicedata.' . $linename . '.vatCategory'] = "High"; + } else { + $formFields['openinvoicedata.' . $linename . '.vatCategory'] = "None"; + } + return $formFields; + } } \ No newline at end of file diff --git a/Helper/PaymentMethods.php b/Helper/PaymentMethods.php index 195531c4d..0b2a9befb 100644 --- a/Helper/PaymentMethods.php +++ b/Helper/PaymentMethods.php @@ -154,10 +154,16 @@ protected function _addHppMethodsToConfig($store, $country) { $paymentMethods = []; - $ccEnabled = $this->_config->getValue('payment/'.\Adyen\Payment\Model\Ui\AdyenCcConfigProvider::CODE.'/active'); + $ccEnabled = $this->_config->getValue( + 'payment/' . \Adyen\Payment\Model\Ui\AdyenCcConfigProvider::CODE . '/active', + \Magento\Store\Model\ScopeInterface::SCOPE_STORES, + $store->getCode() + ); $ccTypes = array_keys($this->_adyenHelper->getCcTypesAltData()); $sepaEnabled = $this->_config->getValue( - 'payment/'.\Adyen\Payment\Model\Ui\AdyenSepaConfigProvider::CODE.'/active' + 'payment/' . \Adyen\Payment\Model\Ui\AdyenSepaConfigProvider::CODE . '/active', + \Magento\Store\Model\ScopeInterface::SCOPE_STORES, + $store->getCode() ); foreach ($this->_fetchHppMethods($store, $country) as $methodCode => $methodData) { @@ -192,20 +198,20 @@ protected function _fetchHppMethods($store, $country) } $adyFields = [ - "paymentAmount" => (int) $this->_adyenHelper->formatAmount( + "paymentAmount" => (int)$this->_adyenHelper->formatAmount( $this->_getCurrentPaymentAmount(), $this->_getCurrentCurrencyCode($store) ), - "currencyCode" => $this->_getCurrentCurrencyCode($store), + "currencyCode" => $this->_getCurrentCurrencyCode($store), "merchantReference" => "Get Payment methods", - "skinCode" => $skinCode, - "merchantAccount" => $merchantAccount, - "sessionValidity" => date( + "skinCode" => $skinCode, + "merchantAccount" => $merchantAccount, + "sessionValidity" => date( DATE_ATOM, mktime(date("H") + 1, date("i"), date("s"), date("m"), date("j"), date("Y")) ), - "countryCode" => $this->_getCurrentCountryCode($store, $country), - "shopperLocale" => $this->_getCurrentLocaleCode($store) + "countryCode" => $this->_getCurrentCountryCode($store, $country), + "shopperLocale" => $this->_getCurrentLocaleCode($store) ]; $responseData = $this->_getDirectoryLookupResponse($adyFields, $store); @@ -228,9 +234,9 @@ protected function _fetchHppMethods($store, $country) $themeCode = "Magento/blank"; $themeId = $this->_design->getConfigurationDesignTheme(\Magento\Framework\App\Area::AREA_FRONTEND); - if(!empty($themeId)) { + if (!empty($themeId)) { $theme = $this->_themeProvider->getThemeById($themeId); - if($theme && !empty($theme->getCode())) { + if ($theme && !empty($theme->getCode())) { $themeCode = $theme->getCode(); } } @@ -405,7 +411,7 @@ protected function _getDirectoryLookupResponse($requestParams, $store) $service = new \Adyen\Service\DirectoryLookup($client); try { - $responseData = $service->directoryLookup($requestParams); + $responseData = $service->directoryLookup($requestParams); } catch (\Adyen\AdyenException $e) { $this->_adyenLogger->error( "The Directory Lookup response is empty check your Adyen configuration in Magento." diff --git a/Model/Cron.php b/Model/Cron.php index 733cf5713..a2d238857 100755 --- a/Model/Cron.php +++ b/Model/Cron.php @@ -41,7 +41,7 @@ class Cron protected $_logger; /** - * @var Resource\Notification\CollectionFactory + * @var ResourceModel\Notification\CollectionFactory */ protected $_notificationFactory; @@ -88,7 +88,7 @@ class Cron protected $_billingAgreementFactory; /** - * @var Resource\Billing\Agreement\CollectionFactory + * @var ResourceModel\Billing\Agreement\CollectionFactory */ protected $_billingAgreementCollectionFactory; @@ -112,6 +112,11 @@ class Cron */ protected $_merchantReference; + /** + * @var + */ + protected $_acquirerReference; + /** * @var */ @@ -168,10 +173,15 @@ class Cron protected $_adyenOrderPaymentFactory; /** - * @var Resource\Order\Payment\CollectionFactory + * @var ResourceModel\Order\Payment\CollectionFactory */ protected $_adyenOrderPaymentCollectionFactory; + /** + * @var ResourceModel\InvoiceFactory + */ + protected $_adyenInvoiceFactory; + /** * @var AreaList */ @@ -182,33 +192,34 @@ class Cron * * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Adyen\Payment\Logger\AdyenLogger $adyenLogger - * @param Resource\Notification\CollectionFactory $notificationFactory + * @param ResourceModel\Notification\CollectionFactory $notificationFactory * @param \Magento\Sales\Model\OrderFactory $orderFactory * @param \Adyen\Payment\Helper\Data $adyenHelper * @param OrderSender $orderSender * @param InvoiceSender $invoiceSender * @param \Magento\Framework\DB\TransactionFactory $transactionFactory * @param Billing\AgreementFactory $billingAgreementFactory - * @param Resource\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory + * @param ResourceModel\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory * @param Api\PaymentRequest $paymentRequest * @param Order\PaymentFactory $adyenOrderPaymentFactory - * @param Resource\Order\Payment\CollectionFactory $adyenOrderPaymentCollectionFactory + * @param ResourceModel\Order\Payment\CollectionFactory $adyenOrderPaymentCollectionFactory * @param AreaList $areaList */ public function __construct( \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Adyen\Payment\Logger\AdyenLogger $adyenLogger, - \Adyen\Payment\Model\Resource\Notification\CollectionFactory $notificationFactory, + \Adyen\Payment\Model\ResourceModel\Notification\CollectionFactory $notificationFactory, \Magento\Sales\Model\OrderFactory $orderFactory, \Adyen\Payment\Helper\Data $adyenHelper, OrderSender $orderSender, InvoiceSender $invoiceSender, \Magento\Framework\DB\TransactionFactory $transactionFactory, \Adyen\Payment\Model\Billing\AgreementFactory $billingAgreementFactory, - \Adyen\Payment\Model\Resource\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory, + \Adyen\Payment\Model\ResourceModel\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory, \Adyen\Payment\Model\Api\PaymentRequest $paymentRequest, \Adyen\Payment\Model\Order\PaymentFactory $adyenOrderPaymentFactory, - \Adyen\Payment\Model\Resource\Order\Payment\CollectionFactory $adyenOrderPaymentCollectionFactory, + \Adyen\Payment\Model\ResourceModel\Order\Payment\CollectionFactory $adyenOrderPaymentCollectionFactory, + \Adyen\Payment\Model\InvoiceFactory $adyenInvoiceFactory, AreaList $areaList ) { $this->_scopeConfig = $scopeConfig; @@ -224,6 +235,7 @@ public function __construct( $this->_adyenPaymentRequest = $paymentRequest; $this->_adyenOrderPaymentFactory = $adyenOrderPaymentFactory; $this->_adyenOrderPaymentCollectionFactory = $adyenOrderPaymentCollectionFactory; + $this->_adyenInvoiceFactory = $adyenInvoiceFactory; $this->_areaList = $areaList; } @@ -235,7 +247,7 @@ public function processNotification() { try { $this->execute(); - } catch(\Exception $e) { + } catch (\Exception $e) { $this->_adyenLogger->addAdyenNotificationCronjob($e->getMessage() . "\n" . $e->getTraceAsString()); throw $e; } @@ -478,6 +490,10 @@ protected function _declareVariables($notification) if ($additionalData2 && is_array($additionalData2)) { $this->_klarnaReservationNumber = isset($additionalData2['acquirerReference']) ? trim($additionalData2['acquirerReference']) : ""; } + $acquirerReference = isset($additionalData['acquirerReference']) ? $additionalData['acquirerReference'] : null; + if ($acquirerReference != "") { + $this->_acquirerReference = $acquirerReference; + } } } @@ -536,11 +552,7 @@ protected function _addStatusHistoryComment() } // if payment method is klarna, ratepay or openinvoice/afterpay show the reservartion number - if (($this->_paymentMethod == "klarna" || $this->_paymentMethod == "afterpay_default" || - $this->_paymentMethod == "openinvoice" || $this->_paymentMethod == "ratepay" - ) && ($this->_klarnaReservationNumber != null && - $this->_klarnaReservationNumber != "") - ) { + if ($this->_adyenHelper->isPaymentMethodOpenInvoiceMethod($this->_paymentMethod) && !empty($this->_klarnaReservationNumber)) { $klarnaReservationNumberText = "
reservationNumber: " . $this->_klarnaReservationNumber; } else { $klarnaReservationNumberText = ""; @@ -802,6 +814,22 @@ protected function _processNotification() */ if (!$this->_isAutoCapture()) { $this->_setPaymentAuthorized(false, true); + + /* + * Add invoice in the adyen_invoice table + */ + $invoiceCollection = $this->_order->getInvoiceCollection(); + foreach ($invoiceCollection as $invoice) { + if ($invoice->getTransactionId() == $this->_pspReference) { + $this->_adyenInvoiceFactory->create() + ->setInvoiceId($invoice->getEntityId()) + ->setPspreference($this->_pspReference) + ->setOriginalReference($this->_originalReference) + ->setAcquirerReference($this->_acquirerReference) + ->save(); + $this->_adyenLogger->addAdyenNotificationCronjob('Created invoice entry in the Adyen table'); + } + } } } else { // FOR POS authorize the payment on the CAPTURE notification @@ -1211,7 +1239,7 @@ protected function _isAutoCapture() $captureModeOpenInvoice = $this->_getConfigData( 'auto_capture_openinvoice', 'adyen_abstract', $this->_order->getStoreId() ); - $captureModePayPal = trim($this->_getConfigData( + $manualCapturePayPal = trim($this->_getConfigData( 'paypal_capture_mode', 'adyen_abstract', $this->_order->getStoreId()) ); @@ -1248,18 +1276,19 @@ protected function _isAutoCapture() ); return true; } + // if PayPal capture modues is different from the default use this one - if (strcmp($this->_paymentMethod, 'paypal') === 0 && $captureModePayPal != "") { - if (strcmp($captureModePayPal, 'auto') === 0) { - $this->_adyenLogger->addAdyenNotificationCronjob( - 'This payment method is paypal and configured to work as auto capture' - ); - return true; - } elseif (strcmp($captureModePayPal, 'manual') === 0) { + if (strcmp($this->_paymentMethod, 'paypal') === 0) { + if ($manualCapturePayPal) { $this->_adyenLogger->addAdyenNotificationCronjob( 'This payment method is paypal and configured to work as manual capture' ); return false; + } else { + $this->_adyenLogger->addAdyenNotificationCronjob( + 'This payment method is paypal and configured to work as auto capture' + ); + return true; } } if (strcmp($captureMode, 'manual') === 0) { @@ -1298,6 +1327,11 @@ protected function _manualCaptureAllowed() $manualCaptureAllowed = null; $paymentMethod = $this->_paymentMethod; + // For all openinvoice methods manual capture is the default + if ($this->_adyenHelper->isPaymentMethodOpenInvoiceMethod($paymentMethod)) { + return true; + } + switch ($paymentMethod) { case 'cup': case 'cartebancaire': @@ -1306,7 +1340,6 @@ protected function _manualCaptureAllowed() case 'mc': case 'uatp': case 'amex': - case 'bcmc': case 'maestro': case 'maestrouk': case 'diners': @@ -1314,17 +1347,10 @@ protected function _manualCaptureAllowed() case 'jcb': case 'laser': case 'paypal': - case 'klarna': - case 'afterpay_default': - case 'ratepay': case 'sepadirectdebit': $manualCaptureAllowed = true; break; default: - // To be sure check if it payment method starts with afterpay_ then manualCapture is allowed - if (strlen($this->_paymentMethod) >= 9 && substr($this->_paymentMethod, 0, 9) == "afterpay_") { - $manualCaptureAllowed = true; - } $manualCaptureAllowed = false; } @@ -1451,6 +1477,19 @@ protected function _createInvoice() $invoice->save(); $this->_adyenLogger->addAdyenNotificationCronjob('Created invoice'); + + /* + * Add invoice in the adyen_invoice table + */ + $this->_adyenInvoiceFactory->create() + ->setInvoiceId($invoice->getEntityId()) + ->setPspreference($this->_pspReference) + ->setOriginalReference($this->_pspReference) + ->setAcquirerReference($this->_acquirerReference) + ->save(); + + $this->_adyenLogger->addAdyenNotificationCronjob('Created invoice entry in the Adyen table'); + } catch (Exception $e) { $this->_adyenLogger->addAdyenNotificationCronjob( 'Error saving invoice. The error message is: ' . $e->getMessage() @@ -1609,4 +1648,6 @@ protected function _getConfigData($field, $paymentMethodCode = 'adyen_cc', $stor $path = 'payment/' . $paymentMethodCode . '/' . $field; return $this->_scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId); } + + } diff --git a/Model/Invoice.php b/Model/Invoice.php new file mode 100644 index 000000000..16c435af6 --- /dev/null +++ b/Model/Invoice.php @@ -0,0 +1,143 @@ + + */ + +namespace Adyen\Payment\Model; + +use Adyen\Payment\Api\Data\InvoiceInterface; + +class Invoice extends \Magento\Framework\Model\AbstractModel + implements InvoiceInterface +{ + /** + * Notification constructor. + * + * @param \Magento\Framework\Model\Context $context + * @param \Magento\Framework\Registry $registry + * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource + * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection + * @param array $data + */ + public function __construct( + \Magento\Framework\Model\Context $context, + \Magento\Framework\Registry $registry, + \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, + \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, + array $data = [] + ) { + parent::__construct($context, $registry, $resource, $resourceCollection, $data); + } + + /** + * Initialize resource model + * + * @return void + */ + protected function _construct() + { + $this->_init('Adyen\Payment\Model\ResourceModel\Invoice'); + } + + /** + * Gets the Pspreference for the invoice(capture). + * + * @return int|null Pspreference. + */ + public function getPspreference() + { + return $this->getData(self::PSPREFERENCE); + } + + /** + * Sets Pspreference. + * + * @param string $pspreference + * @return $this + */ + public function setPspreference($pspreference) + { + return $this->setData(self::PSPREFERENCE, $pspreference); + } + + /** + * Gets the Pspreference of the original Payment + * @return mixed + */ + public function getOriginalReference() + { + return $this->getData(self::ORIGINAL_REFERENCE); + } + + /** + * Sets the OriginalReference + * + * @param $originalReference + * @return $this + */ + public function setOriginalReference($originalReference) + { + return $this->setData(self::ORIGINAL_REFERENCE, $originalReference); + } + /** + * Gets the AcquirerReference for the invoice. + * + * @return int|null Acquirerreference. + */ + public function getAcquirerReference() + { + return $this->getData(self::ACQUIRER_REFERENCE); + } + + /** + * Sets AcquirerReference. + * + * @param string $acquirerReference + * @return $this + */ + public function setAcquirerReference($acquirerReference) + { + return $this->setData(self::ACQUIRER_REFERENCE, $acquirerReference); + } + + /** + * Gets the InvoiceID for the invoice. + * + * @return int|null Invoice ID. + */ + public function getInvoiceId() + { + return $this->getData(self::INVOICE_ID); + } + + /** + * Sets InvoiceID. + * + * @param int $invoiceId + * @return $this + */ + public function setInvoiceId($invoiceId) + { + return $this->setData(self::INVOICE_ID, $invoiceId); + } + +} \ No newline at end of file diff --git a/Model/Method/Adapter.php b/Model/Method/Adapter.php index e8f991449..926c9444d 100644 --- a/Model/Method/Adapter.php +++ b/Model/Method/Adapter.php @@ -96,7 +96,7 @@ public function updateBillingAgreementStatus(\Adyen\Payment\Model\Billing\Agreem $agreement->getCustomerReference(), $agreement->getStoreId() ); - } catch(Exception $e) { + } catch(\Exception $e) { throw new \Magento\Framework\Exception\LocalizedException(__('Failed to disable this contract')); } } diff --git a/Model/Notification.php b/Model/Notification.php index 2506426bc..e73431fd9 100755 --- a/Model/Notification.php +++ b/Model/Notification.php @@ -76,7 +76,7 @@ public function __construct( */ protected function _construct() { - $this->_init('Adyen\Payment\Model\Resource\Notification'); + $this->_init('Adyen\Payment\Model\ResourceModel\Notification'); } /** diff --git a/Model/Order/Payment.php b/Model/Order/Payment.php index 67e923ae7..2435bb579 100644 --- a/Model/Order/Payment.php +++ b/Model/Order/Payment.php @@ -55,7 +55,7 @@ public function __construct( */ protected function _construct() { - $this->_init('Adyen\Payment\Model\Resource\Order\Payment'); + $this->_init('Adyen\Payment\Model\ResourceModel\Order\Payment'); } /** diff --git a/Model/Resource/Billing/Agreement.php b/Model/ResourceModel/Billing/Agreement.php similarity index 95% rename from Model/Resource/Billing/Agreement.php rename to Model/ResourceModel/Billing/Agreement.php index ddd4b6939..96217aa00 100644 --- a/Model/Resource/Billing/Agreement.php +++ b/Model/ResourceModel/Billing/Agreement.php @@ -21,7 +21,7 @@ * Author: Adyen */ -namespace Adyen\Payment\Model\Resource\Billing; +namespace Adyen\Payment\Model\ResourceModel\Billing; /** * Billing agreement resource model diff --git a/Model/Resource/Billing/Agreement/Collection.php b/Model/ResourceModel/Billing/Agreement/Collection.php similarity index 96% rename from Model/Resource/Billing/Agreement/Collection.php rename to Model/ResourceModel/Billing/Agreement/Collection.php index 6ed82b375..3da0d313c 100755 --- a/Model/Resource/Billing/Agreement/Collection.php +++ b/Model/ResourceModel/Billing/Agreement/Collection.php @@ -21,7 +21,7 @@ * Author: Adyen */ -namespace Adyen\Payment\Model\Resource\Billing\Agreement; +namespace Adyen\Payment\Model\ResourceModel\Billing\Agreement; /** * Billing agreements resource collection diff --git a/Model/ResourceModel/Invoice.php b/Model/ResourceModel/Invoice.php new file mode 100644 index 000000000..804bfc84f --- /dev/null +++ b/Model/ResourceModel/Invoice.php @@ -0,0 +1,38 @@ + + */ + +namespace Adyen\Payment\Model\ResourceModel; + +class Invoice extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb +{ + /** + * Resource initialization + * + * @return void + */ + protected function _construct() + { + $this->_init('adyen_invoice', 'entity_id'); + } +} \ No newline at end of file diff --git a/Model/ResourceModel/Invoice/Collection.php b/Model/ResourceModel/Invoice/Collection.php new file mode 100644 index 000000000..43dcf59dd --- /dev/null +++ b/Model/ResourceModel/Invoice/Collection.php @@ -0,0 +1,37 @@ + + */ + +namespace Adyen\Payment\Model\ResourceModel\Invoice; + +class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection +{ + /** + * Construct + */ + public function _construct() + { + $this->_init('Adyen\Payment\Model\Invoice', 'Adyen\Payment\Model\ResourceModel\Invoice'); + } + +} \ No newline at end of file diff --git a/Model/Resource/Notification.php b/Model/ResourceModel/Notification.php similarity index 97% rename from Model/Resource/Notification.php rename to Model/ResourceModel/Notification.php index dd1970618..063747bf9 100755 --- a/Model/Resource/Notification.php +++ b/Model/ResourceModel/Notification.php @@ -21,7 +21,7 @@ * Author: Adyen */ -namespace Adyen\Payment\Model\Resource; +namespace Adyen\Payment\Model\ResourceModel; class Notification extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/Model/Resource/Notification/Collection.php b/Model/ResourceModel/Notification/Collection.php similarity index 94% rename from Model/Resource/Notification/Collection.php rename to Model/ResourceModel/Notification/Collection.php index a098f7284..9b177986f 100755 --- a/Model/Resource/Notification/Collection.php +++ b/Model/ResourceModel/Notification/Collection.php @@ -21,7 +21,7 @@ * Author: Adyen */ -namespace Adyen\Payment\Model\Resource\Notification; +namespace Adyen\Payment\Model\ResourceModel\Notification; class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection { @@ -30,7 +30,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab */ public function _construct() { - $this->_init('Adyen\Payment\Model\Notification', 'Adyen\Payment\Model\Resource\Notification'); + $this->_init('Adyen\Payment\Model\Notification', 'Adyen\Payment\Model\ResourceModel\Notification'); } /** diff --git a/Model/Resource/Order/Payment.php b/Model/ResourceModel/Order/Payment.php similarity index 95% rename from Model/Resource/Order/Payment.php rename to Model/ResourceModel/Order/Payment.php index 71b86342a..9eacce21e 100644 --- a/Model/Resource/Order/Payment.php +++ b/Model/ResourceModel/Order/Payment.php @@ -21,7 +21,7 @@ * Author: Adyen */ -namespace Adyen\Payment\Model\Resource\Order; +namespace Adyen\Payment\Model\ResourceModel\Order; class Payment extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/Model/Resource/Order/Payment/Collection.php b/Model/ResourceModel/Order/Payment/Collection.php similarity index 95% rename from Model/Resource/Order/Payment/Collection.php rename to Model/ResourceModel/Order/Payment/Collection.php index f8ea731aa..5b394b931 100644 --- a/Model/Resource/Order/Payment/Collection.php +++ b/Model/ResourceModel/Order/Payment/Collection.php @@ -21,7 +21,7 @@ * Author: Adyen */ -namespace Adyen\Payment\Model\Resource\Order\Payment; +namespace Adyen\Payment\Model\ResourceModel\Order\Payment; /** * Billing agreements resource collection @@ -36,7 +36,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab */ protected function _construct() { - $this->_init('Adyen\Payment\Model\Order\Payment', 'Adyen\Payment\Model\Resource\Order\Payment'); + $this->_init('Adyen\Payment\Model\Order\Payment', 'Adyen\Payment\Model\ResourceModel\Order\Payment'); } /** diff --git a/Model/Ui/AdyenBoletoConfigProvider.php b/Model/Ui/AdyenBoletoConfigProvider.php index 9eefc7c41..6f70e791b 100644 --- a/Model/Ui/AdyenBoletoConfigProvider.php +++ b/Model/Ui/AdyenBoletoConfigProvider.php @@ -34,7 +34,7 @@ class AdyenBoletoConfigProvider implements ConfigProviderInterface * @var PaymentHelper */ protected $_paymentHelper; - + /** * @var \Adyen\Payment\Helper\Data */ @@ -86,12 +86,32 @@ public function getConfig() 'checkout/onepage/success/', ['_secure' => $this->_getRequest()->isSecure()]) ], 'adyenBoleto' => [ - 'boletoTypes' => $this->_adyenHelper->getBoletoTypes() + 'boletoTypes' => $this->getBoletoAvailableTypes() ] ] ]; } + /** + * @return array + */ + protected function getBoletoAvailableTypes() + { + $types = []; + $boletoTypes = $this->_adyenHelper->getBoletoTypes(); + $availableTypes = $this->_adyenHelper->getAdyenBoletoConfigData('boletotypes'); + if ($availableTypes) { + $availableTypes = explode(',', $availableTypes); + foreach ($boletoTypes as $boletoType) { + if (in_array($boletoType['value'], $availableTypes)) { + $types[] = $boletoType; + } + } + } + return $types; + } + + /** * Retrieve request object * diff --git a/README.md b/README.md index 3b0f64901..6df0b7e41 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Adyen Payment plugin for Magento2. This plugin supports Magento2 version 2.1 and For Magento2 version 2.0 support, use plugin version 1.4.6. ## Installation ## ``` -bin/composer require adyen/module-payment +composer require adyen/module-payment bin/magento module:enable Adyen_Payment bin/magento setup:upgrade ``` diff --git a/Setup/UpgradeSchema.php b/Setup/UpgradeSchema.php index 80a6fe673..9328e058a 100755 --- a/Setup/UpgradeSchema.php +++ b/Setup/UpgradeSchema.php @@ -35,6 +35,7 @@ class UpgradeSchema implements UpgradeSchemaInterface { const ADYEN_ORDER_PAYMENT = 'adyen_order_payment'; + const ADYEN_INVOICE = 'adyen_invoice'; /** * {@inheritdoc} @@ -63,6 +64,10 @@ public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $con $this->updateSchemaVersion207($setup); } + if (version_compare($context->getVersion(), '2.2.1', '<')) { + $this->updateSchemaVersion221($setup); + } + $setup->endSetup(); } @@ -100,7 +105,7 @@ public function updateSchemaVersion1001(SchemaSetupInterface $setup) $connection->addColumn($setup->getTable('sales_order_payment'), 'adyen_psp_reference', $pspReferenceColumn); } - + /** * Upgrade to 1.0.0.2 * @@ -220,7 +225,7 @@ public function updateSchemaVersion200(SchemaSetupInterface $setup) \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE ) ->setComment('Adyen Order Payment'); - + $setup->getConnection()->createTable($table); // add originalReference to notification table @@ -231,7 +236,7 @@ public function updateSchemaVersion200(SchemaSetupInterface $setup) 'length' => 255, 'nullable' => true, 'comment' => 'Original Reference', - 'after' => \Adyen\Payment\Model\Notification::PSPREFRENCE + 'after' => \Adyen\Payment\Model\Notification::PSPREFRENCE ]; $connection->addColumn( @@ -268,9 +273,9 @@ public function updateSchemaVersion204(SchemaSetupInterface $setup) } - /** + /** * Upgrade to 2.0.7 - * + * * @param SchemaSetupInterface $setup * @return void */ @@ -285,7 +290,7 @@ public function updateSchemaVersion207(SchemaSetupInterface $setup) 'nullable' => true, 'default' => 0, 'comment' => 'Adyen Notification Cron Processing', - 'after' => \Adyen\Payment\Model\Notification::DONE + 'after' => \Adyen\Payment\Model\Notification::DONE ]; $connection->addColumn( @@ -294,4 +299,59 @@ public function updateSchemaVersion207(SchemaSetupInterface $setup) $adyenNotificationProcessingColumn ); } + + public function updateSchemaVersion221(SchemaSetupInterface $setup) + { + + $table = $setup->getConnection() + ->newTable($setup->getTable(self::ADYEN_INVOICE)) + ->addColumn( + 'entity_id', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true], + 'Adyen Invoice Entity ID' + ) + ->addColumn( + 'pspreference', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 255, + ['unsigned' => true, 'nullable' => false], + 'Adyen pspreference of the capture' + ) + ->addColumn( + 'original_reference', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 255, + ['unsigned' => true, 'nullable' => true], + 'Adyen OriginalReference of the payment' + ) + ->addColumn('acquirer_reference', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 255, + ['unsigned' => true, 'nullable' => true], + 'Adyen AcquirerReference of the capture') + ->addColumn( + 'invoice_id', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + 11, + ['unsigned' => true, 'nullable' => false], + 'Invoice Id' + ) + ->addForeignKey( + $setup->getFkName( + self::ADYEN_INVOICE, + 'invoice_id', + 'sales_invoice', + 'entity_id' + ), + 'invoice_id', + $setup->getTable('sales_invoice'), + 'entity_id', + \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE + ) + ->setComment('Adyen Invoice'); + + $setup->getConnection()->createTable($table); + } } \ No newline at end of file diff --git a/Test/Unit/Helper/DataTest.php b/Test/Unit/Helper/DataTest.php new file mode 100755 index 000000000..f5afc7e8a --- /dev/null +++ b/Test/Unit/Helper/DataTest.php @@ -0,0 +1,73 @@ + + */ + +namespace Adyen\Payment\Tests\Helper; + +class DataTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Adyen\Payment\Helper\Data + */ + private $dataHelper; + + private function getSimpleMock($originalClassName) + { + return $this->getMockBuilder($originalClassName) + ->disableOriginalConstructor() + ->getMock(); + } + + public function setUp() + { + $context = $this->getSimpleMock(\Magento\Framework\App\Helper\Context::class); + $encryptor = $this->getSimpleMock(\Magento\Framework\Encryption\EncryptorInterface::class); + $dataStorage = $this->getSimpleMock(\Magento\Framework\Config\DataInterface::class); + $country = $this->getSimpleMock(\Magento\Directory\Model\Config\Source\Country::class); + $moduleList = $this->getSimpleMock(\Magento\Framework\Module\ModuleListInterface::class); + $billingAgreementCollectionFactory = $this->getSimpleMock(\Adyen\Payment\Model\ResourceModel\Billing\Agreement\CollectionFactory::class); + $assetRepo = $this->getSimpleMock(\Magento\Framework\View\Asset\Repository::class); + $assetSource = $this->getSimpleMock(\Magento\Framework\View\Asset\Source::class); + $notificationFactory = $this->getSimpleMock(\Adyen\Payment\Model\ResourceModel\Notification\CollectionFactory::class); + + $this->dataHelper = new \Adyen\Payment\Helper\Data($context, $encryptor, $dataStorage, $country, $moduleList, + $billingAgreementCollectionFactory, $assetRepo, $assetSource, $notificationFactory); + } + + public function testFormatAmount() + { + $this->assertEquals('1234', $this->dataHelper->formatAmount('12.34', 'EUR')); + $this->assertEquals('1200', $this->dataHelper->formatAmount('12.00', 'USD')); + $this->assertEquals('12', $this->dataHelper->formatAmount('12.00', 'JPY')); + } + + public function testisPaymentMethodOpenInvoiceMethod() + { + $this->assertEquals(true, $this->dataHelper->isPaymentMethodOpenInvoiceMethod('klarna')); + $this->assertEquals(true, $this->dataHelper->isPaymentMethodOpenInvoiceMethod('klarna_account')); + $this->assertEquals(true, $this->dataHelper->isPaymentMethodOpenInvoiceMethod('afterpay')); + $this->assertEquals(true, $this->dataHelper->isPaymentMethodOpenInvoiceMethod('afterpay_default')); + $this->assertEquals(true, $this->dataHelper->isPaymentMethodOpenInvoiceMethod('ratepay')); + $this->assertEquals(false, $this->dataHelper->isPaymentMethodOpenInvoiceMethod('ideal')); + $this->assertEquals(true, $this->dataHelper->isPaymentMethodOpenInvoiceMethod('test_klarna')); + } +} diff --git a/composer.json b/composer.json index 8f283fdb8..5b37a3f6b 100755 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "adyen/module-payment", "description": "Official Magento2 Plugin to connect to Payment Service Provider Adyen.", "type": "magento2-module", - "version": "2.2.0", + "version": "2.3.0", "license": [ "OSL-3.0", "AFL-3.0" @@ -17,9 +17,6 @@ "adyen/php-api-library": "*", "magento/framework": ">=100.1.0" }, - "require-dev": { - "phpunit/phpunit": "~5" - }, "autoload": { "files": [ "registration.php" diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml index a25fb9167..b25c16bd6 100644 --- a/etc/adminhtml/di.xml +++ b/etc/adminhtml/di.xml @@ -3,7 +3,8 @@ - Adyen\Payment\AdminMessage\CronMessage + Adyen\Payment\AdminMessage\CronMessage + Adyen\Payment\AdminMessage\VersionMessage diff --git a/etc/adminhtml/system/adyen_boleto.xml b/etc/adminhtml/system/adyen_boleto.xml index 338d10a06..ea39b9683 100644 --- a/etc/adminhtml/system/adyen_boleto.xml +++ b/etc/adminhtml/system/adyen_boleto.xml @@ -44,6 +44,8 @@ + 1 + validate-no-empty Adyen\Payment\Model\Config\Source\BoletoType payment/adyen_boleto/boletotypes diff --git a/etc/adminhtml/system/adyen_checkout_experience.xml b/etc/adminhtml/system/adyen_checkout_experience.xml index 1ae38c5dc..5bd4a5e94 100644 --- a/etc/adminhtml/system/adyen_checkout_experience.xml +++ b/etc/adminhtml/system/adyen_checkout_experience.xml @@ -37,6 +37,10 @@ Adyen\Payment\Model\Config\Source\RenderMode payment/adyen_abstract/title_renderer - + + + payment/adyen_abstract/return_path + not successful. Default is checkout/cart.]]> + \ No newline at end of file diff --git a/etc/adminhtml/system/adyen_hpp.xml b/etc/adminhtml/system/adyen_hpp.xml index 5ad9547dd..4ced40429 100755 --- a/etc/adminhtml/system/adyen_hpp.xml +++ b/etc/adminhtml/system/adyen_hpp.xml @@ -55,7 +55,7 @@ Magento\Config\Model\Config\Backend\Encrypted payment/adyen_hpp/hmac_live - + Magento\Config\Block\System\Config\Form\Fieldset @@ -85,7 +85,7 @@ payment/adyen_hpp/ratepay_id - + Magento\Config\Block\System\Config\Form\Fieldset @@ -122,7 +122,7 @@ payment/adyen_hpp/country_code - + Magento\Config\Block\System\Config\Form\Fieldset diff --git a/etc/adminhtml/system/adyen_pos.xml b/etc/adminhtml/system/adyen_pos.xml index 3fa112a9b..ab1b3d3a4 100755 --- a/etc/adminhtml/system/adyen_pos.xml +++ b/etc/adminhtml/system/adyen_pos.xml @@ -48,7 +48,7 @@ Adyen\Payment\Model\Config\Source\RecurringType payment/adyen_pos/recurring_type - + Magento\Config\Block\System\Config\Form\Fieldset diff --git a/etc/config.xml b/etc/config.xml index eb3d8834c..4ad6620dc 100755 --- a/etc/config.xml +++ b/etc/config.xml @@ -35,6 +35,7 @@ title_image sale 1 + checkout/cart adyen diff --git a/etc/module.xml b/etc/module.xml index fe82b29da..8a64d1837 100755 --- a/etc/module.xml +++ b/etc/module.xml @@ -24,7 +24,7 @@ --> - + diff --git a/i18n/en_US.csv b/i18n/en_US.csv index 8b1caf63b..8efc49472 100644 --- a/i18n/en_US.csv +++ b/i18n/en_US.csv @@ -11,7 +11,7 @@ "Select your Bank","Select your Bank" "You will be redirected to the Adyen website.","You will be redirected to the Adyen website." "Update","Update" -"Place order","Place order" +"Place Order","Place Order" "Continue to Adyen","Continue to Adyen" "Unknown","Unknown" "Mismatch between Live/Test modes of Magento store and the Adyen platform","Mismatch between Live/Test modes of Magento store and the Adyen platform" diff --git a/i18n/nl_NL.csv b/i18n/nl_NL.csv new file mode 100644 index 000000000..3b4c88fdb --- /dev/null +++ b/i18n/nl_NL.csv @@ -0,0 +1,54 @@ +"Name on Card","Naam op kaart" +"Credit Card Information","Creditcard gegevens" +"Credit Card Type","Creditcard type" +"Credit Card Number","Creditcard Number" +"Credit Card Owner","Creditcardnummer" +"Expiration Date","Verloopdatum" +"Card Verification Number","Creditcard Verificatie Nummer" +"--Please Select--","--Selecteer--" +"What is this?","Wat is dit?" +"Remember these details","Onthoud deze details" +"Select Your Bank","Selecteer uw bank" +"You will be redirected to the Adyen website.","U wordt doorverwezen naar de Adyen-website." +"Update","Bijwerken" +"Place Order","Plaats bestelling" +"Continue to Adyen","Doorgaan naar Adyen" +"Unknown","Onbekend" +"Mismatch between Live/Test modes of Magento store and the Adyen platform","Niet-overeenstemming tussen Live / Test-modi van Magento-winkel en het Adyen-platform" +"You have cancelled the order. Please try again","U hebt de bestelling geannuleerd Probeer het opnieuw" +"Your payment failed, Please try again later","Uw betaling is mislukt. Probeer het later opnieuw" +"Response is empty, please check your webserver that the result url accepts parameters","Reactie is leeg, controleer uw webserver dat de resultaat-URL parameters accepteert" +"ResultUrl authentification failure","ResultUrl authenticatie fout " +"Order does not exists with increment_id: %1","Bestelling bestaat niet met increment_id: %1" +"Empty merchantReference","Lege verkoperReferentie" +"3D-secure validation was successful","3D-beveiligde validatie was succesvol" +"3D-secure validation was unsuccessful.","3D-beveiligde validatie was niet succesvol." +"Customer was redirected to bank for 3D-secure validation.","Klant is doorgestuurd naar bank voor 3D-beveiligde validatie." +"Used existing billing agreement #%s.","Gebruikte bestaande factureringsovereenkomst #%s." +"Created billing agreement #%1.","Factureringsovereenkomst gemaakt #%1." +"Failed to create billing agreement for this order.","Kan geen factuurovereenkomst voor deze bestelling maken." +"Failed to create billing agreement for this order (listRecurringCall did not contain contract)","Kan geen factuurovereenkomst voor deze bestelling maken (listRecurringCall bevat geen contract)" +"Adyen Refund Successfully completed","Adyen Refund succesvol afgerond" +"Payment is pre authorised waiting for capture","De betaling wordt vooraf geautoriseerd om te wachten op opname" +"Capture Mode set to Manual","Capture Mode ingesteld op Manual" +"Adyen Payment is in Manual Review check the Adyen platform","Adyen Payment is in Manual Review, controleer het Adyen-platform" +"Adyen Payment Successfully completed","Adyen-betaling succesvol afgerond" +"Shipment created by Adyen","Verzending gemaakt door Adyen" +"3D secure failed","3D-beveiligd is mislukt" +"The capture action failed","De opnameactie is mislukt" +"The refund action failed","De actie voor teruggave is mislukt" +"Failed to disable this contract","Kan dit contract niet uitschakelen" +"Card encryption failed","Kaartversleuteling mislukt" +"The authorize action is not available.","De autorisatie-actie is niet beschikbaar." +"Empty result.","Leeg resultaat." +"3D secure is not valid","3D Secure is niet geldig" +"The transaction is not permitted.","De transactie is niet toegestaan." +"Declined due to the Card Security Code(CVC) being incorrect. Please check your CVC code!","Afgewezen vanwege de Card Security Code(CVC) onjuist zijn. Controleer alstublieft uw CVC code!" +"The card is restricted.","De kaart is beperkt." +"The payment is REFUSED because the saved card is removed. Please try an other payment method.","De betaling wordt GEWEIGERD omdat de opgeslagen kaart is verwijderd. Probeer een andere betaalmethode." +"The expiry month is not set. Please check your expiry month!","De vervalmaand is niet ingesteld. Controleer alstublieft uw verloopmaand!" +"The payment is REFUSED","De betaling is GEWEIGERD" +"Failed to disable this contract","Kan dit contract niet uitschakelen" +"You will be redirected to the Adyen App", "U wordt doorgestuurd naar de Adyen-app" +"Continue to Adyen App", "Doorgaan naar Adyen-app" +"Do not use Installments", "Gebruik geen wederkerende betalingen" diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index 2279deb18..000000000 --- a/phpunit.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - tests - - - diff --git a/tests/Helper/DataTest.php b/tests/Helper/DataTest.php deleted file mode 100755 index 4daaa0fdf..000000000 --- a/tests/Helper/DataTest.php +++ /dev/null @@ -1,62 +0,0 @@ - - */ - -namespace Adyen\Payment\Tests\Helper; - -use Adyen\Payment\Helper\Data; -use PHPUnit\Framework\TestCase; - -class DataTest extends TestCase -{ - private $dataHelper; - - private function getSimpleMock($originalClassName) - { - return $this->getMockBuilder($originalClassName) - ->disableOriginalConstructor() - ->getMock(); - } - - public function setUp() - { - $context = $this->getSimpleMock('\Magento\Framework\App\Helper\Context'); - $encryptor = $this->getSimpleMock('\Magento\Framework\Encryption\EncryptorInterface'); - $dataStorage = $this->getSimpleMock('\Magento\Framework\Config\DataInterface'); - $country = $this->getSimpleMock('\Magento\Directory\Model\Config\Source\Country'); - $moduleList = $this->getSimpleMock('\Magento\Framework\Module\ModuleListInterface'); - $billingAgreementCollectionFactory = $this->getSimpleMock('\Adyen\Payment\Model\Resource\Billing\Agreement\CollectionFactory'); - $assetRepo = $this->getSimpleMock('\Magento\Framework\View\Asset\Repository'); - $assetSource = $this->getSimpleMock('\Magento\Framework\View\Asset\Source'); - $notificationFactory = $this->getSimpleMock('\Adyen\Payment\Model\Resource\Notification\CollectionFactory'); - - $this->dataHelper = new Data($context, $encryptor, $dataStorage, $country, $moduleList, - $billingAgreementCollectionFactory, $assetRepo, $assetSource, $notificationFactory); - } - - public function testFormatAmount() - { - $this->assertEquals("1234", $this->dataHelper->formatAmount("12.34", "EUR")); - $this->assertEquals("1200", $this->dataHelper->formatAmount("12.00", "USD")); - $this->assertEquals("12", $this->dataHelper->formatAmount("12.00", "JPY")); - } -} diff --git a/view/adminhtml/layout/sales_order_view.xml b/view/adminhtml/layout/sales_order_view.xml new file mode 100644 index 000000000..415cdd952 --- /dev/null +++ b/view/adminhtml/layout/sales_order_view.xml @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/view/adminhtml/templates/info/adyen_paymentlink.phtml b/view/adminhtml/templates/info/adyen_paymentlink.phtml new file mode 100644 index 000000000..d62cae6e1 --- /dev/null +++ b/view/adminhtml/templates/info/adyen_paymentlink.phtml @@ -0,0 +1,44 @@ + + */ + +/** @var \Adyen\Payment\Block\Info\PaymentLink $block */ +?> +
+
+ +
+ + + + + + diff --git a/view/base/web/images/logos/wechatpay.png b/view/base/web/images/logos/wechatpay.png new file mode 100644 index 000000000..9452654eb Binary files /dev/null and b/view/base/web/images/logos/wechatpay.png differ diff --git a/view/base/web/images/logos/wechatpay_small.png b/view/base/web/images/logos/wechatpay_small.png new file mode 100644 index 000000000..43bfe5ad3 Binary files /dev/null and b/view/base/web/images/logos/wechatpay_small.png differ diff --git a/view/base/web/images/logos/wechatpay_tiny.png b/view/base/web/images/logos/wechatpay_tiny.png new file mode 100644 index 000000000..59f4b331c Binary files /dev/null and b/view/base/web/images/logos/wechatpay_tiny.png differ diff --git a/view/frontend/layout/checkout_index_index.xml b/view/frontend/layout/checkout_index_index.xml index 1d66a29ef..23b448d8d 100755 --- a/view/frontend/layout/checkout_index_index.xml +++ b/view/frontend/layout/checkout_index_index.xml @@ -61,6 +61,9 @@ true + + true + true diff --git a/view/frontend/web/css/styles.css b/view/frontend/web/css/styles.css index c0fe77c39..971e416d1 100644 --- a/view/frontend/web/css/styles.css +++ b/view/frontend/web/css/styles.css @@ -61,6 +61,10 @@ background-position: 0 -272px; } +.checkout-payment-method .payment-method-title label div.adyen-sprite.adyen_boleto { + background-position: 0 -2092px; +} + .checkout-payment-method .payment-method-title label div.adyen-sprite.adyen_apple_pay { background:url(../images/logos/apple_pay.png) no-repeat; height:43px; diff --git a/view/frontend/web/js/action/place-order.js b/view/frontend/web/js/action/place-order.js deleted file mode 100755 index 737a649fe..000000000 --- a/view/frontend/web/js/action/place-order.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * ###### - * ###### - * ############ ####( ###### #####. ###### ############ ############ - * ############# #####( ###### #####. ###### ############# ############# - * ###### #####( ###### #####. ###### ##### ###### ##### ###### - * ###### ###### #####( ###### #####. ###### ##### ##### ##### ###### - * ###### ###### #####( ###### #####. ###### ##### ##### ###### - * ############# ############# ############# ############# ##### ###### - * ############ ############ ############# ############ ##### ###### - * ###### - * ############# - * ############ - * - * Adyen Payment module (https://www.adyen.com/) - * - * Copyright (c) 2015 Adyen BV (https://www.adyen.com/) - * See LICENSE.txt for license details. - * - * Author: Adyen - */ -define( - [ - 'Magento_Checkout/js/model/quote', - 'Magento_Checkout/js/model/url-builder', - 'mage/storage', - 'mage/url', - 'Magento_Checkout/js/model/error-processor', - 'Magento_Customer/js/model/customer', - 'Magento_Checkout/js/model/full-screen-loader' - ], - function (quote, urlBuilder, storage, url, errorProcessor, customer, fullScreenLoader) { - 'use strict'; - - return function (paymentData, redirectOnSuccess) { - var serviceUrl, - payload; - //redirectOnSuccess = redirectOnSuccess !== false; - redirectOnSuccess = redirectOnSuccess === false ? false : true; - - /** Checkout for guest and registered customer. */ - if (!customer.isLoggedIn()) { - serviceUrl = urlBuilder.createUrl('/guest-carts/:quoteId/payment-information', { - quoteId: quote.getQuoteId() - }); - payload = { - cartId: quote.getQuoteId(), - email: quote.guestEmail, - paymentMethod: paymentData, - billingAddress: quote.billingAddress() - }; - } else { - serviceUrl = urlBuilder.createUrl('/carts/mine/payment-information', {}); - payload = { - cartId: quote.getQuoteId(), - paymentMethod: paymentData, - billingAddress: quote.billingAddress() - }; - } - - fullScreenLoader.startLoader(); - return storage.post( - serviceUrl, JSON.stringify(payload) - ).done( - function (response) { - if (redirectOnSuccess) { - window.location.replace(url.build(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl)); - } else{ - fullScreenLoader.stopLoader(); - } - } - ).fail( - function (response) { - errorProcessor.process(response); - fullScreenLoader.stopLoader(); - } - ); - }; - } -); diff --git a/view/frontend/web/js/action/set-payment-method.js b/view/frontend/web/js/action/set-payment-method.js deleted file mode 100755 index 78bcfa45d..000000000 --- a/view/frontend/web/js/action/set-payment-method.js +++ /dev/null @@ -1,82 +0,0 @@ -/** - * ###### - * ###### - * ############ ####( ###### #####. ###### ############ ############ - * ############# #####( ###### #####. ###### ############# ############# - * ###### #####( ###### #####. ###### ##### ###### ##### ###### - * ###### ###### #####( ###### #####. ###### ##### ##### ##### ###### - * ###### ###### #####( ###### #####. ###### ##### ##### ###### - * ############# ############# ############# ############# ##### ###### - * ############ ############ ############# ############ ##### ###### - * ###### - * ############# - * ############ - * - * Adyen Payment module (https://www.adyen.com/) - * - * Copyright (c) 2015 Adyen BV (https://www.adyen.com/) - * See LICENSE.txt for license details. - * - * Author: Adyen - */ -define( - [ - 'jquery', - 'Magento_Checkout/js/model/quote', - 'Magento_Checkout/js/model/url-builder', - 'mage/storage', - 'Magento_Checkout/js/model/error-processor', - 'Magento_Customer/js/model/customer', - 'Magento_Checkout/js/model/full-screen-loader', - 'Magento_CheckoutAgreements/js/model/agreements-assigner' - ], - function ($, quote, urlBuilder, storage, errorProcessor, customer, fullScreenLoader, agreementsAssigner) { - 'use strict'; - - return function () { - - var serviceUrl, - payload, - paymentData = quote.paymentMethod(); - - // use core code to assign the agreement - agreementsAssigner(paymentData); - - /** Checkout for guest and registered customer. */ - if (!customer.isLoggedIn()) { - serviceUrl = urlBuilder.createUrl('/guest-carts/:quoteId/payment-information', { - quoteId: quote.getQuoteId() - }); - payload = { - cartId: quote.getQuoteId(), - email: quote.guestEmail, - paymentMethod: paymentData, - billingAddress: quote.billingAddress() - }; - } else { - serviceUrl = urlBuilder.createUrl('/carts/mine/payment-information', {}); - payload = { - cartId: quote.getQuoteId(), - paymentMethod: paymentData, - billingAddress: quote.billingAddress() - }; - } - - - fullScreenLoader.startLoader(); - - return storage.post( - serviceUrl, JSON.stringify(payload) - ).done( - function () { - $.mage.redirect(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl); - } - ).fail( - function (response) { - errorProcessor.process(response); - fullScreenLoader.stopLoader(); - } - ); - }; - } -); diff --git a/view/frontend/web/js/view/payment/method-renderer/adyen-boleto-method.js b/view/frontend/web/js/view/payment/method-renderer/adyen-boleto-method.js index 4071165d3..d6016e803 100644 --- a/view/frontend/web/js/view/payment/method-renderer/adyen-boleto-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/adyen-boleto-method.js @@ -19,19 +19,14 @@ * * Author: Adyen */ -/*browser:true*/ -/*global define*/ define( [ 'underscore', 'jquery', 'Magento_Checkout/js/model/quote', - 'Magento_Payment/js/view/payment/cc-form', - 'Adyen_Payment/js/action/place-order', - 'mage/translate', - 'Magento_Checkout/js/model/payment/additional-validators' + 'Magento_Payment/js/view/payment/cc-form' ], - function (_, $, quote, Component, placeOrderAction, $t, additionalValidators) { + function (_, $, quote, Component) { 'use strict'; var billingAddress = quote.billingAddress(); return Component.extend({ @@ -51,16 +46,16 @@ define( ]); return this; }, - setPlaceOrderHandler: function(handler) { + setPlaceOrderHandler: function (handler) { this.placeOrderHandler = handler; }, - setValidateHandler: function(handler) { + setValidateHandler: function (handler) { this.validateHandler = handler; }, - getCode: function() { + getCode: function () { return 'adyen_boleto'; }, - getData: function() { + getData: function () { return { 'method': this.item.method, 'additional_data': { @@ -71,56 +66,34 @@ define( } }; }, - isActive: function() { + isActive: function () { return true; }, - /** - * @override - */ - placeOrder: function(data, event) { - var self = this, - placeOrder; - - if (event) { - event.preventDefault(); - } - - if (this.validate() && additionalValidators.validate()) { - this.isPlaceOrderActionAllowed(false); - placeOrder = placeOrderAction(this.getData(), this.redirectAfterPlaceOrder); - - $.when(placeOrder).fail(function(response) { - self.isPlaceOrderActionAllowed(true); - }); - return true; - } - return false; - }, - getControllerName: function() { + getControllerName: function () { return window.checkoutConfig.payment.iframe.controllerName[this.getCode()]; }, - getPlaceOrderUrl: function() { + getPlaceOrderUrl: function () { return window.checkoutConfig.payment.iframe.placeOrderUrl[this.getCode()]; }, - context: function() { + context: function () { return this; }, validate: function () { var form = 'form[data-role=adyen-boleto-form]'; - var validate = $(form).validation() && $(form).validation('isValid'); + var validate = $(form).validation() && $(form).validation('isValid'); - if(!validate) { + if (!validate) { return false; } return true; }, - showLogo: function() { + showLogo: function () { return window.checkoutConfig.payment.adyen.showLogo; }, - getBoletoTypes: function() { - return _.map(window.checkoutConfig.payment.adyenBoleto.boletoTypes, function(value, key) { + getBoletoTypes: function () { + return _.map(window.checkoutConfig.payment.adyenBoleto.boletoTypes, function (value, key) { return { 'key': value.value, 'value': value.label diff --git a/view/frontend/web/js/view/payment/method-renderer/adyen-cc-method.js b/view/frontend/web/js/view/payment/method-renderer/adyen-cc-method.js index 32c821484..817a9f886 100755 --- a/view/frontend/web/js/view/payment/method-renderer/adyen-cc-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/adyen-cc-method.js @@ -19,23 +19,19 @@ * * Author: Adyen */ -/*browser:true*/ -/*global define*/ define( [ - 'underscore', 'jquery', + 'ko', 'Magento_Payment/js/view/payment/cc-form', - 'Adyen_Payment/js/action/place-order', - 'mage/translate', - 'Magento_Checkout/js/model/payment/additional-validators', 'Magento_Customer/js/model/customer', 'Magento_Payment/js/model/credit-card-validation/credit-card-data', + 'Magento_Checkout/js/model/payment/additional-validators', 'Magento_Checkout/js/model/quote', - 'ko', 'Adyen_Payment/js/model/installments', + 'mage/url' ], - function (_, $, Component, placeOrderAction, $t, additionalValidators, customer, creditCardData, quote, ko, installments) { + function ($, ko, Component, customer, creditCardData, additionalValidators, quote, installments, url) { 'use strict'; var cvcLength = ko.observable(4); @@ -156,43 +152,63 @@ define( isActive: function () { return true; }, + + /** + * Returns state of place order button + * @returns {boolean} + */ + isButtonActive: function() { + return this.isActive() && this.getCode() == this.isChecked() && this.isPlaceOrderActionAllowed(); + }, + /** * @override */ placeOrder: function (data, event) { - var self = this, - placeOrder; + var self = this; if (event) { event.preventDefault(); } - var options = {}; var cseInstance = adyen.createEncryption(options); - var generationtime = self.getGenerationTime(); + var generationtime = this.getGenerationTime(); var cardData = { - number: self.creditCardNumber(), - cvc: self.creditCardVerificationNumber(), - holderName: self.creditCardOwner(), - expiryMonth: self.creditCardExpMonth(), - expiryYear: self.creditCardExpYear(), + number: this.creditCardNumber(), + cvc: this.creditCardVerificationNumber(), + holderName: this.creditCardOwner(), + expiryMonth: this.creditCardExpMonth(), + expiryYear: this.creditCardExpYear(), generationtime: generationtime }; var data = cseInstance.encrypt(cardData); - self.encryptedData(data); + this.encryptedData(data); if (this.validate() && additionalValidators.validate()) { this.isPlaceOrderActionAllowed(false); - placeOrder = placeOrderAction(this.getData(), this.redirectAfterPlaceOrder); - $.when(placeOrder).fail(function (response) { - self.isPlaceOrderActionAllowed(true); - }); + this.getPlaceOrderDeferredObject() + .fail( + function () { + self.isPlaceOrderActionAllowed(true); + } + ).done( + function () { + self.afterPlaceOrder(); + + if (self.redirectAfterPlaceOrder) { + // use custom redirect Link for supporting 3D secure + window.location.replace(url.build(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl)); + } + } + ); + return true; } + return false; }, getControllerName: function () { diff --git a/view/frontend/web/js/view/payment/method-renderer/adyen-hpp-method.js b/view/frontend/web/js/view/payment/method-renderer/adyen-hpp-method.js index 33f96ff9e..56cd6a224 100755 --- a/view/frontend/web/js/view/payment/method-renderer/adyen-hpp-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/adyen-hpp-method.js @@ -19,14 +19,11 @@ * * Author: Adyen */ -/*browser:true*/ -/*global define*/ define( [ 'ko', 'jquery', 'Magento_Checkout/js/view/payment/default', - 'Adyen_Payment/js/action/set-payment-method', 'Magento_Checkout/js/action/select-payment-method', 'Magento_Checkout/js/model/quote', 'Magento_Checkout/js/checkout-data', @@ -35,14 +32,17 @@ define( 'Magento_Checkout/js/model/url-builder', 'Adyen_Payment/js/model/adyen-payment-service', 'Magento_Customer/js/model/customer', - 'Magento_Checkout/js/model/full-screen-loader' + 'Magento_Checkout/js/model/full-screen-loader', + 'Magento_Checkout/js/action/place-order', + 'uiLayout', + 'Magento_Ui/js/model/messages' ], - function (ko, $, Component, setPaymentMethodAction, selectPaymentMethodAction, quote, checkoutData, additionalValidators, storage, urlBuilder, adyenPaymentService, customer, fullScreenLoader) { + function (ko, $, Component, selectPaymentMethodAction, quote, checkoutData, additionalValidators, storage, urlBuilder, adyenPaymentService, customer, fullScreenLoader, placeOrderAction, layout, Messages) { 'use strict'; var brandCode = ko.observable(null); var paymentMethod = ko.observable(null); var dfValue = ko.observable(null); - + var messageComponents; return Component.extend({ self: this, defaults: { @@ -128,6 +128,27 @@ define( document.body.appendChild(dfScriptTag); waitForDfSet(); + // create component needs to be in initialize method + var messageComponents = {}; + _.map(response, function (value) { + + var messageContainer = new Messages(); + var name = 'messages-' + value.brandCode; + var messagesComponent = { + parent: self.name, + name: 'messages-' + value.brandCode, + displayArea: 'messages-' + value.brandCode, + component: 'Magento_Ui/js/view/messages', + config: { + messageContainer: messageContainer + } + }; + layout([messagesComponent]); + + messageComponents[name] = messageContainer; + }); + self.messageComponents = messageComponents; + fullScreenLoader.stopLoader(); } ).fail(function (error) { @@ -150,6 +171,15 @@ define( result.validate = function () { return self.validate(value.brandCode); }; + result.placeRedirectOrder = function placeRedirectOrder(data) { + return self.placeRedirectOrder(data); + }; + result.isPlaceOrderActionAllowed = function(bool) { + return self.isPlaceOrderActionAllowed(bool); + }; + result.afterPlaceOrder = function() { + return self.afterPlaceOrder(); + }; result.isPaymentMethodOpenInvoiceMethod = function () { return value.isPaymentMethodOpenInvoiceMethod; }; @@ -212,10 +242,12 @@ define( }, /** Redirect to adyen */ continueToAdyen: function () { + var self = this; + if (this.validate() && additionalValidators.validate()) { - //update payment method information if additional data was changed - this.selectPaymentMethod(); - setPaymentMethodAction(); + var data = {}; + data.method = self.method; + this.placeRedirectOrder(data); return false; } }, @@ -246,9 +278,7 @@ define( } data.additional_data = additionalData; - - selectPaymentMethodAction(data); - setPaymentMethodAction(); + this.placeRedirectOrder(data); } return false; @@ -276,6 +306,32 @@ define( return true; }, + placeRedirectOrder: function(data) { + // Place Order but use our own redirect url after + var self = this; + + var messageContainer = this.messageContainer; + if(brandCode()) { + messageContainer = self.messageComponents['messages-' + brandCode()]; + } + + this.isPlaceOrderActionAllowed(false); + fullScreenLoader.startLoader(); + $.when( + placeOrderAction(data, messageContainer) + ).fail( + function () { + self.isPlaceOrderActionAllowed(true); + } + ).done( + function () { + self.afterPlaceOrder(); + $.mage.redirect( + window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl + ); + } + ) + }, isBrandCodeChecked: ko.computed(function () { if (!quote.paymentMethod()) { diff --git a/view/frontend/web/js/view/payment/method-renderer/adyen-oneclick-method.js b/view/frontend/web/js/view/payment/method-renderer/adyen-oneclick-method.js index f1633201d..60ff51163 100755 --- a/view/frontend/web/js/view/payment/method-renderer/adyen-oneclick-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/adyen-oneclick-method.js @@ -19,31 +19,38 @@ * * Author: Adyen */ -/*browser:true*/ -/*global define*/ define( [ 'ko', 'underscore', 'jquery', 'Magento_Payment/js/view/payment/cc-form', - 'Adyen_Payment/js/action/place-order', - 'mage/translate', - 'Magento_Checkout/js/model/payment/additional-validators', 'Magento_Checkout/js/action/select-payment-method', + 'Magento_Checkout/js/model/payment/additional-validators', 'Magento_Checkout/js/model/quote', - 'Magento_Checkout/js/checkout-data' + 'Magento_Checkout/js/checkout-data', + 'Magento_Checkout/js/action/redirect-on-success', + 'uiLayout', + 'Magento_Ui/js/model/messages', + 'Magento_Checkout/js/action/place-order', + 'mage/url' ], - function (ko, _, $, Component, placeOrderAction, $t, additionalValidators, selectPaymentMethodAction, quote, checkoutData) { + function (ko, _, $, Component, selectPaymentMethodAction, additionalValidators, quote, checkoutData, redirectOnSuccessAction, layout, Messages, placeOrderAction, url) { 'use strict'; var updatedExpiryDate = false; var recurringDetailReference = ko.observable(null); + var variant = ko.observable(null); var paymentMethod = ko.observable(null); + var encryptedData = ko.observable(null); + var numberOfInstallments = ko.observable(null); + var messageComponents; return Component.extend({ defaults: { template: 'Adyen_Payment/payment/oneclick-form', recurringDetailReference: '', - encryptedData: '' + encryptedData: '', + variant: '', + numberOfInstallments: '' }, initObservable: function () { this._super() @@ -51,13 +58,37 @@ define( 'recurringDetailReference', 'creditCardType', 'creditCardVerificationNumber', - 'encryptedData' + 'encryptedData', + 'variant', + 'numberOfInstallments' ]); return this; }, initialize: function () { var self = this; this._super(); + + // create component needs to be in initialize method + var messageComponents = {}; + _.map(window.checkoutConfig.payment.adyenOneclick.billingAgreements, function (value) { + + var messageContainer = new Messages(); + var name = 'messages-' + value.reference_id; + var messagesComponent = { + parent: self.name, + name: 'messages-' + value.reference_id, + // name: self.name + '.messages', + displayArea: 'messages-' + value.reference_id, + component: 'Magento_Ui/js/view/messages', + config: { + messageContainer: messageContainer + } + }; + layout([messagesComponent]); + + messageComponents[name] = messageContainer; + }); + this.messageComponents = messageComponents; }, placeOrderHandler: null, validateHandler: null, @@ -73,63 +104,6 @@ define( isActive: function () { return true; }, - /** - * @override - */ - placeOrder: function (data, event) { - var self = this, - placeOrder; - - if (event) { - event.preventDefault(); - } - - var data = { - "method": self.method, - "additional_data": { - variant: self.agreement_data.variant, - recurring_detail_reference: self.value - } - } - - // only use CSE and installments for cards - if (self.agreement_data.card) { - - var generationtime = self.getGenerationTime(); - - var cardData = { - cvc: self.creditCardVerificationNumber, - expiryMonth: self.creditCardExpMonth(), - expiryYear: self.creditCardExpYear(), - generationtime: generationtime - }; - - if (updatedExpiryDate || self.hasVerification()) { - - var options = {enableValidations: false}; - - var cseInstance = adyen.createEncryption(options); - - var encryptedData = cseInstance.encrypt(cardData); - data.additional_data.encrypted_data = encryptedData; - } - - - // set payment method to adyen_hpp - data.additional_data.number_of_installments = self.installment; - } - - if (this.validate() && additionalValidators.validate()) { - //this.isPlaceOrderActionAllowed(false); - placeOrder = placeOrderAction(data, this.redirectAfterPlaceOrder); - - $.when(placeOrder).fail(function (response) { - //self.isPlaceOrderActionAllowed(true); - }); - return true; - } - return false; - }, getControllerName: function () { return window.checkoutConfig.payment.iframe.controllerName[this.getCode()]; }, @@ -172,6 +146,8 @@ define( } } + var messageContainer = self.messageComponents['messages-' + value.reference_id]; + return { 'expiry': ko.observable(false), 'label': value.agreement_label, @@ -195,6 +171,91 @@ define( hasVerification: function () { return window.checkoutConfig.payment.adyenOneclick.hasCustomerInteraction; }, + /** + * @override + */ + placeOrder: function (data, event) { + var self = this; + + if (event) { + event.preventDefault(); + } + + var data = { + "method": self.method, + "additional_data": { + variant: self.agreement_data.variant, + recurring_detail_reference: self.value + } + } + + // only use CSE and installments for cards + if (self.agreement_data.card) { + + var generationtime = self.getGenerationTime(); + + var cardData = { + cvc: self.creditCardVerificationNumber, + expiryMonth: self.creditCardExpMonth(), + expiryYear: self.creditCardExpYear(), + generationtime: generationtime + }; + + if (updatedExpiryDate || self.hasVerification()) { + + var options = {enableValidations: false}; + var cseInstance = adyen.createEncryption(options); + var encryptedDataResult = cseInstance.encrypt(cardData); + encryptedData(encryptedDataResult) + } + + // set payment method to adyen_hpp + // TODO can observer in front-end this not needed + numberOfInstallments(self.installment); + } + + // in different context so need custom place order logic + if (this.validate() && additionalValidators.validate()) { + self.isPlaceOrderActionAllowed(false); + + this.getPlaceOrderDeferredObject() + .fail( + function () { + self.isPlaceOrderActionAllowed(true); + } + ).done( + function () { + self.afterPlaceOrder(); + // use custom redirect Link for supporting 3D secure + window.location.replace(url.build(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl)); + } + ); + return true; + } + return false; + }, + getData: function () { + return { + "method": self.item.method, + "additional_data": { + variant: variant(), + recurring_detail_reference: recurringDetailReference(), + number_of_installments: numberOfInstallments(), + encrypted_data: encryptedData() + } + }; + }, + isPlaceOrderActionAllowed: function () { + return self.isPlaceOrderActionAllowed(); // needed for placeOrder method + }, + afterPlaceOrder: function () { + return self.afterPlaceOrder(); // needed for placeOrder method + }, + getPlaceOrderDeferredObject: function () { + return $.when( + placeOrderAction(this.getData(), this.getMessageContainer()) + ); + }, validate: function () { var code = self.item.method; @@ -233,7 +294,13 @@ define( var self = this; self.expiry(true); return true; - } + }, + getMessageName: function () { + return 'messages-' + value.reference_id; + }, + getMessageContainer: function () { + return messageContainer; + }, } }); return paymentList; @@ -254,6 +321,7 @@ define( // set the brandCode recurringDetailReference(self.value); + variant(self.agreement_data.variant); // set payment method paymentMethod(self.method); diff --git a/view/frontend/web/js/view/payment/method-renderer/adyen-pos-method.js b/view/frontend/web/js/view/payment/method-renderer/adyen-pos-method.js index 757b306f8..933e35d3c 100755 --- a/view/frontend/web/js/view/payment/method-renderer/adyen-pos-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/adyen-pos-method.js @@ -19,42 +19,53 @@ * * Author: Adyen */ -/*browser:true*/ -/*global define*/ define( [ - 'ko', + 'jquery', 'Magento_Checkout/js/view/payment/default', - 'Adyen_Payment/js/action/set-payment-method', - 'Magento_Checkout/js/model/payment/additional-validators' + 'Magento_Checkout/js/model/payment/additional-validators', + 'Magento_Checkout/js/model/full-screen-loader', + 'Magento_Checkout/js/action/place-order', + 'Magento_Checkout/js/model/quote' ], - function (ko, Component, setPaymentMethodAction, additionalValidators) { + function ($, Component, additionalValidators, fullScreenLoader, placeOrderAction, quote) { 'use strict'; - var brandCode = ko.observable(null); - var paymentMethod = ko.observable(null); - return Component.extend({ - self: this, defaults: { - template: 'Adyen_Payment/payment/pos-form', - brandCode: '' + template: 'Adyen_Payment/payment/pos-form' }, initObservable: function () { this._super() - .observe([ - ]); + .observe([]); return this; }, /** Redirect to adyen */ continueToAdyen: function () { + var self = this; + if (this.validate() && additionalValidators.validate()) { //update payment method information if additional data was changed - this.selectPaymentMethod(); - setPaymentMethodAction(); - return false; + this.isPlaceOrderActionAllowed(false); + fullScreenLoader.startLoader(); + + $.when( + placeOrderAction(this.getData(), this.messageContainer) + ).fail( + function () { + self.isPlaceOrderActionAllowed(true); + } + ).done( + function () { + self.afterPlaceOrder(); + $.mage.redirect( + window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl + ); + } + ); } + return false; }, - showLogo: function() { + showLogo: function () { return window.checkoutConfig.payment.adyen.showLogo; }, validate: function () { diff --git a/view/frontend/web/js/view/payment/method-renderer/adyen-sepa-method.js b/view/frontend/web/js/view/payment/method-renderer/adyen-sepa-method.js index 143dced92..2d01a84e6 100644 --- a/view/frontend/web/js/view/payment/method-renderer/adyen-sepa-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/adyen-sepa-method.js @@ -19,19 +19,14 @@ * * Author: Adyen */ -/*browser:true*/ -/*global define*/ define( [ 'underscore', 'jquery', 'Magento_Checkout/js/model/quote', - 'Magento_Payment/js/view/payment/cc-form', - 'Adyen_Payment/js/action/place-order', - 'mage/translate', - 'Magento_Checkout/js/model/payment/additional-validators' + 'Magento_Payment/js/view/payment/cc-form' ], - function (_, $, quote, Component, placeOrderAction, $t, additionalValidators) { + function (_, $, quote, Component) { 'use strict'; var billingAddress = quote.billingAddress(); return Component.extend({ @@ -56,16 +51,16 @@ define( isShowLegend: function () { return true; }, - setPlaceOrderHandler: function(handler) { + setPlaceOrderHandler: function (handler) { this.placeOrderHandler = handler; }, - setValidateHandler: function(handler) { + setValidateHandler: function (handler) { this.validateHandler = handler; }, - getCode: function() { + getCode: function () { return 'adyen_sepa'; }, - getData: function() { + getData: function () { return { 'method': this.item.method, 'additional_data': { @@ -76,56 +71,34 @@ define( } }; }, - isActive: function() { + isActive: function () { return true; }, - /** - * @override - */ - placeOrder: function(data, event) { - var self = this, - placeOrder; - - if (event) { - event.preventDefault(); - } - - if (this.validate() && additionalValidators.validate()) { - this.isPlaceOrderActionAllowed(false); - placeOrder = placeOrderAction(this.getData(), this.redirectAfterPlaceOrder); - - $.when(placeOrder).fail(function(response) { - self.isPlaceOrderActionAllowed(true); - }); - return true; - } - return false; - }, - getControllerName: function() { + getControllerName: function () { return window.checkoutConfig.payment.iframe.controllerName[this.getCode()]; }, - getPlaceOrderUrl: function() { + getPlaceOrderUrl: function () { return window.checkoutConfig.payment.iframe.placeOrderUrl[this.getCode()]; }, - context: function() { + context: function () { return this; }, validate: function () { var form = 'form[data-role=adyen-sepa-form]'; - var validate = $(form).validation() && $(form).validation('isValid'); + var validate = $(form).validation() && $(form).validation('isValid'); - if(!validate) { + if (!validate) { return false; } return true; }, - showLogo: function() { + showLogo: function () { return window.checkoutConfig.payment.adyen.showLogo; }, - getCountries: function() { - return _.map(window.checkoutConfig.payment.adyenSepa.countries, function(value, key) { + getCountries: function () { + return _.map(window.checkoutConfig.payment.adyenSepa.countries, function (value, key) { return { 'key': key, 'value': value diff --git a/view/frontend/web/template/payment/boleto-form.html b/view/frontend/web/template/payment/boleto-form.html index 8b52491b7..126960bbb 100755 --- a/view/frontend/web/template/payment/boleto-form.html +++ b/view/frontend/web/template/payment/boleto-form.html @@ -55,6 +55,10 @@ 'orderSaveUrl':getPlaceOrderUrl(), }, 'validation':[]}"> + + + +
@@ -80,6 +84,8 @@ + +
- +
+
@@ -53,6 +54,11 @@ }, 'validation':[]}"> + + + + +
@@ -268,16 +274,15 @@
+ +
diff --git a/view/frontend/web/template/payment/hpp-form.html b/view/frontend/web/template/payment/hpp-form.html index be9211fe0..717bfe915 100755 --- a/view/frontend/web/template/payment/hpp-form.html +++ b/view/frontend/web/template/payment/hpp-form.html @@ -97,13 +97,17 @@
@@ -170,7 +174,7 @@ type="submit" data-bind="click: $parent.continueToAdyenBrandCode, enable: (value == $parent.isBrandCodeChecked())" disabled> - +
diff --git a/view/frontend/web/template/payment/oneclick-form.html b/view/frontend/web/template/payment/oneclick-form.html index 25962f6c1..2f8b5d1fd 100755 --- a/view/frontend/web/template/payment/oneclick-form.html +++ b/view/frontend/web/template/payment/oneclick-form.html @@ -23,9 +23,11 @@ --> - +
+ +
+ + + +
+ +
@@ -235,7 +240,7 @@
+ + + + +
diff --git a/view/frontend/web/template/payment/sepa-form.html b/view/frontend/web/template/payment/sepa-form.html index 75006dbfb..7b21871dc 100755 --- a/view/frontend/web/template/payment/sepa-form.html +++ b/view/frontend/web/template/payment/sepa-form.html @@ -46,7 +46,9 @@
- + + +