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**
<!-- Please provide a description of the changes proposed in the Pull Request -->
**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 -->
\ 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
$this->addColumn(
'amount',
[
'label' => __('Amount Range (minor units)'),
'label' => __('Amount Range'),
'renderer' => false,
]
);
$this->addColumn(
'installments',
[
'label' => __('Max Number Of Installments'),
'label' => __('Number Of Installments'),
'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
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Checkout\Model\Session $checkoutSession,
array $data = []
) {
)
{
parent::__construct($context, $paymentConfig);
$this->_adyenHelper = $adyenHelper;
$this->_appState = $context->getAppState();
......@@ -79,7 +80,7 @@ class Cc extends \Magento\Payment\Block\Form\Cc
* @return mixed
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getCsePublicKey()
public function getLibrarySource()
{
// get storeId for admin
if (!$this->_appState->getAreaCode() === \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE) {
......@@ -88,15 +89,7 @@ class Cc extends \Magento\Payment\Block\Form\Cc
$storeId = null;
}
$demoMode = $this->_adyenHelper->getAdyenAbstractConfigDataFlag('demo_mode', $storeId);
if($demoMode) {
$cseKey = $this->_adyenHelper->getAdyenCcConfigData('cse_publickey_test', $storeId);
} else {
$cseKey = $this->_adyenHelper->getAdyenCcConfigData('cse_publickey_live', $storeId);
}
return $cseKey;
return $this->_adyenHelper->getLibrarySource($storeId);
}
/**
......@@ -111,7 +104,7 @@ class Cc extends \Magento\Payment\Block\Form\Cc
$this->getCheckoutSession();
$store = $this->_checkoutSession->getQuote()->getStore();
$enableMoto = $this->_adyenHelper->getAdyenCcConfigDataFlag('enable_moto', $store->getId());
if($enableMoto) {
if ($enableMoto) {
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
// don't allow editable shipping/delivery address
$formFields['billingAddressType'] = "1";
$formFields['deliveryAddressType'] = "1";
// make setting to make this optional
$formFields['shopperType'] = "1";
}
if ($this->_order->getPayment()->getAdditionalInformation("df_value") != "") {
......
......@@ -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->getResponse()
->clearHeader('Content-Type')
->setHeader('Content-Type', 'text/html')
->setBody("[accepted]");
->setBody($acceptedMessage);
return;
} else {
if ($notificationMode == "") {
......@@ -139,11 +150,12 @@ class Json extends \Magento\Framework\App\Action\Action
{
$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 false;
}
/**
* save notification into the database for cronjob to execute notification
*
......@@ -157,7 +169,7 @@ class Json extends \Magento\Framework\App\Action\Action
// validate the notification
if ($this->authorised($response)) {
// check if notificaiton already exists
// check if notification already exists
if (!$this->_isDuplicate($response)) {
try {
$notification = $this->_objectManager->create('Adyen\Payment\Model\Notification');
......@@ -215,7 +227,7 @@ class Json extends \Magento\Framework\App\Action\Action
}
return false;
}
/**
* HTTP Authentication of the notification
*
......@@ -234,8 +246,7 @@ class Json extends \Magento\Framework\App\Action\Action
$submitedMerchantAccount = $response['merchantAccountCode'];
if (empty($submitedMerchantAccount) && empty($internalMerchantAccount)) {
if (strtolower(substr($response['pspReference'], 0, 17)) == "testnotification_" ||
strtolower(substr($response['pspReference'], 0, 5)) == "test_") {
if ($this->_isTestNotification($response['pspReference'])) {
echo 'merchantAccountCode is empty in magento settings';
exit();
}
......@@ -244,8 +255,7 @@ class Json extends \Magento\Framework\App\Action\Action
// validate username and password
if ((!isset($_SERVER['PHP_AUTH_USER']) && !isset($_SERVER['PHP_AUTH_PW']))) {
if (strtolower(substr($response['pspReference'], 0, 17)) == "testnotification_" ||
strtolower(substr($response['pspReference'], 0, 5)) == "test_") {
if ($this->_isTestNotification($response['pspReference'])) {
echo 'Authentication failed: PHP_AUTH_USER and PHP_AUTH_PW are empty. See Adyen Magento manual CGI mode';
exit();
}
......@@ -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 (strtolower(substr($response['pspReference'], 0, 17)) == "testnotification_" ||
strtolower(substr($response['pspReference'], 0, 5)) == "test_") {
if ($this->_isTestNotification($response['pspReference'])) {
if ($accountCmp != 0) {
echo 'MerchantAccount in notification is not the same as in Magento settings';
exit();
......@@ -288,7 +297,7 @@ class Json extends \Magento\Framework\App\Action\Action
$eventCode = trim($response['eventCode']);
$success = trim($response['success']);
$originalReference = null;
if(isset($response['originalReference'])) {
if (isset($response['originalReference'])) {
$originalReference = trim($response['originalReference']);
}
$notification = $this->_objectManager->create('Adyen\Payment\Model\Notification');
......@@ -301,24 +310,25 @@ class Json extends \Magento\Framework\App\Action\Action
protected function _fixCgiHttpAuthentication()
{
// 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;
} elseif (isset($_SERVER['REDIRECT_REMOTE_AUTHORIZATION']) &&
$_SERVER['REDIRECT_REMOTE_AUTHORIZATION'] != '') {
$_SERVER['REDIRECT_REMOTE_AUTHORIZATION'] != ''
) {
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'])) {
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'])) {
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'])) {
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'])) {
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
{
$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
$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
$order->setAdyenResulturlEventCode($authResult);
switch ($authResult) {
case Notification::AUTHORISED:
$result = true;
$this->_adyenLogger->addAdyenResult('Do nothing wait for the notification');
break;
case Notification::PENDING:
// do nothing wait for the notification
$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');
break;
case Notification::CANCELLED:
......@@ -250,6 +257,15 @@ class Result extends \Magento\Framework\App\Action\Action
break;
}
$history = $this->_orderHistoryFactory->create()
//->setStatus($status)
->setComment($comment)
->setEntityName('order')
->setOrder($order)
;
$history->save();
return $result;
}
......
......@@ -156,9 +156,10 @@ class Validate3d extends \Magento\Framework\App\Action\Action
} else {
$this->_adyenLogger->addAdyenResult("Customer was redirected to bank for 3D-secure validation.");
$order->addStatusHistoryComment(
__('Customer was redirected to bank for 3D-secure validation.')
)->save();
__('Customer was redirected to bank for 3D-secure validation. Once the shopper authenticated, the order status will be updated accordingly.
<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->getLayout()->initMessages();
$this->_view->renderLayout();
......
......@@ -66,15 +66,11 @@ class AddressDataBuilder implements BuilderInterface
$requestBilling = ["street" => $billingAddress->getStreetLine1(),
"postalCode" => $billingAddress->getPostcode(),
"city" => $billingAddress->getCity(),
"houseNumberOrName" => 'NA',
"houseNumberOrName" => '',
"stateOrProvince" => $billingAddress->getRegionCode(),
"country" => $billingAddress->getCountryId()
];
// houseNumberOrName is mandatory
if ($requestBilling['houseNumberOrName'] == "") {
$requestBilling['houseNumberOrName'] = "NA";
}
$result['billingAddress'] = $requestBilling;
}
......@@ -86,15 +82,11 @@ class AddressDataBuilder implements BuilderInterface
$requestDelivery = ["street" => $shippingAddress->getStreetLine1(),
"postalCode" => $shippingAddress->getPostcode(),
"city" => $shippingAddress->getCity(),
"houseNumberOrName" => 'NA',
"houseNumberOrName" => '',
"stateOrProvince" => $shippingAddress->getRegionCode(),
"country" => $shippingAddress->getCountryId()
];
// houseNumberOrName is mandatory
if ($requestDelivery['houseNumberOrName'] == "") {
$requestDelivery['houseNumberOrName'] = "NA";
}
$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 @@
namespace Adyen\Payment\Gateway\Request;
use Magento\Payment\Gateway\Request\BuilderInterface;
use Adyen\Payment\Observer\AdyenCcDataAssignObserver;
class CcAuthorizationDataBuilder implements BuilderInterface
{
......@@ -46,7 +47,8 @@ class CcAuthorizationDataBuilder implements BuilderInterface
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\Model\Context $context
) {
)
{
$this->adyenHelper = $adyenHelper;
$this->appState = $context->getAppState();
}
......@@ -64,35 +66,30 @@ class CcAuthorizationDataBuilder implements BuilderInterface
$storeId = $order->getStoreId();
$request = [];
if ($this->adyenHelper->getAdyenCcConfigDataFlag('cse_enabled', $storeId)) {
$request['additionalData']['card.encrypted.json'] =
$payment->getAdditionalInformation("encrypted_data");
} else {
$requestCreditCardDetails = [
"expiryMonth" => $payment->getCcExpMonth(),
"expiryYear" => $payment->getCcExpYear(),
"holderName" => $payment->getCcOwner(),
"number" => $payment->getCcNumber(),
"cvc" => $payment->getCcCid(),
];
$cardDetails['card'] = $requestCreditCardDetails;
$request = array_merge($request, $cardDetails);
}
$request['additionalData']['card.encrypted.json'] =
$payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_DATA);
// Remove from additional data
$payment->unsAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_DATA);
/**
* if MOTO for backend is enabled use MOTO as shopper interaction type
*/
$enableMoto = $this->adyenHelper->getAdyenCcConfigDataFlag('enable_moto', $storeId);
if ($this->appState->getAreaCode() === \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE &&
$enableMoto) {
$enableMoto
) {
$request['shopperInteraction'] = "Moto";
}
// if installments is set add it into the request
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');
}
return $request;
}
}
\ No newline at end of file
......@@ -114,31 +114,7 @@ class GeneralResponseValidator extends AbstractValidator
}
break;
case "Refused":
if ($response['refusalReason']) {
$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.');
}
$errorMsg = __('The payment is REFUSED.');
// this will result the specific error
throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg));
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);
}
}
......@@ -31,6 +31,9 @@ use Magento\Framework\App\Helper\AbstractHelper;
class Data extends AbstractHelper
{
const TEST = 'test';
const LIVE = 'live';
/**
* @var \Magento\Framework\Encryption\EncryptorInterface
*/
......@@ -68,7 +71,7 @@ class Data extends AbstractHelper
/**
* Data constructor.
*
*
* @param \Magento\Framework\App\Helper\Context $context
* @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
* @param \Magento\Framework\Config\DataInterface $dataStorage
......@@ -86,8 +89,10 @@ class Data extends AbstractHelper
\Magento\Framework\Module\ModuleListInterface $moduleList,
\Adyen\Payment\Model\Resource\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory,
\Magento\Framework\View\Asset\Repository $assetRepo,
\Magento\Framework\View\Asset\Source $assetSource
) {
\Magento\Framework\View\Asset\Source $assetSource,
\Adyen\Payment\Model\Resource\Notification\CollectionFactory $notificationFactory
)
{
parent::__construct($context);
$this->_encryptor = $encryptor;
$this->_dataStorage = $dataStorage;
......@@ -96,6 +101,7 @@ class Data extends AbstractHelper
$this->_billingAgreementCollectionFactory = $billingAgreementCollectionFactory;
$this->_assetRepo = $assetRepo;
$this->_assetSource = $assetSource;
$this->_notificationFactory = $notificationFactory;
}
/**
......@@ -127,7 +133,8 @@ class Data extends AbstractHelper
* @desc return recurring types for configuration setting
* @return array
*/
public function getCaptureModes() {
public function getCaptureModes()
{
return [
'auto' => 'immediate',
'manual' => 'manual'
......@@ -138,7 +145,8 @@ class Data extends AbstractHelper
* @desc return recurring types for configuration setting
* @return array
*/
public function getPaymentRoutines() {
public function getPaymentRoutines()
{
return [
'single' => 'Single Page Payment Routine',
'multi' => 'Multi-page Payment Routine'
......@@ -154,7 +162,7 @@ class Data extends AbstractHelper
*/
public function formatAmount($amount, $currency)
{
switch($currency) {
switch ($currency) {
case "JPY":
case "IDR":
case "KRW":
......@@ -213,7 +221,7 @@ class Data extends AbstractHelper
public function originalAmount($amount, $currency)
{
// check the format
switch($currency) {
switch ($currency) {
case "JPY":
case "IDR":
case "KRW":
......@@ -446,6 +454,45 @@ class Data extends AbstractHelper
return $this->getConfigData($field, 'adyen_boleto', $storeId, true);
}
/**
* @desc Gives back adyen_apple_pay configuration values
* @param $field
* @param null $storeId
* @return mixed
*/
public function getAdyenApplePayConfigData($field, $storeId = null)
{
return $this->getConfigData($field, 'adyen_apple_pay', $storeId);
}
/**
* @param null $storeId
* @return mixed
*/
public function getAdyenApplePayMerchantIdentifier($storeId = null)
{
$demoMode = $this->getAdyenAbstractConfigDataFlag('demo_mode');
if ($demoMode) {
return $this->getAdyenApplePayConfigData('merchant_identifier_test', $storeId);
} else {
return $this->getAdyenApplePayConfigData('merchant_identifier_live', $storeId);
}
}
/**
* @param null $storeId
* @return mixed
*/
public function getAdyenApplePayPemFileLocation($storeId = null)
{
$demoMode = $this->getAdyenAbstractConfigDataFlag('demo_mode');
if ($demoMode) {
return $this->getAdyenApplePayConfigData('full_path_location_pem_file_test', $storeId);
} else {
return $this->getAdyenApplePayConfigData('full_path_location_pem_file_live', $storeId);
}
}
/**
* @desc Retrieve decrypted hmac key
* @return string
......@@ -454,7 +501,7 @@ class Data extends AbstractHelper
{
switch ($this->isDemoMode()) {
case true:
$secretWord = $this->_encryptor->decrypt(trim($this->getAdyenHppConfigData('hmac_test')));
$secretWord = $this->_encryptor->decrypt(trim($this->getAdyenHppConfigData('hmac_test')));
break;
default:
$secretWord = $this->_encryptor->decrypt(trim($this->getAdyenHppConfigData('hmac_live')));
......@@ -467,7 +514,7 @@ class Data extends AbstractHelper
{
switch ($this->isDemoMode()) {
case true:
$secretWord = $this->_encryptor->decrypt(trim($this->getAdyenPayByMailConfigData('hmac_test')));
$secretWord = $this->_encryptor->decrypt(trim($this->getAdyenPayByMailConfigData('hmac_test')));
break;
default:
$secretWord = $this->_encryptor->decrypt(trim($this->getAdyenPayByMailConfigData('hmac_live')));
......@@ -501,7 +548,7 @@ class Data extends AbstractHelper
public function getWsUsername($storeId = null)
{
if ($this->isDemoMode($storeId)) {
$wsUsername = trim($this->getAdyenAbstractConfigData('ws_username_test', $storeId));
$wsUsername = trim($this->getAdyenAbstractConfigData('ws_username_test', $storeId));
} else {
$wsUsername = trim($this->getAdyenAbstractConfigData('ws_username_live', $storeId));
}
......@@ -515,9 +562,11 @@ class Data extends AbstractHelper
public function getWsPassword($storeId = null)
{
if ($this->isDemoMode($storeId)) {
$wsPassword = $this->_encryptor->decrypt(trim($this->getAdyenAbstractConfigData('ws_password_test', $storeId)));
$wsPassword = $this->_encryptor->decrypt(trim($this->getAdyenAbstractConfigData('ws_password_test',
$storeId)));
} else {
$wsPassword = $this->_encryptor->decrypt(trim($this->getAdyenAbstractConfigData('ws_password_live', $storeId)));
$wsPassword = $this->_encryptor->decrypt(trim($this->getAdyenAbstractConfigData('ws_password_live',
$storeId)));
}
return $wsPassword;
}
......@@ -567,7 +616,7 @@ class Data extends AbstractHelper
*/
public function getCcTypesAltData()
{
$adyenCcTypes = $this->getAdyenCcTypes();
$adyenCcTypes = $this->getAdyenCcTypes();
$types = [];
foreach ($adyenCcTypes as $key => $data) {
$types[$data['code_alt']] = $data;
......@@ -596,7 +645,7 @@ class Data extends AbstractHelper
{
$path = 'payment/' . $paymentMethodCode . '/' . $field;
if(!$flag) {
if (!$flag) {
return $this->scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId);
} else {
return $this->scopeConfig->isSetFlag($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId);
......@@ -610,9 +659,44 @@ class Data extends AbstractHelper
public function getSepaCountries()
{
$sepaCountriesAllowed = [
"AT", "BE", "BG", "CH", "CY", "CZ", "DE", "DK", "EE", "ES", "FI", "FR", "GB", "GF", "GI", "GP", "GR", "HR",
"HU", "IE", "IS", "IT", "LI", "LT", "LU", "LV", "MC", "MQ", "MT", "NL", "NO", "PL", "PT", "RE", "RO", "SE",
"SI", "SK"
"AT",
"BE",
"BG",
"CH",
"CY",
"CZ",
"DE",
"DK",
"EE",
"ES",
"FI",
"FR",
"GB",
"GF",
"GI",
"GP",
"GR",
"HR",
"HU",
"IE",
"IS",
"IT",
"LI",
"LT",
"LU",
"LV",
"MC",
"MQ",
"MT",
"NL",
"NO",
"PL",
"PT",
"RE",
"RO",
"SE",
"SI",
"SK"
];
$countryList = $this->_country->toOptionArray();
......@@ -629,7 +713,7 @@ class Data extends AbstractHelper
public function getModuleVersion()
{
return (string) $this->_moduleList->getOne("Adyen_Payment")['setup_version'];
return (string)$this->_moduleList->getOne("Adyen_Payment")['setup_version'];
}
public function getBoletoTypes()
......@@ -695,7 +779,8 @@ class Data extends AbstractHelper
$agreementData['variant'] = 'sepadirectdebit';
}
$data = ['reference_id' => $billingAgreement->getReferenceId(),
$data = [
'reference_id' => $billingAgreement->getReferenceId(),
'agreement_label' => $billingAgreement->getAgreementLabel(),
'agreement_data' => $agreementData
];
......@@ -706,7 +791,7 @@ class Data extends AbstractHelper
$asset = $this->createAsset(
'Adyen_Payment::images/logos/' . $logoName . '.png'
);
$icon = null;
$placeholder = $this->_assetSource->findSource($asset);
if ($placeholder) {
......@@ -732,18 +817,19 @@ class Data extends AbstractHelper
}
if ($installments) {
$numberOfInstallments = null;
$numberOfInstallments = [];
foreach ($installments as $ccTypeInstallment => $installment) {
if ($ccTypeInstallment == $ccType) {
foreach ($installment as $amount => $installments) {
if ($grandTotal <= $amount) {
$numberOfInstallments = $installments;
if ($grandTotal >= $amount) {
array_push($numberOfInstallments, $installments);
}
}
}
}
if ($numberOfInstallments) {
sort($numberOfInstallments);
$data['number_of_installments'] = $numberOfInstallments;
}
}
......@@ -763,10 +849,12 @@ class Data extends AbstractHelper
{
if (strlen($paymentMethod) >= 9 && substr($paymentMethod, 0, 9) == 'afterpay_') {
return true;
} else if($paymentMethod == 'klarna' || $paymentMethod == 'ratepay') {
return true;
} else {
return false;
if ($paymentMethod == 'klarna' || $paymentMethod == 'ratepay') {
return true;
} else {
return false;
}
}
}
......@@ -790,7 +878,7 @@ class Data extends AbstractHelper
}
return false;
}
/**
* @return bool
*/
......@@ -816,9 +904,68 @@ class Data extends AbstractHelper
return $this->_assetRepo->createAsset($fileId, $params);
}
public function getStoreLocale($storeId) {
public function getStoreLocale($storeId)
{
$path = \Magento\Directory\Helper\Data::XML_PATH_DEFAULT_LOCALE;
return $this->scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId);
}
public function getApplePayShippingTypes()
{
return [
[
'value' => 'shipping',
'label' => __('Shipping Method')
],
[
'value' => 'delivery',
'label' => __('Delivery Method')
],
[
'value' => 'storePickup',
'label' => __('Store Pickup Method')
],
[
'value' => 'servicePickup',
'label' => __('Service Pickup Method')
]
];
}
public function getUnprocessedNotifications()
{
$notifications = $this->_notificationFactory->create();
$notifications->unprocessedNotificationsFilter();
return $notifications->getSize();;
}
/**
* @param $storeId
* @return mixed
*/
public function getLibraryToken($storeId = null)
{
if ($this->isDemoMode($storeId)) {
$libraryToken = $this->getAdyenCcConfigData('cse_library_token_test', $storeId);
} else {
$libraryToken = $this->getAdyenCcConfigData('cse_library_token_live', $storeId);
}
return $libraryToken;
}
/**
* Returns the hosted location of the client side encryption file
*
* @param null $storeId
* @return string
*/
public function getLibrarySource($storeId = null)
{
$environment = self::LIVE;
if ($this->isDemoMode($storeId)) {
$environment = self::TEST;
}
return "https://" . $environment . ".adyen.com/hpp/cse/js/" . $this->getLibraryToken($storeId) . ".shtml";
}
}
\ 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;
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
public function beforeSave()
{
$value = $this->getValue();
$unserialized = @unserialize($value);
if ($unserialized !== false) {
return $this;
}
$result = [];
foreach ($value as $data) {
if (!$data) {
......@@ -79,12 +82,19 @@ class Installments extends \Magento\Framework\App\Config\Value
$installments = $data['installments'];
$ccTypes = $data['cc_types'];
foreach($ccTypes as $ccType) {
$result[$ccType][$amount] = $installments;
foreach ($ccTypes as $ccType) {
$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;
}
......
<?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
* @return void
*/
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
$renderer = Phrase::getRenderer();
......@@ -1189,7 +1199,7 @@ class Cron
*/
protected function _isAutoCapture()
{
// validate if payment methods allowes manual capture
// validate if payment methods allows manual capture
if ($this->_manualCaptureAllowed()) {
$captureMode = trim($this->_getConfigData(
'capture_mode', 'adyen_abstract', $this->_order->getStoreId())
......@@ -1292,6 +1302,7 @@ class Cron
case 'cup':
case 'cartebancaire':
case 'visa':
case 'visadankort':
case 'mc':
case 'uatp':
case 'amex':
......
......@@ -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');
}
/**
* 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
* @var \Magento\Payment\Model\CcConfig
*/
private $ccConfig;
/**
* AdyenCcConfigProvider constructor.
......@@ -84,7 +84,8 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
\Magento\Framework\UrlInterface $urlBuilder,
Source $assetSource,
\Magento\Payment\Model\CcConfig $ccConfig
) {
)
{
$this->_paymentHelper = $paymentHelper;
$this->_adyenHelper = $adyenHelper;
$this->_request = $request;
......@@ -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');
$canCreateBillingAgreement = false;
if ($recurringType == "ONECLICK" || $recurringType == "ONECLICK,RECURRING") {
$canCreateBillingAgreement = true;
}
$config['payment'] ['adyenCc']['cseKey'] = $cseKey;
$config['payment'] ['adyenCc']['cseEnabled'] = $cseEnabled;
$config['payment'] ['adyenCc']['cseEnabled'] = $cseEnabled;
$config['payment'] ['adyenCc']['librarySource'] = $this->_adyenHelper->getLibrarySource();
$config['payment']['adyenCc']['generationTime'] = date("c");
$config['payment']['adyenCc']['canCreateBillingAgreement'] = $canCreateBillingAgreement;
$config['payment']['adyenCc']['icons'] = $this->getIcons();
......@@ -150,9 +139,10 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
$config['payment']['adyenCc']['hasInstallments'] = false;
// get Installments
$installmentsEnabled = $this->_adyenHelper->getAdyenCcConfigData('enable_installments');
$installments = $this->_adyenHelper->getAdyenCcConfigData('installments');
if ($installments) {
if ($installmentsEnabled && $installments) {
$config['payment']['adyenCc']['installments'] = unserialize($installments);
$config['payment']['adyenCc']['hasInstallments'] = true;
} else {
......@@ -250,7 +240,7 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
{
return $this->ccConfig->getCvvImageUrl();
}
/**
* Retrieve request object
*
......
......@@ -109,6 +109,9 @@ class AdyenHppConfigProvider implements ConfigProviderInterface
]
];
$gender = "";
$dob = "";
// get customer
if ($this->_customerSession->isLoggedIn()) {
......@@ -118,11 +121,10 @@ class AdyenHppConfigProvider implements ConfigProviderInterface
// format to calendar date
$dob = $this->_customerSession->getCustomerData()->getDob();
$dob = strtotime($dob);
$dob = date('m/d/Y', $dob);
} else {
$gender = "";
$dob = "";
if($dob) {
$dob = strtotime($dob);
$dob = date('m/d/Y', $dob);
}
}
// add to config
......
......@@ -90,7 +90,8 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\UrlInterface $urlBuilder,
\Magento\Payment\Model\CcConfig $ccConfig
) {
)
{
$this->_adyenHelper = $adyenHelper;
$this->_request = $request;
$this->_customerSession = $customerSession;
......@@ -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');
$canCreateBillingAgreement = false;
if ($recurringType == "ONECLICK" || $recurringType == "ONECLICK,RECURRING") {
$canCreateBillingAgreement = true;
}
$config['payment'] ['adyenOneclick']['cseKey'] = $cseKey;
$config['payment'] ['adyenOneclick']['cseEnabled'] = $cseEnabled;
$config['payment'] ['adyenOneclick']['cseEnabled'] = $cseEnabled;
$config['payment'] ['adyenOneclick']['librarySource'] = $this->_adyenHelper->getLibrarySource();
$config['payment']['adyenOneclick']['generationTime'] = date("c");
$config['payment']['adyenOneclick']['canCreateBillingAgreement'] = $canCreateBillingAgreement;
......@@ -178,9 +167,9 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
$recurringType = $this->_getRecurringContractType();
$billingAgreements = $this->_adyenHelper->getOneClickPaymentMethods(
$customerId,
$storeId,
$grandTotal,
$customerId,
$storeId,
$grandTotal,
$recurringType
);
}
......@@ -227,7 +216,6 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
}
/**
* 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
```
## 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 ##
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 @@
"name": "adyen/module-payment",
"description": "Official Magento2 Plugin to connect to Payment Service Provider Adyen.",
"type": "magento2-module",
"version": "2.1.3",
"version": "2.2.0",
"license": [
"OSL-3.0",
"AFL-3.0"
],
"repositories": [
{
"type": "composer",
"url": "https://repo.magento.com/"
}
],
"require": {
"adyen/php-api-library": "*"
"adyen/php-api-library": "*",
"magento/framework": ">=100.1.0"
},
"require-dev": {
"phpunit/phpunit": "~5"
},
"autoload": {
"files": [
......@@ -17,5 +27,10 @@
"psr-4": {
"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 @@
<include path="Adyen_Payment::system/adyen_pos.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_apple_pay.xml"/>
</group>
<group id="test" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<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 @@
<source_model>Adyen\Payment\Model\Config\Source\CcType</source_model>
<config_path>payment/adyen_cc/cctypes</config_path>
</field>
<!--<field id="cse_enabled" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">-->
<!--<label>Enable CSE</label>-->
<!--<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>-->
<!--<config_path>payment/adyen_cc/cse_enabled</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 id="cse_library_token_test" translate="label" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Library token of Test Adyen Web Service User</label>
<tooltip>Copy this from the Test Adyen Customer Area => Settings => Users => System => [web service user]=> Library token.</tooltip>
<config_path>payment/adyen_cc/cse_library_token_test</config_path>
</field>
<field id="cse_publickey_live" translate="label" type="textarea" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enter CSE Public Key of Live Adyen Web Service User</label>
<depends><field id="cse_enabled">1</field></depends>
<config_path>payment/adyen_cc/cse_publickey_live</config_path>
<field id="cse_library_token_live" translate="label" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Library token of Live Adyen Web Service User</label>
<tooltip>Copy this from the Live Adyen Customer Area => Settings => Users => System => [web service user]=> Library token.</tooltip>
<config_path>payment/adyen_cc/cse_library_token_live</config_path>
</field>
<group id="adyen_cc_advanced_settings" translate="label" showInDefault="1" showInWebsite="1" sortOrder="150">
......@@ -72,9 +67,17 @@
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/adyen_cc/enable_moto</config_path>
</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>
<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>
<backend_model>Adyen\Payment\Model\Config\Backend\Installments</backend_model>
<config_path>payment/adyen_cc/installments</config_path>
......
......@@ -45,7 +45,6 @@
<sort_order>2</sort_order>
<cctypes>AE,VI,MC,DI</cctypes>
<useccv>1</useccv>
<cse_enabled>1</cse_enabled>
<enable_moto>0</enable_moto>
<payment_action>authorize</payment_action>
<is_gateway>1</is_gateway>
......@@ -71,7 +70,6 @@
<recurring_payment_type>ONECLICK</recurring_payment_type>
<payment_action>authorize</payment_action>
<useccv>1</useccv>
<cse_enabled>1</cse_enabled>
<enable_moto>0</enable_moto>
<payment_action>authorize</payment_action>
<is_gateway>1</is_gateway>
......@@ -191,6 +189,25 @@
<can_cancel>1</can_cancel>
<group>adyen</group>
</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>
</default>
</config>
......@@ -104,6 +104,16 @@
<argument name="commandPool" xsi:type="object">AdyenPaymentPayByMailCommandPool</argument>
</arguments>
</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 -->
<virtualType name="AdyenPaymentGenericValueHandlerPool" type="Magento\Payment\Gateway\Config\ValueHandlerPool">
......@@ -211,6 +221,19 @@
</arguments>
</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 -->
<virtualType name="AdyenPaymentGenericConfig" type="Magento\Payment\Gateway\Config\Config">
<arguments>
......@@ -253,6 +276,12 @@
<argument name="methodCode" xsi:type="const">Adyen\Payment\Model\Ui\AdyenPayByMailConfigProvider::CODE</argument>
</arguments>
</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 -->
<virtualType name="AdyenPaymentCcCommandPool" type="Magento\Payment\Gateway\Command\CommandPool">
......@@ -341,6 +370,18 @@
</arguments>
</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 -->
<virtualType name="AdyenPaymentCcAuthorizeCommand" type="Magento\Payment\Gateway\Command\GatewayCommand">
<arguments>
......@@ -391,6 +432,16 @@
</arguments>
</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 -->
<virtualType name="AdyenPaymentCaptureCommand" type="Magento\Payment\Gateway\Command\GatewayCommand">
<arguments>
......@@ -496,6 +547,20 @@
</arguments>
</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 -->
<virtualType name="AdyenPaymentCaptureRequest" type="Magento\Payment\Gateway\Request\BuilderComposite">
<arguments>
......@@ -549,6 +614,15 @@
</argument>
</arguments>
</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">
<arguments>
<argument name="handlers" xsi:type="array">
......@@ -579,6 +653,7 @@
<arguments>
<argument name="validators" xsi:type="array">
<item name="country" xsi:type="string">AdyenCcCountryValidator</item>
<item name="global" xsi:type="string">Adyen\Payment\Gateway\Validator\InstallmentValidator</item>
</argument>
</arguments>
</virtualType>
......@@ -592,6 +667,7 @@
<arguments>
<argument name="validators" xsi:type="array">
<item name="country" xsi:type="string">AdyenOneclickCountryValidator</item>
<item name="global" xsi:type="string">Adyen\Payment\Gateway\Validator\InstallmentValidator</item>
</argument>
</arguments>
</virtualType>
......@@ -667,6 +743,19 @@
</arguments>
</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-->
<virtualType name="GeneralResponseValidator" type="Adyen\Payment\Gateway\Validator\GeneralResponseValidator">
......@@ -743,4 +832,5 @@
</type>
<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\AdyenRequestMerchantSessionInterface" type="Adyen\Payment\Model\AdyenRequestMerchantSession" />
</config>
\ No newline at end of file
......@@ -38,4 +38,7 @@
<event name="payment_method_assign_data_adyen_boleto">
<observer name="adyen_boleto_gateway_data_assign" instance="Adyen\Payment\Observer\AdyenBoletoDataAssignObserver" />
</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>
......@@ -34,6 +34,7 @@
<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_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>
</arguments>
</type>
......
......@@ -24,12 +24,13 @@
-->
<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>
<module name="Magento_Sales"/>
<module name="Magento_Quote"/>
<module name="Magento_Checkout"/>
<module name="Magento_Paypal"/>
<module name="Magento_AdminNotification"/>
</sequence>
</module>
</config>
......@@ -39,6 +39,9 @@
<method name="adyen_hpp">
<allow_multiple_address>0</allow_multiple_address>
</method>
<method name="adyen_apple_pay">
<allow_multiple_address>0</allow_multiple_address>
</method>
</methods>
</payment>
......
......@@ -30,18 +30,24 @@
<route url="/V1/guest-carts/:cartId/retrieve-adyen-payment-methods" method="POST">
<service class="Adyen\Payment\Api\GuestAdyenPaymentMethodManagementInterface" method="getPaymentMethods"/>
<resources>
<resource ref="anonymous" />
<resource ref="anonymous"/>
</resources>
</route>
<route url="/V1/carts/mine/retrieve-adyen-payment-methods" method="POST">
<service class="Adyen\Payment\Api\AdyenPaymentMethodManagementInterface" method="getPaymentMethods"/>
<resources>
<resource ref="self" />
<resource ref="self"/>
</resources>
<data>
<parameter name="cartId" force="true">%cart_id%</parameter>
</data>
</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>
\ No newline at end of file
......@@ -50,4 +50,5 @@
"The payment is REFUSED","The payment is REFUSED"
"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"
"Continue to Adyen App", "Continue to Adyen App"
\ No newline at end of file
"Continue to Adyen App", "Continue to Adyen App"
"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"));
}
}
......@@ -31,32 +31,39 @@ $ccExpMonth = $block->getInfoData('cc_exp_month');
$ccExpYear = $block->getInfoData('cc_exp_year');
?>
<fieldset class="admin__fieldset payment-method" id="payment_form_<?php /* @noEscape */ echo $code; ?>"
<fieldset class="admin__fieldset payment-method" id="payment_form_<?php /* @noEscape */
echo $code; ?>"
style="display:none">
<div class="field admin__field _required">
<label class="admin__field-label" for="<?php /* @noEscape */ echo $code; ?>_cc_owner">
<label class="admin__field-label" for="<?php /* @noEscape */
echo $code; ?>_cc_owner">
<span><?php echo $block->escapeHtml(__('Name on Card')); ?></span>
</label>
<div class="admin__field-control">
<input type="text" id="<?php /* @noEscape */ echo $code; ?>_cc_owner" data-encrypted-name="holderName"
<input type="text" id="<?php /* @noEscape */
echo $code; ?>_cc_owner" data-encrypted-name="holderName"
title="<?php echo $block->escapeHtml(__('Name on Card')); ?>" class="admin__control-text"
value="<?php /* @noEscape */ echo $block->getInfoData('cc_owner'); ?>"/>
value="<?php /* @noEscape */
echo $block->getInfoData('cc_owner'); ?>"/>
</div>
</div>
<div class="field-type admin__field _required">
<label class="admin__field-label" for="<?php /* @noEscape */ echo $code; ?>_cc_type">
<label class="admin__field-label" for="<?php /* @noEscape */
echo $code; ?>_cc_type">
<span><?php echo $block->escapeHtml(__('Credit Card Type')); ?></span>
</label>
<div class="admin__field-control">
<select id="<?php /* @noEscape */ echo $code; ?>_cc_type" name="payment[cc_type]"
<select id="<?php /* @noEscape */
echo $code; ?>_cc_type" name="payment[cc_type]"
class="required-entry validate-cc-type-select admin__control-select">
<option value=""></option>
<?php foreach ($block->getCcAvailableTypes() as $typeCode => $typeName): ?>
<option value="<?php echo $block->escapeHtml($typeCode); ?>" <?php if ($typeCode == $ccType): ?>selected="selected"<?php endif ?>>
<option value="<?php echo $block->escapeHtml($typeCode); ?>"
<?php if ($typeCode == $ccType): ?>selected="selected"<?php endif ?>>
<?php echo $block->escapeHtml($typeName); ?>
</option>
<?php endforeach ?>
......@@ -64,21 +71,27 @@ $ccExpYear = $block->getInfoData('cc_exp_year');
</div>
</div>
<div class="field-number admin__field _required">
<label class="admin__field-label" for="<?php /* @noEscape */ echo $code; ?>_cc_number">
<label class="admin__field-label" for="<?php /* @noEscape */
echo $code; ?>_cc_number">
<span><?php echo $block->escapeHtml(__('Credit Card Number')); ?></span>
</label>
<div class="admin__field-control">
<input type="text" id="<?php /* @noEscape */ echo $code; ?>_cc_number" data-encrypted-name="number"
title="<?php echo $block->escapeHtml(__('Credit Card Number')); ?>" class="admin__control-text validate-cc-number"
value="<?php /* @noEscape */ echo $block->getInfoData('cc_number'); ?>"/>
<input type="text" id="<?php /* @noEscape */
echo $code; ?>_cc_number" data-encrypted-name="number"
title="<?php echo $block->escapeHtml(__('Credit Card Number')); ?>"
class="admin__control-text validate-cc-number"
value="<?php /* @noEscape */
echo $block->getInfoData('cc_number'); ?>"/>
</div>
</div>
<div class="field-date admin__field _required">
<label class="admin__field-label" for="<?php /* @noEscape */ echo $code; ?>_expiration">
<label class="admin__field-label" for="<?php /* @noEscape */
echo $code; ?>_expiration">
<span><?php echo $block->escapeHtml(__('Expiration Date')); ?></span>
</label>
<div class="admin__field-control">
<select id="<?php /* @noEscape */ echo $code ?>_expiration" data-encrypted-name="expiryMonth"
<select id="<?php /* @noEscape */
echo $code ?>_expiration" data-encrypted-name="expiryMonth"
class="admin__control-select admin__control-select-month validate-cc-exp required-entry">
<?php foreach ($block->getCcMonths() as $k => $v): ?>
<option value="<?php echo $block->escapeHtml($k); ?>"
......@@ -87,10 +100,12 @@ $ccExpYear = $block->getInfoData('cc_exp_year');
</option>
<?php endforeach; ?>
</select>
<select id="<?php /* @noEscape */ echo $code ?>_expiration_yr" data-encrypted-name="expiryYear"
<select id="<?php /* @noEscape */
echo $code ?>_expiration_yr" data-encrypted-name="expiryYear"
class="admin__control-select admin__control-select-year required-entry">
<?php foreach ($block->getCcYears() as $k => $v): ?>
<option value="<?php /* @noEscape */ echo $k ? $block->escapeHtml($k) : '' ?>"
<option value="<?php /* @noEscape */
echo $k ? $block->escapeHtml($k) : '' ?>"
<?php if ($k == $ccExpYear): ?>selected="selected"<?php endif ?>>
<?php echo $block->escapeHtml($v); ?>
</option>
......@@ -98,41 +113,50 @@ $ccExpYear = $block->getInfoData('cc_exp_year');
</select>
<input type="hidden" id="<?php echo $code ?>_encrypted_form_expiry_generationtime" value="<?php echo date("c"); ?>" data-encrypted-name="generationtime" />
<input type="hidden" id="<?php echo $code ?>_encrypted_form_expiry_generationtime"
value="<?php echo date("c"); ?>" data-encrypted-name="generationtime"/>
</div>
</div>
<?php if ($block->hasVerification()): ?>
<div class="field-number required admin__field _required">
<label class="admin__field-label" for="<?php /* @noEscape */ echo $code; ?>_cc_cid">
<label class="admin__field-label" for="<?php /* @noEscape */
echo $code; ?>_cc_cid">
<span><?php echo $block->escapeHtml(__('Card Verification Number')); ?></span>
</label>
<div class="admin__field-control">
<input type="text" title="<?php echo $block->escapeHtml(__('Card Verification Number')); ?>"
class="required-entry validate-cc-cvn admin__control-cvn admin__control-text"
id="<?php /* @noEscape */ echo $code; ?>_cc_cid"
data-encrypted-name="cvc" value="<?php /* @noEscape */ echo $block->getInfoData('cc_cid') ?>"/>
id="<?php /* @noEscape */
echo $code; ?>_cc_cid"
data-encrypted-name="cvc" value="<?php /* @noEscape */
echo $block->getInfoData('cc_cid') ?>"/>
</div>
</div>
<?php endif; ?>
<script>
require(['jquery',
'Magento_Sales/order/create/scripts',
"Magento_Sales/order/create/form",
'Adyen_Payment/js/adyen-encrypt'],
function(jQuery){
require(
[
'jquery',
'Magento_Sales/order/create/scripts',
"Magento_Sales/order/create/form"
],
function () {
//<![CDATA[
var dfScriptTag = document.createElement('script');
dfScriptTag.src = "<?php echo $block->getLibrarySource(); ?>";
dfScriptTag.type = "text/javascript";
document.body.appendChild(dfScriptTag);
//<![CDATA[
var element = $('payment_form_<?php echo $code ?>');
var cse_form = $(element).closest('form');
var cse_key = <?php echo json_encode($block->getCsePublicKey()); ?>;
var cse_options = {
name: 'payment[encrypted_data]'
name: 'payment[encrypted_data]'
};
var cse = function() {
var cse = function () {
if (order.paymentMethod && order.paymentMethod == '<?php echo $code ?>') {
try {
......@@ -140,7 +164,7 @@ $ccExpYear = $block->getInfoData('cc_exp_year');
// do not validate because it could be that CVC field does not exists (because MOTO this is not needed)
cse_options.enableValidations = false;
var cseForm = adyen.encrypt.createEncryptedForm(cse_form, cse_key, cse_options);
var cseForm = adyen.createEncryptedForm(cse_form, cse_options);
// encrypt data directly because submit button is not always on the page
var test = cseForm.encrypt();
cseForm.createEncryptedField(test);
......@@ -154,9 +178,9 @@ $ccExpYear = $block->getInfoData('cc_exp_year');
}
}
var cse_initialize = function() {
var cse_initialize = function () {
order.submit = order.submit.wrap(function(originalSaveMethod) {
order.submit = order.submit.wrap(function (originalSaveMethod) {
cse.call(this);
originalSaveMethod();
});
......@@ -169,9 +193,8 @@ $ccExpYear = $block->getInfoData('cc_exp_year');
else {
Event.observe(window, 'load', cse_initialize);
}
//]]>
});
//]]>
});
</script>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -61,6 +61,9 @@
<item name="adyen_boleto" xsi:type="array">
<item name="isBillingAddressRequired" xsi:type="boolean">true</item>
</item>
<item name="adyen_apple_pay" xsi:type="array">
<item name="isBillingAddressRequired" xsi:type="boolean">true</item>
</item>
</item>
</item>
</item>
......
......@@ -5,9 +5,6 @@
/*jshint browser:true jquery:true*/
/*global alert*/
var config = {
paths: {
'adyen/encrypt' : 'Adyen_Payment/js/view/payment/adyen.encrypt.min'
},
config: {
mixins: {
'Adyen_Payment/js/action/place-order': {
......
......@@ -61,11 +61,76 @@
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 {
width:20%;
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(
return function (paymentData, redirectOnSuccess) {
var serviceUrl,
payload;
//redirectOnSuccess = redirectOnSuccess !== false;
redirectOnSuccess = redirectOnSuccess === false ? false : true;
......@@ -60,13 +59,14 @@ define(
}
fullScreenLoader.startLoader();
return storage.post(
serviceUrl, JSON.stringify(payload)
).done(
function () {
function (response) {
if (redirectOnSuccess) {
window.location.replace(url.build(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl));
} else{
fullScreenLoader.stopLoader();
}
}
).fail(
......
......@@ -8,7 +8,7 @@ define(
],
function (ko) {
'use strict';
var installments = ko.observableArray([]);
var installments = ko.observableArray(['key', 'value']);
return {
/**
* Populate the list of installments
......@@ -17,14 +17,15 @@ define(
setInstallments: function (installmentData) {
// remove everything from the current list
installments.removeAll();
// populate installments
var i;
for (i = 1; i <= installmentData; i++) {
installments.push({
key: i,
value: i
});
for (i = 0; i < installmentData.length; i++) {
installments.push(
{
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(
{
type: 'adyen_boleto',
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 */
......
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);
}
);
}
});
}
);
......@@ -34,11 +34,12 @@ define(
'Magento_Checkout/js/model/quote',
'ko',
'Adyen_Payment/js/model/installments',
'adyen/encrypt'
],
function (_, $, Component, placeOrderAction, $t, additionalValidators, customer, creditCardData, quote, ko, installments, adyenEncrypt) {
function (_, $, Component, placeOrderAction, $t, additionalValidators, customer, creditCardData, quote, ko, installments) {
'use strict';
var cvcLength = ko.observable(4);
return Component.extend({
defaults: {
template: 'Adyen_Payment/payment/cc-form',
......@@ -67,53 +68,77 @@ define(
return this;
},
getInstallments: installments.getInstallments(),
initialize: function() {
initialize: function () {
var self = this;
this._super();
installments.setInstallments(0);
// include dynamic cse javascript
var dfScriptTag = document.createElement('script');
dfScriptTag.src = this.getLibrarySource();
dfScriptTag.type = "text/javascript";
document.body.appendChild(dfScriptTag);
//Set credit card number to credit card data object
this.creditCardNumber.subscribe(function(value) {
this.creditCardNumber.subscribe(function (value) {
// installments enabled ??
var allInstallments = self.getAllInstallments();
// what card is this ??
var creditcardType = creditCardData.creditCard.type;
if(creditcardType) {
if (creditCardData.creditCard) {
var creditcardType = creditCardData.creditCard.type;
cvcLength(4);
if (creditcardType != "AE") {
cvcLength(3);
}
if (creditcardType in allInstallments) {
// get for the creditcard the installments
var installmentCreditcard = allInstallments[creditcardType];
var grandTotal = quote.totals().grand_total;
var numberOfInstallments = 0;
var numberOfInstallments = [];
var dividedAmount = 0;
var dividedString = "";
$.each(installmentCreditcard, function (amount, installment) {
if(grandTotal <= amount) {
numberOfInstallments = installment;
if (grandTotal >= amount) {
dividedAmount = (grandTotal / installment).toFixed(quote.getPriceFormat().precision);
dividedString = installment + " x " + dividedAmount + " " + quote.totals().quote_currency_code;
numberOfInstallments.push({
key: [dividedString],
value: installment
});
}
else {
return false;
}
});
if(numberOfInstallments > 0) {
installments.setInstallments(numberOfInstallments);
}
} else {
}
if (numberOfInstallments) {
installments.setInstallments(numberOfInstallments);
}
else {
installments.setInstallments(0);
}
}
});
},
setPlaceOrderHandler: function(handler) {
setPlaceOrderHandler: function (handler) {
this.placeOrderHandler = handler;
},
setValidateHandler: function(handler) {
setValidateHandler: function (handler) {
this.validateHandler = handler;
},
getCode: function() {
getCode: function () {
return 'adyen_cc';
},
getData: function() {
getData: function () {
return {
'method': this.item.method,
additional_data: {
......@@ -125,13 +150,16 @@ define(
}
};
},
isActive: function() {
getCvcLength: function () {
return cvcLength();
},
isActive: function () {
return true;
},
/**
* @override
*/
placeOrder: function(data, event) {
placeOrder: function (data, event) {
var self = this,
placeOrder;
......@@ -139,19 +167,18 @@ define(
event.preventDefault();
}
var cse_key = this.getCSEKey();
var options = {};
var cseInstance = adyenEncrypt.createEncryption(cse_key, options);
var options = {};
var cseInstance = adyen.createEncryption(options);
var generationtime = self.getGenerationTime();
var cardData = {
number : self.creditCardNumber(),
cvc : self.creditCardVerificationNumber(),
holderName : self.creditCardOwner(),
expiryMonth : self.creditCardExpMonth(),
expiryYear : self.creditCardExpYear(),
generationtime : generationtime
number: self.creditCardNumber(),
cvc: self.creditCardVerificationNumber(),
holderName: self.creditCardOwner(),
expiryMonth: self.creditCardExpMonth(),
expiryYear: self.creditCardExpYear(),
generationtime: generationtime
};
var data = cseInstance.encrypt(cardData);
......@@ -161,58 +188,65 @@ define(
this.isPlaceOrderActionAllowed(false);
placeOrder = placeOrderAction(this.getData(), this.redirectAfterPlaceOrder);
$.when(placeOrder).fail(function(response) {
$.when(placeOrder).fail(function (response) {
self.isPlaceOrderActionAllowed(true);
});
return true;
}
return false;
},
getControllerName: function() {
getControllerName: function () {
return window.checkoutConfig.payment.iframe.controllerName[this.getCode()];
},
getPlaceOrderUrl: function() {
getPlaceOrderUrl: function () {
return window.checkoutConfig.payment.iframe.placeOrderUrl[this.getCode()];
},
context: function() {
context: function () {
return this;
},
isCseEnabled: function() {
isCseEnabled: function () {
return window.checkoutConfig.payment.adyenCc.cseEnabled;
},
getCSEKey: function() {
getCSEKey: function () {
return window.checkoutConfig.payment.adyenCc.cseKey;
},
getGenerationTime: function() {
getLibrarySource: function () {
return window.checkoutConfig.payment.adyenCc.librarySource;
},
getGenerationTime: function () {
return window.checkoutConfig.payment.adyenCc.generationTime;
},
canCreateBillingAgreement: function() {
if(customer.isLoggedIn()) {
canCreateBillingAgreement: function () {
if (customer.isLoggedIn()) {
return window.checkoutConfig.payment.adyenCc.canCreateBillingAgreement;
}
return false;
},
isShowLegend: function() {
isShowLegend: function () {
return true;
},
validate: function () {
var form = 'form[data-role=adyen-cc-form]';
var validate = $(form).validation() && $(form).validation('isValid');
// add extra validation because jqeury validation will not work on non name attributes
var validate = $(form).validation() && $(form).validation('isValid');
// add extra validation because jquery validation will not work on non name attributes
var ccNumber = Boolean($(form + ' #creditCardNumber').valid());
var owner = Boolean($(form + ' #creditCardHolderName').valid());
var expiration = Boolean($(form + ' #adyen_cc_expiration').valid());
var expiration_yr = Boolean($(form + ' #adyen_cc_expiration_yr').valid());
var cid = Boolean($(form + ' #adyen_cc_cc_cid').valid());
if(!validate || !ccNumber || !owner || !expiration || !expiration_yr || !cid) {
if (!validate || !ccNumber || !owner || !expiration || !expiration_yr || !cid) {
return false;
}
return true;
},
showLogo: function() {
showLogo: function () {
return window.checkoutConfig.payment.adyen.showLogo;
},
getIcons: function (type) {
......@@ -220,10 +254,10 @@ define(
? window.checkoutConfig.payment.adyenCc.icons[type]
: false
},
hasInstallments: function() {
hasInstallments: function () {
return window.checkoutConfig.payment.adyenCc.hasInstallments;
},
getAllInstallments: function() {
getAllInstallments: function () {
return window.checkoutConfig.payment.adyenCc.installments;
}
});
......
......@@ -148,7 +148,7 @@ define(
return self.item.method;
};
result.validate = function () {
return self.validate();
return self.validate(value.brandCode);
};
result.isPaymentMethodOpenInvoiceMethod = function () {
return value.isPaymentMethodOpenInvoiceMethod;
......@@ -234,7 +234,8 @@ define(
if (brandCode() == "ideal") {
additionalData.issuer_id = this.issuerId();
} else if (self.isPaymentMethodOpenInvoiceMethod()) {
}
else if (self.isPaymentMethodOpenInvoiceMethod()) {
additionalData.gender = this.gender();
additionalData.dob = this.dob();
additionalData.telephone = this.telephone();
......@@ -292,7 +293,14 @@ define(
isIconEnabled: function () {
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;
},
getRatePayDeviceIdentToken: function () {
......
......@@ -32,8 +32,7 @@ define(
'Magento_Checkout/js/model/payment/additional-validators',
'Magento_Checkout/js/action/select-payment-method',
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/checkout-data',
'Adyen_Payment/js/view/payment/adyen-encrypt'
'Magento_Checkout/js/checkout-data'
],
function (ko, _, $, Component, placeOrderAction, $t, additionalValidators, selectPaymentMethodAction, quote, checkoutData) {
'use strict';
......@@ -56,24 +55,28 @@ define(
]);
return this;
},
initialize: function () {
var self = this;
this._super();
},
placeOrderHandler: null,
validateHandler: null,
setPlaceOrderHandler: function(handler) {
setPlaceOrderHandler: function (handler) {
this.placeOrderHandler = handler;
},
setValidateHandler: function(handler) {
setValidateHandler: function (handler) {
this.validateHandler = handler;
},
getCode: function() {
getCode: function () {
return 'adyen_oneclick';
},
isActive: function() {
isActive: function () {
return true;
},
/**
* @override
*/
placeOrder: function(data, event) {
placeOrder: function (data, event) {
var self = this,
placeOrder;
......@@ -81,7 +84,7 @@ define(
event.preventDefault();
}
var data = {
var data = {
"method": self.method,
"additional_data": {
variant: self.agreement_data.variant,
......@@ -95,17 +98,18 @@ define(
var generationtime = self.getGenerationTime();
var cardData = {
cvc : self.creditCardVerificationNumber,
expiryMonth : self.creditCardExpMonth(),
expiryYear : self.creditCardExpYear(),
generationtime : generationtime
cvc: self.creditCardVerificationNumber,
expiryMonth: self.creditCardExpMonth(),
expiryYear: self.creditCardExpYear(),
generationtime: generationtime
};
if(updatedExpiryDate || self.hasVerification()){
if (updatedExpiryDate || self.hasVerification()) {
var options = {enableValidations: false};
var cseInstance = adyen.createEncryption(options);
var options = { enableValidations: false};
var cse_key = this.getCSEKey();
var cseInstance = adyen.encrypt.createEncryption(cse_key, options);
var encryptedData = cseInstance.encrypt(cardData);
data.additional_data.encrypted_data = encryptedData;
}
......@@ -119,46 +123,51 @@ define(
//this.isPlaceOrderActionAllowed(false);
placeOrder = placeOrderAction(data, this.redirectAfterPlaceOrder);
$.when(placeOrder).fail(function(response) {
$.when(placeOrder).fail(function (response) {
//self.isPlaceOrderActionAllowed(true);
});
return true;
}
return false;
},
getControllerName: function() {
getControllerName: function () {
return window.checkoutConfig.payment.iframe.controllerName[this.getCode()];
},
context: function() {
context: function () {
return this;
},
isCseEnabled: function() {
return window.checkoutConfig.payment.adyenCc.cseEnabled;
},
canCreateBillingAgreement: function() {
canCreateBillingAgreement: function () {
return window.checkoutConfig.payment.adyenCc.canCreateBillingAgreement;
},
isShowLegend: function() {
isShowLegend: function () {
return true;
},
getAdyenBillingAgreements: function() {
getAdyenBillingAgreements: function () {
var self = this;
// convert to list so you can iterate
var paymentList = _.map(window.checkoutConfig.payment.adyenOneclick.billingAgreements, function(value) {
var paymentList = _.map(window.checkoutConfig.payment.adyenOneclick.billingAgreements, function (value) {
var creditCardExpMonth, creditCardExpYear = false;
if(value.agreement_data.card) {
if (value.agreement_data.card) {
creditCardExpMonth = value.agreement_data.card.expiryMonth;
creditCardExpYear = value.agreement_data.card.expiryYear;
creditCardExpYear = value.agreement_data.card.expiryYear;
}
// pre-define installments if they are set
var i, installments = [];
if(value.number_of_installments > 0) {
for (i = 1; i <= value.number_of_installments; i++) {
var grandTotal = quote.totals().grand_total;
var dividedString = "";
var dividedAmount = 0;
if (value.number_of_installments) {
for (i = 0; i < value.number_of_installments.length; i++) {
dividedAmount = (grandTotal / value.number_of_installments[i]).toFixed(quote.getPriceFormat().precision);
dividedString = value.number_of_installments[i] + " x " + dividedAmount + " " + quote.totals().quote_currency_code;
installments.push({
key: i,
value: i
key: [dividedString],
value: value.number_of_installments[i]
});
}
}
......@@ -173,19 +182,17 @@ define(
'number_of_installments': value.number_of_installments,
getInstallments: ko.observableArray(installments),
'method': self.item.method,
getCode: function() {
getCode: function () {
return self.item.method;
},
creditCardVerificationNumber: '',
creditCardExpMonth: ko.observable(creditCardExpMonth),
creditCardExpYear: ko.observable(creditCardExpYear),
getCSEKey: function() {
return window.checkoutConfig.payment.adyenCc.cseKey;
},
getGenerationTime: function() {
getGenerationTime: function () {
return window.checkoutConfig.payment.adyenCc.generationTime;
},
hasVerification: function() {
hasVerification: function () {
return window.checkoutConfig.payment.adyenOneclick.hasCustomerInteraction;
},
validate: function () {
......@@ -196,17 +203,17 @@ define(
var form = 'form[data-role=' + codeValue + ']';
var validate = $(form).validation() && $(form).validation('isValid');
var validate = $(form).validation() && $(form).validation('isValid');
// if oneclick or recurring is a card do validation on expiration date
if(this.agreement_data.card) {
if (this.agreement_data.card) {
// add extra validation because jquery validation will not work on non name attributes
var expiration = Boolean($(form + ' #' + codeValue + '_expiration').valid());
var expiration_yr = Boolean($(form + ' #' + codeValue + '_expiration_yr').valid());
// only check if recurring type is set to oneclick
var cid = true;
if(this.hasVerification()) {
if (this.hasVerification()) {
var cid = Boolean($(form + ' #' + codeValue + '_cc_cid').valid());
}
} else {
......@@ -214,14 +221,14 @@ define(
var expiration_yr = true;
var cid = true;
}
if(!validate || !expiration || !expiration_yr || !cid) {
if (!validate || !expiration || !expiration_yr || !cid) {
return false;
}
return true;
},
selectExpiry: function() {
selectExpiry: function () {
updatedExpiryDate = true;
var self = this;
self.expiry(true);
......@@ -231,13 +238,13 @@ define(
});
return paymentList;
},
selectBillingAgreement: function() {
selectBillingAgreement: function () {
var self = this;
self.expiry(false);
updatedExpiryDate = false;
// set payment method data
var data = {
var data = {
"method": self.method,
"po_number": null,
"additional_data": {
......@@ -258,16 +265,16 @@ define(
},
isBillingAgreementChecked: ko.computed(function () {
if(!quote.paymentMethod()) {
if (!quote.paymentMethod()) {
return null;
}
if(quote.paymentMethod().method == paymentMethod()) {
if (quote.paymentMethod().method == paymentMethod()) {
return recurringDetailReference();
}
return null;
}),
getPlaceOrderUrl: function() {
getPlaceOrderUrl: function () {
return window.checkoutConfig.payment.iframe.placeOrderUrl[this.getCode()];
}
});
......
<!--
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* 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 @@
</div>
<form class="form" id="adyen-cc-form" data-role="adyen-cc-form" action="#" method="post" data-bind="mageInit: {
'transparent':{
'context': context(),
......@@ -54,13 +53,15 @@
}, '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())-->
<legend class="legend">
<span><!-- ko text: $t('Credit Card Information')--><!-- /ko --></span>
</legend><br />
</legend>
<br/>
<!-- /ko -->
<div class="field type required">
<label data-bind="attr: {for: getCode() + '_cc_type'}" class="label">
<span><!-- ko text: $t('Credit Card Type')--><!-- /ko --></span>
......@@ -125,7 +126,7 @@
value: creditCardOwner,
valueUpdate: 'keyup' "
data-validate="{required:true}"
/>
/>
</div>
</div>
<div class="field date required" data-bind="attr: {id: getCode() + '_cc_type_exp_div'}">
......@@ -136,9 +137,9 @@
<div class="fields group group-2">
<div class="field no-label month">
<div class="control">
<select class="select select-month"
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'})},
<select class="select select-month"
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'})},
enable: isActive($parents),
options: getCcMonthsValues(),
optionsValue: 'value',
......@@ -178,13 +179,18 @@
class="input-text cvv"
data-encrypted-name="cvc"
value=""
data-bind="attr: {id: getCode() + '_cc_cid',
data-bind="attr: {
id: getCode() + '_cc_cid',
title: $t('Card Verification Number'),
'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),
value: creditCardVerificationNumber"
data-validate="{required:true}"/>
value: creditCardVerificationNumber" ,
data-validate="{required:true}"
/>
<div class="field-tooltip toggle">
<span class="field-tooltip-action action-cvv"
tabindex="0"
......@@ -203,21 +209,24 @@
<!-- 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">
<span><!-- ko text: $t('Installments')--><!-- /ko --></span>
</label>
<div class="control">
<select class="select"
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),
options: getInstallments,
optionsValue: 'value',
optionsText: 'key',
optionsCaption: $t('Installments'),
optionsCaption: $t('Do not use Installments'),
value: installment"
data-validate="{required:true}">
data-validate="{required:true}">
</select>
</div>
</div>
......@@ -234,7 +243,7 @@
autocomplete="off"
class="checkbox"
data-bind="attr: {title: $t('Remember Me')}, checked: setStoreCc"
/>
/>
<label data-bind="attr: {for: getCode() + '_remember_details'}" class="label">
<span><!-- ko text: $t('Remember these details')--><!-- /ko --></span>
</label>
......@@ -243,19 +252,14 @@
<!-- /ko -->
<!-- ko if: (isCseEnabled())-->
<input type="hidden"
name="payment[generationtime]"
class="input-text"
value=""
data-encrypted-name="generationtime"
data-bind="attr: {id: getCode() + '_generationtime', 'data-container': getCode() + '-generationtime'},
value: getGenerationTime()
">
<!-- /ko -->
<input type="hidden"
name="payment[generationtime]"
class="input-text"
value=""
data-encrypted-name="generationtime"
data-bind="attr: {id: getCode() + '_generationtime', 'data-container': getCode() + '-generationtime'},
value: getGenerationTime()"
/>
</fieldset>
</form>
......
......@@ -52,8 +52,8 @@
<!--/ko-->
</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' -->
<label data-bind="attr: {'for': 'issuerId'}" class="label">
<span><!-- ko text: $t('Select Your Bank') --><!-- /ko --></span>
......@@ -68,17 +68,16 @@
</select>
<!--/ko-->
<!-- ko if: isPaymentMethodOpenInvoiceMethod() -->
<!-- ko if: showGender() -->
<div class="field gender_type type required">
<label data-bind="attr: {for: getCode() + '_gender_type'}" class="label">
<div class="field gender required">
<label data-bind="attr: {for: getCode() + '_gender_type_' + value}" class="label">
<span><!-- ko text: $t('Gender')--><!-- /ko --></span>
</label>
<div class="control">
<select class="select select-gender-type"
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(),
optionsValue: 'key',
optionsText: 'value',
......@@ -91,50 +90,51 @@
<!--/ko-->
<!-- ko if: showDob() -->
<div class="field required">
<label data-bind="attr: {for: getCode() + '_dob'}" class="label">
<div class="field dob type required">
<label data-bind="attr: {for: getCode() + '_dob_' + value}" class="label">
<span><!-- ko text: $t('Date of Birth')--><!-- /ko --></span>
</label>
<div class="control">
<input type="text" class="input-text"
name="payment[dob]"
data-bind="
datepicker: { storage: datepickerValue, options: { showOn: 'both', changeYear: true, yearRange: '-99:-1', defaultDate: '-20y' } },
attr: {
title: $t('Date of Birth'),
'data-container': getCode() + '-dob',
'data-validate': JSON.stringify({'required':true })
},
value: dob"
data-bind=" datepicker: { storage: datepickerValue, options: { showOn: 'both', changeYear: true, yearRange: '-99:-1', defaultDate: '-20y' } },
attr: {
id: getCode() + '_dob_' + value,
title: $t('Date of Birth'),
'data-container': getCode() + '-dob'
},
value: dob"
data-validate="{required:true}"
/>
</div>
</div>
<!--/ko-->
<!-- ko if: showTelephone() -->
<div class="field required">
<label data-bind="attr: {for: getCode() + '_telephone'}" class="label">
<div class="field telephone type required">
<label data-bind="attr: {for: getCode() + '_telephone_' + value}" class="label">
<span><!-- ko text: $t('Telephone')--><!-- /ko --></span>
</label>
<div class="control">
<input type="number" class="input-text"
name="payment[telephone]"
data-bind="
attr: {
id: getCode() + '_telephone',
title: $t('Telephone'),
'data-container': getCode() + '-telephone',
'data-validate': JSON.stringify({'required-number':true })
},
value: telephone"
attr: {
id: getCode() + '_telephone_' + value,
title: $t('Telephone'),
'data-container': getCode() + '-telephone_' + value,
'data-validate': JSON.stringify({'required-number':true})
},
value: telephone"
data-validate="{required:true}"
/>
</div>
</div>
<!--/ko-->
<!-- ko if: showSsn() -->
<div class="field required">
<label data-bind="attr: {for: getCode() + '_ssn'}" class="label">
<div class="field ssn type required">
<label data-bind="attr: {for: getCode() + '_ssn_' + value}" class="label">
<span><!-- ko text: $t('Personal number (last digits)')--><!-- /ko --></span>
</label>
<div class="control">
......@@ -142,13 +142,14 @@
name="payment[ssn]"
data-bind="
attr: {
id: getCode() + '_ssn',
id: getCode() + '_ssn_' + value,
title: $t('Social Security Number'),
'data-container': getCode() + '-ssn',
'data-validate': JSON.stringify({'required-number':true }),
'data-validate': JSON.stringify({'required-number':true}),
maxlength : getSsnLength()
},
value: ssn"
data-validate="{required:true}"
/>
</div>
</div>
......@@ -156,6 +157,8 @@
<!--/ko-->
</fieldset>
</form>
<div class="checkout-agreements-block">
<!-- ko foreach: $parents[1].getRegion('before-place-order') -->
<!-- ko template: getTemplate() --><!-- /ko -->
......@@ -177,10 +180,6 @@
<!--/ko-->
<input type="hidden" name="payment[dfValue]" data-bind="attr: { id: 'dfValue', value: dfValue }" />
<!-- ko if: (isPaymentMethodSelectionOnAdyen()) -->
<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
......
......@@ -196,7 +196,7 @@
<!--/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">
<label data-bind="attr: {for: getCode() + '_installments'}" class="label">
......@@ -205,12 +205,12 @@
<div class="control">
<select class="select"
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),
options: getInstallments,
optionsValue: 'value',
optionsText: 'key',
optionsCaption: $t('Installments'),
optionsCaption: $t('Do not use Installments'),
value: installment"
data-validate="{required:true}">
</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