We will be off from 27/1 (Monday) to 31/1 (Friday) (GMT +7) for our Tet Holiday (Lunar New Year) in our country

Commit 787f9f5f authored by Rik ter Beek's avatar Rik ter Beek Committed by GitHub

Merge pull request #237 from Adyen/develop

Release 2.2.0
parents 798c6448 80266bd7
<!-- Thank you for considering contributing to this repository! We encourage you to use PSR-2. -->
**Description** **Description**
<!-- Please provide a description of the changes proposed in the Pull Request --> <!-- Please provide a description of the changes proposed in the Pull Request -->
**Tested scenarios** **Tested scenarios**
<!-- Description of tested scenarios --> <!-- Description of tested scenarios -->
<!-- Please verify that the unit tests are passing by running "vendor/bin/phpunit -c ." -->
**Fixed issue**: <!-- #-prefixed issue number --> **Fixed issue**: <!-- #-prefixed issue number -->
\ No newline at end of file
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\AdminMessage;
class CronMessage implements \Magento\Framework\Notification\MessageInterface
{
protected $_authSession;
protected $_cronCheck;
protected $_dateChecked;
protected $_adyenHelper;
protected $_timezoneInterface;
public function __construct(
\Magento\Backend\Model\Auth\Session $authSession,
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezoneInterface
) {
$this->_authSession = $authSession;
$this->_cronCheck = $this->getSessionData("cronCheck");
$this->_dateChecked = $this->getSessionData("dateChecked");
$this->_adyenHelper = $adyenHelper;
$this->_timezoneInterface = $timezoneInterface;
}
/**
* Message identity
*/
const MESSAGE_IDENTITY = 'Adyen Cronjob system 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()) {
$this->_dateChecked = $this->_timezoneInterface->date();
$this->_cronCheck = $this->_adyenHelper->getUnprocessedNotifications();
$this->setSessionData("cronCheck", $this->_cronCheck);
$this->setSessionData("dateChecked", $this->_dateChecked);
}
// Do not show any message if there are no unprocessed notifications
if ($this->_cronCheck > 0) {
return true;
} else {
return false;
}
}
/**
* Retrieve system message text
*
* @return \Magento\Framework\Phrase
*/
public function getText()
{
$message = __('You have ' . $this->_cronCheck . ' unprocessed notification(s). Please check your Cron');
$urlMagento = "http://devdocs.magento.com/guides/v2.0/config-guide/cli/config-cli-subcommands-cron.html";
$urlAdyen = "https://docs.adyen.com/developers/plug-ins-and-partners/magento/magento-2/configuring-the-adyen-plug-in";
$message .= __(' and visit <a href="%1">Magento DevDocs</a> and <a href="%2">Adyen Docs</a> on how to configure Cron.',
$urlMagento, $urlAdyen);
$message .= __('<i> Last cron check was: %1</i> ', $this->_dateChecked->format('d/m/Y H:i:s'));
return __($message);
}
/**
* Retrieve system message severity
*
* @return int
*/
public function getSeverity()
{
return self::SEVERITY_CRITICAL;
}
/**
* 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);
}
}
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Api;
interface AdyenRequestMerchantSessionInterface
{
/**
* @return mixed
*/
public function getMerchantSession();
}
\ No newline at end of file
...@@ -80,14 +80,14 @@ class Installments extends \Magento\Config\Block\System\Config\Form\Field\FieldA ...@@ -80,14 +80,14 @@ class Installments extends \Magento\Config\Block\System\Config\Form\Field\FieldA
$this->addColumn( $this->addColumn(
'amount', 'amount',
[ [
'label' => __('Amount Range (minor units)'), 'label' => __('Amount Range'),
'renderer' => false, 'renderer' => false,
] ]
); );
$this->addColumn( $this->addColumn(
'installments', 'installments',
[ [
'label' => __('Max Number Of Installments'), 'label' => __('Number Of Installments'),
'renderer' => $this->getNumberOfInstallmentsRenderer(), 'renderer' => $this->getNumberOfInstallmentsRenderer(),
] ]
); );
......
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Block\Form;
class ApplePay extends \Magento\Payment\Block\Form
{
/**
* @var \Adyen\Payment\Helper\Data
*/
protected $_adyenHelper;
/**
* ApplePay constructor.
*
* @param \Magento\Framework\View\Element\Template\Context $context
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Adyen\Payment\Helper\Data $adyenHelper,
array $data = []
)
{
parent::__construct($context, $data);
$this->_adyenHelper = $adyenHelper;
}
/**
* @return array
*/
public function getApplePayShippingTypes()
{
$applePayShippingTypes = $this->_adyenHelper->getApplePayShippingTypes();
$types = [];
foreach ($applePayShippingTypes as $applePayShippingType) {
$types[$applePayShippingType['value']] = $applePayShippingType['label'];
}
return $types;
}
}
\ No newline at end of file
...@@ -67,7 +67,8 @@ class Cc extends \Magento\Payment\Block\Form\Cc ...@@ -67,7 +67,8 @@ class Cc extends \Magento\Payment\Block\Form\Cc
\Adyen\Payment\Helper\Data $adyenHelper, \Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Checkout\Model\Session $checkoutSession, \Magento\Checkout\Model\Session $checkoutSession,
array $data = [] array $data = []
) { )
{
parent::__construct($context, $paymentConfig); parent::__construct($context, $paymentConfig);
$this->_adyenHelper = $adyenHelper; $this->_adyenHelper = $adyenHelper;
$this->_appState = $context->getAppState(); $this->_appState = $context->getAppState();
...@@ -79,7 +80,7 @@ class Cc extends \Magento\Payment\Block\Form\Cc ...@@ -79,7 +80,7 @@ class Cc extends \Magento\Payment\Block\Form\Cc
* @return mixed * @return mixed
* @throws \Magento\Framework\Exception\LocalizedException * @throws \Magento\Framework\Exception\LocalizedException
*/ */
public function getCsePublicKey() public function getLibrarySource()
{ {
// get storeId for admin // get storeId for admin
if (!$this->_appState->getAreaCode() === \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE) { if (!$this->_appState->getAreaCode() === \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE) {
...@@ -88,15 +89,7 @@ class Cc extends \Magento\Payment\Block\Form\Cc ...@@ -88,15 +89,7 @@ class Cc extends \Magento\Payment\Block\Form\Cc
$storeId = null; $storeId = null;
} }
$demoMode = $this->_adyenHelper->getAdyenAbstractConfigDataFlag('demo_mode', $storeId); return $this->_adyenHelper->getLibrarySource($storeId);
if($demoMode) {
$cseKey = $this->_adyenHelper->getAdyenCcConfigData('cse_publickey_test', $storeId);
} else {
$cseKey = $this->_adyenHelper->getAdyenCcConfigData('cse_publickey_live', $storeId);
}
return $cseKey;
} }
/** /**
...@@ -111,7 +104,7 @@ class Cc extends \Magento\Payment\Block\Form\Cc ...@@ -111,7 +104,7 @@ class Cc extends \Magento\Payment\Block\Form\Cc
$this->getCheckoutSession(); $this->getCheckoutSession();
$store = $this->_checkoutSession->getQuote()->getStore(); $store = $this->_checkoutSession->getQuote()->getStore();
$enableMoto = $this->_adyenHelper->getAdyenCcConfigDataFlag('enable_moto', $store->getId()); $enableMoto = $this->_adyenHelper->getAdyenCcConfigDataFlag('enable_moto', $store->getId());
if($enableMoto) { if ($enableMoto) {
return false; return false;
} }
} }
......
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Block\Info;
class ApplePay extends Cc
{
}
\ No newline at end of file
...@@ -301,9 +301,6 @@ class Redirect extends \Magento\Payment\Block\Form ...@@ -301,9 +301,6 @@ class Redirect extends \Magento\Payment\Block\Form
// don't allow editable shipping/delivery address // don't allow editable shipping/delivery address
$formFields['billingAddressType'] = "1"; $formFields['billingAddressType'] = "1";
$formFields['deliveryAddressType'] = "1"; $formFields['deliveryAddressType'] = "1";
// make setting to make this optional
$formFields['shopperType'] = "1";
} }
if ($this->_order->getPayment()->getAdditionalInformation("df_value") != "") { if ($this->_order->getPayment()->getAdditionalInformation("df_value") != "") {
......
...@@ -110,12 +110,23 @@ class Json extends \Magento\Framework\App\Action\Action ...@@ -110,12 +110,23 @@ class Json extends \Magento\Framework\App\Action\Action
} }
} }
$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
if ($this->_isTestNotification($cronCheckTest)) {
$unprocessedNotifications = $this->_adyenHelper->getUnprocessedNotifications();
if ($unprocessedNotifications > 0) {
$acceptedMessage .= "\nYou have " . $unprocessedNotifications . " unprocessed notifications.";
}
}
$this->_adyenLogger->addAdyenNotification("The result is accepted"); $this->_adyenLogger->addAdyenNotification("The result is accepted");
$this->getResponse() $this->getResponse()
->clearHeader('Content-Type') ->clearHeader('Content-Type')
->setHeader('Content-Type', 'text/html') ->setHeader('Content-Type', 'text/html')
->setBody("[accepted]"); ->setBody($acceptedMessage);
return; return;
} else { } else {
if ($notificationMode == "") { if ($notificationMode == "") {
...@@ -139,11 +150,12 @@ class Json extends \Magento\Framework\App\Action\Action ...@@ -139,11 +150,12 @@ class Json extends \Magento\Framework\App\Action\Action
{ {
$mode = $this->_adyenHelper->getAdyenAbstractConfigData('demo_mode'); $mode = $this->_adyenHelper->getAdyenAbstractConfigData('demo_mode');
if (($mode=='1' && $notificationMode == "false") || ($mode=='0' && $notificationMode == 'true')) { if (($mode == '1' && $notificationMode == "false") || ($mode == '0' && $notificationMode == 'true')) {
return true; return true;
} }
return false; return false;
} }
/** /**
* save notification into the database for cronjob to execute notification * save notification into the database for cronjob to execute notification
* *
...@@ -157,7 +169,7 @@ class Json extends \Magento\Framework\App\Action\Action ...@@ -157,7 +169,7 @@ class Json extends \Magento\Framework\App\Action\Action
// validate the notification // validate the notification
if ($this->authorised($response)) { if ($this->authorised($response)) {
// check if notificaiton already exists // check if notification already exists
if (!$this->_isDuplicate($response)) { if (!$this->_isDuplicate($response)) {
try { try {
$notification = $this->_objectManager->create('Adyen\Payment\Model\Notification'); $notification = $this->_objectManager->create('Adyen\Payment\Model\Notification');
...@@ -215,7 +227,7 @@ class Json extends \Magento\Framework\App\Action\Action ...@@ -215,7 +227,7 @@ class Json extends \Magento\Framework\App\Action\Action
} }
return false; return false;
} }
/** /**
* HTTP Authentication of the notification * HTTP Authentication of the notification
* *
...@@ -234,8 +246,7 @@ class Json extends \Magento\Framework\App\Action\Action ...@@ -234,8 +246,7 @@ class Json extends \Magento\Framework\App\Action\Action
$submitedMerchantAccount = $response['merchantAccountCode']; $submitedMerchantAccount = $response['merchantAccountCode'];
if (empty($submitedMerchantAccount) && empty($internalMerchantAccount)) { if (empty($submitedMerchantAccount) && empty($internalMerchantAccount)) {
if (strtolower(substr($response['pspReference'], 0, 17)) == "testnotification_" || if ($this->_isTestNotification($response['pspReference'])) {
strtolower(substr($response['pspReference'], 0, 5)) == "test_") {
echo 'merchantAccountCode is empty in magento settings'; echo 'merchantAccountCode is empty in magento settings';
exit(); exit();
} }
...@@ -244,8 +255,7 @@ class Json extends \Magento\Framework\App\Action\Action ...@@ -244,8 +255,7 @@ class Json extends \Magento\Framework\App\Action\Action
// validate username and password // validate username and password
if ((!isset($_SERVER['PHP_AUTH_USER']) && !isset($_SERVER['PHP_AUTH_PW']))) { if ((!isset($_SERVER['PHP_AUTH_USER']) && !isset($_SERVER['PHP_AUTH_PW']))) {
if (strtolower(substr($response['pspReference'], 0, 17)) == "testnotification_" || if ($this->_isTestNotification($response['pspReference'])) {
strtolower(substr($response['pspReference'], 0, 5)) == "test_") {
echo 'Authentication failed: PHP_AUTH_USER and PHP_AUTH_PW are empty. See Adyen Magento manual CGI mode'; echo 'Authentication failed: PHP_AUTH_USER and PHP_AUTH_PW are empty. See Adyen Magento manual CGI mode';
exit(); exit();
} }
...@@ -263,8 +273,7 @@ class Json extends \Magento\Framework\App\Action\Action ...@@ -263,8 +273,7 @@ class Json extends \Magento\Framework\App\Action\Action
} }
// If notification is test check if fields are correct if not return error // If notification is test check if fields are correct if not return error
if (strtolower(substr($response['pspReference'], 0, 17)) == "testnotification_" || if ($this->_isTestNotification($response['pspReference'])) {
strtolower(substr($response['pspReference'], 0, 5)) == "test_") {
if ($accountCmp != 0) { if ($accountCmp != 0) {
echo 'MerchantAccount in notification is not the same as in Magento settings'; echo 'MerchantAccount in notification is not the same as in Magento settings';
exit(); exit();
...@@ -288,7 +297,7 @@ class Json extends \Magento\Framework\App\Action\Action ...@@ -288,7 +297,7 @@ class Json extends \Magento\Framework\App\Action\Action
$eventCode = trim($response['eventCode']); $eventCode = trim($response['eventCode']);
$success = trim($response['success']); $success = trim($response['success']);
$originalReference = null; $originalReference = null;
if(isset($response['originalReference'])) { if (isset($response['originalReference'])) {
$originalReference = trim($response['originalReference']); $originalReference = trim($response['originalReference']);
} }
$notification = $this->_objectManager->create('Adyen\Payment\Model\Notification'); $notification = $this->_objectManager->create('Adyen\Payment\Model\Notification');
...@@ -301,24 +310,25 @@ class Json extends \Magento\Framework\App\Action\Action ...@@ -301,24 +310,25 @@ class Json extends \Magento\Framework\App\Action\Action
protected function _fixCgiHttpAuthentication() protected function _fixCgiHttpAuthentication()
{ {
// do nothing if values are already there // do nothing if values are already there
if(!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) { if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) {
return; return;
} elseif (isset($_SERVER['REDIRECT_REMOTE_AUTHORIZATION']) && } elseif (isset($_SERVER['REDIRECT_REMOTE_AUTHORIZATION']) &&
$_SERVER['REDIRECT_REMOTE_AUTHORIZATION'] != '') { $_SERVER['REDIRECT_REMOTE_AUTHORIZATION'] != ''
) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
explode(':', base64_decode($_SERVER['REDIRECT_REMOTE_AUTHORIZATION']),2); explode(':', base64_decode($_SERVER['REDIRECT_REMOTE_AUTHORIZATION']), 2);
} elseif (!empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) { } elseif (!empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
explode(':', base64_decode(substr($_SERVER['REDIRECT_HTTP_AUTHORIZATION'], 6)),2); explode(':', base64_decode(substr($_SERVER['REDIRECT_HTTP_AUTHORIZATION'], 6)), 2);
} elseif (!empty($_SERVER['HTTP_AUTHORIZATION'])) { } elseif (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)),2); explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)), 2);
} elseif (!empty($_SERVER['REMOTE_USER'])) { } elseif (!empty($_SERVER['REMOTE_USER'])) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
explode(':', base64_decode(substr($_SERVER['REMOTE_USER'], 6)),2); explode(':', base64_decode(substr($_SERVER['REMOTE_USER'], 6)), 2);
} elseif (!empty($_SERVER['REDIRECT_REMOTE_USER'])) { } elseif (!empty($_SERVER['REDIRECT_REMOTE_USER'])) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
explode(':', base64_decode(substr($_SERVER['REDIRECT_REMOTE_USER'], 6)),2); explode(':', base64_decode(substr($_SERVER['REDIRECT_REMOTE_USER'], 6)), 2);
} }
} }
...@@ -329,4 +339,21 @@ class Json extends \Magento\Framework\App\Action\Action ...@@ -329,4 +339,21 @@ class Json extends \Magento\Framework\App\Action\Action
{ {
$this->getResponse()->setHttpResponseCode(401); $this->getResponse()->setHttpResponseCode(401);
} }
/**
* If notification is a test notification from Adyen Customer Area
*
* @param $pspReference
* @return bool
*/
protected function _isTestNotification($pspReference)
{
if (strpos(strtolower($pspReference), "test_") !== false
|| strpos(strtolower($pspReference), "testnotification_") !== false
) {
return true;
} else {
return false;
}
}
} }
\ No newline at end of file
...@@ -211,23 +211,30 @@ class Result extends \Magento\Framework\App\Action\Action ...@@ -211,23 +211,30 @@ class Result extends \Magento\Framework\App\Action\Action
$type, $authResult, $pspReference, $paymentMethod $type, $authResult, $pspReference, $paymentMethod
); );
$history = $this->_orderHistoryFactory->create()
//->setStatus($status)
->setComment($comment)
->setEntityName('order')
->setOrder($order)
;
$history->save();
// needed because then we need to save $order objects // needed because then we need to save $order objects
$order->setAdyenResulturlEventCode($authResult); $order->setAdyenResulturlEventCode($authResult);
switch ($authResult) { switch ($authResult) {
case Notification::AUTHORISED: case Notification::AUTHORISED:
$result = true;
$this->_adyenLogger->addAdyenResult('Do nothing wait for the notification');
break;
case Notification::PENDING: case Notification::PENDING:
// do nothing wait for the notification // do nothing wait for the notification
$result = true; $result = true;
if (strpos($paymentMethod,"bankTransfer") !== false){
$comment .= "<br /><br />Waiting for the customer to transfer the money.";
}
elseif($paymentMethod == "sepadirectdebit"){
$comment .= "<br /><br />This request will be send to the bank at the end of the day.";
}
else {
$comment .= "<br /><br />The payment result is not confirmed (yet).
<br />Once the payment is authorised, the order status will be updated accordingly.
<br />If the order is stuck on this status, the payment can be seen as unsuccessful.
<br />The order can be automatically cancelled based on the OFFER_CLOSED notification. Please contact Adyen Support to enable this.";
}
$this->_adyenLogger->addAdyenResult('Do nothing wait for the notification'); $this->_adyenLogger->addAdyenResult('Do nothing wait for the notification');
break; break;
case Notification::CANCELLED: case Notification::CANCELLED:
...@@ -250,6 +257,15 @@ class Result extends \Magento\Framework\App\Action\Action ...@@ -250,6 +257,15 @@ class Result extends \Magento\Framework\App\Action\Action
break; break;
} }
$history = $this->_orderHistoryFactory->create()
//->setStatus($status)
->setComment($comment)
->setEntityName('order')
->setOrder($order)
;
$history->save();
return $result; return $result;
} }
......
...@@ -156,9 +156,10 @@ class Validate3d extends \Magento\Framework\App\Action\Action ...@@ -156,9 +156,10 @@ class Validate3d extends \Magento\Framework\App\Action\Action
} else { } else {
$this->_adyenLogger->addAdyenResult("Customer was redirected to bank for 3D-secure validation."); $this->_adyenLogger->addAdyenResult("Customer was redirected to bank for 3D-secure validation.");
$order->addStatusHistoryComment( $order->addStatusHistoryComment(
__('Customer was redirected to bank for 3D-secure validation.') __('Customer was redirected to bank for 3D-secure validation. Once the shopper authenticated, the order status will be updated accordingly.
)->save(); <br />Make sure that your notifications are being processed!
<br />If the order is stuck on this status, the shopper abandoned the session. The payment can be seen as unsuccessful.
<br />The order can be automatically cancelled based on the OFFER_CLOSED notification. Please contact Adyen Support to enable this.'))->save();
$this->_view->loadLayout(); $this->_view->loadLayout();
$this->_view->getLayout()->initMessages(); $this->_view->getLayout()->initMessages();
$this->_view->renderLayout(); $this->_view->renderLayout();
......
...@@ -66,15 +66,11 @@ class AddressDataBuilder implements BuilderInterface ...@@ -66,15 +66,11 @@ class AddressDataBuilder implements BuilderInterface
$requestBilling = ["street" => $billingAddress->getStreetLine1(), $requestBilling = ["street" => $billingAddress->getStreetLine1(),
"postalCode" => $billingAddress->getPostcode(), "postalCode" => $billingAddress->getPostcode(),
"city" => $billingAddress->getCity(), "city" => $billingAddress->getCity(),
"houseNumberOrName" => 'NA', "houseNumberOrName" => '',
"stateOrProvince" => $billingAddress->getRegionCode(), "stateOrProvince" => $billingAddress->getRegionCode(),
"country" => $billingAddress->getCountryId() "country" => $billingAddress->getCountryId()
]; ];
// houseNumberOrName is mandatory
if ($requestBilling['houseNumberOrName'] == "") {
$requestBilling['houseNumberOrName'] = "NA";
}
$result['billingAddress'] = $requestBilling; $result['billingAddress'] = $requestBilling;
} }
...@@ -86,15 +82,11 @@ class AddressDataBuilder implements BuilderInterface ...@@ -86,15 +82,11 @@ class AddressDataBuilder implements BuilderInterface
$requestDelivery = ["street" => $shippingAddress->getStreetLine1(), $requestDelivery = ["street" => $shippingAddress->getStreetLine1(),
"postalCode" => $shippingAddress->getPostcode(), "postalCode" => $shippingAddress->getPostcode(),
"city" => $shippingAddress->getCity(), "city" => $shippingAddress->getCity(),
"houseNumberOrName" => 'NA', "houseNumberOrName" => '',
"stateOrProvince" => $shippingAddress->getRegionCode(), "stateOrProvince" => $shippingAddress->getRegionCode(),
"country" => $shippingAddress->getCountryId() "country" => $shippingAddress->getCountryId()
]; ];
// houseNumberOrName is mandatory
if ($requestDelivery['houseNumberOrName'] == "") {
$requestDelivery['houseNumberOrName'] = "NA";
}
$result['deliveryAddress'] = $requestDelivery; $result['deliveryAddress'] = $requestDelivery;
} }
......
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Gateway\Request;
use Magento\Payment\Gateway\Request\BuilderInterface;
use Magento\Setup\Exception;
class ApplePayAuthorizationDataBuilder implements BuilderInterface
{
/**
* @var \Adyen\Payment\Helper\Data
*/
private $_adyenHelper;
/**
* @var \Adyen\Payment\Logger\AdyenLogger
*/
private $_adyenLogger;
/**
* CaptureDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper,
\Adyen\Payment\Logger\AdyenLogger $adyenLogger
)
{
$this->_adyenHelper = $adyenHelper;
$this->_adyenLogger = $adyenLogger;
}
public function build(array $buildSubject)
{
$request = [];
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$payment = $paymentDataObject->getPayment();
$token = $payment->getAdditionalInformation('token');
// get payment data
if ($token) {
$parsedToken = json_decode($token);
$paymentData = $parsedToken->token->paymentData;
try {
$paymentData = base64_encode(json_encode($paymentData));
$request['additionalData']['payment.token'] = $paymentData;
} catch (\Exception $exception) {
$this->_adyenLogger->addAdyenDebug("exception: " . $exception->getMessage());
}
} else {
$this->_adyenLogger->addAdyenDebug("PaymentToken is empty");
}
return $request;
}
}
\ No newline at end of file
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
namespace Adyen\Payment\Gateway\Request; namespace Adyen\Payment\Gateway\Request;
use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Payment\Gateway\Request\BuilderInterface;
use Adyen\Payment\Observer\AdyenCcDataAssignObserver;
class CcAuthorizationDataBuilder implements BuilderInterface class CcAuthorizationDataBuilder implements BuilderInterface
{ {
...@@ -46,7 +47,8 @@ class CcAuthorizationDataBuilder implements BuilderInterface ...@@ -46,7 +47,8 @@ class CcAuthorizationDataBuilder implements BuilderInterface
public function __construct( public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper, \Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\Model\Context $context \Magento\Framework\Model\Context $context
) { )
{
$this->adyenHelper = $adyenHelper; $this->adyenHelper = $adyenHelper;
$this->appState = $context->getAppState(); $this->appState = $context->getAppState();
} }
...@@ -64,35 +66,30 @@ class CcAuthorizationDataBuilder implements BuilderInterface ...@@ -64,35 +66,30 @@ class CcAuthorizationDataBuilder implements BuilderInterface
$storeId = $order->getStoreId(); $storeId = $order->getStoreId();
$request = []; $request = [];
if ($this->adyenHelper->getAdyenCcConfigDataFlag('cse_enabled', $storeId)) {
$request['additionalData']['card.encrypted.json'] = $request['additionalData']['card.encrypted.json'] =
$payment->getAdditionalInformation("encrypted_data"); $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_DATA);
} else {
$requestCreditCardDetails = [ // Remove from additional data
"expiryMonth" => $payment->getCcExpMonth(), $payment->unsAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_DATA);
"expiryYear" => $payment->getCcExpYear(),
"holderName" => $payment->getCcOwner(),
"number" => $payment->getCcNumber(),
"cvc" => $payment->getCcCid(),
];
$cardDetails['card'] = $requestCreditCardDetails;
$request = array_merge($request, $cardDetails);
}
/** /**
* if MOTO for backend is enabled use MOTO as shopper interaction type * if MOTO for backend is enabled use MOTO as shopper interaction type
*/ */
$enableMoto = $this->adyenHelper->getAdyenCcConfigDataFlag('enable_moto', $storeId); $enableMoto = $this->adyenHelper->getAdyenCcConfigDataFlag('enable_moto', $storeId);
if ($this->appState->getAreaCode() === \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE && if ($this->appState->getAreaCode() === \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE &&
$enableMoto) { $enableMoto
) {
$request['shopperInteraction'] = "Moto"; $request['shopperInteraction'] = "Moto";
} }
// if installments is set add it into the request // if installments is set add it into the request
if ($payment->getAdditionalInformation('number_of_installments') && if ($payment->getAdditionalInformation('number_of_installments') &&
$payment->getAdditionalInformation('number_of_installments') > 0) { $payment->getAdditionalInformation('number_of_installments') > 0
) {
$request['installments']['value'] = $payment->getAdditionalInformation('number_of_installments'); $request['installments']['value'] = $payment->getAdditionalInformation('number_of_installments');
} }
return $request; return $request;
} }
} }
\ No newline at end of file
...@@ -114,31 +114,7 @@ class GeneralResponseValidator extends AbstractValidator ...@@ -114,31 +114,7 @@ class GeneralResponseValidator extends AbstractValidator
} }
break; break;
case "Refused": case "Refused":
if ($response['refusalReason']) { $errorMsg = __('The payment is REFUSED.');
$refusalReason = $response['refusalReason'];
switch($refusalReason) {
case "Transaction Not Permitted":
$errorMsg = __('The transaction is not permitted.');
break;
case "CVC Declined":
$errorMsg = __('Declined due to the Card Security Code(CVC) being incorrect. Please check your CVC code!');
break;
case "Restricted Card":
$errorMsg = __('The card is restricted.');
break;
case "803 PaymentDetail not found":
$errorMsg = __('The payment is REFUSED because the saved card is removed. Please try an other payment method.');
break;
case "Expiry month not set":
$errorMsg = __('The expiry month is not set. Please check your expiry month!');
break;
default:
$errorMsg = __('The payment is REFUSED.');
break;
}
} else {
$errorMsg = __('The payment is REFUSED.');
}
// this will result the specific error // this will result the specific error
throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg)); throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg));
break; break;
......
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Gateway\Validator;
use Magento\Payment\Gateway\Validator\AbstractValidator;
class InstallmentValidator extends AbstractValidator
{
/**
* @var \Adyen\Payment\Logger\AdyenLogger
*/
private $adyenLogger;
/**
* @var \Adyen\Payment\Helper\Data
*/
private $adyenHelper;
/**
* @var \Magento\Checkout\Model\Session
*/
private $session;
/**
* InstallmentValidator constructor.
* @param \Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory
* @param \Adyen\Payment\Logger\AdyenLogger $adyenLogger
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Magento\Framework\App\ObjectManager $objectManager
*/
public function __construct(
\Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory,
\Adyen\Payment\Logger\AdyenLogger $adyenLogger,
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Checkout\Model\Session $session
) {
$this->adyenLogger = $adyenLogger;
$this->adyenHelper = $adyenHelper;
$this->session = $session;
parent::__construct($resultFactory);
}
public function validate(array $validationSubject)
{
$isValid = true;
$fails = [];
$payment = $validationSubject['payment'];
$quote = $this->session->getQuote();
if ($quote) {
$grandTotal = $quote->getGrandTotal();
$installmentsAvailable = $this->adyenHelper->getAdyenCcConfigData('installments');
$installmentSelected = $payment->getAdditionalInformation('number_of_installments');
$ccType = $payment->getAdditionalInformation('cc_type');
if ($installmentsAvailable) {
$installments = unserialize($installmentsAvailable);
}
if ($installmentSelected && $installmentsAvailable) {
$isValid = false;
$fails[] = __('Installments not valid.');
if ($installments) {
foreach ($installments as $ccTypeInstallment => $installment) {
if ($ccTypeInstallment == $ccType) {
foreach ($installment as $amount => $installmentsData) {
if ($installmentSelected == $installmentsData) {
if ($grandTotal >= $amount) {
$isValid = true;
}
}
}
}
}
}
}
}
return $this->createResult($isValid, $fails);
}
}
This diff is collapsed.
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Model;
use Adyen\Payment\Api\AdyenRequestMerchantSessionInterface;
class AdyenRequestMerchantSession implements AdyenRequestMerchantSessionInterface
{
/**
* @var \Adyen\Payment\Helper\Data
*/
protected $_adyenHelper;
/**
* @var \Adyen\Payment\Logger\AdyenLogger
*/
protected $_adyenLogger;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $_storeManager;
/**
* AdyenRequestMerchantSession constructor.
* @param \Adyen\Payment\Helper\Data $adyenHelper
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper,
\Adyen\Payment\Logger\AdyenLogger $adyenLogger,
\Magento\Store\Model\StoreManagerInterface $storeManager
) {
$this->_adyenHelper = $adyenHelper;
$this->_adyenLogger = $adyenLogger;
$this->_storeManager = $storeManager;
}
/**
* Get the merchant Session from Apple to start Apple Pay transaction
*
* @return mixed
*/
public function getMerchantSession()
{
// Works for test and live. Maybe we need to switch for validationUrl from callback event waiting for apple to respond
$validationUrl = "https://apple-pay-gateway-cert.apple.com/paymentservices/startSession";
// create a new cURL resource
$ch = curl_init();
$merchantIdentifier = $this->_adyenHelper->getAdyenApplePayMerchantIdentifier();
$domainName = parse_url($this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_WEB))['host'];
$displayName = $this->_storeManager->getStore()->getName();
$data = '{
"merchantIdentifier":"' . $merchantIdentifier . '",
"domainName":"' . $domainName . '",
"displayName":"' . $displayName . '"
}';
$this->_adyenLogger->addAdyenDebug("JSON Requesst is: " . print_r($data,true));
curl_setopt($ch, CURLOPT_URL, $validationUrl);
// location applepay certificates
$fullPathLocationPEMFile = $this->_adyenHelper->getAdyenApplePayPemFileLocation();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSLCERT, $fullPathLocationPEMFile);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data)
)
);
$result = curl_exec($ch);
$httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// log the raw response
$this->_adyenLogger->addAdyenDebug("JSON Response is: " . $result);
// result not 200 throw error
if ($httpStatus != 200 && $result) {
$this->_adyenLogger->addAdyenDebug("Error Apple, API HTTP Status is: " . $httpStatus . " result is:" . $result);
} elseif(!$result) {
$errno = curl_errno($ch);
$message = curl_error($ch);
$msg = "(Network error [errno $errno]: $message)";
$this->_adyenLogger->addAdyenDebug($msg);
}
curl_close($ch);
return $result;
}
}
\ No newline at end of file
...@@ -62,7 +62,10 @@ class Installments extends \Magento\Framework\App\Config\Value ...@@ -62,7 +62,10 @@ class Installments extends \Magento\Framework\App\Config\Value
public function beforeSave() public function beforeSave()
{ {
$value = $this->getValue(); $value = $this->getValue();
$unserialized = @unserialize($value);
if ($unserialized !== false) {
return $this;
}
$result = []; $result = [];
foreach ($value as $data) { foreach ($value as $data) {
if (!$data) { if (!$data) {
...@@ -79,12 +82,19 @@ class Installments extends \Magento\Framework\App\Config\Value ...@@ -79,12 +82,19 @@ class Installments extends \Magento\Framework\App\Config\Value
$installments = $data['installments']; $installments = $data['installments'];
$ccTypes = $data['cc_types']; $ccTypes = $data['cc_types'];
foreach($ccTypes as $ccType) { foreach ($ccTypes as $ccType) {
$result[$ccType][$amount] = $installments; $result[$ccType][$amount] = $installments;
} }
} }
$this->setValue(serialize($result)); // sort on installments
$finalResult = [];
foreach ($result as $key => $installments) {
asort($installments);
$finalResult[$key] = $installments;
}
$this->setValue(serialize($finalResult));
return $this; return $this;
} }
......
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Model\Config\Source;
class ApplePayShippingType implements \Magento\Framework\Option\ArrayInterface
{
/**
* @var \Adyen\Payment\Helper\Data
*/
protected $_adyenHelper;
/**
* ApplePayShippingType constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper
) {
$this->_adyenHelper = $adyenHelper;
}
/**
* @return array
*/
public function toOptionArray() {
return $this->_adyenHelper->getApplePayShippingTypes();
}
}
\ No newline at end of file
...@@ -232,6 +232,16 @@ class Cron ...@@ -232,6 +232,16 @@ class Cron
* @return void * @return void
*/ */
public function processNotification() public function processNotification()
{
try {
$this->execute();
} catch(\Exception $e) {
$this->_adyenLogger->addAdyenNotificationCronjob($e->getMessage() . "\n" . $e->getTraceAsString());
throw $e;
}
}
public function execute()
{ {
// needed for Magento < 2.2.0 https://github.com/magento/magento2/pull/8413 // needed for Magento < 2.2.0 https://github.com/magento/magento2/pull/8413
$renderer = Phrase::getRenderer(); $renderer = Phrase::getRenderer();
...@@ -1189,7 +1199,7 @@ class Cron ...@@ -1189,7 +1199,7 @@ class Cron
*/ */
protected function _isAutoCapture() protected function _isAutoCapture()
{ {
// validate if payment methods allowes manual capture // validate if payment methods allows manual capture
if ($this->_manualCaptureAllowed()) { if ($this->_manualCaptureAllowed()) {
$captureMode = trim($this->_getConfigData( $captureMode = trim($this->_getConfigData(
'capture_mode', 'adyen_abstract', $this->_order->getStoreId()) 'capture_mode', 'adyen_abstract', $this->_order->getStoreId())
...@@ -1292,6 +1302,7 @@ class Cron ...@@ -1292,6 +1302,7 @@ class Cron
case 'cup': case 'cup':
case 'cartebancaire': case 'cartebancaire':
case 'visa': case 'visa':
case 'visadankort':
case 'mc': case 'mc':
case 'uatp': case 'uatp':
case 'amex': case 'amex':
......
...@@ -32,4 +32,18 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab ...@@ -32,4 +32,18 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
{ {
$this->_init('Adyen\Payment\Model\Notification', 'Adyen\Payment\Model\Resource\Notification'); $this->_init('Adyen\Payment\Model\Notification', 'Adyen\Payment\Model\Resource\Notification');
} }
/**
* Filter the notifications table to see if there are any unprocessed ones that have been created more than 10 minutes ago
*/
public function unprocessedNotificationsFilter()
{
$dateEnd = new \DateTime();
$dateEnd->modify('-10 minute');
$dateRange = ['to' => $dateEnd, 'datetime' => true];
$this->addFieldToFilter('done', 0);
$this->addFieldToFilter('processing', 0);
$this->addFieldToFilter('created_at', $dateRange);
return $this;
}
} }
\ No newline at end of file
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Model\Ui;
use Magento\Checkout\Model\ConfigProviderInterface;
use Magento\Payment\Helper\Data as PaymentHelper;
class AdyenApplePayConfigProvider implements ConfigProviderInterface
{
const CODE = 'adyen_apple_pay';
/**
* @var PaymentHelper
*/
protected $_paymentHelper;
/**
* @var \Adyen\Payment\Helper\Data
*/
protected $_adyenHelper;
/**
* @var \Magento\Framework\UrlInterface
*/
protected $_urlBuilder;
/**
* Request object
*
* @var \Magento\Framework\App\RequestInterface
*/
protected $_request;
/**
* AdyenApplePayConfigProvider constructor.
*
* @param PaymentHelper $paymentHelper
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Magento\Framework\App\RequestInterface $request
* @param \Magento\Framework\UrlInterface $urlBuilder
*/
public function __construct(
PaymentHelper $paymentHelper,
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\App\RequestInterface $request,
\Magento\Framework\UrlInterface $urlBuilder
) {
$this->_paymentHelper = $paymentHelper;
$this->_adyenHelper = $adyenHelper;
$this->_request = $request;
$this->_urlBuilder = $urlBuilder;
}
/**
* Retrieve assoc array of checkout configuration
*
* @return array
*/
public function getConfig()
{
// set to active
return [
'payment' => [
self::CODE => [
'isActive' => true,
'redirectUrl' => $this->_urlBuilder->getUrl(
'checkout/onepage/success/', ['_secure' => $this->_getRequest()->isSecure()]),
'merchant_identifier' => $this->_adyenHelper->getAdyenApplePayMerchantIdentifier()
]
]
];
}
/**
* Retrieve request object
*
* @return \Magento\Framework\App\RequestInterface
*/
protected function _getRequest()
{
return $this->_request;
}
}
\ No newline at end of file
...@@ -64,7 +64,7 @@ class AdyenCcConfigProvider implements ConfigProviderInterface ...@@ -64,7 +64,7 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
* @var \Magento\Payment\Model\CcConfig * @var \Magento\Payment\Model\CcConfig
*/ */
private $ccConfig; private $ccConfig;
/** /**
* AdyenCcConfigProvider constructor. * AdyenCcConfigProvider constructor.
...@@ -84,7 +84,8 @@ class AdyenCcConfigProvider implements ConfigProviderInterface ...@@ -84,7 +84,8 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
\Magento\Framework\UrlInterface $urlBuilder, \Magento\Framework\UrlInterface $urlBuilder,
Source $assetSource, Source $assetSource,
\Magento\Payment\Model\CcConfig $ccConfig \Magento\Payment\Model\CcConfig $ccConfig
) { )
{
$this->_paymentHelper = $paymentHelper; $this->_paymentHelper = $paymentHelper;
$this->_adyenHelper = $adyenHelper; $this->_adyenHelper = $adyenHelper;
$this->_request = $request; $this->_request = $request;
...@@ -123,25 +124,13 @@ class AdyenCcConfigProvider implements ConfigProviderInterface ...@@ -123,25 +124,13 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
] ]
]); ]);
$demoMode = $this->_adyenHelper->getAdyenAbstractConfigDataFlag('demo_mode');
if ($demoMode) {
$cseKey = $this->_adyenHelper->getAdyenCcConfigData('cse_publickey_test');
} else {
$cseKey = $this->_adyenHelper->getAdyenCcConfigData('cse_publickey_live');
}
$cseEnabled = $this->_adyenHelper->getAdyenCcConfigDataFlag('cse_enabled');
$recurringType = $this->_adyenHelper->getAdyenAbstractConfigData('recurring_type'); $recurringType = $this->_adyenHelper->getAdyenAbstractConfigData('recurring_type');
$canCreateBillingAgreement = false; $canCreateBillingAgreement = false;
if ($recurringType == "ONECLICK" || $recurringType == "ONECLICK,RECURRING") { if ($recurringType == "ONECLICK" || $recurringType == "ONECLICK,RECURRING") {
$canCreateBillingAgreement = true; $canCreateBillingAgreement = true;
} }
$config['payment'] ['adyenCc']['cseKey'] = $cseKey; $config['payment'] ['adyenCc']['librarySource'] = $this->_adyenHelper->getLibrarySource();
$config['payment'] ['adyenCc']['cseEnabled'] = $cseEnabled;
$config['payment'] ['adyenCc']['cseEnabled'] = $cseEnabled;
$config['payment']['adyenCc']['generationTime'] = date("c"); $config['payment']['adyenCc']['generationTime'] = date("c");
$config['payment']['adyenCc']['canCreateBillingAgreement'] = $canCreateBillingAgreement; $config['payment']['adyenCc']['canCreateBillingAgreement'] = $canCreateBillingAgreement;
$config['payment']['adyenCc']['icons'] = $this->getIcons(); $config['payment']['adyenCc']['icons'] = $this->getIcons();
...@@ -150,9 +139,10 @@ class AdyenCcConfigProvider implements ConfigProviderInterface ...@@ -150,9 +139,10 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
$config['payment']['adyenCc']['hasInstallments'] = false; $config['payment']['adyenCc']['hasInstallments'] = false;
// get Installments // get Installments
$installmentsEnabled = $this->_adyenHelper->getAdyenCcConfigData('enable_installments');
$installments = $this->_adyenHelper->getAdyenCcConfigData('installments'); $installments = $this->_adyenHelper->getAdyenCcConfigData('installments');
if ($installments) { if ($installmentsEnabled && $installments) {
$config['payment']['adyenCc']['installments'] = unserialize($installments); $config['payment']['adyenCc']['installments'] = unserialize($installments);
$config['payment']['adyenCc']['hasInstallments'] = true; $config['payment']['adyenCc']['hasInstallments'] = true;
} else { } else {
...@@ -250,7 +240,7 @@ class AdyenCcConfigProvider implements ConfigProviderInterface ...@@ -250,7 +240,7 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
{ {
return $this->ccConfig->getCvvImageUrl(); return $this->ccConfig->getCvvImageUrl();
} }
/** /**
* Retrieve request object * Retrieve request object
* *
......
...@@ -109,6 +109,9 @@ class AdyenHppConfigProvider implements ConfigProviderInterface ...@@ -109,6 +109,9 @@ class AdyenHppConfigProvider implements ConfigProviderInterface
] ]
]; ];
$gender = "";
$dob = "";
// get customer // get customer
if ($this->_customerSession->isLoggedIn()) { if ($this->_customerSession->isLoggedIn()) {
...@@ -118,11 +121,10 @@ class AdyenHppConfigProvider implements ConfigProviderInterface ...@@ -118,11 +121,10 @@ class AdyenHppConfigProvider implements ConfigProviderInterface
// format to calendar date // format to calendar date
$dob = $this->_customerSession->getCustomerData()->getDob(); $dob = $this->_customerSession->getCustomerData()->getDob();
$dob = strtotime($dob); if($dob) {
$dob = date('m/d/Y', $dob); $dob = strtotime($dob);
} else { $dob = date('m/d/Y', $dob);
$gender = ""; }
$dob = "";
} }
// add to config // add to config
......
...@@ -90,7 +90,8 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface ...@@ -90,7 +90,8 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
\Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\UrlInterface $urlBuilder, \Magento\Framework\UrlInterface $urlBuilder,
\Magento\Payment\Model\CcConfig $ccConfig \Magento\Payment\Model\CcConfig $ccConfig
) { )
{
$this->_adyenHelper = $adyenHelper; $this->_adyenHelper = $adyenHelper;
$this->_request = $request; $this->_request = $request;
$this->_customerSession = $customerSession; $this->_customerSession = $customerSession;
...@@ -130,25 +131,13 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface ...@@ -130,25 +131,13 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
] ]
]); ]);
$demoMode = $this->_adyenHelper->getAdyenAbstractConfigDataFlag('demo_mode');
if ($demoMode) {
$cseKey = $this->_adyenHelper->getAdyenCcConfigData('cse_publickey_test');
} else {
$cseKey = $this->_adyenHelper->getAdyenCcConfigData('cse_publickey_live');
}
$cseEnabled = $this->_adyenHelper->getAdyenCcConfigDataFlag('cse_enabled');
$recurringType = $this->_adyenHelper->getAdyenAbstractConfigData('recurring_type'); $recurringType = $this->_adyenHelper->getAdyenAbstractConfigData('recurring_type');
$canCreateBillingAgreement = false; $canCreateBillingAgreement = false;
if ($recurringType == "ONECLICK" || $recurringType == "ONECLICK,RECURRING") { if ($recurringType == "ONECLICK" || $recurringType == "ONECLICK,RECURRING") {
$canCreateBillingAgreement = true; $canCreateBillingAgreement = true;
} }
$config['payment'] ['adyenOneclick']['cseKey'] = $cseKey; $config['payment'] ['adyenOneclick']['librarySource'] = $this->_adyenHelper->getLibrarySource();
$config['payment'] ['adyenOneclick']['cseEnabled'] = $cseEnabled;
$config['payment'] ['adyenOneclick']['cseEnabled'] = $cseEnabled;
$config['payment']['adyenOneclick']['generationTime'] = date("c"); $config['payment']['adyenOneclick']['generationTime'] = date("c");
$config['payment']['adyenOneclick']['canCreateBillingAgreement'] = $canCreateBillingAgreement; $config['payment']['adyenOneclick']['canCreateBillingAgreement'] = $canCreateBillingAgreement;
...@@ -178,9 +167,9 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface ...@@ -178,9 +167,9 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
$recurringType = $this->_getRecurringContractType(); $recurringType = $this->_getRecurringContractType();
$billingAgreements = $this->_adyenHelper->getOneClickPaymentMethods( $billingAgreements = $this->_adyenHelper->getOneClickPaymentMethods(
$customerId, $customerId,
$storeId, $storeId,
$grandTotal, $grandTotal,
$recurringType $recurringType
); );
} }
...@@ -227,7 +216,6 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface ...@@ -227,7 +216,6 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
} }
/** /**
* Retrieve credit card expire months * Retrieve credit card expire months
* *
......
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Observer;
use Magento\Framework\Event\Observer;
use Magento\Payment\Observer\AbstractDataAssignObserver;
use Magento\Quote\Api\Data\PaymentInterface;
/**
* Class DataAssignObserver
*/
class AdyenApplePayDataAssignObserver extends AbstractDataAssignObserver
{
const TOKEN = 'token';
/**
* @var array
*/
protected $additionalInformationList = [
self::TOKEN
];
/**
* @param Observer $observer
* @return void
*/
public function execute(Observer $observer)
{
$data = $this->readDataArgument($observer);
$additionalData = $data->getData(PaymentInterface::KEY_ADDITIONAL_DATA);
if (!is_array($additionalData)) {
return;
}
$paymentInfo = $this->readPaymentModelArgument($observer);
// set ccType
$paymentInfo->setCcType('apple_pay');
foreach ($this->additionalInformationList as $additionalInformationKey) {
if (isset($additionalData[$additionalInformationKey])) {
$paymentInfo->setAdditionalInformation(
$additionalInformationKey,
$additionalData[$additionalInformationKey]
);
}
}
}
}
...@@ -9,7 +9,7 @@ bin/magento setup:upgrade ...@@ -9,7 +9,7 @@ bin/magento setup:upgrade
``` ```
## Manual ## ## Manual ##
<a href="https://docs.adyen.com/developers/magento#magento2integration" target="_blank">https://docs.adyen.com/developers/magento#magento2integration</a> [Magento 2 documentation](https://docs.adyen.com/developers/plug-ins-and-partners/magento/magento-2)
## Setup Cron ## ## Setup Cron ##
Make sure that your magento cron is running every minute. We are using a cronjob to process the notifications. The cronjob will be executed every minute. It only executes the notifications that have been received at least 2 minutes ago. We have built in this 2 minutes so we are sure Magento has created the order and all save after events are executed. A handy tool to get insight into your cronjobs is AOE scheduler. You can download this tool through Magento Connect or GitHub Make sure that your magento cron is running every minute. We are using a cronjob to process the notifications. The cronjob will be executed every minute. It only executes the notifications that have been received at least 2 minutes ago. We have built in this 2 minutes so we are sure Magento has created the order and all save after events are executed. A handy tool to get insight into your cronjobs is AOE scheduler. You can download this tool through Magento Connect or GitHub
......
...@@ -2,13 +2,23 @@ ...@@ -2,13 +2,23 @@
"name": "adyen/module-payment", "name": "adyen/module-payment",
"description": "Official Magento2 Plugin to connect to Payment Service Provider Adyen.", "description": "Official Magento2 Plugin to connect to Payment Service Provider Adyen.",
"type": "magento2-module", "type": "magento2-module",
"version": "2.1.3", "version": "2.2.0",
"license": [ "license": [
"OSL-3.0", "OSL-3.0",
"AFL-3.0" "AFL-3.0"
], ],
"repositories": [
{
"type": "composer",
"url": "https://repo.magento.com/"
}
],
"require": { "require": {
"adyen/php-api-library": "*" "adyen/php-api-library": "*",
"magento/framework": ">=100.1.0"
},
"require-dev": {
"phpunit/phpunit": "~5"
}, },
"autoload": { "autoload": {
"files": [ "files": [
...@@ -17,5 +27,10 @@ ...@@ -17,5 +27,10 @@
"psr-4": { "psr-4": {
"Adyen\\Payment\\": "" "Adyen\\Payment\\": ""
} }
},
"autoload-dev": {
"psr-4": {
"Adyen\\Payment\\Tests\\": "tests/"
}
} }
} }
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\Notification\MessageList">
<arguments>
<argument name="messages" xsi:type="array">
<item name="cronMessage" xsi:type="string">Adyen\Payment\AdminMessage\CronMessage</item>
</argument>
</arguments>
</type>
</config>
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
<include path="Adyen_Payment::system/adyen_pos.xml"/> <include path="Adyen_Payment::system/adyen_pos.xml"/>
<include path="Adyen_Payment::system/adyen_pay_by_mail.xml"/> <include path="Adyen_Payment::system/adyen_pay_by_mail.xml"/>
<include path="Adyen_Payment::system/adyen_boleto.xml"/> <include path="Adyen_Payment::system/adyen_boleto.xml"/>
<include path="Adyen_Payment::system/adyen_apple_pay.xml"/>
</group> </group>
<group id="test" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1"> <group id="test" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Test</label> <label>Test</label>
......
<?xml version="1.0"?>
<!--
~ ######
~ ######
~ ############ ####( ###### #####. ###### ############ ############
~ ############# #####( ###### #####. ###### ############# #############
~ ###### #####( ###### #####. ###### ##### ###### ##### ######
~ ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
~ ###### ###### #####( ###### #####. ###### ##### ##### ######
~ ############# ############# ############# ############# ##### ######
~ ############ ############ ############# ############ ##### ######
~ ######
~ #############
~ ############
~
~ Adyen Payment Module
~
~ Copyright (c) 2017 Adyen B.V.
~ This file is open source and available under the MIT license.
~ See the LICENSE file for more info.
~
~ Author: Adyen <magento@adyen.com>
-->
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="adyen_apple_pay" translate="label" type="text" sortOrder="460" showInDefault="1" showInWebsite="1" showInStore="1">
<label><![CDATA[Apple Pay integration]]></label>
<frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
<fieldset_css>adyen-method-adyen-cc</fieldset_css>
<comment>Process Apple Pay transactions</comment>
<field id="active" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enabled</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/adyen_apple_pay/active</config_path>
</field>
<field id="title" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Title</label>
<config_path>payment/adyen_apple_pay/title</config_path>
</field>
<field id="sort_order" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Sort Order</label>
<frontend_class>validate-number</frontend_class>
<config_path>payment/adyen_apple_pay/sort_order</config_path>
</field>
<field id="merchant_identifier_test" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Test: Apple Merchant Identifier</label>
<tooltip>You can retrieve this from your Apple Account.</tooltip>
<config_path>payment/adyen_apple_pay/merchant_identifier_test</config_path>
</field>
<field id="merchant_identifier_live" translate="label" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Live: Apple Merchant Identifier</label>
<tooltip>You can retrieve this from your Apple Account.</tooltip>
<config_path>payment/adyen_apple_pay/merchant_identifier_live</config_path>
</field>
<field id="full_path_location_pem_file_test" translate="label" type="text" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Test: PEM File location</label>
<tooltip>You need to generate a pem file from the apple certificate. You need to upload this to your webserver and define the full path location here.</tooltip>
<config_path>payment/adyen_apple_pay/full_path_location_pem_file_test</config_path>
</field>
<field id="full_path_location_pem_file_live" translate="label" type="text" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Live: PEM File location</label>
<tooltip>You need to generate a pem file from the apple certificate. You need to upload this to your webserver and define the full path location here.</tooltip>
<config_path>payment/adyen_apple_pay/full_path_location_pem_file_live</config_path>
</field>
</group>
</include>
\ No newline at end of file
...@@ -47,20 +47,15 @@ ...@@ -47,20 +47,15 @@
<source_model>Adyen\Payment\Model\Config\Source\CcType</source_model> <source_model>Adyen\Payment\Model\Config\Source\CcType</source_model>
<config_path>payment/adyen_cc/cctypes</config_path> <config_path>payment/adyen_cc/cctypes</config_path>
</field> </field>
<!--<field id="cse_enabled" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">--> <field id="cse_library_token_test" translate="label" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<!--<label>Enable CSE</label>--> <label>Library token of Test Adyen Web Service User</label>
<!--<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>--> <tooltip>Copy this from the Test Adyen Customer Area => Settings => Users => System => [web service user]=> Library token.</tooltip>
<!--<config_path>payment/adyen_cc/cse_enabled</config_path>--> <config_path>payment/adyen_cc/cse_library_token_test</config_path>
<!--</field>-->
<field id="cse_publickey_test" translate="label" type="textarea" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enter CSE Public Key of Test Adyen Web Service User</label>
<depends><field id="cse_enabled">1</field></depends>
<config_path>payment/adyen_cc/cse_publickey_test</config_path>
</field> </field>
<field id="cse_publickey_live" translate="label" type="textarea" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1"> <field id="cse_library_token_live" translate="label" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enter CSE Public Key of Live Adyen Web Service User</label> <label>Library token of Live Adyen Web Service User</label>
<depends><field id="cse_enabled">1</field></depends> <tooltip>Copy this from the Live Adyen Customer Area => Settings => Users => System => [web service user]=> Library token.</tooltip>
<config_path>payment/adyen_cc/cse_publickey_live</config_path> <config_path>payment/adyen_cc/cse_library_token_live</config_path>
</field> </field>
<group id="adyen_cc_advanced_settings" translate="label" showInDefault="1" showInWebsite="1" sortOrder="150"> <group id="adyen_cc_advanced_settings" translate="label" showInDefault="1" showInWebsite="1" sortOrder="150">
...@@ -72,9 +67,17 @@ ...@@ -72,9 +67,17 @@
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/adyen_cc/enable_moto</config_path> <config_path>payment/adyen_cc/enable_moto</config_path>
</field> </field>
<field id="installments" translate="label" sortOrder="220" showInDefault="1" showInWebsite="1" showInStore="0"> <field id="enable_installments" translate="label" type="select" sortOrder="219" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable Installments</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<tooltip>Enable installments for each credit card type.</tooltip>
<config_path>payment/adyen_cc/enable_installments</config_path>
</field>
<field id="installments" translate="label" sortOrder="220" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Installments</label> <label>Installments</label>
<tooltip>Configure your installment foreach creditcard type.</tooltip> <depends><field id="enable_installments">1</field></depends>
<tooltip>Configure your installment for each credit card type: Insert the minimum amount required to make the configured installment available in the amount range column.
Example: if the amount range is configured to 100 and the number of installments to 4x, the shopper will see the 4x option only if the payment total is higher or equal than 100.</tooltip>
<frontend_model>Adyen\Payment\Block\Adminhtml\System\Config\Field\Installments</frontend_model> <frontend_model>Adyen\Payment\Block\Adminhtml\System\Config\Field\Installments</frontend_model>
<backend_model>Adyen\Payment\Model\Config\Backend\Installments</backend_model> <backend_model>Adyen\Payment\Model\Config\Backend\Installments</backend_model>
<config_path>payment/adyen_cc/installments</config_path> <config_path>payment/adyen_cc/installments</config_path>
......
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
<sort_order>2</sort_order> <sort_order>2</sort_order>
<cctypes>AE,VI,MC,DI</cctypes> <cctypes>AE,VI,MC,DI</cctypes>
<useccv>1</useccv> <useccv>1</useccv>
<cse_enabled>1</cse_enabled>
<enable_moto>0</enable_moto> <enable_moto>0</enable_moto>
<payment_action>authorize</payment_action> <payment_action>authorize</payment_action>
<is_gateway>1</is_gateway> <is_gateway>1</is_gateway>
...@@ -71,7 +70,6 @@ ...@@ -71,7 +70,6 @@
<recurring_payment_type>ONECLICK</recurring_payment_type> <recurring_payment_type>ONECLICK</recurring_payment_type>
<payment_action>authorize</payment_action> <payment_action>authorize</payment_action>
<useccv>1</useccv> <useccv>1</useccv>
<cse_enabled>1</cse_enabled>
<enable_moto>0</enable_moto> <enable_moto>0</enable_moto>
<payment_action>authorize</payment_action> <payment_action>authorize</payment_action>
<is_gateway>1</is_gateway> <is_gateway>1</is_gateway>
...@@ -191,6 +189,25 @@ ...@@ -191,6 +189,25 @@
<can_cancel>1</can_cancel> <can_cancel>1</can_cancel>
<group>adyen</group> <group>adyen</group>
</adyen_boleto> </adyen_boleto>
<adyen_apple_pay>
<active>0</active>
<model>AdyenPaymentApplePayFacade</model>
<title>Adyen Apple Pay</title>
<allowspecific>0</allowspecific>
<sort_order>8</sort_order>
<payment_action>authorize</payment_action>
<is_gateway>1</is_gateway>
<can_use_checkout>1</can_use_checkout>
<can_authorize>1</can_authorize>
<can_capture>1</can_capture>
<can_capture_partial>1</can_capture_partial>
<can_use_internal>0</can_use_internal>
<can_refund_partial_per_invoice>1</can_refund_partial_per_invoice>
<can_refund>1</can_refund>
<can_void>1</can_void>
<can_cancel>1</can_cancel>
<group>adyen</group>
</adyen_apple_pay>
</payment> </payment>
</default> </default>
</config> </config>
...@@ -104,6 +104,16 @@ ...@@ -104,6 +104,16 @@
<argument name="commandPool" xsi:type="object">AdyenPaymentPayByMailCommandPool</argument> <argument name="commandPool" xsi:type="object">AdyenPaymentPayByMailCommandPool</argument>
</arguments> </arguments>
</virtualType> </virtualType>
<virtualType name="AdyenPaymentApplePayFacade" type="Magento\Payment\Model\Method\Adapter">
<arguments>
<argument name="code" xsi:type="const">Adyen\Payment\Model\Ui\AdyenApplePayConfigProvider::CODE</argument>
<argument name="formBlockType" xsi:type="string">Adyen\Payment\Block\Form\ApplePay</argument>
<argument name="infoBlockType" xsi:type="string">Adyen\Payment\Block\Info\ApplePay</argument>
<argument name="valueHandlerPool" xsi:type="object">AdyenPaymentApplePayValueHandlerPool</argument>
<argument name="validatorPool" xsi:type="object">AdyenPaymentApplePayValidatorPool</argument>
<argument name="commandPool" xsi:type="object">AdyenPaymentApplePayCommandPool</argument>
</arguments>
</virtualType>
<!-- Value handlers infrastructure --> <!-- Value handlers infrastructure -->
<virtualType name="AdyenPaymentGenericValueHandlerPool" type="Magento\Payment\Gateway\Config\ValueHandlerPool"> <virtualType name="AdyenPaymentGenericValueHandlerPool" type="Magento\Payment\Gateway\Config\ValueHandlerPool">
...@@ -211,6 +221,19 @@ ...@@ -211,6 +221,19 @@
</arguments> </arguments>
</virtualType> </virtualType>
<virtualType name="AdyenPaymentApplePayValueHandlerPool" type="Magento\Payment\Gateway\Config\ValueHandlerPool">
<arguments>
<argument name="handlers" xsi:type="array">
<item name="default" xsi:type="string">AdyenPaymentApplePayConfigValueHandler</item>
</argument>
</arguments>
</virtualType>
<virtualType name="AdyenPaymentApplePayConfigValueHandler" type="Magento\Payment\Gateway\Config\ConfigValueHandler">
<arguments>
<argument name="configInterface" xsi:type="object">AdyenPaymentApplePayConfig</argument>
</arguments>
</virtualType>
<!-- Configuration reader --> <!-- Configuration reader -->
<virtualType name="AdyenPaymentGenericConfig" type="Magento\Payment\Gateway\Config\Config"> <virtualType name="AdyenPaymentGenericConfig" type="Magento\Payment\Gateway\Config\Config">
<arguments> <arguments>
...@@ -253,6 +276,12 @@ ...@@ -253,6 +276,12 @@
<argument name="methodCode" xsi:type="const">Adyen\Payment\Model\Ui\AdyenPayByMailConfigProvider::CODE</argument> <argument name="methodCode" xsi:type="const">Adyen\Payment\Model\Ui\AdyenPayByMailConfigProvider::CODE</argument>
</arguments> </arguments>
</virtualType> </virtualType>
<virtualType name="AdyenPaymentApplePayConfig" type="Magento\Payment\Gateway\Config\Config">
<arguments>
<argument name="methodCode" xsi:type="const">Adyen\Payment\Model\Ui\AdyenApplePayConfigProvider::CODE</argument>
</arguments>
</virtualType>
<!-- Commands infrastructure --> <!-- Commands infrastructure -->
<virtualType name="AdyenPaymentCcCommandPool" type="Magento\Payment\Gateway\Command\CommandPool"> <virtualType name="AdyenPaymentCcCommandPool" type="Magento\Payment\Gateway\Command\CommandPool">
...@@ -341,6 +370,18 @@ ...@@ -341,6 +370,18 @@
</arguments> </arguments>
</virtualType> </virtualType>
<virtualType name="AdyenPaymentApplePayCommandPool" type="Magento\Payment\Gateway\Command\CommandPool">
<arguments>
<argument name="commands" xsi:type="array">
<item name="authorize" xsi:type="string">AdyenPaymentApplePayAuthorizeCommand</item>
<item name="capture" xsi:type="string">AdyenPaymentCaptureCommand</item>
<item name="void" xsi:type="string">AdyenPaymentCancelCommand</item>
<item name="refund" xsi:type="string">AdyenPaymentRefundCommand</item>
<item name="cancel" xsi:type="string">AdyenPaymentCancelCommand</item>
</argument>
</arguments>
</virtualType>
<!-- Authorization command --> <!-- Authorization command -->
<virtualType name="AdyenPaymentCcAuthorizeCommand" type="Magento\Payment\Gateway\Command\GatewayCommand"> <virtualType name="AdyenPaymentCcAuthorizeCommand" type="Magento\Payment\Gateway\Command\GatewayCommand">
<arguments> <arguments>
...@@ -391,6 +432,16 @@ ...@@ -391,6 +432,16 @@
</arguments> </arguments>
</virtualType> </virtualType>
<virtualType name="AdyenPaymentApplePayAuthorizeCommand" type="Magento\Payment\Gateway\Command\GatewayCommand">
<arguments>
<argument name="requestBuilder" xsi:type="object">AdyenPaymentApplePayAuthorizeRequest</argument>
<argument name="transferFactory" xsi:type="object">Adyen\Payment\Gateway\Http\TransferFactory</argument>
<argument name="client" xsi:type="object">Adyen\Payment\Gateway\Http\Client\TransactionAuthorization</argument>
<argument name="validator" xsi:type="object">GeneralResponseValidator</argument>
<argument name="handler" xsi:type="object">AdyenPaymentResponseHandlerComposite</argument>
</arguments>
</virtualType>
<!-- Capture command --> <!-- Capture command -->
<virtualType name="AdyenPaymentCaptureCommand" type="Magento\Payment\Gateway\Command\GatewayCommand"> <virtualType name="AdyenPaymentCaptureCommand" type="Magento\Payment\Gateway\Command\GatewayCommand">
<arguments> <arguments>
...@@ -496,6 +547,20 @@ ...@@ -496,6 +547,20 @@
</arguments> </arguments>
</virtualType> </virtualType>
<virtualType name="AdyenPaymentApplePayAuthorizeRequest" type="Magento\Payment\Gateway\Request\BuilderComposite">
<arguments>
<argument name="builders" xsi:type="array">
<item name="merchantaccount" xsi:type="string">Adyen\Payment\Gateway\Request\MerchantAccountDataBuilder</item>
<item name="customer" xsi:type="string">Adyen\Payment\Gateway\Request\CustomerDataBuilder</item>
<item name="customerip" xsi:type="string">Adyen\Payment\Gateway\Request\CustomerIpDataBuilder</item>
<item name="address" xsi:type="string">Adyen\Payment\Gateway\Request\AddressDataBuilder</item>
<item name="payment" xsi:type="string">Adyen\Payment\Gateway\Request\PaymentDataBuilder</item>
<item name="browserinfo" xsi:type="string">Adyen\Payment\Gateway\Request\BrowserInfoDataBuilder</item>
<item name="transaction" xsi:type="string">Adyen\Payment\Gateway\Request\ApplePayAuthorizationDataBuilder</item>
</argument>
</arguments>
</virtualType>
<!-- Capture Request --> <!-- Capture Request -->
<virtualType name="AdyenPaymentCaptureRequest" type="Magento\Payment\Gateway\Request\BuilderComposite"> <virtualType name="AdyenPaymentCaptureRequest" type="Magento\Payment\Gateway\Request\BuilderComposite">
<arguments> <arguments>
...@@ -549,6 +614,15 @@ ...@@ -549,6 +614,15 @@
</argument> </argument>
</arguments> </arguments>
</virtualType> </virtualType>
<virtualType name="AdyenPaymentResponseHandlerComposite" type="Magento\Payment\Gateway\Response\HandlerChain">
<arguments>
<argument name="handlers" xsi:type="array">
<item name="payment_details" xsi:type="string">Adyen\Payment\Gateway\Response\PaymentAuthorisationDetailsHandler</item>
<item name="payment_comments" xsi:type="string">Adyen\Payment\Gateway\Response\PaymentCommentHistoryHandler</item>
</argument>
</arguments>
</virtualType>
<virtualType name="AdyenPaymentCaptureResponseHandlerComposite" type="Magento\Payment\Gateway\Response\HandlerChain"> <virtualType name="AdyenPaymentCaptureResponseHandlerComposite" type="Magento\Payment\Gateway\Response\HandlerChain">
<arguments> <arguments>
<argument name="handlers" xsi:type="array"> <argument name="handlers" xsi:type="array">
...@@ -579,6 +653,7 @@ ...@@ -579,6 +653,7 @@
<arguments> <arguments>
<argument name="validators" xsi:type="array"> <argument name="validators" xsi:type="array">
<item name="country" xsi:type="string">AdyenCcCountryValidator</item> <item name="country" xsi:type="string">AdyenCcCountryValidator</item>
<item name="global" xsi:type="string">Adyen\Payment\Gateway\Validator\InstallmentValidator</item>
</argument> </argument>
</arguments> </arguments>
</virtualType> </virtualType>
...@@ -592,6 +667,7 @@ ...@@ -592,6 +667,7 @@
<arguments> <arguments>
<argument name="validators" xsi:type="array"> <argument name="validators" xsi:type="array">
<item name="country" xsi:type="string">AdyenOneclickCountryValidator</item> <item name="country" xsi:type="string">AdyenOneclickCountryValidator</item>
<item name="global" xsi:type="string">Adyen\Payment\Gateway\Validator\InstallmentValidator</item>
</argument> </argument>
</arguments> </arguments>
</virtualType> </virtualType>
...@@ -667,6 +743,19 @@ ...@@ -667,6 +743,19 @@
</arguments> </arguments>
</virtualType> </virtualType>
<virtualType name="AdyenPaymentApplePayValidatorPool" type="Magento\Payment\Gateway\Validator\ValidatorPool">
<arguments>
<argument name="validators" xsi:type="array">
<item name="country" xsi:type="string">AdyenApplePayCountryValidator</item>
</argument>
</arguments>
</virtualType>
<virtualType name="AdyenApplePayCountryValidator" type="Magento\Payment\Gateway\Validator\CountryValidator">
<arguments>
<argument name="config" xsi:type="object">AdyenPaymentApplePayConfig</argument>
</arguments>
</virtualType>
<!--General Response validator--> <!--General Response validator-->
<virtualType name="GeneralResponseValidator" type="Adyen\Payment\Gateway\Validator\GeneralResponseValidator"> <virtualType name="GeneralResponseValidator" type="Adyen\Payment\Gateway\Validator\GeneralResponseValidator">
...@@ -743,4 +832,5 @@ ...@@ -743,4 +832,5 @@
</type> </type>
<preference for="Adyen\Payment\Api\GuestAdyenPaymentMethodManagementInterface" type="Adyen\Payment\Model\GuestAdyenPaymentMethodManagement" /> <preference for="Adyen\Payment\Api\GuestAdyenPaymentMethodManagementInterface" type="Adyen\Payment\Model\GuestAdyenPaymentMethodManagement" />
<preference for="Adyen\Payment\Api\AdyenPaymentMethodManagementInterface" type="Adyen\Payment\Model\AdyenPaymentMethodManagement" /> <preference for="Adyen\Payment\Api\AdyenPaymentMethodManagementInterface" type="Adyen\Payment\Model\AdyenPaymentMethodManagement" />
<preference for="Adyen\Payment\Api\AdyenRequestMerchantSessionInterface" type="Adyen\Payment\Model\AdyenRequestMerchantSession" />
</config> </config>
\ No newline at end of file
...@@ -38,4 +38,7 @@ ...@@ -38,4 +38,7 @@
<event name="payment_method_assign_data_adyen_boleto"> <event name="payment_method_assign_data_adyen_boleto">
<observer name="adyen_boleto_gateway_data_assign" instance="Adyen\Payment\Observer\AdyenBoletoDataAssignObserver" /> <observer name="adyen_boleto_gateway_data_assign" instance="Adyen\Payment\Observer\AdyenBoletoDataAssignObserver" />
</event> </event>
<event name="payment_method_assign_data_adyen_apple_pay">
<observer name="adyen_apple_pay_gateway_data_assign" instance="Adyen\Payment\Observer\AdyenApplePayDataAssignObserver" />
</event>
</config> </config>
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
<item name="adyen_sepa_config_provider" xsi:type="object">Adyen\Payment\Model\Ui\AdyenSepaConfigProvider</item> <item name="adyen_sepa_config_provider" xsi:type="object">Adyen\Payment\Model\Ui\AdyenSepaConfigProvider</item>
<item name="adyen_boleto_config_provider" xsi:type="object">Adyen\Payment\Model\Ui\AdyenBoletoConfigProvider</item> <item name="adyen_boleto_config_provider" xsi:type="object">Adyen\Payment\Model\Ui\AdyenBoletoConfigProvider</item>
<item name="adyen_pos_config_provider" xsi:type="object">Adyen\Payment\Model\Ui\AdyenPosConfigProvider</item> <item name="adyen_pos_config_provider" xsi:type="object">Adyen\Payment\Model\Ui\AdyenPosConfigProvider</item>
<item name="adyen_apple_pay_config_provider" xsi:type="object">Adyen\Payment\Model\Ui\AdyenApplePayConfigProvider</item>
</argument> </argument>
</arguments> </arguments>
</type> </type>
......
...@@ -24,12 +24,13 @@ ...@@ -24,12 +24,13 @@
--> -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Adyen_Payment" setup_version="2.1.3"> <module name="Adyen_Payment" setup_version="2.2.0">
<sequence> <sequence>
<module name="Magento_Sales"/> <module name="Magento_Sales"/>
<module name="Magento_Quote"/> <module name="Magento_Quote"/>
<module name="Magento_Checkout"/> <module name="Magento_Checkout"/>
<module name="Magento_Paypal"/> <module name="Magento_Paypal"/>
<module name="Magento_AdminNotification"/>
</sequence> </sequence>
</module> </module>
</config> </config>
...@@ -39,6 +39,9 @@ ...@@ -39,6 +39,9 @@
<method name="adyen_hpp"> <method name="adyen_hpp">
<allow_multiple_address>0</allow_multiple_address> <allow_multiple_address>0</allow_multiple_address>
</method> </method>
<method name="adyen_apple_pay">
<allow_multiple_address>0</allow_multiple_address>
</method>
</methods> </methods>
</payment> </payment>
......
...@@ -30,18 +30,24 @@ ...@@ -30,18 +30,24 @@
<route url="/V1/guest-carts/:cartId/retrieve-adyen-payment-methods" method="POST"> <route url="/V1/guest-carts/:cartId/retrieve-adyen-payment-methods" method="POST">
<service class="Adyen\Payment\Api\GuestAdyenPaymentMethodManagementInterface" method="getPaymentMethods"/> <service class="Adyen\Payment\Api\GuestAdyenPaymentMethodManagementInterface" method="getPaymentMethods"/>
<resources> <resources>
<resource ref="anonymous" /> <resource ref="anonymous"/>
</resources> </resources>
</route> </route>
<route url="/V1/carts/mine/retrieve-adyen-payment-methods" method="POST"> <route url="/V1/carts/mine/retrieve-adyen-payment-methods" method="POST">
<service class="Adyen\Payment\Api\AdyenPaymentMethodManagementInterface" method="getPaymentMethods"/> <service class="Adyen\Payment\Api\AdyenPaymentMethodManagementInterface" method="getPaymentMethods"/>
<resources> <resources>
<resource ref="self" /> <resource ref="self"/>
</resources> </resources>
<data> <data>
<parameter name="cartId" force="true">%cart_id%</parameter> <parameter name="cartId" force="true">%cart_id%</parameter>
</data> </data>
</route> </route>
<route url="/V1/adyen/request-merchant-session" method="POST">
<service class="Adyen\Payment\Api\AdyenRequestMerchantSessionInterface" method="getMerchantSession"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
</routes> </routes>
\ No newline at end of file
...@@ -50,4 +50,5 @@ ...@@ -50,4 +50,5 @@
"The payment is REFUSED","The payment is REFUSED" "The payment is REFUSED","The payment is REFUSED"
"Failed to disable this contract","Failed to disable this contract" "Failed to disable this contract","Failed to disable this contract"
"You will be redirected to the Adyen App", "You will be redirected to the Adyen App" "You will be redirected to the Adyen App", "You will be redirected to the Adyen App"
"Continue to Adyen App", "Continue to Adyen App" "Continue to Adyen App", "Continue to Adyen App"
\ No newline at end of file "Do not use Installments", "Do not use Installments"
\ No newline at end of file
<phpunit bootstrap="vendor/autoload.php">
<testsuites>
<testsuite name="Adyen payment module tests">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2015 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/
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"));
}
}
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -61,6 +61,9 @@ ...@@ -61,6 +61,9 @@
<item name="adyen_boleto" xsi:type="array"> <item name="adyen_boleto" xsi:type="array">
<item name="isBillingAddressRequired" xsi:type="boolean">true</item> <item name="isBillingAddressRequired" xsi:type="boolean">true</item>
</item> </item>
<item name="adyen_apple_pay" xsi:type="array">
<item name="isBillingAddressRequired" xsi:type="boolean">true</item>
</item>
</item> </item>
</item> </item>
</item> </item>
......
...@@ -5,9 +5,6 @@ ...@@ -5,9 +5,6 @@
/*jshint browser:true jquery:true*/ /*jshint browser:true jquery:true*/
/*global alert*/ /*global alert*/
var config = { var config = {
paths: {
'adyen/encrypt' : 'Adyen_Payment/js/view/payment/adyen.encrypt.min'
},
config: { config: {
mixins: { mixins: {
'Adyen_Payment/js/action/place-order': { 'Adyen_Payment/js/action/place-order': {
......
...@@ -61,11 +61,76 @@ ...@@ -61,11 +61,76 @@
background-position: 0 -272px; background-position: 0 -272px;
} }
.checkout-payment-method .payment-method-title label div.adyen-sprite.adyen_apple_pay {
background:url(../images/logos/apple_pay.png) no-repeat;
height:43px;
}
.checkout-payment-method .input-text._has-datepicker { .checkout-payment-method .input-text._has-datepicker {
width:20%; width:20%;
margin-right:10px; margin-right:10px;
} }
.apple-pay-button-with-text {
--apple-pay-scale: 1.5625; /* (height / 32) */
display: inline-flex;
justify-content: center;
font-size: 12px;
border-radius: 5px;
padding: 0px;
box-sizing: border-box;
/*min-width: 200px;*/
width:100%;
min-height: 32px;
max-height: 64px;
margin-bottom: 10px;
cursor: pointer;
}
.apple-pay-button-black-with-text {
background-color: black;
color: white;
}
.apple-pay-button-white-with-text {
background-color: white;
color: black;
}
.apple-pay-button-white-with-line-with-text {
background-color: white;
color: black;
border: .5px solid black;
}
.apple-pay-button-with-text.apple-pay-button-black-with-text > .logo {
background-image: -webkit-named-image(apple-pay-logo-white);
background-color: black;
}
.apple-pay-button-with-text.apple-pay-button-white-with-text > .logo {
background-image: -webkit-named-image(apple-pay-logo-black);
background-color: white;
}
.apple-pay-button-with-text.apple-pay-button-white-with-line-with-text > .logo {
background-image: -webkit-named-image(apple-pay-logo-black);
background-color: white;
}
.apple-pay-button-with-text > .text {
font-family: -apple-system;
font-size: calc(1em * var(--apple-pay-scale));
font-weight: 300;
align-self: center;
margin-right: calc(2px * var(--apple-pay-scale));
}
.apple-pay-button-with-text > .logo {
width: calc(35px * var(--apple-pay-scale));
height: 100%;
background-size: 100% 60%;
background-repeat: no-repeat;
background-position: 0 50%;
margin: 0;
border: none;
min-width: 0px; /* override magento min-width */
min-height: 42px; /* override magento min-height */
}
...@@ -35,7 +35,6 @@ define( ...@@ -35,7 +35,6 @@ define(
return function (paymentData, redirectOnSuccess) { return function (paymentData, redirectOnSuccess) {
var serviceUrl, var serviceUrl,
payload; payload;
//redirectOnSuccess = redirectOnSuccess !== false; //redirectOnSuccess = redirectOnSuccess !== false;
redirectOnSuccess = redirectOnSuccess === false ? false : true; redirectOnSuccess = redirectOnSuccess === false ? false : true;
...@@ -60,13 +59,14 @@ define( ...@@ -60,13 +59,14 @@ define(
} }
fullScreenLoader.startLoader(); fullScreenLoader.startLoader();
return storage.post( return storage.post(
serviceUrl, JSON.stringify(payload) serviceUrl, JSON.stringify(payload)
).done( ).done(
function () { function (response) {
if (redirectOnSuccess) { if (redirectOnSuccess) {
window.location.replace(url.build(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl)); window.location.replace(url.build(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl));
} else{
fullScreenLoader.stopLoader();
} }
} }
).fail( ).fail(
......
...@@ -8,7 +8,7 @@ define( ...@@ -8,7 +8,7 @@ define(
], ],
function (ko) { function (ko) {
'use strict'; 'use strict';
var installments = ko.observableArray([]); var installments = ko.observableArray(['key', 'value']);
return { return {
/** /**
* Populate the list of installments * Populate the list of installments
...@@ -17,14 +17,15 @@ define( ...@@ -17,14 +17,15 @@ define(
setInstallments: function (installmentData) { setInstallments: function (installmentData) {
// remove everything from the current list // remove everything from the current list
installments.removeAll(); installments.removeAll();
// populate installments
var i; var i;
for (i = 1; i <= installmentData; i++) { for (i = 0; i < installmentData.length; i++) {
installments.push({ installments.push(
key: i, {
value: i key: installmentData[i].key,
}); value: installmentData[i].value
}
);
} }
}, },
/** /**
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -55,6 +55,10 @@ define( ...@@ -55,6 +55,10 @@ define(
{ {
type: 'adyen_boleto', type: 'adyen_boleto',
component: 'Adyen_Payment/js/view/payment/method-renderer/adyen-boleto-method' component: 'Adyen_Payment/js/view/payment/method-renderer/adyen-boleto-method'
},
{
type: 'adyen_apple_pay',
component: 'Adyen_Payment/js/view/payment/method-renderer/adyen-apple-pay-method'
} }
); );
/** Add view logic here if needed */ /** Add view logic here if needed */
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
define(
[
'jquery',
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/view/payment/default',
'Magento_Checkout/js/action/place-order',
'Magento_Checkout/js/model/payment/additional-validators',
'Magento_Checkout/js/model/url-builder',
'mage/storage',
'mage/url',
'Magento_Ui/js/model/messages',
'mage/translate',
],
function ($, quote, Component, placeOrderAction, additionalValidators, urlBuilder, storage, url, Messages, $t) {
'use strict';
return Component.extend({
self: this,
defaults: {
template: 'Adyen_Payment/payment/apple-pay-form'
},
/**
* @returns {Boolean}
*/
isShowLegend: function () {
return true;
},
setPlaceOrderHandler: function (handler) {
this.placeOrderHandler = handler;
},
setValidateHandler: function (handler) {
this.validateHandler = handler;
},
getCode: function () {
return 'adyen_apple_pay';
},
getData: function () {
return {
'method': this.item.method,
'additional_data': {}
};
},
isActive: function () {
return true;
},
/**
* @override
*/
placeApplePayOrder: function (data, event) {
event.preventDefault();
var self = this;
if (!additionalValidators.validate()) {
return false;
}
var request = {
countryCode: quote.billingAddress().countryId,
currencyCode: quote.totals().quote_currency_code,
supportedNetworks: ['visa', 'masterCard', 'amex', 'discover'],
merchantCapabilities: ['supports3DS'],
total: {label: $t('Grand Total'), amount: quote.totals().base_grand_total}
};
var session = new ApplePaySession(2, request);
session.onvalidatemerchant = function (event) {
var promise = self.performValidation(event.validationURL);
promise.then(function (merchantSession) {
session.completeMerchantValidation(merchantSession);
});
}
session.onpaymentauthorized = function (event) {
var data = {
'method': self.item.method,
'additional_data': {'token': JSON.stringify(event.payment)}
};
var promise = self.sendPayment(event.payment, data);
promise.then(function (success) {
var status;
if (success)
status = ApplePaySession.STATUS_SUCCESS;
else
status = ApplePaySession.STATUS_FAILURE;
session.completePayment(status);
if (success) {
window.location.replace(url.build(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl));
}
}, function (reason) {
if (reason.message == "ERROR BILLING") {
var status = session.STATUS_INVALID_BILLING_POSTAL_ADDRESS;
} else if (reason.message == "ERROR SHIPPING") {
var status = session.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS;
} else {
var status = session.STATUS_FAILURE;
}
session.completePayment(status);
});
}
session.begin();
},
getControllerName: function () {
return window.checkoutConfig.payment.iframe.controllerName[this.getCode()];
},
getPlaceOrderUrl: function () {
return window.checkoutConfig.payment.iframe.placeOrderUrl[this.getCode()];
},
context: function () {
return this;
},
validate: function () {
return true;
},
showLogo: function () {
return window.checkoutConfig.payment.adyen.showLogo;
},
isApplePayAllowed: function () {
if (window.ApplePaySession) {
return true;
}
return false;
},
performValidation: function (validationURL) {
// Return a new promise.
return new Promise(function (resolve, reject) {
// retrieve payment methods
var serviceUrl = urlBuilder.createUrl('/adyen/request-merchant-session', {});
storage.post(
serviceUrl, JSON.stringify('{}')
).done(
function (response) {
var data = JSON.parse(response);
resolve(data);
}
).fail(function (error) {
console.log(JSON.stringify(error));
reject(Error("Network Error"));
});
});
},
sendPayment: function (payment, data) {
var deferred = $.Deferred();
return $.when(
placeOrderAction(data, new Messages())
).fail(
function (response) {
deferred.reject(Error(response));
}
).done(
function () {
deferred.resolve(true);
}
);
}
});
}
);
...@@ -148,7 +148,7 @@ define( ...@@ -148,7 +148,7 @@ define(
return self.item.method; return self.item.method;
}; };
result.validate = function () { result.validate = function () {
return self.validate(); return self.validate(value.brandCode);
}; };
result.isPaymentMethodOpenInvoiceMethod = function () { result.isPaymentMethodOpenInvoiceMethod = function () {
return value.isPaymentMethodOpenInvoiceMethod; return value.isPaymentMethodOpenInvoiceMethod;
...@@ -234,7 +234,8 @@ define( ...@@ -234,7 +234,8 @@ define(
if (brandCode() == "ideal") { if (brandCode() == "ideal") {
additionalData.issuer_id = this.issuerId(); additionalData.issuer_id = this.issuerId();
} else if (self.isPaymentMethodOpenInvoiceMethod()) { }
else if (self.isPaymentMethodOpenInvoiceMethod()) {
additionalData.gender = this.gender(); additionalData.gender = this.gender();
additionalData.dob = this.dob(); additionalData.dob = this.dob();
additionalData.telephone = this.telephone(); additionalData.telephone = this.telephone();
...@@ -292,7 +293,14 @@ define( ...@@ -292,7 +293,14 @@ define(
isIconEnabled: function () { isIconEnabled: function () {
return window.checkoutConfig.payment.adyen.showLogo; return window.checkoutConfig.payment.adyen.showLogo;
}, },
validate: function () { validate: function (brandCode) {
var form = '#payment_form_' + this.getCode() + '_' + brandCode;
var validate = $(form).validation() && $(form).validation('isValid');
if(!validate) {
return false;
}
return true; return true;
}, },
getRatePayDeviceIdentToken: function () { getRatePayDeviceIdentToken: function () {
......
<!--
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2017 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/
-->
<!-- ko if: isApplePayAllowed() -->
<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
<div class="payment-method-title field choice">
<input type="radio"
name="payment[method]"
class="radio"
data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()"/>
<label data-bind="attr: {'for': getCode()}" class="label">
<!-- ko if: showLogo() -->
<div data-bind="attr: { 'class': 'adyen-sprite ' + getCode() }"></div>
<!--/ko-->
<span data-bind="text: getTitle()"></span>
</label>
</div>
<div class="payment-method-content">
<div class="payment-method-billing-address">
<!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</div>
<div class="checkout-agreements-block">
<!-- ko foreach: $parent.getRegion('before-place-order') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</div>
<div id="adyen-apple-pay-button" class="apple-pay-button-with-text apple-pay-button-black-with-text"
data-bind= "click: placeApplePayOrder">
<span class="logo"></span>
</div>
</div>
</div>
<!--/ko-->
\ No newline at end of file
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
</div> </div>
<form class="form" id="adyen-cc-form" data-role="adyen-cc-form" action="#" method="post" data-bind="mageInit: { <form class="form" id="adyen-cc-form" data-role="adyen-cc-form" action="#" method="post" data-bind="mageInit: {
'transparent':{ 'transparent':{
'context': context(), 'context': context(),
...@@ -54,13 +53,15 @@ ...@@ -54,13 +53,15 @@
}, 'validation':[]}"> }, 'validation':[]}">
<fieldset data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + getCode()}"> <fieldset
data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + getCode()}">
<!-- ko if: (isShowLegend())--> <!-- ko if: (isShowLegend())-->
<legend class="legend"> <legend class="legend">
<span><!-- ko text: $t('Credit Card Information')--><!-- /ko --></span> <span><!-- ko text: $t('Credit Card Information')--><!-- /ko --></span>
</legend><br /> </legend>
<br/>
<!-- /ko --> <!-- /ko -->
<div class="field type required"> <div class="field type required">
<label data-bind="attr: {for: getCode() + '_cc_type'}" class="label"> <label data-bind="attr: {for: getCode() + '_cc_type'}" class="label">
<span><!-- ko text: $t('Credit Card Type')--><!-- /ko --></span> <span><!-- ko text: $t('Credit Card Type')--><!-- /ko --></span>
...@@ -125,7 +126,7 @@ ...@@ -125,7 +126,7 @@
value: creditCardOwner, value: creditCardOwner,
valueUpdate: 'keyup' " valueUpdate: 'keyup' "
data-validate="{required:true}" data-validate="{required:true}"
/> />
</div> </div>
</div> </div>
<div class="field date required" data-bind="attr: {id: getCode() + '_cc_type_exp_div'}"> <div class="field date required" data-bind="attr: {id: getCode() + '_cc_type_exp_div'}">
...@@ -136,9 +137,9 @@ ...@@ -136,9 +137,9 @@
<div class="fields group group-2"> <div class="fields group group-2">
<div class="field no-label month"> <div class="field no-label month">
<div class="control"> <div class="control">
<select class="select select-month" <select class="select select-month"
data-encrypted-name="expiryMonth" data-encrypted-name="expiryMonth"
data-bind="attr: {id: getCode() + '_expiration', 'data-container': getCode() + '-cc-month', 'data-validate': JSON.stringify({required:true, 'validate-cc-exp':'#' + getCode() + '_expiration_yr'})}, data-bind="attr: {id: getCode() + '_expiration', 'data-container': getCode() + '-cc-month', 'data-validate': JSON.stringify({required:true, 'validate-cc-exp':'#' + getCode() + '_expiration_yr'})},
enable: isActive($parents), enable: isActive($parents),
options: getCcMonthsValues(), options: getCcMonthsValues(),
optionsValue: 'value', optionsValue: 'value',
...@@ -178,13 +179,18 @@ ...@@ -178,13 +179,18 @@
class="input-text cvv" class="input-text cvv"
data-encrypted-name="cvc" data-encrypted-name="cvc"
value="" value=""
data-bind="attr: {id: getCode() + '_cc_cid', data-bind="attr: {
id: getCode() + '_cc_cid',
title: $t('Card Verification Number'), title: $t('Card Verification Number'),
'data-container': getCode() + '-cc-cvv', 'data-container': getCode() + '-cc-cvv',
'data-validate': JSON.stringify({'required-number':true, 'validate-card-cvv':'#' + getCode() + '_cc_type'})}, 'data-validate': JSON.stringify({'required-number':true, 'validate-card-cvv':'#' + getCode() + '_cc_type'}),
maxLength : getCvcLength(),
oninput:'javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);'
},
enable: isActive($parents), enable: isActive($parents),
value: creditCardVerificationNumber" value: creditCardVerificationNumber" ,
data-validate="{required:true}"/> data-validate="{required:true}"
/>
<div class="field-tooltip toggle"> <div class="field-tooltip toggle">
<span class="field-tooltip-action action-cvv" <span class="field-tooltip-action action-cvv"
tabindex="0" tabindex="0"
...@@ -203,21 +209,24 @@ ...@@ -203,21 +209,24 @@
<!-- ko if: (hasInstallments())--> <!-- ko if: (hasInstallments())-->
<div class="field required" data-bind="attr: {id: getCode() + '_installments_div'}, visible: getInstallments().length > 0"> <div class="field required"
data-bind="attr: {id: getCode() + '_installments_div'}, visible: getInstallments().length > 0">
<label data-bind="attr: {for: getCode() + '_installments'}" class="label"> <label data-bind="attr: {for: getCode() + '_installments'}" class="label">
<span><!-- ko text: $t('Installments')--><!-- /ko --></span> <span><!-- ko text: $t('Installments')--><!-- /ko --></span>
</label> </label>
<div class="control"> <div class="control">
<select class="select" <select class="select"
name="payment[number_of_installments]" name="payment[number_of_installments]"
data-bind="attr: {id: getCode() + '_installments', 'data-container': getCode() + '-installments', 'data-validate': JSON.stringify({required:true})}, data-bind="attr: {id: getCode() + '_installments', 'data-container': getCode() + '-installments', 'data-validate': JSON.stringify({required:false})},
enable: isActive($parents), enable: isActive($parents),
options: getInstallments, options: getInstallments,
optionsValue: 'value', optionsValue: 'value',
optionsText: 'key', optionsText: 'key',
optionsCaption: $t('Installments'), optionsCaption: $t('Do not use Installments'),
value: installment" value: installment"
data-validate="{required:true}"> data-validate="{required:true}">
</select> </select>
</div> </div>
</div> </div>
...@@ -234,7 +243,7 @@ ...@@ -234,7 +243,7 @@
autocomplete="off" autocomplete="off"
class="checkbox" class="checkbox"
data-bind="attr: {title: $t('Remember Me')}, checked: setStoreCc" data-bind="attr: {title: $t('Remember Me')}, checked: setStoreCc"
/> />
<label data-bind="attr: {for: getCode() + '_remember_details'}" class="label"> <label data-bind="attr: {for: getCode() + '_remember_details'}" class="label">
<span><!-- ko text: $t('Remember these details')--><!-- /ko --></span> <span><!-- ko text: $t('Remember these details')--><!-- /ko --></span>
</label> </label>
...@@ -243,19 +252,14 @@ ...@@ -243,19 +252,14 @@
<!-- /ko --> <!-- /ko -->
<!-- ko if: (isCseEnabled())--> <input type="hidden"
name="payment[generationtime]"
<input type="hidden" class="input-text"
name="payment[generationtime]" value=""
class="input-text" data-encrypted-name="generationtime"
value="" data-bind="attr: {id: getCode() + '_generationtime', 'data-container': getCode() + '-generationtime'},
data-encrypted-name="generationtime" value: getGenerationTime()"
data-bind="attr: {id: getCode() + '_generationtime', 'data-container': getCode() + '-generationtime'}, />
value: getGenerationTime()
">
<!-- /ko -->
</fieldset> </fieldset>
</form> </form>
......
...@@ -52,8 +52,8 @@ ...@@ -52,8 +52,8 @@
<!--/ko--> <!--/ko-->
</div> </div>
<fieldset class="fieldset" data-bind='attr: {id: "payment_form_" + $parent.getCode() + "_" + value}'> <form class="form" data-role="adyen-hpp-form" action="#" method="post" data-bind="mageInit: { 'validation':[]}, attr: {id: 'payment_form_' + $parent.getCode() + '_' + value}">
<fieldset class="fieldset" data-bind='attr: {id: "payment_fieldset_" + $parent.getCode() + "_" + value}'>
<!-- ko if: value == 'ideal' --> <!-- ko if: value == 'ideal' -->
<label data-bind="attr: {'for': 'issuerId'}" class="label"> <label data-bind="attr: {'for': 'issuerId'}" class="label">
<span><!-- ko text: $t('Select Your Bank') --><!-- /ko --></span> <span><!-- ko text: $t('Select Your Bank') --><!-- /ko --></span>
...@@ -68,17 +68,16 @@ ...@@ -68,17 +68,16 @@
</select> </select>
<!--/ko--> <!--/ko-->
<!-- ko if: isPaymentMethodOpenInvoiceMethod() --> <!-- ko if: isPaymentMethodOpenInvoiceMethod() -->
<!-- ko if: showGender() --> <!-- ko if: showGender() -->
<div class="field gender_type type required"> <div class="field gender required">
<label data-bind="attr: {for: getCode() + '_gender_type'}" class="label"> <label data-bind="attr: {for: getCode() + '_gender_type_' + value}" class="label">
<span><!-- ko text: $t('Gender')--><!-- /ko --></span> <span><!-- ko text: $t('Gender')--><!-- /ko --></span>
</label> </label>
<div class="control"> <div class="control">
<select class="select select-gender-type" <select class="select select-gender-type"
name="payment[gender]" name="payment[gender]"
data-bind="attr: {id: getCode() + '_gender_type', 'data-container': getCode() + '-gender-type', 'data-validate': JSON.stringify({required:true})}, data-bind="attr: {id: getCode() + '_gender_type_' + value, 'data-container': getCode() + '-gender-type'},
options: $parent.getGenderTypes(), options: $parent.getGenderTypes(),
optionsValue: 'key', optionsValue: 'key',
optionsText: 'value', optionsText: 'value',
...@@ -91,50 +90,51 @@ ...@@ -91,50 +90,51 @@
<!--/ko--> <!--/ko-->
<!-- ko if: showDob() --> <!-- ko if: showDob() -->
<div class="field required"> <div class="field dob type required">
<label data-bind="attr: {for: getCode() + '_dob'}" class="label"> <label data-bind="attr: {for: getCode() + '_dob_' + value}" class="label">
<span><!-- ko text: $t('Date of Birth')--><!-- /ko --></span> <span><!-- ko text: $t('Date of Birth')--><!-- /ko --></span>
</label> </label>
<div class="control"> <div class="control">
<input type="text" class="input-text" <input type="text" class="input-text"
name="payment[dob]" name="payment[dob]"
data-bind=" data-bind=" datepicker: { storage: datepickerValue, options: { showOn: 'both', changeYear: true, yearRange: '-99:-1', defaultDate: '-20y' } },
datepicker: { storage: datepickerValue, options: { showOn: 'both', changeYear: true, yearRange: '-99:-1', defaultDate: '-20y' } }, attr: {
attr: { id: getCode() + '_dob_' + value,
title: $t('Date of Birth'), title: $t('Date of Birth'),
'data-container': getCode() + '-dob', 'data-container': getCode() + '-dob'
'data-validate': JSON.stringify({'required':true }) },
}, value: dob"
value: dob" data-validate="{required:true}"
/> />
</div> </div>
</div> </div>
<!--/ko--> <!--/ko-->
<!-- ko if: showTelephone() --> <!-- ko if: showTelephone() -->
<div class="field required"> <div class="field telephone type required">
<label data-bind="attr: {for: getCode() + '_telephone'}" class="label"> <label data-bind="attr: {for: getCode() + '_telephone_' + value}" class="label">
<span><!-- ko text: $t('Telephone')--><!-- /ko --></span> <span><!-- ko text: $t('Telephone')--><!-- /ko --></span>
</label> </label>
<div class="control"> <div class="control">
<input type="number" class="input-text" <input type="number" class="input-text"
name="payment[telephone]" name="payment[telephone]"
data-bind=" data-bind="
attr: { attr: {
id: getCode() + '_telephone', id: getCode() + '_telephone_' + value,
title: $t('Telephone'), title: $t('Telephone'),
'data-container': getCode() + '-telephone', 'data-container': getCode() + '-telephone_' + value,
'data-validate': JSON.stringify({'required-number':true }) 'data-validate': JSON.stringify({'required-number':true})
}, },
value: telephone" value: telephone"
data-validate="{required:true}"
/> />
</div> </div>
</div> </div>
<!--/ko--> <!--/ko-->
<!-- ko if: showSsn() --> <!-- ko if: showSsn() -->
<div class="field required"> <div class="field ssn type required">
<label data-bind="attr: {for: getCode() + '_ssn'}" class="label"> <label data-bind="attr: {for: getCode() + '_ssn_' + value}" class="label">
<span><!-- ko text: $t('Personal number (last digits)')--><!-- /ko --></span> <span><!-- ko text: $t('Personal number (last digits)')--><!-- /ko --></span>
</label> </label>
<div class="control"> <div class="control">
...@@ -142,13 +142,14 @@ ...@@ -142,13 +142,14 @@
name="payment[ssn]" name="payment[ssn]"
data-bind=" data-bind="
attr: { attr: {
id: getCode() + '_ssn', id: getCode() + '_ssn_' + value,
title: $t('Social Security Number'), title: $t('Social Security Number'),
'data-container': getCode() + '-ssn', 'data-container': getCode() + '-ssn',
'data-validate': JSON.stringify({'required-number':true }), 'data-validate': JSON.stringify({'required-number':true}),
maxlength : getSsnLength() maxlength : getSsnLength()
}, },
value: ssn" value: ssn"
data-validate="{required:true}"
/> />
</div> </div>
</div> </div>
...@@ -156,6 +157,8 @@ ...@@ -156,6 +157,8 @@
<!--/ko--> <!--/ko-->
</fieldset> </fieldset>
</form>
<div class="checkout-agreements-block"> <div class="checkout-agreements-block">
<!-- ko foreach: $parents[1].getRegion('before-place-order') --> <!-- ko foreach: $parents[1].getRegion('before-place-order') -->
<!-- ko template: getTemplate() --><!-- /ko --> <!-- ko template: getTemplate() --><!-- /ko -->
...@@ -177,10 +180,6 @@ ...@@ -177,10 +180,6 @@
<!--/ko--> <!--/ko-->
<input type="hidden" name="payment[dfValue]" data-bind="attr: { id: 'dfValue', value: dfValue }" />
<!-- ko if: (isPaymentMethodSelectionOnAdyen()) --> <!-- ko if: (isPaymentMethodSelectionOnAdyen()) -->
<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}"> <div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
......
...@@ -196,7 +196,7 @@ ...@@ -196,7 +196,7 @@
<!--/ko--> <!--/ko-->
<!-- ko if: number_of_installments > 0 --> <!-- ko if: number_of_installments.length > 0 -->
<div class="field required" data-bind="attr: {id: getCode() + '_installments_div'}, visible: getInstallments().length > 0"> <div class="field required" data-bind="attr: {id: getCode() + '_installments_div'}, visible: getInstallments().length > 0">
<label data-bind="attr: {for: getCode() + '_installments'}" class="label"> <label data-bind="attr: {for: getCode() + '_installments'}" class="label">
...@@ -205,12 +205,12 @@ ...@@ -205,12 +205,12 @@
<div class="control"> <div class="control">
<select class="select" <select class="select"
name="payment[number_of_installments]" name="payment[number_of_installments]"
data-bind="attr: {id: getCode() + '_installments', 'data-container': getCode() + '-installments', 'data-validate': JSON.stringify({required:true})}, data-bind="attr: {id: getCode() + '_installments', 'data-container': getCode() + '-installments', 'data-validate': JSON.stringify({required:false})},
enable: $parent.isActive($parents), enable: $parent.isActive($parents),
options: getInstallments, options: getInstallments,
optionsValue: 'value', optionsValue: 'value',
optionsText: 'key', optionsText: 'key',
optionsCaption: $t('Installments'), optionsCaption: $t('Do not use Installments'),
value: installment" value: installment"
data-validate="{required:true}"> data-validate="{required:true}">
</select> </select>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment