Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ECP-9491] Refactor instantiating AdyenCheckout library and components #2770

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ define(
isPlaceOrderActionAllowed: ko.observable(
quote.billingAddress() != null),
comboCardOption: ko.observable('credit'),
checkoutComponent: null,

defaults: {
template: 'Adyen_Payment/payment/cc-form',
Expand Down Expand Up @@ -84,18 +85,23 @@ define(
let paymentMethodsObserver = adyenPaymentService.getPaymentMethods();
paymentMethodsObserver.subscribe(
function (paymentMethodsResponse) {
self.loadCheckoutComponent(paymentMethodsResponse)
self.enablePaymentMethod(paymentMethodsResponse)
}
);

if(!!paymentMethodsObserver()) {
self.loadCheckoutComponent(paymentMethodsObserver());
self.enablePaymentMethod(paymentMethodsObserver());
}
},
isSchemePaymentsEnabled: function (paymentMethod) {
return paymentMethod.type === "scheme";
},
loadCheckoutComponent: async function (paymentMethodsResponse) {

/*
* Enables the payment method and sets the required attributes
* if `/paymentMethods` response contains this payment method.
*/
enablePaymentMethod: async function (paymentMethodsResponse) {
let self = this;

// Check the paymentMethods response to enable Credit Card payments
Expand All @@ -104,20 +110,47 @@ define(
return;
}

this.checkoutComponent = await adyenCheckout.buildCheckoutComponent(
paymentMethodsResponse,
this.handleOnAdditionalDetails.bind(this)
)
self.adyenCCMethod({
icon: !!paymentMethodsResponse.paymentMethodsExtraDetails.card
? paymentMethodsResponse.paymentMethodsExtraDetails.card.icon
: undefined
})
},

if (!!this.checkoutComponent) {
// Setting the icon as an accessible field if it is available
self.adyenCCMethod({
icon: !!paymentMethodsResponse.paymentMethodsExtraDetails.card
? paymentMethodsResponse.paymentMethodsExtraDetails.card.icon
: undefined
})
/*
* Create generic AdyenCheckout library and mount payment method component
* after selecting the payment method via overriding parent `selectPaymentMethod()` function.
*/
selectPaymentMethod: function () {
this._super();
this.createCheckoutComponent();

return true;
},
/*
* Pre-selected payment methods don't trigger parent's `selectPaymentMethod()` function.
*
* This function is triggered via `afterRender` attribute of the html template
* and creates checkout component for pre-selected payment method.
*/
renderPreSelected: function () {
if (this.isChecked() === this.getCode()) {
this.createCheckoutComponent();
}
},
// Build AdyenCheckout library and creates the payment method component
createCheckoutComponent: async function () {
if (!this.checkoutComponent) {
const paymentMethodsResponse = adyenPaymentService.getPaymentMethods();

this.checkoutComponent = await adyenCheckout.buildCheckoutComponent(
paymentMethodsResponse(),
this.handleOnAdditionalDetails.bind(this)
)
}

this.renderCCPaymentMethod();
},
/**
* Returns true if card details can be stored
* @returns {*|boolean}
Expand Down Expand Up @@ -245,22 +278,28 @@ define(
* @returns {{method: *}}
*/
getData: function() {
let stateData = JSON.stringify(this.cardComponent.data);

window.sessionStorage.setItem('adyen.stateData', stateData);
return {
let data = {
'method': this.item.method,
additional_data: {
'stateData': stateData,
'stateData': {},
'guestEmail': quote.guestEmail,
'cc_type': this.creditCardType(),
'combo_card_type': this.comboCardOption(),
//This is required by magento to store the token
'is_active_payment_token_enabler' : this.storeCc,
'number_of_installments': this.installment(),
'frontendType': 'default'
},
}
};

// Get state data only if the checkout component is ready,
if (this.checkoutComponent) {
const stateData = JSON.stringify(this.cardComponent.data)
data.additional_data.stateData = stateData;
window.sessionStorage.setItem('adyen.stateData', stateData);
}

return data;
},
/**
* Returns state of place order button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ define(
modalLabel: 'hpp_actionModal'
},
placeOrderButtonVisible: true,
checkoutComponent: null,
paymentMethodStates: {},

initObservable: function() {
this._super().observe([
'paymentMethod',
Expand All @@ -64,54 +67,78 @@ define(
this._super();
let self = this;


let paymentMethodsObserver = adyenPaymentService.getPaymentMethods();
paymentMethodsObserver.subscribe(
function(paymentMethodsResponse) {
self.createCheckoutComponent(paymentMethodsResponse);
self.enablePaymentMethod(paymentMethodsResponse);
}
);

if(!!paymentMethodsObserver()) {
self.createCheckoutComponent(paymentMethodsObserver());
self.enablePaymentMethod(paymentMethodsObserver());
}
},

paymentMethodStates: {},

createCheckoutComponent: async function(paymentMethodsResponse) {
// Set to null by default and modify depending on the paymentMethods response
this.adyenPaymentMethod(null);
enablePaymentMethod: function (paymentMethodsResponse) {
if (this.checkBrowserCompatibility() && !!paymentMethodsResponse.paymentMethodsResponse) {
this.paymentMethod(
adyenPaymentService.getPaymentMethodFromResponse(
this.getTxVariant(),
paymentMethodsResponse.paymentMethodsResponse.paymentMethods
)
);

if (!!this.paymentMethod()) {
this.paymentMethodsExtraInfo(paymentMethodsResponse.paymentMethodsExtraDetails);
// Setting the icon and method txvariant as an accessible field if it is available
this.adyenPaymentMethod({
icon: !!paymentMethodsResponse.paymentMethodsExtraDetails[this.getTxVariant()]
? paymentMethodsResponse.paymentMethodsExtraDetails[this.getTxVariant()].icon
: undefined,
method: this.getTxVariant()
});
}

fullScreenLoader.stopLoader();
}
},

/*
* Create generic AdyenCheckout library and mount payment method component
* after selecting the payment method via overriding parent `selectPaymentMethod()` function.
*/
selectPaymentMethod: function () {
this._super();
this.createCheckoutComponent();
return true;
},

/*
* Pre-selected payment methods don't trigger parent's `selectPaymentMethod()` function.
*
* This function is triggered via `afterRender` attribute of the html template
* and creates checkout component for pre-selected payment method.
*/
renderPreSelected: function () {
if (this.isChecked() === this.getCode()) {
this.createCheckoutComponent();
}
},

// Build AdyenCheckout library and creates the payment method component
createCheckoutComponent: async function() {
if (!this.checkoutComponent) {
const paymentMethodsResponse = adyenPaymentService.getPaymentMethods();

this.checkoutComponent = await adyenCheckout.buildCheckoutComponent(
paymentMethodsResponse,
paymentMethodsResponse(),
this.handleOnAdditionalDetails.bind(this),
this.handleOnCancel.bind(this),
this.handleOnSubmit.bind(this)
);

if (!!this.checkoutComponent) {
this.paymentMethod(
adyenPaymentService.getPaymentMethodFromResponse(
this.getTxVariant(),
paymentMethodsResponse.paymentMethodsResponse.paymentMethods
)
);

if (!!this.paymentMethod()) {
this.paymentMethodsExtraInfo(paymentMethodsResponse.paymentMethodsExtraDetails);
// Setting the icon and method txvariant as an accessible field if it is available
this.adyenPaymentMethod({
icon: !!paymentMethodsResponse.paymentMethodsExtraDetails[this.getTxVariant()]
? paymentMethodsResponse.paymentMethodsExtraDetails[this.getTxVariant()].icon
: undefined,
method: this.getTxVariant()
});
}
}
}

fullScreenLoader.stopLoader();
this.renderCheckoutComponent();
},

handleOnSubmit: async function(state, component) {
Expand Down Expand Up @@ -179,17 +206,15 @@ define(
self.isPlaceOrderAllowed(true);
});
},

renderCheckoutComponent: function() {
let methodCode = this.getMethodCode();

let configuration = this.buildComponentConfiguration(this.paymentMethod(), this.paymentMethodsExtraInfo());

this.mountPaymentMethodComponent(this.paymentMethod(), configuration, methodCode);

setTimeout(() => {
this.updatePlaceOrderButtonState(methodCode);
}, 0);
this.updatePlaceOrderButtonState(methodCode);
},

updatePlaceOrderButtonState: function(methodCode) {
let state = this.initializeMethod(methodCode);
let container = $(`#${methodCode}Container`);
Expand Down
66 changes: 51 additions & 15 deletions view/frontend/web/js/view/payment/method-renderer/vault.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ define([
return VaultComponent.extend({
defaults: {
template: 'Adyen_Payment/payment/card-vault-form.html',
checkoutComponentBuilt: false,
modalLabel: null,
installment: ''
},
checkoutComponent: null,

initObservable: function () {
this._super()
.observe([
'checkoutComponentBuilt',
'installment',
'installments',
'adyenVaultPaymentMethod'
]);

return this;
Expand All @@ -70,27 +70,63 @@ define([
let self = this;
this._super();
this.modalLabel = 'card_action_modal_' + this.getId();

let paymentMethodsObserver = adyenPaymentService.getPaymentMethods();
paymentMethodsObserver.subscribe(
function (paymentMethodsResponse) {
self.loadCheckoutComponent(paymentMethodsResponse)
});
self.loadCheckoutComponent(paymentMethodsObserver());
paymentMethodsObserver.subscribe(function (paymentMethodsResponse) {
self.enablePaymentMethod(paymentMethodsResponse)
});

if(!!paymentMethodsObserver()) {
self.enablePaymentMethod(paymentMethodsObserver());
}

return this;
},

loadCheckoutComponent: async function(paymentMethodsResponse) {
this.checkoutComponent = await adyenCheckout.buildCheckoutComponent(
paymentMethodsResponse,
this.handleOnAdditionalDetails.bind(this)
);
enablePaymentMethod: function (paymentMethodsResponse) {
if (!!paymentMethodsResponse.paymentMethodsResponse) {
this.adyenVaultPaymentMethod(true);
fullScreenLoader.stopLoader();
}
},

/*
* Create generic AdyenCheckout library and mount payment method component
* after selecting the payment method via overriding parent `selectPaymentMethod()` function.
*/
selectPaymentMethod: function () {
this._super();
this.createCheckoutComponent();

return true;
},

if (this.checkoutComponent) {
this.checkoutComponentBuilt(true)
/*
* Pre-selected payment methods don't trigger parent's `selectPaymentMethod()` function.
*
* This function is triggered via `afterRender` attribute of the html template
* and creates checkout component for pre-selected payment method.
*/
renderPreSelected: function () {
if (this.isChecked() === this.getCode()) {
this.createCheckoutComponent();
}
},

// Build AdyenCheckout library and creates the payment method component
createCheckoutComponent: async function() {
if (!this.checkoutComponent) {
const paymentMethodsResponse = adyenPaymentService.getPaymentMethods();

this.checkoutComponent = await adyenCheckout.buildCheckoutComponent(
paymentMethodsResponse(),
this.handleOnAdditionalDetails.bind(this)
);
}

this.renderCheckoutComponent();
},

handleOnAdditionalDetails: function (result) {
let self = this;
let request = result.data;
Expand All @@ -110,7 +146,7 @@ define([
});
},

renderCardVaultToken: function () {
renderCheckoutComponent: function () {
let self = this;
if (!this.getClientKey()) {
return false
Expand Down
4 changes: 2 additions & 2 deletions view/frontend/web/template/payment/card-vault-form.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*/
-->

<!-- ko if: checkoutComponentBuilt -->
<!-- ko if: adyenVaultPaymentMethod -->
<div class="payment-method" css="'_active': (getId() === isChecked())">
<div class="payment-method-title field choice">
<input type="radio"
Expand Down Expand Up @@ -67,7 +67,7 @@
</div>
</div>

<div class="checkout-component-dock" afterRender="renderCardVaultToken()" data-bind="attr: { id: 'cvcContainer-' + getId()}"></div>
<div class="checkout-component-dock" afterRender="renderPreSelected()" data-bind="attr: { id: 'cvcContainer-' + getId()}"></div>
</fieldset>
</form>

Expand Down
Loading
Loading