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 fe0bb518 authored by rikterbeek's avatar rikterbeek

Implemented OneClick payment method, seperate log file for notfiications,...

Implemented OneClick payment method, seperate log file for notfiications, implemented recurring_contract notification saved into billing agreements
parent 3552776c
<?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\Block\Form;
class Oneclick extends \Adyen\Payment\Block\Form\Cc
{
/**
* @var string
*/
protected $_template = 'Adyen_Payment::form/oneclick.phtml';
}
\ No newline at end of file
<?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\Block\Info;
class Oneclick extends AbstractInfo
{
/**
* @var string
*/
protected $_template = 'Adyen_Payment::info/adyen_oneclick.phtml';
/**
* @return string
*/
// public function toPdf()
// {
// $this->setTemplate('Magento_OfflinePayments::info/pdf/checkmo.phtml');
// return $this->toHtml();
// }
}
......@@ -77,7 +77,7 @@ class Json extends \Magento\Framework\App\Action\Action
$notificationItems = json_decode(file_get_contents('php://input'), true);
// log the notification
$this->_adyenLogger->info("The content of the notification is: " . print_r($notificationItems,1));
$this->_adyenLogger->addAdyenNotification("The content of the notification is: " . print_r($notificationItems,1));
$notificationMode = isset($notificationItems['live']) ? $notificationItems['live'] : "";
......@@ -92,7 +92,7 @@ class Json extends \Magento\Framework\App\Action\Action
}
}
$this->_adyenLogger->info("The result is accepted");
$this->_adyenLogger->addAdyenNotification("The result is accepted");
$this->getResponse()
->clearHeader('Content-Type')
......
......@@ -85,11 +85,7 @@ class Result extends \Magento\Framework\App\Action\Action
public function execute()
{
$response = $this->getRequest()->getParams();
$this->_adyenLogger->notification(print_r($response, true));
// testing
$this->_adyenLogger->notification("WAAR KOMT DEZE REGEL 1");
$this->_adyenLogger->notificationtest("WAAR KOMT DEZE REGEL 2");
$this->_adyenLogger->addAdyenResult(print_r($response, true));
$result = $this->validateResponse($response);
......@@ -170,7 +166,7 @@ class Result extends \Magento\Framework\App\Action\Action
]);
} else {
throw new \Magento\Framework\Exception\LocalizedException(__('Order does not exists with increment_id: %s1', $incrementId));
throw new \Magento\Framework\Exception\LocalizedException(__('Order does not exists with increment_id: %1', $incrementId));
}
} else {
throw new \Magento\Framework\Exception\LocalizedException(__('Empty merchantReference'));
......
......@@ -62,23 +62,27 @@ class Validate3d extends \Magento\Framework\App\Action\Action
public function execute()
{
$active = null;
// check if 3d is active
$order = $this->_getOrder();
if($order->getPayment()) {
$active = $order->getPayment()->getAdditionalInformation('3dActive');
$md = $order->getPayment()->getAdditionalInformation('md');
}
// check if 3D secure is active. If not just go to success page
if($active) {
$this->_adyenLogger->info("3D secure is active");
$this->_adyenLogger->addAdyenResult("3D secure is active");
// check if it is already processed
if ($this->getRequest()->isPost()) {
$this->_adyenLogger->info("Process 3D secure payment");
$this->_adyenLogger->addAdyenResult("Process 3D secure payment");
$requestMD = $this->getRequest()->getPost('MD');
$requestPaRes = $this->getRequest()->getPost('PaRes');
$md = $order->getPayment()->getAdditionalInformation('md');
if ($requestMD == $md) {
......@@ -101,7 +105,7 @@ class Validate3d extends \Magento\Framework\App\Action\Action
}
}
} else {
$this->_adyenLogger->info("Customer was redirected to bank for 3D-secure validation.");
$this->_adyenLogger->addAdyenResult("Customer was redirected to bank for 3D-secure validation.");
$order->addStatusHistoryComment(__('Customer was redirected to bank for 3D-secure validation.'))->save();
$this->_view->loadLayout();
......
......@@ -36,17 +36,30 @@ class Data extends AbstractHelper
*/
protected $_encryptor;
/**
* @var \Magento\Payment\Model\Config
*/
protected $_config;
/**
* @var \Magento\Framework\Config\DataInterface
*/
protected $_dataStorage;
/**
* @param Context $context
*/
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Framework\Encryption\EncryptorInterface $encryptor
\Magento\Framework\Encryption\EncryptorInterface $encryptor,
\Magento\Payment\Model\Config $config,
\Magento\Framework\Config\DataInterface $dataStorage
)
{
parent::__construct($context);
$this->_encryptor = $encryptor;
$this->_config = $config;
$this->_dataStorage = $dataStorage;
}
......@@ -249,6 +262,28 @@ class Data extends AbstractHelper
return $this->getConfigData($field, 'adyen_hpp', $storeId, true);
}
/**
* @desc Gives back adyen_hpp configuration values
* @param $field
* @param null $storeId
* @return mixed
*/
public function getAdyenOneclickConfigData($field, $storeId = null)
{
return $this->getConfigData($field, 'adyen_oneclick', $storeId);
}
/**
* @desc Gives back adyen_hpp configuration values as flag
* @param $field
* @param null $storeId
* @return mixed
*/
public function getAdyenOneclickConfigDataFlag($field, $storeId = null)
{
return $this->getConfigData($field, 'adyen_oneclick', $storeId, true);
}
/**
* @desc Retrieve decrypted hmac key
* @return string
......@@ -349,6 +384,21 @@ class Data extends AbstractHelper
}
}
public function getCcTypesAltData()
{
$adyenCcTypes = $this->getAdyenCcTypes();
$types = array();
foreach ($adyenCcTypes as $key => $data) {
$types[$data['code_alt']] = $data;
}
return $types;
}
public function getAdyenCcTypes()
{
return $this->_dataStorage->get('adyen_credit_cards');
}
/**
* @desc Retrieve information from payment configuration
* @param $field
......
......@@ -28,6 +28,34 @@ use Monolog\Logger;
class AdyenLogger extends Logger
{
/**
* Detailed debug information
*/
const ADYEN_DEBUG = 101;
const ADYEN_NOTIFICATION = 201;
const ADYEN_RESULT = 202;
const ADYEN_NOTIFICATION_CRONJOB = 203;
/**
* Logging levels from syslog protocol defined in RFC 5424
* Overrule the default to add Adyen specific loggers to log into seperate files
*
* @var array $levels Logging levels
*/
protected static $levels = array(
100 => 'DEBUG',
101 => 'ADYEN_DEBUG',
200 => 'INFO',
201 => 'ADYEN_NOTIFICATION',
202 => 'ADYEN_RESULT',
203 => 'ADYEN_NOTIFICATION_CRONJOB',
250 => 'NOTICE',
300 => 'WARNING',
400 => 'ERROR',
500 => 'CRITICAL',
550 => 'ALERT',
600 => 'EMERGENCY',
);
/**
* Adds a log record at the INFO level.
......@@ -38,16 +66,25 @@ class AdyenLogger extends Logger
* @param array $context The log context
* @return Boolean Whether the record has been processed
*/
public function notification($message, array $context = array())
public function addAdyenNotification($message, array $context = array())
{
return $this->addRecord(static::INFO, $message, $context);
return $this->addRecord(static::ADYEN_NOTIFICATION, $message, $context);
}
public function addAdyenDebug($message, array $context = array())
{
return $this->addRecord(static::ADYEN_DEBUG, $message, $context);
}
public function notificationtest($message, array $context = array())
public function addAdyenResult($message, array $context = array())
{
return $this->addRecord(static::DEBUG, $message, $context);
return $this->addRecord(static::ADYEN_RESULT, $message, $context);
}
public function addAdyenNotificationCronjob($message, array $context = array())
{
return $this->addRecord(static::ADYEN_NOTIFICATION_CRONJOB, $message, $context);
}
/**
......
......@@ -82,9 +82,9 @@ class AdyenBase extends StreamHandler
*
* {@inheritdoc}
*/
// public function isHandling(array $record)
// {
// return $record['level'] == $this->level;
// }
public function isHandling(array $record)
{
return $record['level'] == $this->level;
}
}
<?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\Logger\Handler;
use Monolog\Logger;
use Adyen\Payment\Logger\AdyenLogger;
class AdyenCronjob extends AdyenBase
{
/**
* @var string
*/
protected $fileName = '/var/log/adyen/cronjob.log';
/**
* @var int
*/
protected $loggerType = AdyenLogger::ADYEN_NOTIFICATION_CRONJOB;
protected $level = AdyenLogger::ADYEN_NOTIFICATION_CRONJOB;
}
......@@ -36,9 +36,8 @@ class AdyenDebug extends AdyenBase
/**
* @var int
*/
protected $loggerType = Logger::DEBUG;
protected $level = Logger::DEBUG;
protected $loggerType = AdyenLogger::ADYEN_DEBUG;
protected $level = AdyenLogger::ADYEN_DEBUG;
}
......@@ -36,10 +36,8 @@ class AdyenNotification extends AdyenBase
/**
* @var int
*/
protected $loggerType = Logger::INFO;
protected $level = Logger::INFO;
protected $loggerType = AdyenLogger::ADYEN_NOTIFICATION;
protected $level = AdyenLogger::ADYEN_NOTIFICATION;
}
<?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\Logger\Handler;
use Monolog\Logger;
use Adyen\Payment\Logger\AdyenLogger;
class AdyenResult extends AdyenBase
{
/**
* @var string
*/
protected $fileName = '/var/log/adyen/result.log';
/**
* @var int
*/
protected $loggerType = AdyenLogger::ADYEN_RESULT;
protected $level = AdyenLogger::ADYEN_RESULT;
}
\ No newline at end of file
......@@ -84,10 +84,19 @@ class AdyenCcConfigProvider extends CcGenericConfigProvider
$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']['generationTime'] = date("c");
$config['payment']['adyenCc']['canCreateBillingAgreement'] = $canCreateBillingAgreement;
foreach ($this->methodCodes as $code) {
if ($this->methods[$code]->isAvailable()) {
......
......@@ -127,7 +127,6 @@ class AdyenHppConfigProvider implements ConfigProviderInterface
$config['payment']['adyenHpp']['redirectUrl'][$code] = $this->getMethodRedirectUrl($code);
// get payment methods
// print_r($this->getAdyenHppPaymentMethods());die();
$config['payment'] ['adyenHpp']['paymentMethods'] = $this->getAdyenHppPaymentMethods();
}
}
......
<?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\Model;
use Magento\Payment\Model\CcGenericConfigProvider;
use Magento\Payment\Helper\Data as PaymentHelper;
class AdyenOneclickConfigProvider extends CcGenericConfigProvider
{
/**
* @var Config
*/
protected $config;
/**
* @var string[]
*/
protected $methodCodes = [
\Adyen\Payment\Model\Method\Oneclick::METHOD_CODE
];
/**
* @var \Magento\Payment\Model\Method\AbstractMethod[]
*/
protected $methods = [];
/**
* @var PaymentHelper
*/
protected $_paymentHelper;
/**
* @var \Adyen\Payment\Helper\Data
*/
protected $_adyenHelper;
/**
* @var Resource\Billing\Agreement\CollectionFactory
*/
protected $_billingAgreementCollectionFactory;
/**
* @var \Magento\Customer\Model\Session
*/
protected $_customerSession;
/**
* @var \Magento\Checkout\Model\Session
*/
protected $_session;
/**
* @var \Magento\Framework\App\State
*/
protected $_appState;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $_storeManager;
/**
* @param \Magento\Payment\Model\CcConfig $ccConfig
* @param PaymentHelper $paymentHelper
* @param \Adyen\Payment\Helper\Data $adyenHelper
*/
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Payment\Model\CcConfig $ccConfig,
PaymentHelper $paymentHelper,
\Adyen\Payment\Helper\Data $adyenHelper,
\Adyen\Payment\Model\Resource\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory,
\Magento\Customer\Model\Session $customerSession,
\Magento\Checkout\Model\Session $session,
\Magento\Store\Model\StoreManagerInterface $storeManager
) {
parent::__construct($ccConfig, $paymentHelper, $this->methodCodes);
$this->_paymentHelper = $paymentHelper;
$this->_adyenHelper = $adyenHelper;
$this->_billingAgreementCollectionFactory = $billingAgreementCollectionFactory;
$this->_customerSession = $customerSession;
$this->_session = $session;
$this->_appState = $context->getAppState();
$this->_storeManager = $storeManager;
}
public function getConfig()
{
$config = parent::getConfig();
$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']['generationTime'] = date("c");
$config['payment']['adyenOneclick']['canCreateBillingAgreement'] = $canCreateBillingAgreement;
foreach ($this->methodCodes as $code) {
if ($this->methods[$code]->isAvailable()) {
$config['payment']['adyenOneclick']['redirectUrl'][$code] = $this->getMethodRedirectUrl($code);
$config['payment'] ['adyenOneclick']['billingAgreements'] = $this->getAdyenOneclickPaymentMethods();
$recurringContractType = $this->_getRecurringContractType();
$config['payment'] ['adyenOneclick']['recurringContractType'] = $recurringContractType;
if($recurringContractType == \Adyen\Payment\Model\RecurringType::ONECLICK) {
$config['payment'] ['adyenOneclick']['hasCustomerInteraction'] = true;
} else {
$config['payment'] ['adyenOneclick']['hasCustomerInteraction'] = false;
}
$config['payment']['adyenOneclick']['redirectUrl'][$code] = $this->getMethodRedirectUrl($code);
}
}
return $config;
}
/**
* Return redirect URL for method
*
* @param string $code
* @return mixed
*/
protected function getMethodRedirectUrl($code)
{
return $this->methods[$code]->getCheckoutRedirectUrl();
}
public function getAdyenOneclickPaymentMethods()
{
$billingAgreements = [];
if ($this->_customerSession->isLoggedIn()) {
$customerId = $this->_customerSession->getCustomerId();
// is admin?
if ($this->_appState->getAreaCode() === \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE) {
//retrieve storeId from quote
$store = $this->_session->getQuote()->getStore();
} else {
$store = $this->_storeManager->getStore();
}
$baCollection = $this->_billingAgreementCollectionFactory->create();
$baCollection->addFieldToFilter('customer_id', $customerId);
$baCollection->addFieldToFilter('store_id', $store->getId());
$baCollection->addFieldToFilter('method_code', 'adyen_oneclick');
$baCollection->addActiveFilter();
$recurringPaymentType = $this->_getRecurringContractType();
foreach ($baCollection as $billingAgreement) {
$agreementData = $billingAgreement->getAgreementData();
// check if AgreementLabel is set and if contract has an recurringType
if($billingAgreement->getAgreementLabel()) {
$data = ['reference_id' => $billingAgreement->getReferenceId(),
'agreement_label' => $billingAgreement->getAgreementLabel(),
'agreement_data' => $agreementData
];
$billingAgreements[] = $data;
}
}
}
return $billingAgreements;
}
/**
* @param Adyen_Payment_Model_Billing_Agreement $billingAgreement
* @param Mage_Core_Model_Store $store
*
* @return bool
*/
protected function _createPaymentMethodFromBA($billingAgreement, $store)
{
$methodInstance = $billingAgreement->getPaymentMethodInstance();
if (! $methodInstance || ! $methodInstance->getConfigData('active', $store)) {
return false;
}
$methodNewCode = 'adyen_oneclick_'.$billingAgreement->getReferenceId();
$methodData = array('model' => 'adyen/adyen_oneclick')
+ $billingAgreement->getOneClickData()
+ Mage::getStoreConfig('payment/adyen_oneclick', $store);
foreach ($methodData as $key => $value) {
$store->setConfig('payment/'.$methodNewCode.'/'.$key, $value);
}
return true;
}
protected function _getRecurringContractType()
{
return $this->_adyenHelper->getAdyenOneclickConfigData('recurring_payment_type');
}
}
\ No newline at end of file
......@@ -24,7 +24,6 @@
namespace Adyen\Payment\Model\Api;
use Magento\Framework\DataObject;
//use \Adyen\Client;
class PaymentRequest extends DataObject
{
......@@ -58,12 +57,20 @@ class PaymentRequest extends DataObject
*/
protected $_client;
/**
* @var \Adyen\Payment\Model\RecurringType
*/
protected $_recurringType;
const GUEST_ID = 'customer_';
/**
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
* @param \Psr\Log\LoggerInterface $logger
* @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Adyen\Payment\Logger\AdyenLogger $adyenLogger
* @param \Adyen\Payment\Model\RecurringType $recurringType
* @param array $data
*/
public function __construct(
......@@ -72,6 +79,7 @@ class PaymentRequest extends DataObject
\Magento\Framework\Encryption\EncryptorInterface $encryptor,
\Adyen\Payment\Helper\Data $adyenHelper,
\Adyen\Payment\Logger\AdyenLogger $adyenLogger,
\Adyen\Payment\Model\RecurringType $recurringType,
array $data = []
) {
$this->_scopeConfig = $scopeConfig;
......@@ -79,6 +87,7 @@ class PaymentRequest extends DataObject
$this->_encryptor = $encryptor;
$this->_adyenHelper = $adyenHelper;
$this->_adyenLogger = $adyenLogger;
$this->_recurringType = $recurringType;
// initialize client
$webserviceUsername = $this->_adyenHelper->getWsUsername();
......@@ -102,7 +111,7 @@ class PaymentRequest extends DataObject
}
public function fullApiRequest($payment)
public function fullApiRequest($payment, $paymentMethodCode)
{
$order = $payment->getOrder();
$amount = $order->getGrandTotal();
......@@ -110,6 +119,11 @@ class PaymentRequest extends DataObject
$shopperIp = $order->getRemoteIp();
$orderCurrencyCode = $order->getOrderCurrencyCode();
$merchantAccount = $this->_adyenHelper->getAdyenAbstractConfigData("merchant_account");
$recurringType = $this->_adyenHelper->getAdyenAbstractConfigData('recurring_type');
$realOrderId = $order->getRealOrderId();
$customerId = $order->getCustomerId();
$shopperReference = (!empty($customerId)) ? $customerId : self::GUEST_ID . $realOrderId;
// call lib
$service = new \Adyen\Service\Payment($this->_client);
......@@ -123,11 +137,39 @@ class PaymentRequest extends DataObject
"reference" => $order->getIncrementId(),
"shopperIP" => $shopperIp,
"shopperEmail" => $customerEmail,
"shopperReference" => $order->getIncrementId(),
"shopperReference" => $shopperReference,
"fraudOffset" => "0",
"browserInfo" => $browserInfo
);
// set the recurring type
$recurringContractType = null;
if($recurringType) {
if($paymentMethodCode == \Adyen\Payment\Model\Method\Oneclick::METHOD_CODE) {
// For ONECLICK look at the recurringPaymentType that the merchant has selected in Adyen ONECLICK settings
if($payment->getAdditionalInformation('customer_interaction')) {
$recurringContractType = \Adyen\Payment\Model\RecurringType::ONECLICK;
} else {
$recurringContractType = \Adyen\Payment\Model\RecurringType::RECURRING;
}
} else if($paymentMethodCode == \Adyen\Payment\Model\Method\Cc::METHOD_CODE) {
if($payment->getAdditionalInformation("store_cc") == "" && ($recurringType == "ONECLICK,RECURRING" || $recurringType == "RECURRING")) {
$recurringContractType = \Adyen\Payment\Model\RecurringType::RECURRING;
} elseif($payment->getAdditionalInformation("store_cc") == "1") {
$recurringContractType = $recurringType;
}
} else {
$recurringContractType = $recurringType;
}
}
if($recurringContractType)
{
$recurring = array('contract' => $recurringContractType);
$request['recurring'] = $recurring;
}
$billingAddress = $order->getBillingAddress();
if($billingAddress)
......@@ -175,6 +217,33 @@ class PaymentRequest extends DataObject
$request = array_merge($request, $requestDelivery);
}
// define the shopper interaction
if($paymentMethodCode == \Adyen\Payment\Model\Method\Oneclick::METHOD_CODE) {
$recurringDetailReference = $payment->getAdditionalInformation("recurring_detail_reference");
if($payment->getAdditionalInformation('customer_interaction')) {
$shopperInteraction = "Ecommerce";
} else {
$shopperInteraction = "ContAuth";
}
// For recurring Ideal and Sofort needs to be converted to SEPA for this it is mandatory to set selectBrand to sepadirectdebit
if(!$payment->getAdditionalInformation('customer_interaction')) {
if($payment->getCcType() == "directEbanking" || $payment->getCcType() == "ideal") {
$this->selectedBrand = "sepadirectdebit";
}
}
} else {
$recurringDetailReference = null;
$shopperInteraction = "Ecommerce";
}
if($shopperInteraction) {
$request['shopperInteraction'] = $shopperInteraction;
}
if($recurringDetailReference && $recurringDetailReference != "") {
$request['selectedRecurringDetailReference'] = $recurringDetailReference;
}
// If cse is enabled add encrypted card date into request
if($this->_adyenHelper->getAdyenCcConfigDataFlag('cse_enabled')) {
......@@ -324,6 +393,59 @@ class PaymentRequest extends DataObject
return $result;
}
public function getRecurringContractsForShopper($shopperReference, $storeId)
{
$recurringContracts = array();
$recurringTypes = $this->_recurringType->getAllowedRecurringTypesForListRecurringCall();
foreach ($recurringTypes as $recurringType) {
try {
// merge ONECLICK and RECURRING into one record with recurringType ONECLICK,RECURRING
$listRecurringContractByType = $this->listRecurringContractByType($shopperReference, $storeId, $recurringType);
if(isset($listRecurringContractByType['details'] ))
{
foreach($listRecurringContractByType['details'] as $recurringContractDetails) {
if(isset($recurringContractDetails['RecurringDetail'])) {
$recurringContract = $recurringContractDetails['RecurringDetail'];
if(isset($recurringContract['recurringDetailReference'])) {
$recurringDetailReference = $recurringContract['recurringDetailReference'];
// check if recurring reference is already in array
if(isset($recurringContracts[$recurringDetailReference])) {
// recurring reference already exists so recurringType is possible for ONECLICK and RECURRING
$recurringContracts[$recurringDetailReference]['recurring_type']= "ONECLICK,RECURRING";
} else {
$recurringContracts[$recurringDetailReference] = $recurringContract;
}
}
}
}
}
} catch (\Exception $exception) {
print_r($exception);
}
}
return $recurringContracts;
}
public function listRecurringContractByType($shopperReference, $storeId, $recurringType)
{
// rest call to get list of recurring details
$contract = ['contract' => $recurringType];
$request = array(
"merchantAccount" => $this->_adyenHelper->getAdyenAbstractConfigData('merchant_account', $storeId),
"shopperReference" => $shopperReference,
"recurring" => $contract,
);
// call lib
$service = new \Adyen\Service\Recurring($this->_client);
$result = $service->listRecurringDetails($request);
return $result;
}
/**
* Retrieve pspReference from payment object
......
<?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\Model\Billing;
class Agreement extends \Magento\Paypal\Model\Billing\Agreement
{
/**
* @var \Adyen\Payment\Helper\Data
*/
private $_adyenHelper;
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Payment\Helper\Data $paymentData
* @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param array $data
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Payment\Helper\Data $paymentData,
\Magento\Paypal\Model\ResourceModel\Billing\Agreement\CollectionFactory $billingAgreementFactory,
\Magento\Framework\Stdlib\DateTime\DateTimeFactory $dateFactory,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = []
)
{
parent::__construct($context, $registry, $paymentData, $billingAgreementFactory, $dateFactory, $resource, $resourceCollection, $data);
$this->_adyenHelper = $adyenHelper;
}
/**
* Not yet possible to set different reference on customer level like magento 1.x version
*
* @return int
*/
public function getCustomerReference()
{
return $this->getCustomerId();
}
public function parseRecurringContractData($data)
{
$this
->setMethodCode('adyen_oneclick')
->setReferenceId($data['recurringDetailReference'])
->setCreatedAt($data['creationDate']);
$creationDate = str_replace(' ', '-', $data['creationDate']);
$this->setCreatedAt($creationDate);
//Billing agreement SEPA
if (isset($data['bank_iban'])) {
$this->setAgreementLabel(__('%1, %2',
$data['bank_iban'],
$data['bank_ownerName']
));
}
// Billing agreement is CC
if (isset($data['card']['number'])) {
$ccType = $data['variant'];
$ccTypes = $this->_adyenHelper->getCcTypesAltData();
if (isset($ccTypes[$ccType])) {
$ccType = $ccTypes[$ccType]['name'];
}
$label = __('%1, %2, **** %3',
$ccType,
$data['card']['holderName'],
$data['card']['number'],
$data['card']['expiryMonth'],
$data['card']['expiryYear']
);
$this->setAgreementLabel($label);
}
if ($data['variant'] == 'paypal') {
$label = __('PayPal %1',
$data['lastKnownShopperEmail']
);
$this->setAgreementLabel($label);
}
$this->setAgreementData($data);
return $this;
}
public function setAgreementData($data)
{
if (is_array($data)) {
unset($data['creationDate']);
unset($data['recurringDetailReference']);
unset($data['payment_method']);
}
$this->setData('agreement_data', json_encode($data));
return $this;
}
public function getAgreementData()
{
return json_decode($this->getData('agreement_data'), true);
}
}
\ No newline at end of file
<?php
/**
* Payment Config Converter
*
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Adyen\Payment\Model\Config;
class Converter implements \Magento\Framework\Config\ConverterInterface
{
/**
* {@inheritdoc}
*/
public function convert($source)
{
$xpath = new \DOMXPath($source);
return [
'adyen_credit_cards' => $this->convertCreditCards($xpath),
];
}
/**
* Convert credit cards xml tree to array
*
* @param \DOMXPath $xpath
* @return array
*/
protected function convertCreditCards(\DOMXPath $xpath)
{
$creditCards = [];
/** @var \DOMNode $type */
foreach ($xpath->query('/payment/adyen_credit_cards/type') as $type) {
$typeArray = [];
/** @var $typeSubNode \DOMNode */
foreach ($type->childNodes as $typeSubNode) {
switch ($typeSubNode->nodeName) {
case 'label':
$typeArray['name'] = $typeSubNode->nodeValue;
break;
case 'code_alt':
$typeArray['code_alt'] = $typeSubNode->nodeValue;
default:
break;
}
}
$typeAttributes = $type->attributes;
$typeArray['order'] = $typeAttributes->getNamedItem('order')->nodeValue;
$ccId = $typeAttributes->getNamedItem('id')->nodeValue;
$creditCards[$ccId] = $typeArray;
}
uasort($creditCards, [$this, '_compareCcTypes']);
$config = [];
foreach ($creditCards as $code => $data) {
$config[$code] = $data;
}
return $config;
}
/**
* Compare sort order of CC Types
*
* @SuppressWarnings(PHPMD.UnusedPrivateMethod) Used in callback.
*
* @param array $left
* @param array $right
* @return int
*/
private function _compareCcTypes($left, $right)
{
return $left['order'] - $right['order'];
}
/**
* Convert methods xml tree to array
*
* @param \DOMXPath $xpath
* @return array
*/
protected function convertMethods(\DOMXPath $xpath)
{
$config = [];
/** @var \DOMNode $method */
foreach ($xpath->query('/payment/methods/method') as $method) {
$name = $method->attributes->getNamedItem('name')->nodeValue;
/** @var $methodSubNode \DOMNode */
foreach ($method->childNodes as $methodSubNode) {
if ($methodSubNode->nodeType != XML_ELEMENT_NODE) {
continue;
}
$config[$name][$methodSubNode->nodeName] = $methodSubNode->nodeValue;
}
}
return $config;
}
}
<?php
/**
* Loads catalog attributes configuration from multiple XML files by merging them together
*
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Adyen\Payment\Model\Config;
class Reader extends \Magento\Framework\Config\Reader\Filesystem
{
/**
* List of identifier attributes for merging
*
* @var array
*/
protected $_idAttributes = [
'/payment/adyen_credit_cards/type' => 'id'
];
/**
* Load configuration scope
*
* @param string|null $scope
* @return array
*/
public function read($scope = null)
{
$scope = $scope ?: $this->_defaultScope;
$fileList = $this->_fileResolver->get($this->_fileName, $scope);
if (!count($fileList)) {
return [];
}
$output = $this->_readFiles($fileList);
return $output;
}
/**
* Read configuration files
*
* @param array $fileList
* @return array
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _readFiles($fileList)
{
/** @var \Magento\Framework\Config\Dom $configMerger */
$configMerger = null;
foreach ($fileList as $key => $content) {
try {
if (!$configMerger) {
$configMerger = $this->_createConfigMerger($this->_domDocumentClass, $content);
} else {
$configMerger->merge($content);
}
} catch (\Magento\Framework\Config\Dom\ValidationException $e) {
throw new \Magento\Framework\Exception\LocalizedException(
new \Magento\Framework\Phrase("Invalid XML in file %1:\n%2", [$key, $e->getMessage()])
);
}
}
if ($this->validationState->isValidationRequired()) {
$errors = [];
if ($configMerger && !$configMerger->validate($this->_schemaFile, $errors)) {
$message = "Invalid Document \n";
throw new \Magento\Framework\Exception\LocalizedException(
new \Magento\Framework\Phrase($message . implode("\n", $errors))
);
}
}
$output = [];
if ($configMerger) {
$output = $this->_converter->convert($configMerger->getDom());
}
return $output;
}
}
<?php
/**
* Locator for payment config XSD schemas.
*
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Adyen\Payment\Model\Config;
use Magento\Framework\Module\Dir;
class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface
{
/**
* Merged config schema file name
*/
const MERGED_CONFIG_SCHEMA = 'adyen_payment_file.xsd';
/**
* Per file validation schema file name
*/
const PER_FILE_VALIDATION_SCHEMA = 'adyen_payment.xsd';
/**
* Path to corresponding XSD file with validation rules for merged config
*
* @var string
*/
protected $_schema = null;
/**
* Path to corresponding XSD file with validation rules for separate config files
*
* @var string
*/
protected $_perFileSchema = null;
/**
* @param \Magento\Framework\Module\Dir\Reader $moduleReader
*/
public function __construct(\Magento\Framework\Module\Dir\Reader $moduleReader)
{
$etcDir = $moduleReader->getModuleDir(\Magento\Framework\Module\Dir::MODULE_ETC_DIR, 'Adyen_Payment');
$this->_schema = $etcDir . '/' . self::MERGED_CONFIG_SCHEMA;
$this->_perFileSchema = $etcDir . '/' . self::PER_FILE_VALIDATION_SCHEMA;
}
/**
* Get path to merged config schema
*
* @return string|null
*/
public function getSchema()
{
return $this->_schema;
}
/**
* Get path to per file validation schema
*
* @return string|null
*/
public function getPerFileSchema()
{
return $this->_perFileSchema;
}
}
<?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\Model\Config\Source;
/**
* Class CcType
* @codeCoverageIgnore
*/
class CcType extends \Magento\Payment\Model\Source\Cctype
{
/**
* Allowed credit card types
*
* @return string[]
*/
public function getAllowedTypes()
{
return ['VI', 'MC', 'AE', 'DI', 'JCB', 'OT'];
}
}
<?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\Model\Config\Source;
class RecurringPaymentType implements \Magento\Framework\Option\ArrayInterface
{
const UNDEFINED_OPTION_LABEL = 'NONE';
/**
* @var \Magento\Sales\Model\Order\Config
*/
protected $_orderConfig;
/**
* @var \Adyen\Payment\Helper\Data
*/
protected $_adyenHelper;
/**
* @param \Magento\Sales\Model\Order\Config $orderConfig
* @param \Adyen\Payment\Helper\Data $adyenHelper
*/
public function __construct(
\Magento\Sales\Model\Order\Config $orderConfig,
\Adyen\Payment\Helper\Data $adyenHelper
)
{
$this->_orderConfig = $orderConfig;
$this->_adyenHelper = $adyenHelper;
}
/**
* @return array
*/
public function toOptionArray()
{
$recurringTypes = $this->_adyenHelper->getRecurringTypes();
foreach ($recurringTypes as $code => $label) {
if($code == \Adyen\Payment\Model\RecurringType::ONECLICK || $code == \Adyen\Payment\Model\RecurringType::RECURRING) {
$options[] = ['value' => $code, 'label' => $label];
}
}
return $options;
}
}
......@@ -23,6 +23,7 @@
namespace Adyen\Payment\Model;
use Magento\Framework\Webapi\Exception;
use Magento\Sales\Model\Order\Email\Sender\OrderSender;
class Cron
......@@ -81,6 +82,21 @@ class Cron
*/
protected $_transactionFactory;
/**
* @var \Adyen\Payment\Model\Billing\AgreementFactory
*/
protected $_billingAgreementFactory;
/**
* @var Resource\Billing\Agreement\CollectionFactory
*/
protected $_billingAgreementCollectionFactory;
/**
* @var Api\PaymentRequest
*/
protected $_adyenPaymentRequest;
/**
* notification attributes
*/
......@@ -114,6 +130,8 @@ class Cron
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param OrderSender $orderSender
* @param \Magento\Framework\DB\TransactionFactory $transactionFactory
* @param Billing\AgreementFactory $billingAgreementFactory
* @param Api\PaymentRequest $paymentRequest
*/
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
......@@ -124,11 +142,14 @@ class Cron
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
\Adyen\Payment\Helper\Data $adyenHelper,
OrderSender $orderSender,
\Magento\Framework\DB\TransactionFactory $transactionFactory
\Magento\Framework\DB\TransactionFactory $transactionFactory,
\Adyen\Payment\Model\Billing\AgreementFactory $billingAgreementFactory,
\Adyen\Payment\Model\Resource\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory,
\Adyen\Payment\Model\Api\PaymentRequest $paymentRequest
)
{
$this->_scopeConfig = $scopeConfig;
$this->_logger = $adyenLogger;
$this->_adyenLogger = $adyenLogger;
$this->_notificationFactory = $notificationFactory;
$this->_orderFactory = $orderFactory;
$this->_datetime = $dateTime;
......@@ -136,22 +157,25 @@ class Cron
$this->_adyenHelper = $adyenHelper;
$this->_orderSender = $orderSender;
$this->_transactionFactory = $transactionFactory;
$this->_billingAgreementFactory = $billingAgreementFactory;
$this->_billingAgreementCollectionFactory = $billingAgreementCollectionFactory;
$this->_adyenPaymentRequest = $paymentRequest;
}
public function processNotification()
{
$this->_order = null;
$this->_logger->info("START OF THE CRONJOB");
$this->_adyenLogger->addAdyenNotificationCronjob("START OF THE CRONJOB");
//fixme somehow the created_at is saved in my timzone
$dateStart = new \DateTime();
// execute notifications from 5 minute or earlier because order could not yet been created by magento
$dateStart = new \DateTime();
$dateStart->modify('-1 day');
$dateStart->modify('-10 day'); // TODO: KEEP THIS ON -1 day
$dateEnd = new \DateTime();
$dateEnd->modify('-5 minute');
$dateEnd->modify('-1 minute'); // TODO: DO NOT COMMIT KEEP ON -5
$dateRange = ['from' => $dateStart, 'to' => $dateEnd, 'datetime' => true];
// create collection
......@@ -162,6 +186,9 @@ class Cron
// loop over the notifications
foreach($notifications as $notification) {
// log the executed notification
$this->_debugData['notification'] = print_r($notification->debug(), 1);
// get order
$incrementId = $notification->getMerchantReference();
......@@ -182,27 +209,23 @@ class Cron
$previousAdyenEventCode = $this->_order->getData('adyen_notification_event_code');
$_paymentCode = $this->_paymentMethodCode();
// set pspReference on payment object only on authorisation and handled_externally(c_cash)
if ($this->_eventCode == Notification::AUTHORISATION
|| $this->_eventCode == Notification::HANDLED_EXTERNALLY)
{
$this->_order->getPayment()->setAdditionalInformation('pspReference', $this->_pspReference);
$this->_order->getPayment()->setAdyenPspReference($this->_pspReference);
}
// update order details
$this->_updateAdyenAttributes($notification);
// check if success is true of false
if (strcmp($this->_success, 'false') == 0 || strcmp($this->_success, '0') == 0) {
// Only cancel the order when it is in state pending, payment review or if the ORDER_CLOSED is failed (means split payment has not be successful)
if($this->_order->getState() === \Magento\Sales\Model\Order::STATE_PENDING_PAYMENT || $this->_order->getState() === \Magento\Sales\Model\Order::STATE_PAYMENT_REVIEW || $this->_eventCode == \Magento\Sales\Model\Order::ADYEN_EVENT_ORDER_CLOSED) {
if($this->_order->getState() === \Magento\Sales\Model\Order::STATE_PENDING_PAYMENT || $this->_order->getState() === \Magento\Sales\Model\Order::STATE_PAYMENT_REVIEW || $this->_eventCode == Notification::ORDER_CLOSED) {
$this->_debugData['_updateOrder info'] = 'Going to cancel the order';
// if payment is API check, check if API result pspreference is the same as reference
if($this->_eventCode == Adyen_Payment_Model_Event::ADYEN_EVENT_AUTHORISATION && $this->_getPaymentMethodType() == 'api') {
if($this->_eventCode == NOTIFICATION::AUTHORISATION && $this->_getPaymentMethodType() == 'api') {
// don't cancel the order becasue order was successfull through api
$this->_debugData['_updateOrder warning'] = 'order is not cancelled because api result was succesfull';
} else {
// don't cancel the order if previous state is authorisation with success=true
if($previousAdyenEventCode != "AUTHORISATION : TRUE") {
// Split payments can fail if the second payment has failed the first payment is refund/cancelled as well so if it is a split payment that failed cancel the order as well
if($previousAdyenEventCode != "AUTHORISATION : TRUE" || $this->_eventCode == Notification::ORDER_CLOSED) {
$this->_holdCancelOrder(false);
} else {
$this->_order->setData('adyen_notification_event_code', $previousAdyenEventCode);
......@@ -220,7 +243,7 @@ class Cron
$this->_order->save();
foreach($this->_debugData as $debug) {
$this->_logger->info($debug);
$this->_adyenLogger->addAdyenNotificationCronjob($debug);
}
// set done to true
......@@ -229,7 +252,7 @@ class Cron
$notification->setUpdatedAt($dateEnd);
$notification->save();
}
$this->_logger->info("END OF THE CRONJOB");
$this->_adyenLogger->addAdyenNotificationCronjob("END OF THE CRONJOB");
}
protected function _declareVariables($notification)
......@@ -368,6 +391,100 @@ class Cron
$this->_debugData['_addStatusHistoryComment'] = 'Created comment history for this notification';
}
protected function _updateAdyenAttributes($notification)
{
$this->_debugData['_updateAdyenAttributes'] = 'Updating the Adyen attributes of the order';
$additionalData = unserialize($notification->getAdditionalData());
$_paymentCode = $this->_paymentMethodCode();
if ($this->_eventCode == Notification::AUTHORISATION
|| $this->_eventCode == Notification::HANDLED_EXTERNALLY
|| ($this->_eventCode == Notification::CAPTURE && $_paymentCode == "adyen_pos"))
{
// if current notification is authorisation : false and the previous notification was authorisation : true do not update pspreference
if (strcmp($this->_success, 'false') == 0 || strcmp($this->_success, '0') == 0 || strcmp($this->_success, '') == 0) {
$previousAdyenEventCode = $this->_order->getData('adyen_notification_event_code');
if ($previousAdyenEventCode != "AUTHORISATION : TRUE") {
$this->_updateOrderPaymentWithAdyenAttributes($additionalData);
}
} else {
$this->_updateOrderPaymentWithAdyenAttributes($additionalData);
}
}
}
protected function _updateOrderPaymentWithAdyenAttributes($additionalData)
{
if ($additionalData && is_array($additionalData)) {
$avsResult = (isset($additionalData['avsResult'])) ? $additionalData['avsResult'] : "";
$cvcResult = (isset($additionalData['cvcResult'])) ? $additionalData['cvcResult'] : "";
$totalFraudScore = (isset($additionalData['totalFraudScore'])) ? $additionalData['totalFraudScore'] : "";
$ccLast4 = (isset($additionalData['cardSummary'])) ? $additionalData['cardSummary'] : "";
$refusalReasonRaw = (isset($additionalData['refusalReasonRaw'])) ? $additionalData['refusalReasonRaw'] : "";
$acquirerReference = (isset($additionalData['acquirerReference'])) ? $additionalData['acquirerReference'] : "";
$authCode = (isset($additionalData['authCode'])) ? $additionalData['authCode'] : "";
}
// if there is no server communication setup try to get last4 digits from reason field
if (!isset($ccLast4) || $ccLast4 == "") {
$ccLast4 = $this->_retrieveLast4DigitsFromReason($this->_reason);
}
$this->_order->getPayment()->setAdyenPspReference($this->_pspReference);
$this->_order->getPayment()->setAdditionalInformation('pspReference', $this->_pspReference);
if ($this->_klarnaReservationNumber != "") {
$this->_order->getPayment()->setAdditionalInformation('adyen_klarna_number', $this->_klarnaReservationNumber);
}
if (isset($ccLast4) && $ccLast4 != "") {
// this field is column in db by core
$this->_order->getPayment()->setccLast4($ccLast4);
}
if (isset($avsResult) && $avsResult != "") {
$this->_order->getPayment()->setAdditionalInformation('adyen_avs_result', $avsResult);
}
if (isset($cvcResult) && $cvcResult != "") {
$this->_order->getPayment()->setAdditionalInformation('adyen_cvc_result', $cvcResult);
}
if ($this->_boletoPaidAmount != "") {
$this->_order->getPayment()->setAdditionalInformation('adyen_boleto_paid_amount', $this->_boletoPaidAmount);
}
if (isset($totalFraudScore) && $totalFraudScore != "") {
$this->_order->getPayment()->setAdditionalInformation('adyen_total_fraud_score', $totalFraudScore);
}
if (isset($refusalReasonRaw) && $refusalReasonRaw != "") {
$this->_order->getPayment()->setAdditionalInformation('adyen_refusal_reason_raw', $refusalReasonRaw);
}
if (isset($acquirerReference) && $acquirerReference != "") {
$this->_order->getPayment()->setAdditionalInformation('adyen_acquirer_reference', $acquirerReference);
}
if (isset($authCode) && $authCode != "") {
$this->_order->getPayment()->setAdditionalInformation('adyen_auth_code', $authCode);
}
}
/**
* retrieve last 4 digits of card from the reason field
* @param $reason
* @return string
*/
protected function _retrieveLast4DigitsFromReason($reason)
{
$result = "";
if($reason != "") {
$reasonArray = explode(":", $reason);
if($reasonArray != null && is_array($reasonArray)) {
if(isset($reasonArray[1])) {
$result = $reasonArray[1];
}
}
}
return $result;
}
/**
* @param $order
* @return bool
......@@ -496,8 +613,108 @@ class Cron
}
}
break;
case Notification::RECURRING_CONTRACT:
// storedReferenceCode
$recurringDetailReference = $this->_pspReference;
// check if there is already a BillingAgreement
$billingAgreement = $this->_billingAgreementFactory->create();
$billingAgreement->load($recurringDetailReference, 'reference_id');
if ($billingAgreement && $billingAgreement->getAgreementId() > 0 && $billingAgreement->isValid()) {
try {
$billingAgreement->addOrderRelation($this->_order);
$billingAgreement->setStatus($billingAgreement::STATUS_ACTIVE);
$billingAgreement->setIsObjectChanged(true);
$this->_order->addRelatedObject($billingAgreement);
$message = __('Used existing billing agreement #%s.', $billingAgreement->getReferenceId());
} catch (Exception $e) {
// could be that it is already linked to this order
$message = __('Used existing billing agreement #%s.', $billingAgreement->getReferenceId());
}
} else {
$this->_order->getPayment()->setBillingAgreementData(
[
'billing_agreement_id' => $recurringDetailReference,
'method_code' => $this->_order->getPayment()->getMethodCode(),
]
);
// create new object
$billingAgreement = $this->_billingAgreementFactory->create();
$billingAgreement->setStoreId($this->_order->getStoreId());
$billingAgreement->importOrderPayment($this->_order->getPayment());
// get all data for this contract by doing a listRecurringCall
$customerReference = $billingAgreement->getCustomerReference();
$storeId = $billingAgreement->getStoreId();
$listRecurringContracts = $this->_adyenPaymentRequest->getRecurringContractsForShopper($customerReference, $storeId);
$contractDetail = null;
// get currenct Contract details and get list of all current ones
$recurringReferencesList = array();
foreach ($listRecurringContracts as $rc) {
$recurringReferencesList[] = $rc['recurringDetailReference'];
if (isset($rc['recurringDetailReference']) && $rc['recurringDetailReference'] == $recurringDetailReference) {
$contractDetail = $rc;
}
}
if($contractDetail != null) {
// update status of all the current saved agreements in magento
$billingAgreements = $this->_billingAgreementCollectionFactory->create();
$billingAgreements->addFieldToFilter('customer_id', $customerReference);
// get collection
foreach($billingAgreements as $updateBillingAgreement) {
if(!in_array($updateBillingAgreement->getReferenceId(), $recurringReferencesList)) {
$updateBillingAgreement->setStatus(\Adyen\Payment\Model\Billing\Agreement::STATUS_CANCELED);
$updateBillingAgreement->save();
} else {
$updateBillingAgreement->setStatus(\Adyen\Payment\Model\Billing\Agreement::STATUS_ACTIVE);
$updateBillingAgreement->save();
}
}
// add this billing agreement
$billingAgreement->parseRecurringContractData($contractDetail);
if ($billingAgreement->isValid()) {
$message = __('Created billing agreement #%1.', $billingAgreement->getReferenceId());
// save into sales_billing_agreement_order
$billingAgreement->addOrderRelation($this->_order);
// add to order to save agreement
$this->_order->addRelatedObject($billingAgreement);
} else {
$message = __('Failed to create billing agreement for this order.');
}
}else {
$this->_debugData[$this->_count]['_processNotification error'] = 'Failed to create billing agreement for this order (listRecurringCall did not contain contract)';
$this->_debugData[$this->_count]['_processNotification ref'] = printf('recurringDetailReference in notification is %1', $recurringDetailReference) ;
$this->_debugData[$this->_count]['_processNotification customer ref'] = printf('CustomerReference is: %1 and storeId is %2', $customerReference, $storeId);
$this->_debugData[$this->_count]['_processNotification customer result'] = $listRecurringContracts;
$message = __('Failed to create billing agreement for this order (listRecurringCall did not contain contract)');
}
$comment = $this->_order->addStatusHistoryComment($message);
$this->_order->addRelatedObject($comment);
}
break;
default:
$this->_order->getPayment()->getMethodInstance()->writeLog('notification event not supported!');
$this->_debugData[$this->_count]['_processNotification info'] = sprintf('This notification event: %s is not supported so will be ignored', $this->_eventCode);
break;
}
}
......@@ -695,6 +912,9 @@ class Cron
* @return bool
*/
protected function _isAutoCapture()
{
// validate if payment methods allowes manual capture
if($this->_manualCaptureAllowed())
{
$captureMode = trim($this->_getConfigData('capture_mode', 'adyen_abstract', $this->_order->getStoreId()));
$sepaFlow = trim($this->_getConfigData('flow', 'adyen_sepa', $this->_order->getStoreId()));
......@@ -702,18 +922,16 @@ class Cron
$captureModeOpenInvoice = $this->_getConfigData('auto_capture_openinvoice', 'adyen_abstract', $this->_order->getStoreId());
$captureModePayPal = trim($this->_getConfigData('paypal_capture_mode', 'adyen_abstract', $this->_order->getStoreId()));
//check if it is a banktransfer. Banktransfer only a Authorize notification is send.
$isBankTransfer = $this->_isBankTransfer();
// if you are using authcap the payment method is manual. There will be a capture send to indicate if payment is succesfull
if($_paymentCode == "adyen_sepa" && $sepaFlow == "authcap") {
return false;
}
// payment method ideal, cash adyen_boleto or adyen_pos has direct capture
if (strcmp($this->_paymentMethod, 'ideal') === 0 || strcmp($this->_paymentMethod, 'c_cash' ) === 0 || $_paymentCode == "adyen_pos" || $isBankTransfer == true || ($_paymentCode == "adyen_sepa" && $sepaFlow != "authcap") || $_paymentCode == "adyen_boleto") {
if ($_paymentCode == "adyen_pos" || ($_paymentCode == "adyen_sepa" && $sepaFlow != "authcap")) {
return true;
}
// if auto capture mode for openinvoice is turned on then use auto capture
if ($captureModeOpenInvoice == true && (strcmp($this->_paymentMethod, 'openinvoice') === 0 || strcmp($this->_paymentMethod, 'afterpay_default') === 0 || strcmp($this->_paymentMethod, 'klarna') === 0)) {
return true;
......@@ -734,6 +952,51 @@ class Cron
return false;
}
return true;
} else {
// does not allow manual capture so is always immediate capture
return true;
}
}
/**
* Validate if this payment methods allows manual capture
* This is a default can be forced differently to overrule on acquirer level
*/
protected function _manualCaptureAllowed()
{
$manualCaptureAllowed = null;
$paymentMethod = $this->_paymentMethod;
switch($paymentMethod) {
case 'cup':
case 'cartebancaire':
case 'visa':
case 'mc':
case 'uatp':
case 'amex':
case 'bcmc':
case 'maestro':
case 'diners':
case 'discover':
case 'jcb':
case 'laser':
case 'paypal':
case 'klarna':
case 'afterpay_default':
case 'sepadirectdebit':
$manualCaptureAllowed = true;
break;
default:
// To be sure check if it payment method starts with afterpay_ then manualCapture is allowed
if(strlen($this->_paymentMethod) >= 9 && substr($this->_paymentMethod, 0, 9) == "afterpay_") {
$manualCaptureAllowed = true;
}
$manualCaptureAllowed = false;
}
return $manualCaptureAllowed;
}
/**
......
......@@ -166,6 +166,24 @@ class Cc extends \Magento\Payment\Model\Method\Cc
throw new \Magento\Framework\Exception\LocalizedException(__('Card encryption failed'));
}
}
// save value remember details checkbox
$infoInstance->setAdditionalInformation('store_cc', $data['store_cc']);
return $this;
}
/**
* Validate payment method information object
*
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function validate()
{
// validation only possible on front-end for CSE script
return $this;
}
......@@ -195,7 +213,7 @@ class Cc extends \Magento\Payment\Model\Method\Cc
{
switch ($request) {
case "authorise":
$response = $this->_paymentRequest->fullApiRequest($payment);
$response = $this->_paymentRequest->fullApiRequest($payment, $this->_code);
break;
}
......
......@@ -191,7 +191,7 @@ class Hpp extends \Magento\Payment\Model\Method\AbstractMethod implements Gatewa
$infoInstance->setAdditionalInformation('issuer_id', $data['issuer_id']);
}
$this->_adyenLogger->info(print_r($data,1));
$this->_adyenLogger->debug(print_r($data,1));
return $this;
}
......@@ -337,7 +337,7 @@ class Hpp extends \Magento\Payment\Model\Method\AbstractMethod implements Gatewa
$formFields['merchantSig'] = $merchantSig;
$this->_adyenLogger->info(print_r($formFields, true));
$this->_adyenLogger->debug(print_r($formFields, true));
return $formFields;
}
......
<?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\Model\Method;
/**
* Adyen CreditCard payment method
* @SuppressWarnings(PHPMD.ExcessivePublicCount)
* @SuppressWarnings(PHPMD.TooManyFields)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Oneclick extends \Adyen\Payment\Model\Method\Cc
{
const METHOD_CODE = 'adyen_oneclick';
/**
* @var string
*/
protected $_code = self::METHOD_CODE;
/**
* @var string
*/
protected $_formBlockType = 'Adyen\Payment\Block\Form\Oneclick';
protected $_infoBlockType = 'Adyen\Payment\Block\Info\Oneclick';
// public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null) {
// return true;
// }
/**
* Assign data to info model instance
*
* @param \Magento\Framework\DataObject|mixed $data
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function assignData(\Magento\Framework\DataObject $data)
{
parent::assignData($data);
$infoInstance = $this->getInfoInstance();
// save value remember details checkbox
$infoInstance->setAdditionalInformation('recurring_detail_reference', $data['recurring_detail_reference']);
$recurringPaymentType = $this->_adyenHelper->getAdyenOneclickConfigData('recurring_payment_type');
if($recurringPaymentType == \Adyen\Payment\Model\RecurringType::ONECLICK) {
$customerInteraction = true;
} else {
$customerInteraction = false;
}
$infoInstance->setAdditionalInformation('customer_interaction', $customerInteraction);
return $this;
}
}
\ No newline at end of file
......@@ -30,4 +30,14 @@ class RecurringType {
const ONECLICK_RECURRING = 'ONECLICK_RECURRING';
const RECURRING = 'RECURRING';
protected $_allowedRecurringTypesForListRecurringCall = [
self::ONECLICK,
self::RECURRING
];
public function getAllowedRecurringTypesForListRecurringCall()
{
return $this->_allowedRecurringTypesForListRecurringCall;
}
}
\ No newline at end of file
<?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\Model\Resource\Billing;
/**
* Billing agreement resource model
*/
class Agreement extends \Magento\Paypal\Model\ResourceModel\Billing\Agreement
{
}
\ No newline at end of file
<?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\Model\Resource\Billing\Agreement;
/**
* Billing agreements resource collection
*/
class Collection extends \Magento\Paypal\Model\ResourceModel\Billing\Agreement\Collection
{
/**
* Collection initialization
*
* @return void
*/
protected function _construct()
{
$this->_init('Adyen\Payment\Model\Billing\Agreement', 'Magento\Paypal\Model\ResourceModel\Billing\Agreement');
}
/**
* @return $this
*/
public function addActiveFilter()
{
$this->addFieldToFilter('status', \Magento\Paypal\Model\Billing\Agreement::STATUS_ACTIVE);
return $this;
}
}
......@@ -44,6 +44,11 @@ class UpgradeSchema implements UpgradeSchemaInterface
$this->updateSchemaVersion1001($setup);
}
if (version_compare($context->getVersion(), '1.0.0.2', '<')) {
$this->updateSchemaVersion1002($setup);
}
$setup->endSetup();
}
......@@ -71,4 +76,18 @@ class UpgradeSchema implements UpgradeSchemaInterface
$connection->addColumn($setup->getTable('sales_order_payment'), 'adyen_psp_reference', $pspReferenceColumn);
}
public function updateSchemaVersion1002($setup)
{
$connection = $setup->getConnection();
// Add column to indicate if last notification has success true or false
$adyenAgreementDataColumn = [
'type' => Table::TYPE_TEXT,
'nullable' => true,
'comment' => 'Agreement Data'
];
$connection->addColumn($setup->getTable('paypal_billing_agreement'), 'agreement_data', $adyenAgreementDataColumn);
}
}
\ No newline at end of file
......@@ -43,6 +43,7 @@
<include path="Adyen_Payment::system/adyen_advanced_notifications.xml"/>
<include path="Adyen_Payment::system/adyen_billing_agreements.xml"/>
<include path="Adyen_Payment::system/adyen_cc.xml"/>
<include path="Adyen_Payment::system/adyen_oneclick.xml"/>
<include path="Adyen_Payment::system/adyen_hpp.xml"/>
</group>
......
......@@ -46,6 +46,11 @@
<frontend_class>validate-number</frontend_class>
<config_path>payment/adyen_cc/sort_order</config_path>
</field>
<field id="cctypes" translate="label" type="multiselect" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Credit Card Types</label>
<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>-->
......
<?xml version="1.0"?>
<!--
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2015 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <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_oneclick" translate="label" type="text" sortOrder="150" showInDefault="1" showInWebsite="1" showInStore="1">
<label><![CDATA[OneClick - Requires Adyen Credit Card]]></label>
<frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
<fieldset_css>adyen-method-adyen-cc</fieldset_css>
<comment><![CDATA[During checkout shoppers can choose to have their payment details remembered and stored for trusted websites in Adyen’s highly secure platform. Adyen takes care of this process for its customers. Shoppers can then select in the Magento checkout the saved card and checkout with ‘OneClick’.]]></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_oneclick/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_oneclick/title</config_path>
</field>
<field id="sort_order" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Sort Order</label>
<frontend_class>validate-number</frontend_class>
<config_path>payment/adyen_oneclick/sort_order</config_path>
</field>
<field id="recurring_payment_type" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Agreement Type</label>
<tooltip>With ONECLICK the shopper needs to fill in their security code for credit cards. For RECURRING, this is not needed. If you want to use RECURRING make sure you have Agreement Type set to RECURRING or ONECLICK,RECURRING</tooltip>
<source_model>Adyen\Payment\Model\Config\Source\RecurringPaymentType</source_model>
<config_path>payment/adyen_oneclick/recurring_payment_type</config_path>
</field>
</group>
</include>
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<payment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Adyen_Payment:etc/adyen_payment.xsd">
<adyen_credit_cards>
<type id="AE" order="0">
<label>American Express</label>
<code_alt>amex</code_alt>
</type>
<type id="VI" order="10">
<label>Visa</label>
<code_alt>visa</code_alt>
</type>
<type id="MC" order="20">
<label>MasterCard</label>
<code_alt>mc</code_alt>
</type>
<type id="DI" order="30">
<label>Discover</label>
<code_alt>discover</code_alt>
</type>
<type id="SM" order="40">
<label>Maestro/Switch</label>
<code_alt>maestro</code_alt>
</type>
<type id="JCB" order="50">
<label>JCB</label>
<code_alt>jcb</code_alt>
</type>
<type id="DN" order="60">
<label>Diners</label>
<code_alt>diners</code_alt>
</type>
</adyen_credit_cards>
</payment>
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="payment">
<xs:annotation>
<xs:documentation>
The root node for payment configuration
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="adyen_credit_cards" type="adyen_credit_cardsType" minOccurs="0" />
</xs:all>
</xs:complexType>
</xs:element>
<xs:complexType name="adyen_credit_cardsType">
<xs:annotation>
<xs:documentation>
The containing node for a list of credit card types.
</xs:documentation>
</xs:annotation>
<xs:sequence maxOccurs="unbounded">
<xs:element name="type" type="AdyenTypeType" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="AdyenTypeType">
<xs:annotation>
<xs:documentation>
The definition of a credit card type.
</xs:documentation>
</xs:annotation>
<xs:all>
<xs:element name="label" type="xs:string" />
<xs:element name="code_alt" type="xs:string" />
</xs:all>
<xs:attribute name="id" type="xs:ID" use="required" />
<xs:attribute name="order" type="xs:integer" use="required" />
</xs:complexType>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="payment">
<xs:annotation>
<xs:documentation>
The root node for payment configuration
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="adyen_credit_cards" type="adyen_credit_cardsType" minOccurs="0" />
</xs:all>
</xs:complexType>
</xs:element>
<xs:complexType name="adyen_credit_cardsType">
<xs:annotation>
<xs:documentation>
The containing node for a list of credit card types.
</xs:documentation>
</xs:annotation>
<xs:sequence maxOccurs="unbounded">
<xs:element name="type" type="AdyenTypeType" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="AdyenTypeType">
<xs:annotation>
<xs:documentation>
The definition of a credit card type.
</xs:documentation>
</xs:annotation>
<xs:all>
<xs:element name="label" type="xs:string" minOccurs="0" />
<xs:element name="code_alt" type="xs:string" minOccurs="0" />
</xs:all>
<xs:attribute name="id" type="xs:ID" use="required" />
<xs:attribute name="order" type="xs:integer" />
</xs:complexType>
</xs:schema>
......@@ -48,6 +48,17 @@
<payment_action>authorize</payment_action>
<group>adyen</group>
</adyen_cc>
<adyen_oneclick>
<active>1</active>
<model>Adyen\Payment\Model\Method\Oneclick</model>
<title>Adyen OneClick</title>
<allowspecific>0</allowspecific>
<sort_order>1</sort_order>
<cctypes>AE,VI,MC,DI</cctypes> <!-- important to show the payment method isAvailabe()-->
<recurring_payment_type>ONECLICK</recurring_payment_type>
<payment_action>authorize</payment_action>
<group>adyen</group>
</adyen_oneclick>
<adyen_hpp>
<active>0</active>
<model>Adyen\Payment\Model\Method\Hpp</model>
......
......@@ -34,13 +34,66 @@
<argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
</arguments>
</type>
<type name="Adyen\Payment\Logger\Handler\AdyenResult">
<arguments>
<argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
</arguments>
</type>
<type name="Adyen\Payment\Logger\Handler\AdyenCronjob">
<arguments>
<argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
</arguments>
</type>
<type name="Adyen\Payment\Logger\AdyenLogger">
<arguments>
<argument name="name" xsi:type="string">AdyenLoggerTest</argument>
<argument name="handlers" xsi:type="array">
<item name="adyenDebug" xsi:type="object">Adyen\Payment\Logger\Handler\AdyenDebug</item>
<item name="adyenNotification" xsi:type="object">Adyen\Payment\Logger\Handler\AdyenNotification</item>
<item name="adyenResult" xsi:type="object">Adyen\Payment\Logger\Handler\AdyenResult</item>
<item name="adyenCronjob" xsi:type="object">Adyen\Payment\Logger\Handler\AdyenCronjob</item>
</argument>
</arguments>
</type>
<type name="Adyen\Payment\Model\Config\Reader">
<arguments>
<argument name="fileName" xsi:type="string">adyen_payment.xml</argument>
<argument name="converter" xsi:type="object">Adyen\Payment\Model\Config\Converter</argument>
<argument name="schemaLocator" xsi:type="object">Adyen\Payment\Model\Config\SchemaLocator</argument>
</arguments>
</type>
<virtualType name="adyenPaymentConfigDataStorage" type="Magento\Framework\Config\Data">
<arguments>
<argument name="reader" xsi:type="object">Adyen\Payment\Model\Config\Reader</argument>
<argument name="cacheId" xsi:type="string">adyen_payment_config</argument>
</arguments>
</virtualType>
<!--<type name="Adyen\Payment\Helper\Data">-->
<!--<arguments>-->
<!--<argument name="dataStorage" xsi:type="object">Magento\Payment\Model\Config\Data</argument>-->
<!--</arguments>-->
<!--</type>-->
<type name="Adyen\Payment\Helper\Data">
<arguments>
<argument name="dataStorage" xsi:type="object">adyenPaymentConfigDataStorage</argument>
</arguments>
</type>
<!--<virtualType name="adyenPaymentConfigDataStorage" type="Magento\Framework\Config\Data">-->
<!--<arguments>-->
<!--<argument name="reader" xsi:type="object">Adyen\Payment\Model\Config\Reader</argument>-->
<!--<argument name="cacheId" xsi:type="string">adyen_payment_config</argument>-->
<!--</arguments>-->
<!--</virtualType>-->
<!--<type name="Adyen\Payment\Helper\Data">-->
<!--<arguments>-->
<!--<argument name="dataStorage" xsi:type="object">adyenPaymentConfigDataStorage</argument>-->
<!--</arguments>-->
<!--</type>-->
</config>
\ No newline at end of file
......@@ -27,6 +27,7 @@
<arguments>
<argument name="configProviders" xsi:type="array">
<item name="adyen_cc_config_provider" xsi:type="object">Adyen\Payment\Model\AdyenCcConfigProvider</item>
<item name="adyen_oneclick_config_provider" xsi:type="object">Adyen\Payment\Model\AdyenOneclickConfigProvider</item>
<item name="adyen_hpp_config_provider" xsi:type="object">Adyen\Payment\Model\AdyenHppConfigProvider</item>
</argument>
</arguments>
......
......@@ -24,7 +24,7 @@
-->
<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="1.0.0.1">
<module name="Adyen_Payment" setup_version="1.0.0.2">
<sequence>
<module name="Magento_Sales"/>
<module name="Magento_Quote"/>
......
......@@ -41,3 +41,5 @@
</method>
</methods>
</payment>
......@@ -23,6 +23,9 @@
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
<head>
<css src="Adyen_Payment::css/styles.css"/>
</head>
<body>
<referenceBlock name="checkout.root">
<arguments>
......@@ -43,6 +46,9 @@
<item name="adyen_payment" xsi:type="array">
<item name="component" xsi:type="string">Adyen_Payment/js/view/payment/cc-method</item>
<item name="methods" xsi:type="array">
<item name="adyen_oneclick" xsi:type="array">
<item name="isBillingAddressRequired" xsi:type="boolean">true</item>
</item>
<item name="adyen_cc" xsi:type="array">
<item name="isBillingAddressRequired" xsi:type="boolean">true</item>
</item>
......
<?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>
*/
// @codingStandardsIgnoreFile
?>
<?php $_code = $block->getMethodCode() ?>
<fieldset class="fieldset payment items ccard <?php echo $_code ?>" id="payment_form_<?php echo $_code ?>" style="display: none;">
<div class="field type required">
<label for="<?php echo $_code ?>_cc_type" class="label"><span><?php echo __('Credit Card Type') ?></span></label>
<div class="control">
<select id="<?php echo $_code ?>_cc_type"
data-mage-init='{"creditCardType":{"creditCardTypeContainer":"#<?php echo $_code ?>_cc_type_ss_div"}}'
name="payment[cc_type]" data-validate='{required:true, "validate-cc-type-select":"#<?php echo $_code ?>_cc_number"}' class="select">
<option value=""><?php echo __('--Please Select--')?></option>
<?php $_ccType = $block->getInfoData('cc_type') ?>
<?php foreach ($block->getCcAvailableTypes() as $_typeCode => $_typeName): ?>
<option value="<?php echo $_typeCode ?>"<?php if ($_typeCode == $_ccType): ?> selected="selected"<?php endif ?>><?php echo $_typeName ?></option>
<?php endforeach ?>
</select>
</div>
</div>
<div class="field number required">
<label for="<?php echo $_code ?>_cc_number" class="label"><span><?php echo __('Credit Card Number') ?></span></label>
<div class="control">
<input type="number" id="<?php echo $_code ?>_cc_number" name="payment[cc_number]" title="<?php echo __('Credit Card Number') ?>" class="input-text" value="" data-validate='{"required-number":true, "validate-cc-number":"#<?php echo $_code ?>_cc_type", "validate-cc-type":"#<?php echo $_code ?>_cc_type"}'/>
</div>
</div>
<div class="field required">
<label for="<?php echo $_code ?>_cc_owner" class="label"><span><?php echo __('Credit Card Owner') ?></span></label>
<div class="control">
<input type="text" id="<?php echo $_code ?>_cc_owner" name="payment[cc_owner]" title="<?php echo __('Credit Card Owner') ?>" class="input-text" value=""/>
</div>
</div>
<div class="field date required" id="<?php echo $_code ?>_cc_type_exp_div">
<label for="<?php echo $_code ?>_expiration" class="label"><span><?php echo __('Expiration Date') ?></span></label>
<div class="control">
<div class="fields group group-2">
<div class="field no-label month">
<div class="control">
<select id="<?php echo $_code ?>_expiration" name="payment[cc_exp_month]" class="select month" data-validate='{required:true, "validate-cc-exp":"#<?php echo $_code ?>_expiration_yr"}'>
<?php $_ccExpMonth = $block->getInfoData('cc_exp_month') ?>
<?php foreach ($block->getCcMonths() as $k => $v): ?>
<option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpMonth): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
<?php endforeach ?>
</select>
</div>
</div>
<div class="field no-label year">
<div class="control">
<?php $_ccExpYear = $block->getInfoData('cc_exp_year') ?>
<select id="<?php echo $_code ?>_expiration_yr" name="payment[cc_exp_year]" class="select year" data-validate='{required:true}'>
<?php foreach ($block->getCcYears() as $k => $v): ?>
<option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpYear): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
<?php endforeach ?>
</select>
</div>
</div>
</div>
</div>
</div>
<?php if ($block->hasVerification()): ?>
<div class="field cvv required" id="<?php echo $_code ?>_cc_type_cvv_div">
<label for="<?php echo $_code ?>_cc_cid" class="label"><span><?php echo __('Card Verification Number') ?></span></label>
<div class="control">
<input type="number" title="<?php echo __('Card Verification Number') ?>" class="input-text cvv" id="<?php echo $_code ?>_cc_cid" name="payment[cc_cid]" value="" data-validate='{"required-number":true, "validate-cc-cvn":"#<?php echo $_code ?>_cc_type"}' />
<?php $_content = '<img src=\"' . $block->getViewFileUrl('Magento_Checkout::cvv.png') . '\" alt=\"' . __('Card Verification Number Visual Reference') . '\" title=\"' . __('Card Verification Number Visual Reference') . '\" />'; ?>
<div class="note">
<a href="#" class="action cvv" title="<?php echo __('What is this?') ?>" data-mage-init='{"tooltip": {"content": "<?php echo $_content ?>"}}'><span><?php echo __('What is this?') ?></span></a>
</div>
</div>
</div>
<?php endif; ?>
<?php if ($block->hasSsCardType()): ?>
<div class="field switch solo required" id="<?php echo $_code ?>_cc_type_ss_div">
<div class="nested">
<div class="field switch solo required">
<label for="<?php echo $_code ?>_cc_issue" class="label"><span><?php echo __('Switch/Solo/Maestro Only') ?></span></label>
</div>
<div class="field number required">
<label for="<?php echo $_code ?>_cc_issue" class="label"><span><?php echo __('Issue Number') ?></span></label>
<div class="control">
<input type="text" title="<?php echo __('Issue Number') ?>" class="input-text cvv" id="<?php echo $_code ?>_cc_issue" name="payment[cc_ss_issue]" value="" data-validate='{"validate-cc-ukss":true}'/>
</div>
</div>
<div class="field date required">
<label for="<?php echo $_code ?>_start_month" class="label"><span><?php echo __('Start Date') ?></span></label>
<div class="control">
<div class="fields group group-2">
<div class="field no-label">
<div class="control">
<select id="<?php echo $_code ?>_start_month" name="payment[cc_ss_start_month]" class="select month" data-validate='{"validate-cc-ukss":true}'>
<?php foreach ($block->getCcMonths() as $k => $v): ?>
<option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $block->getInfoData('cc_ss_start_month')): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
<?php endforeach ?>
</select>
</div>
</div>
<div class="field no-label">
<div class="control">
<select id="<?php echo $_code ?>_start_year" name="payment[cc_ss_start_year]" class="select year" data-validate='{"validate-cc-ukss":true}'>
<?php foreach ($block->getSsStartYears() as $k => $v): ?>
<option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $block->getInfoData('cc_ss_start_year')): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
<?php endforeach ?>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="adv container" data-validation-msg="validate-cc-ukss">&nbsp;</div>
</div>
</div>
<?php endif; ?>
<?php echo $block->getChildHtml() ?>
</fieldset>
.checkout-payment-method .ccard .changable-card-expiry { display:none; }
.checkout-payment-method .ccard .changable-card-expiry._active { display:block; }
.checkout-payment-method .ccard .expire-update._disable { display:none; }
......@@ -66,9 +66,13 @@ define(
).done(
function () {
if (redirectOnSuccess) {
if(quote.paymentMethod().method == 'adyen_oneclick') {
window.location.replace(url.build(window.checkoutConfig.payment.adyenOneclick.redirectUrl[quote.paymentMethod().method]));
} else {
window.location.replace(url.build(window.checkoutConfig.payment.adyenCc.redirectUrl[quote.paymentMethod().method]));
}
}
}
).fail(
function (response) {
errorProcessor.process(response);
......
......@@ -32,6 +32,10 @@ define(
) {
'use strict';
rendererList.push(
{
type: 'adyen_oneclick',
component: 'Adyen_Payment/js/view/payment/method-renderer/adyen-oneclick-method'
},
{
type: 'adyen_cc',
component: 'Adyen_Payment/js/view/payment/method-renderer/adyen-cc-method'
......
......@@ -77,13 +77,6 @@ define(
'method': this.item.method,
additional_data: {
'cc_type': this.creditCardType(),
'cc_exp_year': this.creditCardExpYear(),
'cc_exp_month': this.creditCardExpMonth(),
'cc_number': this.creditCardNumber(),
'cc_owner' : this.creditCardOwner(),
'cc_cid': this.creditCardVerificationNumber(),
'cc_ss_start_month': this.creditCardSsStartMonth(),
'cc_ss_start_year': this.creditCardSsStartYear(),
'encrypted_data': this.encryptedData(),
'generationtime': this.generationtime()
}
......@@ -103,8 +96,6 @@ define(
event.preventDefault();
}
//var cse_form = $("adyen-cc-form");
var cse_form = document.getElementById('adyen-cc-form');
var cse_key = this.getCSEKey();
var options = {};
......@@ -152,6 +143,9 @@ define(
getGenerationTime: function() {
return window.checkoutConfig.payment.adyenCc.generationTime;
},
canCreateBillingAgreement: function() {
return window.checkoutConfig.payment.adyenCc.canCreateBillingAgreement;
},
isShowLegend: function() {
return true;
},
......@@ -166,7 +160,7 @@ define(
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;
}
......
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* 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>
*/
/*browser:true*/
/*global define*/
define(
[
'ko',
'underscore',
'jquery',
'Magento_Payment/js/view/payment/cc-form',
'Adyen_Payment/js/action/place-order',
'mage/translate',
'Magento_Checkout/js/model/payment/additional-validators',
'Magento_Checkout/js/action/select-payment-method',
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/checkout-data',
'Adyen_Payment/js/view/payment/adyen-encrypt'
],
function (ko, _, $, Component, placeOrderAction, $t, additionalValidators, selectPaymentMethodAction, quote, checkoutData) {
'use strict';
var recurringDetailReference = ko.observable(null);
var paymentMethod = ko.observable(null);
return Component.extend({
defaults: {
template: 'Adyen_Payment/payment/oneclick-form',
recurringDetailReference: '',
encryptedData: ''
},
initObservable: function () {
this._super()
.observe([
'recurringDetailReference',
'creditCardType',
'creditCardExpYear',
'creditCardExpMonth',
'creditCardVerificationNumber',
'encryptedData'
]);
return this;
},
placeOrderHandler: null,
validateHandler: null,
setPlaceOrderHandler: function(handler) {
this.placeOrderHandler = handler;
},
setValidateHandler: function(handler) {
this.validateHandler = handler;
},
getCode: function() {
return 'adyen_oneclick';
},
getData: function() {
return {
'method': this.item.method,
additional_data: {
'cc_type': this.creditCardType(),
'cc_cid': this.creditCardVerificationNumber(),
'encrypted_data': this.encryptedData()
}
};
},
isActive: function() {
return true;
},
/**
* @override
*/
placeOrder: function(data, event) {
var self = this,
placeOrder;
if (event) {
event.preventDefault();
}
var cse_key = this.getCSEKey();
var options = { enableValidations: false};
var cseInstance = adyen.encrypt.createEncryption(cse_key, options);
var generationtime = self.getGenerationTime();
var cardData = {
cvc : self.creditCardVerificationNumber,
expiryMonth : self.creditCardExpMonth,
expiryYear : self.creditCardExpYear,
generationtime : generationtime
};
var encryptedData = cseInstance.encrypt(cardData);
// set payment method to adyen_hpp
var data = {
"method": self.method,
"po_number": null,
"additional_data": {
encrypted_data: encryptedData,
recurring_detail_reference: self.value
}
};
if (this.validate() && additionalValidators.validate()) {
//this.isPlaceOrderActionAllowed(false);
placeOrder = placeOrderAction(data, this.redirectAfterPlaceOrder);
$.when(placeOrder).fail(function(response) {
//self.isPlaceOrderActionAllowed(true);
});
return true;
}
return false;
},
getControllerName: function() {
return window.checkoutConfig.payment.iframe.controllerName[this.getCode()];
},
context: function() {
return this;
},
isCseEnabled: function() {
return window.checkoutConfig.payment.adyenCc.cseEnabled;
},
canCreateBillingAgreement: function() {
return window.checkoutConfig.payment.adyenCc.canCreateBillingAgreement;
},
isShowLegend: function() {
return true;
},
getAdyenBillingAgreements: function() {
var self = this;
// convert to list so you can iterate
var paymentList = _.map(window.checkoutConfig.payment.adyenOneclick.billingAgreements, function(value) {
return {
'expiry': ko.observable(false),
'test': true,
'test2': true,
'label': value.agreement_label,
'value': value.reference_id,
'agreement_data': value.agreement_data,
'method': self.item.method,
getCode: function() {
return self.item.method;
},
creditCardVerificationNumber: '',
creditCardExpMonth: value.agreement_data.card.expiryMonth,
creditCardExpYear: value.agreement_data.card.expiryYear,
getCSEKey: function() {
return window.checkoutConfig.payment.adyenCc.cseKey;
},
getGenerationTime: function() {
return window.checkoutConfig.payment.adyenCc.generationTime;
},
validate: function () {
var code = self.item.method;
var value = this.value;
var codeValue = code + '_' + value;
var form = 'form[data-role=' + codeValue + ']';
var formObject = $(form);
var validate = $(form).validation() && $(form).validation('isValid');
// add extra validation because jqeury 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(self.hasVerification()) {
var cid = Boolean($(form + ' #' + codeValue + '_cc_cid').valid());
}
if(!validate || !expiration || !expiration_yr || !cid) {
return false;
}
return true;
},
selectExpiry: function() {
var self = this;
self.expiry(true);
return true;
}
}
}
);
return paymentList;
},
selectBillingAgreement: function() {
var self = this;
// set payment method to adyen_hpp
var data = {
"method": self.method,
"po_number": null,
"additional_data": {
recurring_detail_reference: self.value
}
};
// set the brandCode
recurringDetailReference(self.value);
// set payment method
paymentMethod(self.method);
selectPaymentMethodAction(data);
checkoutData.setSelectedPaymentMethod(self.method);
return true;
},
isBillingAgreementChecked: ko.computed(function () {
if(!quote.paymentMethod()) {
return null;
}
if(quote.paymentMethod().method == paymentMethod()) {
return recurringDetailReference();
}
return null;
}),
getRecurringContractType: function() {
return window.checkoutConfig.payment.adyenOneClick.recurringContractType;
},
hasVerification: function() {
return window.checkoutConfig.payment.adyenOneclick.hasCustomerInteraction;
},
getPlaceOrderUrl: function() {
return window.checkoutConfig.payment.iframe.placeOrderUrl[this.getCode()];
}
});
}
);
......@@ -192,65 +192,23 @@
</div>
</div>
<!-- /ko -->
<!-- ko if: (hasSsCardType())-->
<div class="field switch solo required" data-bind="attr: {id: getCode() + '_cc_type_ss_div'}">
<div class="nested">
<div class="field switch-solo required">
<label data-bind="attr: {for: getCode() + '_cc_issue'}" class="label">
<span><!-- ko text: $t('Switch/Solo/Maestro Only')--><!-- /ko --></span>
</label>
</div>
<div class="field number required">
<label data-bind="attr: {for: getCode() + '_cc_issue'}" class="label">
<span><!-- ko text: $t('Issue Number')--><!-- /ko --></span>
</label>
<div class="control">
<input type="number"
value=""
class="input-text cvv"
data-bind="attr: {id: getCode() + '_cc_issue', title: $t('Issue Number'), 'data-container': getCode() + '-cc-issue', 'data-validate': JSON.stringify({'validate-cc-ukss':true})}, enable: isActive($parents)"/>
</div>
</div>
<div class="field date required">
<label data-bind="attr: {for: getCode() + '_start_month'}" class="label">
<span><!-- ko text: $t('Start Date'--><!-- /ko --></span>
<!-- ko if: (canCreateBillingAgreement())-->
<div class="field choice">
<input type="checkbox"
name="payment[store_cc]"
autocomplete="off"
class="checkbox"
value="1"
checked
data-bind="attr: {title: $t('Remember Me')}"
data-validate="{required:true}"/>
<label data-bind="attr: {for: getCode() + '_remember_details'}" class="label">
<span><!-- ko text: $t('Remember these details')--><!-- /ko --></span>
</label>
<div class="control">
<div class="fields group group-2">
<div class="field no-label month">
<div class="control">
<select class="select select-month"
data-bind="attr: {id: getCode() + '_start_month', 'data-container': getCode() + '-cc-start-month', 'data-validate': JSON.stringify({'validate-cc-ukss':true})},
enable: isActive($parents),
options: getCcMonthsValues(),
optionsValue: 'value',
optionsText: 'month',
optionsCaption: $t('Month'),
value: creditCardSsStartMonth">
</select>
</div>
</div>
<div class="field no-label year">
<div class="control">
<select class="select select-year"
data-bind="attr: {id: getCode() + '_start_year', 'data-container': getCode() + '-cc-start-year',
'data-validate': JSON.stringify({'validate-cc-ukss':true})},
enable: isActive($parents),
options: getSsStartYearsValues(),
optionsValue: 'value',
optionsText: 'year',
optionsCaption: $t('Year'),
value: creditCardSsStartYear">
</select>
</div>
</div>
</div>
</div>
</div>
<div class="adv container" data-validation-msg="validate-cc-ukss">&nbsp;</div>
</div>
</div>
<!-- /ko -->
......
<!--
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* 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>
*/
-->
<!-- ko foreach: getAdyenBillingAgreements() -->
<div class="payment-method" data-bind="css: {'_active': (value == $parent.isBillingAgreementChecked())}">
<div class="payment-method-title field choice">
<input type="radio"
name="payment[method]"
class="radio"
data-bind="attr: {'id': value}, value: value, checked: $parent.isBillingAgreementChecked, click: $parent.selectBillingAgreement"/>
<label data-bind="attr: {'for': value}" class="label"><span data-bind="text: label"></span></label>
</div>
<div class="payment-method-content">
<div class="payment-method-billing-address">
<!-- ko foreach: $parents[1].getRegion($parent.getBillingAddressFormName()) -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</div>
<form class="form" action="#" method="post" data-bind="
attr: {'id': 'adyen_oneclick_' + value, 'data-role': 'adyen_oneclick_' + value },
mageInit: {
'transparent':{
'context': $parent.context(),
'controller': $parent.getControllerName(),
'orderSaveUrl':$parent.getPlaceOrderUrl(),
}, 'validation':[]}">
<fieldset data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + $parent.getCode() + '_' + value}">
<!-- ko if: agreement_data.card.number -->
<div class="field number">
<label class="label">
<span><!-- ko text: $t('Credit Card Number')--><!-- /ko --></span>
</label>
<div class="control">
<span data-bind="text: '**** **** ****' + agreement_data.card.number"></span>
</div>
</div>
<div class="field number expire-update" data-bind="css: {'_disable': (true == expiry())}">
<label class="label">
<span><!-- ko text: $t('Expiration Date')--><!-- /ko --></span>
</label>
<div class="control">
<span data-bind="text: agreement_data.card.expiryMonth + '/' + agreement_data.card.expiryYear"></span>
<a class="" data-bind="click: selectExpiry"
><!-- ko text: $t('Update') --><!-- /ko --></a>
</div>
</div>
<div class="field date required changable-card-expiry" data-bind="attr: {id: getCode() + '_' + value + '_cc_type_exp_div'}, css: {'_active': (true == expiry())}">
<label data-bind="attr: {for: getCode() + '_' + value + '_expiration'}" class="label">
<span><!-- ko text: $t('Expiration Date')--><!-- /ko --></span>
</label>
<div class="control">
<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() + '_' + value + '_expiration', 'data-container': getCode() + '-' + value + '-cc-month', 'data-validate': JSON.stringify({required:true, 'validate-cc-exp':'#' + getCode() + '_expiration_yr'})},
enable: $parent.isActive($parents),
options: $parent.getCcMonthsValues(),
optionsValue: 'value',
optionsText: 'month',
optionsCaption: $t('Month'),
value: creditCardExpMonth"
data-validate="{required:true}">
</select>
</div>
</div>
<div class="field no-label year">
<div class="control">
<select class="select select-year"
data-encrypted-name="expiryYear"
data-bind="attr: {id: getCode() + '_' + value + '_expiration_yr', 'data-container': getCode() + '-' + value + '-cc-year', 'data-validate': JSON.stringify({required:true})},
enable: $parent.isActive($parents),
options: $parent.getCcYearsValues(),
optionsValue: 'value',
optionsText: 'year',
optionsCaption: $t('Year'),
value: creditCardExpYear"
data-validate="{required:true}">
</select>
</div>
</div>
</div>
</div>
</div>
<!-- ko if: ($parent.hasVerification())-->
<div class="field cvv required" data-bind="attr: {id: getCode() + '_' + value + '_cc_type_cvv_div'}">
<label data-bind="attr: {for: getCode() + '_' + value + '_cc_cid'}" class="label">
<span><!-- ko text: $t('Card Verification Number')--><!-- /ko --></span>
</label>
<div class="control _with-tooltip">
<input type="number"
autocomplete="off"
class="input-text cvv"
data-encrypted-name="cvc"
value=""
data-bind="attr: {id: getCode() + '_' + value + '_cc_cid',
title: $t('Card Verification Number'),
'data-container': getCode() + '-' + value + '-cc-cvv',
'data-validate': JSON.stringify({'required-number':true, 'validate-card-cvv':'#' + getCode() + '_' + value + '_cc_type'})},
enable: $parent.isActive($parents),
value: creditCardVerificationNumber"
data-validate="{required:true}"/>
<div class="field-tooltip toggle">
<span class="field-tooltip-action action-cvv"
tabindex="0"
data-toggle="dropdown"
data-bind="attr: {title: $t('What is this?')}, mageInit: {'dropdown':{'activeClass': '_active'}}">
<span><!-- ko text: $t('What is this?')--><!-- /ko --></span>
</span>
<div class="field-tooltip-content"
data-target="dropdown"
data-bind="html: $parent.getCvvImageHtml()"></div>
</div>
</div>
</div>
<!-- /ko -->
<!--/ko-->
</fieldset>
<div class="checkout-agreements-block">
<!-- ko foreach: $parents[1].getRegion('before-place-order') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</div>
<div class="actions-toolbar">
<div class="primary">
<button class="action primary checkout"
type="submit"
data-bind="
click: $parent.placeOrder,
attr: {title: $t('Place Order')},
enable: (value == $parent.isBillingAgreementChecked())
"
disabled>
<span data-bind="text: $t('Place Order')"></span>
</button>
</div>
</div>
</form>
</div>
</div>
<!--/ko-->
\ No newline at end of file
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