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 99d1ec99 authored by Rik ter Beek's avatar Rik ter Beek

Refactor the complete oneclick process as it was not correctly send to...

Refactor the complete oneclick process as it was not correctly send to checkout api. Build a converter to convert oneclick,recurring to enableOneclick and enableRecurring to make it easier for the merchants to configure. Update version so upgrade script will be executed. Added converter back to oneclick,recurring to be backwards compatible with current billing agreements. Made fixes for oneclick and bcmc. added styles for cards component and oneclick component.
parent 8251eef0
......@@ -235,9 +235,7 @@ class Redirect extends \Magento\Payment\Block\Form
);
$formFields['shopperEmail'] = $shopperEmail;
// recurring
$recurringType = trim($this->_adyenHelper->getAdyenAbstractConfigData(
'recurring_type'
));
$recurringType = $this->_adyenHelper->getRecurringTypeFromOneclickRecurringSetting();
$brandCode = $this->_order->getPayment()->getAdditionalInformation(
\Adyen\Payment\Observer\AdyenHppDataAssignObserver::BRAND_CODE
);
......
......@@ -183,7 +183,7 @@ class PayByMailCommand implements CommandInterface
$formFields['shopperEmail'] = $shopperEmail;
// recurring
$recurringType = trim($this->_adyenHelper->getAdyenAbstractConfigData('recurring_type', $storeId));
$recurringType = $this->_adyenHelper->getRecurringTypeFromOneclickRecurringSetting($storeId);
$sessionValidity = $this->_adyenHelper->getAdyenPayByMailConfigData('session_validity', $storeId);
......
......@@ -65,7 +65,11 @@ class CcAuthorizationDataBuilder implements BuilderInterface
$storeId = $order->getStoreId();
$request = [];
// If ccType is set use this. For bcmc you need bcmc otherwise it will fail
$request['paymentMethod']['type'] = "scheme";
if ($payment->getAdditionalInformation(AdyenCcDataAssignObserver::CC_TYPE)) {
$request['paymentMethod']['type'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::CC_TYPE);
}
if ($cardNumber = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::CREDIT_CARD_NUMBER)) {
$request['paymentMethod']['encryptedCardNumber'] = $cardNumber;
......
......@@ -20,6 +20,7 @@
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Gateway\Request;
use Magento\Payment\Gateway\Request\BuilderInterface;
......@@ -57,9 +58,11 @@ class RecurringDataBuilder implements BuilderInterface
$this->_adyenLogger = $adyenLogger;
}
/**
* @param array $buildSubject
* @return array
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function build(array $buildSubject)
{
......@@ -68,49 +71,26 @@ class RecurringDataBuilder implements BuilderInterface
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$payment = $paymentDataObject->getPayment();
// Needs to change when oneclick,cc using facade impl.
$paymentMethodCode = $payment->getMethodInstance()->getCode();
$customerId = $payment->getOrder()->getCustomerId();
$storeId = null;
if ($this->appState->getAreaCode() === \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE) {
$storeId = $payment->getOrder()->getStoreId();
}
$recurringType = $this->adyenHelper->getAdyenAbstractConfigData('recurring_type', $storeId);
// set the recurring type
$recurringContractType = null;
if ($recurringType) {
if ($paymentMethodCode == \Adyen\Payment\Model\Ui\AdyenOneclickConfigProvider::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;
}
} elseif ($paymentMethodCode == \Adyen\Payment\Model\Ui\AdyenCcConfigProvider::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;
$result['paymentMethod']['storeDetails'] = "true";
}
$enableOneclick = $this->adyenHelper->getAdyenAbstractConfigData('enable_oneclick', $storeId);
$enableRecurring = $this->adyenHelper->getAdyenAbstractConfigData('enable_recurring', $storeId);
if ($enableOneclick) {
$result['enableOneclick'] = true;
}
// $this->_adyenLogger->addAdyenDebug("recurring?: ". $recurringContractType);
if ($enableRecurring) {
$result['enableRecurring'] = true;
}
// // only when recurringContractType is set and when a customer is loggedIn
// if ($recurringContractType && $customerId > 0) {
// $recurring = ['contract' => $recurringContractType];
// $result['recurring'] = $recurring;
// }
if ($payment->getAdditionalInformation("store_cc") === "1") {
$result['paymentMethod']['storeDetails'] = true;
}
return $result;
}
......
This diff is collapsed.
......@@ -119,6 +119,8 @@ class PaymentRequest extends DataObject
throw new \Magento\Framework\Exception\LocalizedException(__('3D secure failed'));
}
$this->_adyenHelper->createAdyenBillingAgreement($order, $result['additionalData']);
return $result;
}
......
......@@ -203,7 +203,8 @@ class Agreement extends \Magento\Paypal\Model\Billing\Agreement
}
$expiryDate = explode('/', $contractDetail['expiryDate']);
$recurringType = $this->_adyenHelper->getAdyenAbstractConfigData('recurring_type');
$recurringType = $this->_adyenHelper->getRecurringTypeFromOneclickRecurringSetting();
$agreementData = [
'card' => [
'holderName' => $contractDetail['cardHolderName'],
......
......@@ -130,10 +130,10 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
]
]);
$recurringType = $this->_adyenHelper->getAdyenAbstractConfigData('recurring_type');
$enableOneclick = $this->_adyenHelper->getAdyenAbstractConfigData('enable_oneclick');
$canCreateBillingAgreement = false;
if ($recurringType == "ONECLICK" || $recurringType == "ONECLICK,RECURRING") {
if ($enableOneclick) {
$canCreateBillingAgreement = true;
}
......
......@@ -138,9 +138,9 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
$config['payment']['adyenOneclick']['checkoutUrl'] = $this->_adyenHelper->getCheckoutContextUrl($this->_storeManager->getStore()->getId());
$config['payment']['adyenOneclick']['locale'] = $this->_adyenHelper->getStoreLocale($this->_storeManager->getStore()->getId());
$recurringType = $this->_adyenHelper->getAdyenAbstractConfigData('recurring_type');
$enableOneclick = $this->_adyenHelper->getAdyenAbstractConfigData('enable_oneclick');
$canCreateBillingAgreement = false;
if ($recurringType == "ONECLICK" || $recurringType == "ONECLICK,RECURRING") {
if ($enableOneclick) {
$canCreateBillingAgreement = true;
}
......
<?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\Setup;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Framework\App\Config\Storage\WriterInterface;
/**
* Class UpgradeData
* @package Adyen\Payment\Setup
*/
class UpgradeData implements UpgradeDataInterface
{
/**
* @var WriterInterface
*/
private $configWriter;
/**
* @var ReinitableConfigInterface
*/
private $reinitableConfig;
public function __construct(
WriterInterface $configWriter,
ReinitableConfigInterface $reinitableConfig
) {
$this->configWriter = $configWriter;
$this->reinitableConfig = $reinitableConfig;
}
/**
* @param ModuleDataSetupInterface $setup
* @param ModuleContextInterface $context
*/
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
if (version_compare($context->getVersion(), '2.4.4', '<')) {
$this->updateSchemaVersion244($setup);
}
$setup->endSetup();
}
/**
* Upgrade to 2.4.4
* We use new configuration options to define if you want to store the payment for oneclick or
* recurring or a combination of those in a more friendly way and make it easier to integrate with our checkout API
*
* @param ModuleDataSetupInterface $setup
*/
public function updateSchemaVersion244(ModuleDataSetupInterface $setup)
{
// convert billing agreement select box to oneclick recurring settings
$pathEnableOneclick = "payment/adyen_abstract/enable_oneclick";
$pathEnableRecurring = "payment/adyen_abstract/enable_recurring";
$configDataTable = $setup->getTable('core_config_data');
$connection = $setup->getConnection();
$select = $connection->select()
->from($configDataTable)
->where(
'path = ?',
'payment/adyen_abstract/recurring_type'
);
$configRecurringTypeValues = $connection->fetchAll($select);
foreach ($configRecurringTypeValues as $configRecurringTypeValue) {
$scope = $configRecurringTypeValue['scope'];
$scopeId = $configRecurringTypeValue['scope_id'];
switch ($configRecurringTypeValue['value']) {
case \Adyen\Payment\Model\RecurringType::ONECLICK:
$this->configWriter->save(
$pathEnableOneclick,
'1',
$scope,
$scopeId
);
$this->configWriter->save(
$pathEnableRecurring,
'0',
$scope,
$scopeId
);
break;
case \Adyen\Payment\Model\RecurringType::ONECLICK_RECURRING:
$this->configWriter->save(
$pathEnableOneclick,
'1',
$scope,
$scopeId
);
$this->configWriter->save(
$pathEnableRecurring,
'1',
$scope,
$scopeId
);
break;
case \Adyen\Payment\Model\RecurringType::RECURRING:
$this->configWriter->save(
$pathEnableOneclick,
'0',
$scope,
$scopeId
);
$this->configWriter->save(
$pathEnableRecurring,
'1',
$scope,
$scopeId
);
break;
case \Adyen\Payment\Model\RecurringType::NONE:
$this->configWriter->save(
$pathEnableOneclick,
'0',
$scope,
$scopeId
);
$this->configWriter->save(
$pathEnableRecurring,
'0',
$scope,
$scopeId
);
break;
}
}
// re-initialize otherwise it will cause errors
$this->reinitableConfig->reinit();
}
}
\ No newline at end of file
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Store\Test\Unit\Setup;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Select;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Adyen\Payment\Setup\UpgradeData;
use PHPUnit_Framework_MockObject_MockObject as MockObject;
class UpgradeDataTest extends \PHPUnit\Framework\TestCase
{
/**
* @var ObjectManager
*/
private $objectManagerHelper;
/**
* @var ModuleDataSetupInterface|MockObject
*/
private $setupMock;
/**
* @var AdapterInterface|MockObject
*/
private $connectionMock;
/**
* @var ModuleContextInterface|MockObject
*/
private $contextMock;
/**
* @var UpgradeData
*/
protected $model;
protected function setUp()
{
$this->objectManagerHelper = new ObjectManager($this);
$this->connectionMock = $this->getMockBuilder(AdapterInterface::class)
->getMockForAbstractClass();
$this->setupMock = $this->getMockBuilder(ModuleDataSetupInterface::class)
->getMockForAbstractClass();
$this->setupMock->expects($this->any())
->method('getConnection')
->willReturn($this->connectionMock);
$this->contextMock = $this->getMockBuilder(ModuleContextInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->model = new UpgradeData();
}
/**
* @param array $groupList
* @param array $expectedCodes
* @dataProvider upgradeDataProvider
*/
public function testUpgradeToVersion244(array $groupList, array $expectedCodes)
{
$tableName = 'core_config_data';
$this->setupMock->expects($this->once())
->method('getTable')
->willReturn($tableName);
$selectMock = $this->getMockBuilder(Select::class)
->setMethods(['from'])
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->contextMock->expects($this->once())
->method('getVersion')
->willReturn('2.4.3');
$this->connectionMock->expects($this->any())
->method('select')
->willReturn($selectMock);
$selectMock->expects($this->once())
->method('from')
->with('store_group', ['group_id', 'name'])
->willReturnSelf();
$this->connectionMock->expects($this->once())
->method('fetchPairs')
->with($selectMock)
->willReturn($groupList);
$i = 2;
foreach ($expectedCodes as $groupId => $code) {
$this->connectionMock->expects($this->at($i++))
->method('update')
->with(
$tableName,
['code' => $code],
['group_id = ?' => $groupId]
);
}
$this->model->upgrade($this->setupMock, $this->contextMock);
}
public function upgradeDataProvider()
{
return [
[
[
1 => 'Test Group'
],
[
1 => 'test_group'
]
],
[
[
1 => 'Test Group',
2 => 'Test Group',
3 => 'Test Group',
],
[
1 => 'test_group',
2 => 'test_group2',
3 => 'test_group3'
]
],
[
[
1 => '123 Group',
2 => '12345',
3 => '123456',
4 => '123456',
5 => '12Group34',
6 => '&#*@#&_group'
],
[
1 => 'group',
2 => 'store_group',
3 => 'store_group2',
4 => 'store_group3',
5 => 'group34',
6 => 'group2'
]
]
];
}
}
......@@ -2,7 +2,7 @@
"name": "adyen/module-payment",
"description": "Official Magento2 Plugin to connect to Payment Service Provider Adyen.",
"type": "magento2-module",
"version": "2.4.3",
"version": "2.4.4",
"license": [
"OSL-3.0",
"AFL-3.0"
......
......@@ -22,33 +22,30 @@
* 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_billing_agreements" translate="label" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="adyen_billing_agreements" translate="label" type="text" sortOrder="50" showInDefault="1"
showInWebsite="1" showInStore="1">
<label><![CDATA[Advanced: Billing Agreements]]></label>
<frontend_model>Magento\Config\Block\System\Config\Form\Fieldset</frontend_model>
<comment>
<![CDATA[
<p>
<strong>ONECLICK</strong>: The shopper opts in to storing their card details for future use.
The shopper is present for the subsequent transaction, for cards the security code (CVC/CVV) is required.
</p>
<p>
<strong>RECURRING*</strong>: Payment details are stored for future use. For cards, the security
code (CVC/CVV) is not required for subsequent payments.
</p>
<p>
<strong>ONECLICK, RECURRING*</strong>: Payment details are stored for future use. This allows the use of
the stored payment details regardless of whether the shopper is on your site or not.
</p>
<p>* keep in mind you need the recurring permission enabled. You can contact magento@adyen.com to enable this for your account.
]]>
</comment>
<field id="enable_oneclick" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1"
showInStore="1">
<label>Enable OneClick</label>
<tooltip>The shopper opts in to storing their card details for future use. The shopper is present for the
subsequent transaction, for cards the security code (CVC/CVV) is required.
</tooltip>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/adyen_abstract/enable_oneclick</config_path>
</field>
<field id="recurring_type" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Agreement Type</label>
<tooltip>When enabled, users can save their Credit Cards and their SEPA authorizations. ONECLICK will require the input of the CVC for subsequent payments, while RECURRING does not.</tooltip>
<source_model>Adyen\Payment\Model\Config\Source\RecurringType</source_model>
<config_path>payment/adyen_abstract/recurring_type</config_path>
<field id="enable_recurring" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1"
showInStore="1">
<label>Enable Recurring</label>
<tooltip>Payment details are stored for future use. For cards, the security
code (CVC/CVV) is not required for subsequent payments.
</tooltip>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/adyen_abstract/enable_recurring</config_path>
</field>
</group>
</include>
\ No newline at end of file
......@@ -28,7 +28,6 @@
<adyen_abstract>
<active>0</active>
<model>AdyenPaymentGenericFacade</model>
<recurring_type>ONECLICK</recurring_type>
<order_status>pending</order_status>
<demo_mode>1</demo_mode>
<debug>1</debug>
......@@ -36,6 +35,8 @@
<sepa_flow>sale</sepa_flow>
<split_payments_refund_strategy>1</split_payments_refund_strategy>
<return_path>checkout/cart</return_path>
<enable_oneclick>1</enable_oneclick>
<enable_recurring>0</enable_recurring>
<group>adyen</group>
</adyen_abstract>
<adyen_cc>
......
......@@ -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="2.4.3">
<module name="Adyen_Payment" setup_version="2.4.4">
<sequence>
<module name="Magento_Sales"/>
<module name="Magento_Quote"/>
......
This diff is collapsed.
......@@ -45,6 +45,7 @@ define(
var variant = ko.observable(null);
var paymentMethod = ko.observable(null);
var numberOfInstallments = ko.observable(null);
var isValid = ko.observable(false);
return Component.extend({
defaults: {
......@@ -189,7 +190,7 @@ define(
* creates the card component,
* sets up the callbacks for card components
*/
renderSecureCVC: function() {
renderSecureCVC: function () {
var self = this;
var oneClickCardNode = document.getElementById('cvcContainer-' + self.value);
......@@ -198,12 +199,19 @@ define(
locale: self.getLocale()
});
// this should be fixed in new version of checkout card component
var hideCVC = false;
if (self.agreement_data.variant == "bcmc") {
hideCVC = true;
}
var oneClickCard = checkout
.create('card', {
originKey: self.getOriginKey(),
loadingContext: self.getLoadingContext(),
type: self.agreement_data.variant,
oneClick: true,
hideCVC: hideCVC,
// Specific for oneClick cards
details: [
......@@ -221,15 +229,32 @@ define(
}
},
onChange: function(state) {
onChange: function (state) {
if (state.isValid) {
self.encryptedCreditCardVerificationNumber = state.data.encryptedSecurityCode;
} else {
self.encryptedCreditCardVerificationNumber = '';
}
},
onValid: function (data) {
if (data.isValid) {
isValid(true);
} else {
isValid(false);
}
return;
},
onError: function(data) {
if(data.fieldType == "encryptedSecurityCode" && data.error != "") {
isValid(false);
}
return;
}
})
.mount(oneClickCardNode);
window.adyencheckout = oneClickCard;
},
/**
* Builds the payment details part of the payment information reqeust
......@@ -260,17 +285,9 @@ define(
var form = 'form[data-role=' + codeValue + ']';
var validate = $(form).validation() && $(form).validation('isValid');
// if oneclick or recurring is a card check CVC validity
var cid = true;
if (this.agreement_data.card) {
// if encrypted cvc is empty the request is not valid
if (this.hasVerification() && this.encryptedCreditCardVerificationNumber.length === 0) {
cid = false;
}
}
if (!validate || !cid) {
debugger;
// bcmc does not have any cvc
if (!validate || (isValid() == false && variant() != "bcmc")) {
return false;
}
......
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