Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
Adyen Magento2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Shared Libs
Adyen Magento2
Commits
c6bdeeec
Commit
c6bdeeec
authored
Jun 08, 2020
by
Attila Kiss
Committed by
GitHub
Jun 08, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #729 from Adyen/PW-2398
[PW-2398] Implement generic component for alternative payment methods
parents
495edf80
3bb32de1
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
328 additions
and
560 deletions
+328
-560
Gateway/Request/CheckoutDataBuilder.php
Gateway/Request/CheckoutDataBuilder.php
+0
-4
Observer/AdyenAbstractDataAssignObserver.php
Observer/AdyenAbstractDataAssignObserver.php
+92
-0
Observer/AdyenCcDataAssignObserver.php
Observer/AdyenCcDataAssignObserver.php
+4
-58
Observer/AdyenHppDataAssignObserver.php
Observer/AdyenHppDataAssignObserver.php
+24
-42
view/frontend/web/js/model/adyen-payment-service.js
view/frontend/web/js/model/adyen-payment-service.js
+15
-1
view/frontend/web/js/view/payment/adyen-methods.js
view/frontend/web/js/view/payment/adyen-methods.js
+31
-11
view/frontend/web/js/view/payment/method-renderer/adyen-hpp-method.js
...d/web/js/view/payment/method-renderer/adyen-hpp-method.js
+152
-433
view/frontend/web/js/view/payment/method-renderer/adyen-oneclick-method.js
.../js/view/payment/method-renderer/adyen-oneclick-method.js
+0
-2
view/frontend/web/template/payment/hpp-form.html
view/frontend/web/template/payment/hpp-form.html
+10
-9
No files found.
Gateway/Request/CheckoutDataBuilder.php
View file @
c6bdeeec
...
...
@@ -76,12 +76,8 @@ class CheckoutDataBuilder implements BuilderInterface
$order
->
setCanSendNewEmailFlag
(
false
);
$componentStateData
=
$payment
->
getAdditionalInformation
(
AdyenCcDataAssignObserver
::
STATE_DATA
);
$this
->
adyenHelper
->
adyenLogger
->
addAdyenDebug
(
json_encode
(
$componentStateData
));
$requestBody
=
array_merge
(
$requestBody
,
$componentStateData
);
$this
->
adyenHelper
->
adyenLogger
->
addAdyenDebug
(
json_encode
(
$requestBody
));
/*foreach ($componentStateData as $key => $data) {
}*/
if
(
empty
(
$requestBody
[
'paymentMethod'
][
'type'
])
&&
!
empty
(
$payment
->
getAdditionalInformation
(
...
...
Observer/AdyenAbstractDataAssignObserver.php
0 → 100644
View file @
c6bdeeec
<?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\Observer
;
use
Magento\Framework\DataObject
;
use
Magento\Payment\Observer\AbstractDataAssignObserver
;
use
Magento\Quote\Api\Data\PaymentInterface
;
abstract
class
AdyenAbstractDataAssignObserver
extends
AbstractDataAssignObserver
{
const
BRAND_CODE
=
'brand_code'
;
const
STATE_DATA
=
'state_data'
;
const
BROWSER_INFO
=
'browserInfo'
;
const
PAYMENT_METHOD
=
'paymentMethod'
;
const
RISK_DATA
=
'riskData'
;
const
STORE_PAYMENT_METHOD
=
'storePaymentMethod'
;
const
CC_TYPE
=
'cc_type'
;
const
NUMBER_OF_INSTALLMENTS
=
'number_of_installments'
;
const
COMBO_CARD_TYPE
=
'combo_card_type'
;
/**
* @param DataObject $data
* @return array
*/
protected
function
getValidatedAdditionalData
(
DataObject
$data
)
{
// Get additional data array
$additionalData
=
$data
->
getData
(
PaymentInterface
::
KEY_ADDITIONAL_DATA
);
if
(
!
is_array
(
$additionalData
))
{
return
[];
}
// Get a validated additional data array
$additionalData
=
$this
->
getArrayOnlyWithApprovedKeys
(
$additionalData
,
$this
->
approvedAdditionalDataKeys
);
// json decode state data
$stateData
=
[];
if
(
!
empty
(
$additionalData
[
self
::
STATE_DATA
]))
{
$stateData
=
json_decode
(
$additionalData
[
self
::
STATE_DATA
],
true
);
}
// Get validated state data array
if
(
!
empty
(
$stateData
))
{
$stateData
=
$this
->
getArrayOnlyWithApprovedKeys
(
$stateData
,
$this
->
approvedStateDataKeys
);
}
// Replace state data with the decoded and validated state data
$additionalData
[
self
::
STATE_DATA
]
=
$stateData
;
return
$additionalData
;
}
/**
* Returns an array with only the approved keys
*
* @param array $array
* @param array $approvedKeys
* @return array
*/
private
function
getArrayOnlyWithApprovedKeys
(
$array
,
$approvedKeys
)
{
$result
=
[];
foreach
(
$approvedKeys
as
$approvedKey
)
{
if
(
isset
(
$array
[
$approvedKey
]))
{
$result
[
$approvedKey
]
=
$array
[
$approvedKey
];
}
}
return
$result
;
}
}
Observer/AdyenCcDataAssignObserver.php
View file @
c6bdeeec
...
...
@@ -24,32 +24,19 @@
namespace
Adyen\Payment\Observer
;
use
Magento\Framework\Event\Observer
;
use
Magento\Payment\Observer\AbstractDataAssignObserver
;
use
Magento\Quote\Api\Data\PaymentInterface
;
/**
* Class DataAssignObserver
*/
class
AdyenCcDataAssignObserver
extends
AbstractDataAssignObserver
class
AdyenCcDataAssignObserver
extends
A
dyenA
bstractDataAssignObserver
{
//TODO do we need these?
const
VARIANT
=
'variant'
;
const
STATE_DATA
=
'state_data'
;
const
STORE_PAYMENT_METHOD
=
'storePaymentMethod'
;
const
CC_TYPE
=
'cc_type'
;
const
NUMBER_OF_INSTALLMENTS
=
'number_of_installments'
;
const
COMBO_CARD_TYPE
=
'combo_card_type'
;
const
BROWSER_INFO
=
'browserInfo'
;
const
PAYMENT_METHOD
=
'paymentMethod'
;
const
RISK_DATA
=
'riskData'
;
/**
* Approved root level keys from additional data array
*
* @var array
*/
pr
ivate
static
$approvedAdditionalDataKeys
=
[
pr
otected
$approvedAdditionalDataKeys
=
[
self
::
STATE_DATA
,
self
::
COMBO_CARD_TYPE
,
self
::
NUMBER_OF_INSTALLMENTS
...
...
@@ -60,7 +47,7 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
*
* @var array
*/
pr
ivate
static
$approvedStateDataKeys
=
[
pr
otected
$approvedStateDataKeys
=
[
self
::
BROWSER_INFO
,
self
::
PAYMENT_METHOD
,
self
::
RISK_DATA
,
...
...
@@ -76,28 +63,7 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
// Get request fields
$data
=
$this
->
readDataArgument
(
$observer
);
// Get additional data array
$additionalData
=
$data
->
getData
(
PaymentInterface
::
KEY_ADDITIONAL_DATA
);
if
(
!
is_array
(
$additionalData
))
{
return
;
}
// Get a validated additional data array
$additionalData
=
$this
->
getArrayOnlyWithApprovedKeys
(
$additionalData
,
self
::
$approvedAdditionalDataKeys
);
// json decode state data
$stateData
=
[];
if
(
!
empty
(
$additionalData
[
self
::
STATE_DATA
]))
{
$stateData
=
json_decode
(
$additionalData
[
self
::
STATE_DATA
],
true
);
}
// Get validated state data array
if
(
!
empty
(
$stateData
))
{
$stateData
=
$this
->
getArrayOnlyWithApprovedKeys
(
$stateData
,
self
::
$approvedStateDataKeys
);
}
// Replace state data with the decoded and validated state data
$additionalData
[
self
::
STATE_DATA
]
=
$stateData
;
$additionalData
=
$this
->
getValidatedAdditionalData
(
$data
);
// Set additional data in the payment
$paymentInfo
=
$this
->
readPaymentModelArgument
(
$observer
);
...
...
@@ -110,24 +76,4 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
$paymentInfo
->
setCcType
(
$additionalData
[
self
::
CC_TYPE
]);
}
}
/**
* Returns an array with only the approved keys
*
* @param array $array
* @param array $approvedKeys
* @return array
*/
private
function
getArrayOnlyWithApprovedKeys
(
$array
,
$approvedKeys
)
{
$result
=
[];
foreach
(
$approvedKeys
as
$approvedKey
)
{
if
(
isset
(
$array
[
$approvedKey
]))
{
$result
[
$approvedKey
]
=
$array
[
$approvedKey
];
}
}
return
$result
;
}
}
Observer/AdyenHppDataAssignObserver.php
View file @
c6bdeeec
...
...
@@ -23,44 +23,32 @@
namespace
Adyen\Payment\Observer
;
use
Magento\Framework\Event\Observer
;
use
Magento\Payment\Observer\AbstractDataAssignObserver
;
use
Magento\Quote\Api\Data\PaymentInterface
;
/**
* Class DataAssignObserver
*/
class
AdyenHppDataAssignObserver
extends
AbstractDataAssignObserver
class
AdyenHppDataAssignObserver
extends
A
dyenA
bstractDataAssignObserver
{
const
BRAND_CODE
=
'brand_code'
;
const
ISSUER_ID
=
'issuer_id'
;
const
GENDER
=
'gender'
;
const
DOB
=
'dob'
;
const
TELEPHONE
=
'telephone'
;
const
DF_VALUE
=
'df_value'
;
const
SSN
=
'ssn'
;
const
OWNER_NAME
=
'ownerName'
;
const
BANK_ACCOUNT_OWNER_NAME
=
'bankAccountOwnerName'
;
const
IBAN_NUMBER
=
'ibanNumber'
;
const
BANK_ACCOUNT_NUMBER
=
'bankAccountNumber'
;
const
BANK_LOCATIONID
=
'bankLocationId'
;
/**
* Approved root level keys from additional data array
*
* @var array
*/
protected
$approvedAdditionalDataKeys
=
[
self
::
STATE_DATA
,
self
::
BRAND_CODE
];
/**
* Approved root level keys from the checkout component's state data object
*
* @var array
*/
protected
$additionalInformationList
=
[
self
::
BRAND_CODE
,
self
::
ISSUER_ID
,
self
::
GENDER
,
self
::
DOB
,
self
::
TELEPHONE
,
self
::
DF_VALUE
,
self
::
SSN
,
self
::
OWNER_NAME
,
self
::
BANK_ACCOUNT_OWNER_NAME
,
self
::
IBAN_NUMBER
,
self
::
BANK_ACCOUNT_NUMBER
,
self
::
BANK_LOCATIONID
protected
$approvedStateDataKeys
=
[
self
::
BROWSER_INFO
,
self
::
PAYMENT_METHOD
,
self
::
RISK_DATA
];
/**
...
...
@@ -69,26 +57,20 @@ class AdyenHppDataAssignObserver extends AbstractDataAssignObserver
*/
public
function
execute
(
Observer
$observer
)
{
// Get request fields
$data
=
$this
->
readDataArgument
(
$observer
);
$additionalData
=
$data
->
getData
(
PaymentInterface
::
KEY_ADDITIONAL_DATA
);
if
(
!
is_array
(
$additionalData
))
{
return
;
}
$additionalData
=
$this
->
getValidatedAdditionalData
(
$data
);
// Set additional data in the payment
$paymentInfo
=
$this
->
readPaymentModelArgument
(
$observer
);
if
(
isset
(
$additionalData
[
self
::
BRAND_CODE
]))
{
$paymentInfo
->
setCcType
(
$additionalData
[
self
::
BRAND_CODE
]);
foreach
(
$additionalData
as
$key
=>
$data
)
{
$paymentInfo
->
setAdditionalInformation
(
$key
,
$data
);
}
foreach
(
$this
->
additionalInformationList
as
$additionalInformationKey
)
{
if
(
isset
(
$additionalData
[
$additionalInformationKey
]))
{
$paymentInfo
->
setAdditionalInformation
(
$additionalInformationKey
,
$additionalData
[
$additionalInformationKey
]
);
}
// Set BrandCode into CCType
if
(
isset
(
$additionalData
[
self
::
BRAND_CODE
]))
{
$paymentInfo
->
setCcType
(
$additionalData
[
self
::
BRAND_CODE
]);
}
}
}
view/frontend/web/js/model/adyen-payment-service.js
View file @
c6bdeeec
...
...
@@ -4,6 +4,7 @@
*/
define
(
[
'
ko
'
,
'
underscore
'
,
'
Magento_Checkout/js/model/quote
'
,
'
Magento_Customer/js/model/customer
'
,
...
...
@@ -11,9 +12,10 @@ define(
'
mage/storage
'
,
'
Adyen_Payment/js/bundle
'
,
],
function
(
_
,
quote
,
customer
,
urlBuilder
,
storage
,
adyenComponent
)
{
function
(
ko
,
_
,
quote
,
customer
,
urlBuilder
,
storage
,
adyenComponent
)
{
'
use strict
'
;
var
checkoutComponent
=
{};
var
paymentMethods
=
ko
.
observable
({})
return
{
/**
* Retrieve the list of available payment methods from the server
...
...
@@ -73,10 +75,22 @@ define(
originKey
:
originKey
,
environment
:
environment
,
paymentMethodsResponse
:
paymentMethodsResponse
,
consentCheckbox
:
false
,
visibility
:
{
personalDetails
:
'
editable
'
,
billingAddress
:
'
editable
'
,
separateDeliveryAddress
:
'
hidden
'
,
deliveryAddress
:
'
hidden
'
}
});
paymentMethods
(
paymentMethodsResponse
.
paymentMethods
);
},
getCheckoutComponent
:
function
()
{
return
checkoutComponent
;
},
getPaymentMethodsObservable
:
function
()
{
return
paymentMethods
;
}
};
}
...
...
view/frontend/web/js/view/payment/adyen-methods.js
View file @
c6bdeeec
...
...
@@ -26,13 +26,17 @@ define(
'
uiComponent
'
,
'
Magento_Checkout/js/model/payment/renderer-list
'
,
'
Adyen_Payment/js/model/adyen-payment-service
'
,
'
Adyen_Payment/js/model/adyen-configuration
'
'
Adyen_Payment/js/model/adyen-configuration
'
,
'
Magento_Checkout/js/model/quote
'
,
'
Magento_Customer/js/model/customer
'
],
function
(
Component
,
rendererList
,
adyenPaymentService
,
adyenConfiguration
adyenConfiguration
,
quote
,
customer
)
{
'
use strict
'
;
rendererList
.
push
(
...
...
@@ -67,14 +71,37 @@ define(
);
/** Add view logic here if needed */
return
Component
.
extend
({
defaults
:
{
countryCode
:
""
},
initialize
:
function
()
{
var
self
=
this
;
this
.
_super
();
adyenPaymentService
.
retrieveAvailablePaymentMethods
().
done
(
function
(
response
)
{
if
(
this
.
isGooglePayEnabled
())
{
var
googlepayscript
=
document
.
createElement
(
'
script
'
);
googlepayscript
.
src
=
"
https://pay.google.com/gp/p/js/pay.js
"
;
googlepayscript
.
type
=
"
text/javascript
"
;
document
.
head
.
appendChild
(
googlepayscript
);
}
if
(
customer
.
isLoggedIn
())
{
self
.
setAdyenPaymentMethods
();
}
quote
.
shippingAddress
.
subscribe
(
function
()
{
if
(
!!
quote
.
shippingAddress
().
countryId
&&
self
.
countryCode
!==
quote
.
shippingAddress
().
countryId
)
{
self
.
countryCode
=
quote
.
shippingAddress
().
countryId
;
self
.
setAdyenPaymentMethods
();
}
})
},
setAdyenPaymentMethods
:
function
()
{
adyenPaymentService
.
retrieveAvailablePaymentMethods
().
done
(
function
(
response
)
{
var
responseJson
=
JSON
.
parse
(
response
);
var
paymentMethodsResponse
=
responseJson
.
paymentMethodsResponse
;
// TODO check if this is still required or if can be outsourced for the generic component, or checkout can create a ratepay component
/*if (!!window.checkoutConfig.payment.adyenHpp) {
if (JSON.stringify(paymentMethods).indexOf("ratepay") > -1) {
...
...
@@ -104,13 +131,6 @@ define(
adyenConfiguration
.
getCheckoutEnvironment
()
);
})
if
(
this
.
isGooglePayEnabled
())
{
var
googlepayscript
=
document
.
createElement
(
'
script
'
);
googlepayscript
.
src
=
"
https://pay.google.com/gp/p/js/pay.js
"
;
googlepayscript
.
type
=
"
text/javascript
"
;
document
.
head
.
appendChild
(
googlepayscript
);
}
},
isGooglePayEnabled
:
function
()
{
return
window
.
checkoutConfig
.
payment
.
adyenGooglePay
.
active
;
...
...
view/frontend/web/js/view/payment/method-renderer/adyen-hpp-method.js
View file @
c6bdeeec
...
...
@@ -36,15 +36,31 @@ define(
'
Magento_Checkout/js/action/place-order
'
,
'
uiLayout
'
,
'
Magento_Ui/js/model/messages
'
,
'
Adyen_Payment/js/bundle
'
'
Adyen_Payment/js/bundle
'
,
'
Adyen_Payment/js/model/adyen-configuration
'
],
function
(
ko
,
$
,
Component
,
selectPaymentMethodAction
,
quote
,
checkoutData
,
additionalValidators
,
storage
,
adyenPaymentService
,
urlBuilder
,
customer
,
fullScreenLoader
,
placeOrderAction
,
layout
,
Messages
,
AdyenComponent
)
{
function
(
ko
,
$
,
Component
,
selectPaymentMethodAction
,
quote
,
checkoutData
,
additionalValidators
,
storage
,
adyenPaymentService
,
urlBuilder
,
customer
,
fullScreenLoader
,
placeOrderAction
,
layout
,
Messages
,
AdyenComponent
,
adyenConfiguration
)
{
'
use strict
'
;
var
brandCode
=
ko
.
observable
(
null
);
var
paymentMethod
=
ko
.
observable
(
null
);
var
messageComponents
;
var
shippingAddressCountryCode
=
quote
.
shippingAddress
().
countryId
;
var
unsupportedPaymentMethods
=
[
'
scheme
'
,
'
boleto
'
,
'
bcmc_mobile_QR
'
,
'
wechatpay
'
,
/^bcmc$/
,
"
applepay
"
,
"
paywithgoogle
"
];
var
unsupportedPaymentMethods
=
[
'
scheme
'
,
'
boleto
'
,
'
bcmc_mobile_QR
'
,
'
wechatpay
'
,
/^bcmc$/
,
"
applepay
"
,
"
paywithgoogle
"
,
"
paypal
"
];
/**
* Shareble adyen checkout component
* @type {AdyenCheckout}
...
...
@@ -55,21 +71,14 @@ define(
self
:
this
,
defaults
:
{
template
:
'
Adyen_Payment/payment/hpp-form
'
,
brandCode
:
''
brandCode
:
''
,
stateData
:
{}
},
initObservable
:
function
()
{
this
.
_super
()
.
observe
([
'
brandCode
'
,
'
issuer
'
,
'
gender
'
,
'
dob
'
,
'
telephone
'
,
'
ownerName
'
,
'
ibanNumber
'
,
'
ssn
'
,
'
bankAccountNumber
'
,
'
bankLocationId
'
'
paymentListObservable
'
]);
return
this
;
},
initialize
:
function
()
{
...
...
@@ -77,15 +86,29 @@ define(
var
self
=
this
;
this
.
_super
();
fullScreenLoader
.
startLoader
();
var
paymentMethodsObservable
=
adyenPaymentService
.
getPaymentMethodsObservable
();
/**
* Create sherable checkout component
* @type {AdyenCheckout}
*/
self
.
checkoutComponent
=
new
AdyenCheckout
({
locale
:
self
.
getLocale
()});
self
.
checkoutComponent
=
adyenPaymentService
.
getCheckoutComponent
();
self
.
setAdyenHppPaymentMethods
();
paymentMethodsObservable
.
subscribe
(
function
()
{
self
.
checkoutComponent
=
adyenPaymentService
.
getCheckoutComponent
();
self
.
setAdyenHppPaymentMethods
();
});
},
getAdyenHppPaymentMethods
:
function
()
{
return
this
.
paymentListObservable
;
},
setAdyenHppPaymentMethods
:
function
()
{
var
self
=
this
;
fullScreenLoader
.
startLoader
();
var
paymentMethods
=
adyenPaymentService
.
getAvailablePaymentMethods
()
;
var
paymentMethods
=
self
.
checkoutComponent
.
paymentMethodsResponse
.
paymentMethods
;
// create component needs to be in initialize method
var
messageComponents
=
{};
...
...
@@ -109,28 +132,9 @@ define(
self
.
messageComponents
=
messageComponents
;
fullScreenLoader
.
stopLoader
();
},
getAdyenHppPaymentMethods
:
function
()
{
var
self
=
this
;
var
currentShippingAddressCountryCode
=
quote
.
shippingAddress
().
countryId
;
// retrieve new payment methods if country code changed
if
(
shippingAddressCountryCode
!=
currentShippingAddressCountryCode
)
{
fullScreenLoader
.
startLoader
();
adyenPaymentService
.
retrieveAvailablePaymentMethods
();
shippingAddressCountryCode
=
currentShippingAddressCountryCode
;
fullScreenLoader
.
stopLoader
();
}
var
paymentMethods
=
adyenPaymentService
.
getAvailablePaymentMethods
();
console
.
log
(
paymentMethods
);
console
.
log
(
paymentMethods
.
paymentMethods
);
var
paymentList
=
_
.
reduce
(
paymentMethods
,
function
(
accumulator
,
value
)
{
console
.
log
(
value
);
if
(
!
self
.
isPaymentMethodSupported
(
value
.
type
))
{
// Iterate through the payment methods and render them
var
paymentList
=
_
.
reduce
(
paymentMethods
,
function
(
accumulator
,
paymentMethod
)
{
if
(
!
self
.
isPaymentMethodSupported
(
paymentMethod
.
type
))
{
return
accumulator
;
}
...
...
@@ -141,11 +145,11 @@ define(
* @returns {*}
*/
result
.
getBrandCode
=
function
()
{
return
self
.
getBrandCodeFromPaymentMethod
(
value
);
return
self
.
getBrandCodeFromPaymentMethod
(
paymentMethod
);
};
result
.
valu
e
=
result
.
getBrandCode
();
result
.
name
=
valu
e
;
result
.
brandCod
e
=
result
.
getBrandCode
();
result
.
name
=
paymentMethod
.
nam
e
;
result
.
method
=
self
.
item
.
method
;
/**
* Observable to enable and disable place order buttons for payment methods
...
...
@@ -176,335 +180,72 @@ define(
result
.
afterPlaceOrder
=
function
()
{
return
self
.
afterPlaceOrder
();
};
/**
* Checks if payment method is open invoice
* @returns {*|isPaymentMethodOpenInvoiceMethod}
*/
result
.
isPaymentMethodOpenInvoiceMethod
=
function
()
{
return
value
.
isPaymentMethodOpenInvoiceMethod
;
};
/**
* Checks if payment method is open invoice but not in the list below
* [klarna, afterpay]
* @returns {boolean}
*/
result
.
isPaymentMethodOtherOpenInvoiceMethod
=
function
()
{
if
(
!
result
.
isPaymentMethodAfterPay
()
&&
!
result
.
isPaymentMethodKlarna
()
&&
!
result
.
isPaymentMethodAfterPayTouch
()
&&
value
.
isPaymentMethodOpenInvoiceMethod
)
{
return
true
;
}
return
false
;
};
/**
* Checks if payment method is klarna
* @returns {boolean}
*/
result
.
isPaymentMethodKlarna
=
function
()
{
if
(
result
.
getBrandCode
()
===
"
klarna
"
)
{
return
true
;
}
return
false
;
};
/**
* Checks if payment method is after pay
* @returns {boolean}
*/
result
.
isPaymentMethodAfterPay
=
function
()
{
if
(
result
.
getBrandCode
()
===
"
afterpay_default
"
)
{
return
true
;
}
return
false
;
};
/**
* Checks if payment method is after pay touch
* @returns {boolean}
*/
result
.
isPaymentMethodAfterPayTouch
=
function
()
{
if
(
result
.
getBrandCode
()
===
"
afterpaytouch
"
)
{
return
true
;
}
return
false
;
};
/**
* Get personal number (SSN) length based on the buyer's country
* @returns {number}
*/
result
.
getSsnLength
=
function
()
{
if
(
quote
.
billingAddress
().
countryId
==
"
NO
"
)
{
//14 digits for Norway ÅÅÅÅMMDD-XXXXX
return
14
;
}
else
{
//13 digits for other Nordic countries ÅÅÅÅMMDD-XXXX
return
13
;
}
};
/**
* Get max length for the Bank account number
*/
result
.
getBankAccountNumberMaxLength
=
function
()
{
return
17
;
};
/**
* Finds the issuer property in the payment method's response and if available returns it's index
* @returns
*/
result
.
findIssuersProperty
=
function
()
{
var
issuerKey
=
false
;
if
(
typeof
value
.
details
!==
'
undefined
'
)
{
$
.
each
(
value
.
details
,
function
(
key
,
detail
)
{
if
(
typeof
detail
.
items
!==
'
undefined
'
&&
detail
.
key
==
'
issuer
'
)
{
issuerKey
=
key
;
}
});
}
return
issuerKey
;
}
/**
* Checks if the payment method has issuers property available
* @returns {boolean}
*/
result
.
hasIssuersProperty
=
function
()
{
if
(
result
.
findIssuersProperty
()
!==
false
)
{
return
true
;
}
return
false
;
};
/**
* Checks if the payment method has issuer(s) available
* @returns {boolean}
*/
result
.
hasIssuersAvailable
=
function
()
{
if
(
result
.
hasIssuersProperty
()
&&
value
.
details
[
result
.
findIssuersProperty
()].
items
.
length
>
0
)
{
return
true
;
}
return
false
;
};
/**
* Returns the issuers for a payment method
* @returns {*}
*/
result
.
getIssuers
=
function
()
{
if
(
result
.
hasIssuersAvailable
())
{
return
value
.
details
[
result
.
findIssuersProperty
()].
items
;
}
return
[];
};
/**
* Checks if payment method is iDeal
* @returns {boolean}
*/
result
.
isIdeal
=
function
()
{
if
(
result
.
getBrandCode
().
indexOf
(
"
ideal
"
)
>=
0
)
{
return
true
;
}
return
false
;
};
/**
* Checks if payment method is ACH
* @returns {boolean}
*/
result
.
isAch
=
function
()
{
if
(
result
.
getBrandCode
().
indexOf
(
"
ach
"
)
==
0
)
{
return
true
;
}
return
false
;
};
/**
* Checks if payment method is sepa direct debit
*/
result
.
isSepaDirectDebit
=
function
()
{
if
(
result
.
getBrandCode
().
indexOf
(
"
sepadirectdebit
"
)
>=
0
)
{
return
true
;
}
return
false
;
};
/**
* Renders the secure fields,
* creates the ideal component,
* sets up the callbacks for ideal components and
*/
result
.
render
Ideal
Component
=
function
()
{
result
.
render
Checkout
Component
=
function
()
{
result
.
isPlaceOrderAllowed
(
false
);
var
idealNode
=
document
.
getElementById
(
'
iDealContainer
'
);
var
showPayButton
=
false
;
const
showPayButtonPaymentMethods
=
[
'
paypal
'
];
var
ideal
=
self
.
checkoutComponent
.
create
(
'
ideal
'
,
{
items
:
result
.
getIssuers
(),
onChange
:
function
(
state
)
{
if
(
!!
state
.
isValid
)
{
result
.
issuer
(
state
.
data
.
paymentMethod
.
issuer
);
result
.
isPlaceOrderAllowed
(
true
);
}
else
{
result
.
isPlaceOrderAllowed
(
false
);
}
}
});
ideal
.
mount
(
idealNode
);
};
/**
* Creates the sepa direct debit component,
* sets up the callbacks for sepa components
*/
result
.
renderSepaDirectDebitComponent
=
function
()
{
result
.
isPlaceOrderAllowed
(
false
);
var
sepaDirectDebitNode
=
document
.
getElementById
(
'
sepaDirectDebitContainer
'
);
var
sepaDirectDebit
=
self
.
checkoutComponent
.
create
(
'
sepadirectdebit
'
,
{
countryCode
:
self
.
getLocale
(),
onChange
:
function
(
state
)
{
if
(
!!
state
.
isValid
)
{
result
.
ownerName
(
state
.
data
.
paymentMethod
[
"
sepa.ownerName
"
]);
result
.
ibanNumber
(
state
.
data
.
paymentMethod
[
"
sepa.ibanNumber
"
]);
result
.
isPlaceOrderAllowed
(
true
);
}
else
{
result
.
isPlaceOrderAllowed
(
false
);
}
}
});
sepaDirectDebit
.
mount
(
sepaDirectDebitNode
);
};
/**
* Creates the klarna component,
* sets up the callbacks for klarna components
*/
result
.
renderKlarnaComponent
=
function
()
{
if
(
showPayButtonPaymentMethods
.
includes
(
paymentMethod
.
type
))
{
showPayButton
=
true
;
}
/* The new Klarna integration doesn't return details and the component does not handle it */
if
(
!
value
.
details
)
{
// If the details are empty and the pay button does not needs to be rendered by the component
// simply skip rendering the adyen checkout component
if
(
!
paymentMethod
.
details
&&
!
showPayButton
)
{
result
.
isPlaceOrderAllowed
(
true
);
return
;
}
var
klarnaNode
=
document
.
getElementById
(
'
klarnaContainer
'
);
var
klarna
=
self
.
checkoutComponent
.
create
(
'
klarna
'
,
{
countryCode
:
self
.
getLocale
(),
details
:
self
.
filterOutOpenInvoiceComponentDetails
(
value
.
details
),
visibility
:
{
personalDetails
:
"
editable
"
},
onChange
:
function
(
state
)
{
if
(
!!
state
.
isValid
)
{
result
.
dob
(
state
.
data
.
paymentMethod
.
personalDetails
.
dateOfBirth
);
result
.
telephone
(
state
.
data
.
paymentMethod
.
personalDetails
.
telephoneNumber
);
result
.
gender
(
state
.
data
.
paymentMethod
.
personalDetails
.
gender
);
result
.
isPlaceOrderAllowed
(
true
);
}
else
{
result
.
isPlaceOrderAllowed
(
false
);
/*Use the storedPaymentMethod object and the custom onChange function as the configuration object together*/
var
configuration
=
{
showPayButton
:
showPayButton
,
data
:
{
billingAddress
:
{
city
:
quote
.
shippingAddress
().
city
,
country
:
quote
.
shippingAddress
().
countryId
,
houseNumberOrName
:
''
,
postalCode
:
quote
.
shippingAddress
().
postcode
,
street
:
quote
.
shippingAddress
().
street
.
join
(
"
"
)
}
}
}).
mount
(
klarnaNode
);
};
/**
* Creates the afterpay component,
* sets up the callbacks for klarna components
*/
result
.
renderAfterPayComponent
=
function
()
{
var
afterPay
=
self
.
checkoutComponent
.
create
(
'
afterpay
'
,
{
countryCode
:
self
.
getLocale
(),
details
:
self
.
filterOutOpenInvoiceComponentDetails
(
value
.
details
),
visibility
:
{
personalDetails
:
"
editable
"
},
onChange
:
function
(
state
)
{
if
(
!!
state
.
isValid
)
{
result
.
dob
(
state
.
data
.
paymentMethod
.
personalDetails
.
dateOfBirth
);
result
.
telephone
(
state
.
data
.
paymentMethod
.
personalDetails
.
telephoneNumber
);
result
.
gender
(
state
.
data
.
paymentMethod
.
personalDetails
.
gender
);
result
.
stateData
=
state
.
data
;
result
.
isPlaceOrderAllowed
(
true
);
}
else
{
result
.
stateData
=
{};
result
.
isPlaceOrderAllowed
(
false
);
}
}
}).
mount
(
document
.
getElementById
(
'
afterPayContainer
'
));
};
};
if
(
result
.
hasIssuersProperty
())
{
if
(
!
result
.
hasIssuersAvailable
())
{
return
false
;
try
{
self
.
checkoutComponent
.
create
(
result
.
getBrandCode
(),
configuration
).
mount
(
'
#adyen-alternative-payment-container-
'
+
result
.
getBrandCode
());
}
catch
(
err
)
{
// The component does not exist yet
}
};
result
.
issuerIds
=
result
.
getIssuers
();
result
.
issuer
=
ko
.
observable
(
null
);
}
else
if
(
value
.
isPaymentMethodOpenInvoiceMethod
)
{
result
.
telephone
=
ko
.
observable
(
quote
.
shippingAddress
().
telephone
);
result
.
gender
=
ko
.
observable
(
window
.
checkoutConfig
.
payment
.
adyenHpp
.
gender
);
result
.
dob
=
ko
.
observable
(
window
.
checkoutConfig
.
payment
.
adyenHpp
.
dob
);
result
.
datepickerValue
=
ko
.
observable
();
// needed ??
result
.
ssn
=
ko
.
observable
();
result
.
getRatePayDeviceIdentToken
=
function
()
{
return
window
.
checkoutConfig
.
payment
.
adyenHpp
.
deviceIdentToken
;
};
result
.
showSsn
=
function
()
{
if
(
result
.
getBrandCode
().
indexOf
(
"
klarna
"
)
>=
0
)
{
var
ba
=
quote
.
billingAddress
();
if
(
ba
!=
null
)
{
var
nordicCountriesList
=
window
.
checkoutConfig
.
payment
.
adyenHpp
.
nordicCountries
;
if
(
nordicCountriesList
.
indexOf
(
ba
.
countryId
)
>=
0
)
{
return
true
;
}
}
}
return
false
;
};
}
else
if
(
result
.
isSepaDirectDebit
())
{
result
.
ownerName
=
ko
.
observable
(
null
);
result
.
ibanNumber
=
ko
.
observable
(
null
);
}
else
if
(
result
.
isAch
())
{
result
.
ownerName
=
ko
.
observable
(
null
);
result
.
bankAccountNumber
=
ko
.
observable
(
null
);
result
.
bankLocationId
=
ko
.
observable
(
null
);
}
result
.
getRatePayDeviceIdentToken
=
function
()
{
return
window
.
checkoutConfig
.
payment
.
adyenHpp
.
deviceIdentToken
;
};
accumulator
.
push
(
result
);
return
accumulator
;
},
[]);
return
paymentList
;
},
/**
* Some payment methods we do not want to render as it requires extra implementation
* or is already implemented in a separate payment method.
* Using a match as we want to prevent to render all Boleto and most of the WeChat types
* @param paymentMethod
* @returns {boolean}
*/
isPaymentMethodSupported
:
function
(
paymentMethod
)
{
if
(
paymentMethod
==
'
wechatpayWeb
'
)
{
return
true
;
}
for
(
var
i
=
0
;
i
<
unsupportedPaymentMethods
.
length
;
i
++
)
{
var
match
=
paymentMethod
.
match
(
unsupportedPaymentMethods
[
i
]);
if
(
match
)
{
return
false
;
}
}
return
true
;
self
.
paymentListObservable
(
paymentList
);
fullScreenLoader
.
stopLoader
();
},
// TODO prefill gender in components where it is available
getGenderTypes
:
function
()
{
return
_
.
map
(
window
.
checkoutConfig
.
payment
.
adyenHpp
.
genderTypes
,
function
(
value
,
key
)
{
return
{
...
...
@@ -523,25 +264,11 @@ define(
data
.
method
=
self
.
method
;
var
additionalData
=
{};
additionalData
.
brand_code
=
self
.
value
;
if
(
self
.
hasIssuersAvailable
())
{
additionalData
.
issuer_id
=
this
.
issuer
();
}
else
if
(
self
.
isPaymentMethodOpenInvoiceMethod
())
{
additionalData
.
gender
=
this
.
gender
();
additionalData
.
dob
=
this
.
dob
();
additionalData
.
telephone
=
this
.
telephone
();
additionalData
.
ssn
=
this
.
ssn
();
if
(
brandCode
()
==
"
ratepay
"
)
{
additionalData
.
df_value
=
this
.
getRatePayDeviceIdentToken
();
}
}
else
if
(
self
.
isSepaDirectDebit
())
{
additionalData
.
ownerName
=
this
.
ownerName
();
additionalData
.
ibanNumber
=
this
.
ibanNumber
();
}
else
if
(
self
.
isAch
())
{
additionalData
.
bankAccountOwnerName
=
this
.
ownerName
();
additionalData
.
bankAccountNumber
=
this
.
bankAccountNumber
();
additionalData
.
bankLocationId
=
this
.
bankLocationId
();
additionalData
.
brand_code
=
self
.
brandCode
;
additionalData
.
state_data
=
JSON
.
stringify
(
self
.
stateData
);
if
(
brandCode
()
==
"
ratepay
"
)
{
additionalData
.
df_value
=
this
.
getRatePayDeviceIdentToken
();
}
data
.
additional_data
=
additionalData
;
...
...
@@ -550,26 +277,16 @@ define(
return
false
;
},
selectPaymentMethodBrandCode
:
function
()
{
var
self
=
this
;
// set payment method to adyen_hpp
var
data
=
{
"
method
"
:
self
.
method
,
"
po_number
"
:
null
,
"
additional_data
"
:
{
brand_code
:
self
.
value
}
};
// set the brandCode
brandCode
(
self
.
value
);
// set payment method
paymentMethod
(
self
.
method
);
// DEFAULT FUNCTIONS
validate
:
function
(
brandCode
)
{
var
form
=
'
#payment_form_
'
+
this
.
getCode
()
+
'
_
'
+
brandCode
;
var
validate
=
$
(
form
).
validation
()
&&
$
(
form
).
validation
(
'
isValid
'
);
selectPaymentMethodAction
(
data
);
checkoutData
.
setSelectedPaymentMethod
(
self
.
method
);
if
(
!
validate
)
{
return
false
;
}
return
true
;
},
...
...
@@ -612,8 +329,48 @@ define(
}
)
},
isBrandCodeChecked
:
ko
.
computed
(
function
()
{
/**
*
* @returns {boolean}
*/
selectPaymentMethodBrandCode
:
function
()
{
var
self
=
this
;
// set payment method to adyen_hpp
var
data
=
{
"
method
"
:
self
.
method
,
"
po_number
"
:
null
,
"
additional_data
"
:
{
brand_code
:
self
.
brandCode
}
};
// set the brandCode
brandCode
(
self
.
brandCode
);
// set payment method
paymentMethod
(
self
.
method
);
selectPaymentMethodAction
(
data
);
checkoutData
.
setSelectedPaymentMethod
(
self
.
method
);
return
true
;
},
// CONFIGURATIONS
isIconEnabled
:
function
()
{
return
window
.
checkoutConfig
.
payment
.
adyen
.
showLogo
;
},
getRatePayDeviceIdentToken
:
function
()
{
return
window
.
checkoutConfig
.
payment
.
adyenHpp
.
deviceIdentToken
;
},
/**
*
*/
isBrandCodeChecked
:
ko
.
computed
(
function
()
{
if
(
!
quote
.
paymentMethod
())
{
return
null
;
}
...
...
@@ -621,19 +378,27 @@ define(
if
(
quote
.
paymentMethod
().
method
==
paymentMethod
())
{
return
brandCode
();
}
return
null
;
}),
isIconEnabled
:
function
()
{
return
window
.
checkoutConfig
.
payment
.
adyen
.
showLogo
;
},
validate
:
function
(
brandCode
)
{
var
form
=
'
#payment_form_
'
+
this
.
getCode
()
+
'
_
'
+
brandCode
;
var
validate
=
$
(
form
).
validation
()
&&
$
(
form
).
validation
(
'
isValid
'
);
if
(
!
validate
)
{
return
false
;
/**
* Some payment methods we do not want to render as it requires extra implementation
* or is already implemented in a separate payment method.
* Using a match as we want to prevent to render all Boleto and most of the WeChat types
* @param paymentMethod
* @returns {boolean}
*/
isPaymentMethodSupported
:
function
(
paymentMethod
)
{
if
(
paymentMethod
==
'
wechatpayWeb
'
)
{
return
true
;
}
for
(
var
i
=
0
;
i
<
unsupportedPaymentMethods
.
length
;
i
++
)
{
var
match
=
paymentMethod
.
match
(
unsupportedPaymentMethods
[
i
]);
if
(
match
)
{
return
false
;
}
}
return
true
;
},
/**
...
...
@@ -647,52 +412,6 @@ define(
}
return
''
;
},
getRatePayDeviceIdentToken
:
function
()
{
return
window
.
checkoutConfig
.
payment
.
adyenHpp
.
deviceIdentToken
;
},
getLocale
:
function
()
{
return
window
.
checkoutConfig
.
payment
.
adyenHpp
.
locale
;
},
/**
* In the open invoice components we need to validate only the personal details and only the
* dateOfBirth, telephoneNumber and gender if it's set in the admin
* @param details
* @returns {Array}
*/
filterOutOpenInvoiceComponentDetails
:
function
(
details
)
{
var
self
=
this
;
var
filteredDetails
=
_
.
map
(
details
,
function
(
parentDetail
)
{
if
(
parentDetail
.
key
==
"
personalDetails
"
)
{
var
detailObject
=
_
.
map
(
parentDetail
.
details
,
function
(
detail
)
{
if
(
detail
.
key
==
'
dateOfBirth
'
||
detail
.
key
==
'
telephoneNumber
'
||
detail
.
key
==
'
gender
'
)
{
return
detail
;
}
});
if
(
!!
detailObject
)
{
return
{
"
key
"
:
parentDetail
.
key
,
"
type
"
:
parentDetail
.
type
,
"
details
"
:
self
.
filterUndefinedItemsInArray
(
detailObject
)
};
}
}
});
return
self
.
filterUndefinedItemsInArray
(
filteredDetails
);
},
/**
* Helper function to filter out the undefined items from an array
* @param arr
* @returns {*}
*/
filterUndefinedItemsInArray
:
function
(
arr
)
{
return
arr
.
filter
(
function
(
item
)
{
return
typeof
item
!==
'
undefined
'
;
});
}
});
}
...
...
view/frontend/web/js/view/payment/method-renderer/adyen-oneclick-method.js
View file @
c6bdeeec
...
...
@@ -145,8 +145,6 @@ define(
var
agreementLabel
=
storedPayment
.
name
+
'
,
'
+
storedPayment
.
holderName
+
'
, ****
'
+
storedPayment
.
lastFour
;
console
.
log
(
self
.
checkoutComponent
);
return
{
'
label
'
:
agreementLabel
,
'
value
'
:
storedPayment
.
storedPaymentMethodId
,
...
...
view/frontend/web/template/payment/hpp-form.html
View file @
c6bdeeec
...
...
@@ -23,14 +23,14 @@
-->
<!-- ko foreach: getAdyenHppPaymentMethods() -->
<div
class=
"payment-method"
data-bind=
"css: {'_active': (
valu
e == $parent.isBrandCodeChecked())}"
>
<div
class=
"payment-method"
data-bind=
"css: {'_active': (
brandCod
e == $parent.isBrandCodeChecked())}"
>
<div
class=
"payment-method-title field choice"
>
<input
type=
"radio"
name=
"payment[method]"
class=
"radio"
data-bind=
"attr: {'id':
value}, value: value, checked:
$parent.isBrandCodeChecked, click: $parent.selectPaymentMethodBrandCode"
/>
<label
data-bind=
"attr: {'for':
valu
e}"
class=
"label"
>
data-bind=
"attr: {'id':
'adyen_' + brandCode}, value: 'adyen_' + brandCode, checked: brandCode ==
$parent.isBrandCodeChecked, click: $parent.selectPaymentMethodBrandCode"
/>
<label
data-bind=
"attr: {'for':
'adyen_' + brandCod
e}"
class=
"label"
>
<!-- ko if: name.icon -->
<img
data-bind=
"attr: {
...
...
@@ -40,7 +40,7 @@
}"
>
<!--/ko-->
<span
data-bind=
"text: name
.title
"
></span>
<span
data-bind=
"text: name"
></span>
</label>
</div>
<div
class=
"payment-method-content"
>
...
...
@@ -51,9 +51,10 @@
<!--/ko-->
</div>
<form
class=
"form"
data-role=
"adyen-hpp-form"
action=
"#"
method=
"post"
data-bind=
"mageInit: { 'validation':[]}, attr: {id: 'payment_form_' + $parent.getCode() + '_' + value}"
>
<fieldset
class=
"fieldset"
data-bind=
'attr: {id: "payment_fieldset_" + $parent.getCode() + "_" + value}'
>
<div
class=
"adyen-alternative-payment-container"
></div>
<form
class=
"form"
data-role=
"adyen-hpp-form"
action=
"#"
method=
"post"
data-bind=
"mageInit: { 'validation':[]}, attr: {id: 'payment_form_' + $parent.getCode() + '_' + brandCode}"
>
<fieldset
class=
"fieldset"
data-bind=
'attr: {id: "payment_fieldset_" + $parent.getCode() + "_" + brandCode}'
>
<div
data-bind=
'attr: {id: "adyen-alternative-payment-container-" + brandCode}'
afterRender=
"renderCheckoutComponent()"
></div>
</fieldset>
...
...
@@ -64,7 +65,7 @@
</div>
<div>
<span
class=
"message message-error error hpp-message"
data-bind=
"attr: {id: 'messages-' +
valu
e}"
></span>
<span
class=
"message message-error error hpp-message"
data-bind=
"attr: {id: 'messages-' +
brandCod
e}"
></span>
</div>
<div
class=
"actions-toolbar"
>
...
...
@@ -73,7 +74,7 @@
type=
"submit"
data-bind=
"
click: $parent.continueToAdyenBrandCode,
enable: placeOrderAllowed() && (
valu
e == $parent.isBrandCodeChecked()),
enable: placeOrderAllowed() && (
brandCod
e == $parent.isBrandCodeChecked()),
css: {disabled: !$parent.isPlaceOrderActionAllowed()}"
disabled
>
<span
data-bind=
"text: $t('Place Order')"
></span>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment