diff --git a/modules/ppcp-axo/resources/js/AxoManager.js b/modules/ppcp-axo/resources/js/AxoManager.js
index e02846b67..905270867 100644
--- a/modules/ppcp-axo/resources/js/AxoManager.js
+++ b/modules/ppcp-axo/resources/js/AxoManager.js
@@ -16,15 +16,20 @@ class AxoManager {
this.fastlane = new Fastlane();
this.$ = jQuery;
- this.isConnectProfile = false;
- this.isNewProfile = false;
this.hideGatewaySelection = false;
+ this.status = {
+ active: false,
+ validEmail: false,
+ hasProfile: false,
+ useEmailWidget: this.useEmailWidget()
+ };
+
this.data = {
billing: null,
shipping: null,
card: null,
- }
+ };
this.el = new DomElementCollection();
@@ -32,7 +37,7 @@ class AxoManager {
root: {
backgroundColorPrimary: '#ffffff'
}
- }
+ };
this.locale = 'en_us';
@@ -40,7 +45,11 @@ class AxoManager {
this.shippingView = new ShippingView(this.el.shippingAddressContainer.selector, this.el);
this.billingView = new BillingView(this.el.billingAddressContainer.selector, this.el);
- this.cardView = new CardView(this.el.paymentContainer.selector, this.el, this);
+ this.cardView = new CardView(this.el.paymentContainer.selector + '-details', this.el, this);
+
+ document.testAxoStatus = (key, value) => {
+ this.setStatus(key, value);
+ }
}
registerEventHandlers() {
@@ -48,9 +57,9 @@ class AxoManager {
// Listen to Gateway Radio button changes.
this.el.gatewayRadioButton.on('change', (ev) => {
if (ev.target.checked) {
- this.showAxo();
+ this.activateAxo();
} else {
- this.hideAxo();
+ this.deactivateAxo();
}
});
@@ -66,33 +75,27 @@ class AxoManager {
// Click change shipping address link.
this.el.changeShippingAddressLink.on('click', async () => {
- if (this.isConnectProfile) {
- console.log('profile', this.fastlane.profile);
-
- //this.shippingView.deactivate();
-
+ if (this.status.hasProfile) {
const { selectionChanged, selectedAddress } = await this.fastlane.profile.showShippingAddressSelector();
console.log('selectedAddress', selectedAddress);
if (selectionChanged) {
this.setShipping(selectedAddress);
- this.shippingView.activate();
+ this.shippingView.refresh();
}
}
});
// Click change billing address link.
this.el.changeBillingAddressLink.on('click', async () => {
- if (this.isConnectProfile) {
+ if (this.status.hasProfile) {
this.el.changeCardLink.trigger('click');
}
});
// Click change card link.
this.el.changeCardLink.on('click', async () => {
- console.log('profile', this.fastlane.profile);
-
const response = await this.fastlane.profile.showCardSelector();
console.log('card response', response);
@@ -114,67 +117,229 @@ class AxoManager {
}
- showAxo() {
- this.initPlacements();
- this.initFastlane();
+ rerender() {
+ /**
+ * active | 0 1 1 1
+ * validEmail | * 0 1 1
+ * hasProfile | * * 0 1
+ * --------------------------------
+ * defaultSubmitButton | 1 0 0 0
+ * defaultEmailField | 1 0 0 0
+ * defaultFormFields | 1 0 1 0
+ * extraFormFields | 0 0 0 1
+ * axoEmailField | 0 1 0 0
+ * axoProfileViews | 0 0 0 1
+ * axoPaymentContainer | 0 0 1 1
+ * axoSubmitButton | 0 0 1 1
+ */
+ const scenario = this.identifyScenario(
+ this.status.active,
+ this.status.validEmail,
+ this.status.hasProfile
+ );
- if (!this.isNewProfile && !this.isConnectProfile) {
- this.el.allFields.hide();
+ log('Scenario', scenario);
+
+ // Reset some elements to a default status.
+ this.el.watermarkContainer.hide();
+
+ if (scenario.defaultSubmitButton) {
+ this.el.defaultSubmitButton.show();
+ } else {
+ this.el.defaultSubmitButton.hide();
}
- if (this.useEmailWidget()) {
+ if (scenario.defaultEmailField) {
+ this.el.fieldBillingEmail.show();
+ } else {
+ this.el.fieldBillingEmail.hide();
+ }
+
+ if (scenario.defaultFormFields) {
+ this.el.customerDetails.show();
+ } else {
+ this.el.customerDetails.hide();
+ }
+
+ if (scenario.extraFormFields) {
+ this.el.customerDetails.show();
+ // Hiding of unwanted will be handled by the axoProfileViews handler.
+ }
+
+ if (scenario.axoEmailField) {
+ this.showAxoEmailField();
+ this.el.watermarkContainer.show();
+
+ // Move watermark to after email.
+ this.$(this.el.fieldBillingEmail.selector).append(
+ this.$(this.el.watermarkContainer.selector)
+ );
+
+ } else {
+ this.el.emailWidgetContainer.hide();
+ if (!scenario.defaultEmailField) {
+ this.el.fieldBillingEmail.hide();
+ }
+ }
+
+ if (scenario.axoProfileViews) {
+ this.shippingView.activate();
+ this.billingView.activate();
+ this.cardView.activate();
+
+ // Move watermark to after shipping.
+ this.$(this.el.shippingAddressContainer.selector).after(
+ this.$(this.el.watermarkContainer.selector)
+ );
+
+ this.el.watermarkContainer.show();
+
+ } else {
+ this.shippingView.deactivate();
+ this.billingView.deactivate();
+ this.cardView.deactivate();
+ }
+
+ if (scenario.axoPaymentContainer) {
+ this.el.paymentContainer.show();
+ } else {
+ this.el.paymentContainer.hide();
+ }
+
+ if (scenario.axoSubmitButton) {
+ this.el.submitButtonContainer.show();
+ } else {
+ this.el.submitButtonContainer.hide();
+ }
+
+ this.ensureBillingFieldsConsistency();
+ this.ensureShippingFieldsConsistency();
+ }
+
+ identifyScenario(active, validEmail, hasProfile) {
+ let response = {
+ defaultSubmitButton: false,
+ defaultEmailField: false,
+ defaultFormFields: false,
+ extraFormFields: false,
+ axoEmailField: false,
+ axoProfileViews: false,
+ axoPaymentContainer: false,
+ axoSubmitButton: false,
+ }
+
+ if (active && validEmail && hasProfile) {
+ response.extraFormFields = true;
+ response.axoProfileViews = true;
+ response.axoPaymentContainer = true;
+ response.axoSubmitButton = true;
+ return response;
+ }
+ if (active && validEmail && !hasProfile) {
+ response.defaultFormFields = true;
+ response.axoEmailField = true;
+ response.axoPaymentContainer = true;
+ response.axoSubmitButton = true;
+ return response;
+ }
+ if (active && !validEmail) {
+ response.axoEmailField = true;
+ return response;
+ }
+ if (!active) {
+ response.defaultSubmitButton = true;
+ response.defaultEmailField = true;
+ response.defaultFormFields = true;
+ return response;
+ }
+ throw new Error('Invalid scenario.');
+ }
+
+ ensureBillingFieldsConsistency() {
+ const $billingFields = this.$('.woocommerce-billing-fields .form-row:visible');
+ const $billingHeaders = this.$('.woocommerce-billing-fields h3');
+ if (this.billingView.isActive()) {
+ if ($billingFields.length) {
+ $billingHeaders.show();
+ } else {
+ $billingHeaders.hide();
+ }
+ } else {
+ $billingHeaders.show();
+ }
+ }
+
+ ensureShippingFieldsConsistency() {
+ const $shippingFields = this.$('.woocommerce-shipping-fields .form-row:visible');
+ const $shippingHeaders = this.$('.woocommerce-shipping-fields h3');
+ if (this.shippingView.isActive()) {
+ if ($shippingFields.length) {
+ $shippingHeaders.show();
+ } else {
+ $shippingHeaders.hide();
+ }
+ } else {
+ $shippingHeaders.show();
+ }
+ }
+
+ showAxoEmailField() {
+ if (this.status.useEmailWidget) {
this.el.emailWidgetContainer.show();
this.el.fieldBillingEmail.hide();
} else {
this.el.emailWidgetContainer.hide();
this.el.fieldBillingEmail.show();
}
-
- if (this.isConnectProfile) {
- this.shippingView.activate();
- this.billingView.activate();
-
- this.el.emailWidgetContainer.hide();
- this.el.fieldBillingEmail.hide();
- }
-
- this.el.watermarkContainer.show();
- this.el.paymentContainer.show();
- this.el.submitButtonContainer.show();
- this.el.defaultSubmitButton.hide();
}
- hideAxo() {
- this.el.allFields.show();
+ setStatus(key, value) {
+ this.status[key] = value;
- this.shippingView.deactivate();
- this.billingView.deactivate();
+ log('Status updated', JSON.parse(JSON.stringify(this.status)));
- this.el.emailWidgetContainer.hide();
- this.el.watermarkContainer.hide();
- this.el.paymentContainer.hide();
- this.el.submitButtonContainer.hide();
- this.el.defaultSubmitButton.show();
+ this.rerender();
+ }
- this.el.emailWidgetContainer.hide();
- this.el.fieldBillingEmail.show();
+ activateAxo() {
+ this.initPlacements();
+ this.initFastlane();
+ this.setStatus('active', true);
+
+ const emailInput = document.querySelector(this.el.fieldBillingEmail.selector + ' input');
+ if (emailInput && this.lastEmailCheckedIdentity !== emailInput.value) {
+ this.onChangeEmail();
+ }
+ }
+
+ deactivateAxo() {
+ this.setStatus('active', false);
}
initPlacements() {
- let emailRow = document.querySelector(this.el.fieldBillingEmail.selector);
+ const wrapper = this.el.axoCustomerDetails;
+ // Customer details container.
+ if (!document.querySelector(wrapper.selector)) {
+ document.querySelector(wrapper.anchorSelector).insertAdjacentHTML('afterbegin', `
+
+ `);
+ }
+
+ const wrapperElement = document.querySelector(wrapper.selector);
+
+ // Billing view container.
const bc = this.el.billingAddressContainer;
- const sc = this.el.shippingAddressContainer;
- const ec = this.el.emailWidgetContainer;
-
if (!document.querySelector(bc.selector)) {
- document.querySelector(bc.anchorSelector).insertAdjacentHTML('beforeend', `
+ wrapperElement.insertAdjacentHTML('beforeend', `
`);
}
+ // Shipping view container.
+ const sc = this.el.shippingAddressContainer;
if (!document.querySelector(sc.selector)) {
- document.querySelector(sc.anchorSelector).insertAdjacentHTML('afterbegin', `
+ wrapperElement.insertAdjacentHTML('beforeend', `
`);
}
@@ -182,8 +347,9 @@ class AxoManager {
if (this.useEmailWidget()) {
// Display email widget.
+ const ec = this.el.emailWidgetContainer;
if (!document.querySelector(ec.selector)) {
- emailRow.parentNode.insertAdjacentHTML('afterbegin', `
+ wrapperElement.insertAdjacentHTML('afterbegin', `
--- EMAIL WIDGET PLACEHOLDER ---
@@ -192,8 +358,9 @@ class AxoManager {
} else {
- // Move email row to first place.
- emailRow.parentNode.prepend(emailRow);
+ // Move email to the AXO container.
+ let emailRow = document.querySelector(this.el.fieldBillingEmail.selector);
+ wrapperElement.prepend(emailRow);
emailRow.querySelector('input').focus();
}
}
@@ -229,7 +396,10 @@ class AxoManager {
const gatewayPaymentContainer = document.querySelector('.payment_method_ppcp-axo-gateway');
gatewayPaymentContainer.insertAdjacentHTML('beforeend', `
-
+
`);
}
@@ -259,20 +429,33 @@ class AxoManager {
if (this.emailInput.value) {
this.onChangeEmail();
}
-
}
}
async onChangeEmail () {
- log('Email changed: ' + this.emailInput.value);
+ if (!this.status.active) {
+ log('Email checking skipped, AXO not active.');
+ return;
+ }
+
+ if (!this.emailInput) {
+ log('Email field not initialized.');
+ return;
+ }
+
+ log('Email changed: ' + (this.emailInput ? this.emailInput.value : ''));
+
+ this.$(this.el.paymentContainer.selector + '-detail').html('');
+ this.$(this.el.paymentContainer.selector + '-form').html('');
+
+ this.setStatus('validEmail', false);
+ this.setStatus('hasProfile', false);
- this.isConnectProfile = false;
- this.isNewProfile = false;
this.hideGatewaySelection = false;
- this.el.allFields.hide();
+ this.lastEmailCheckedIdentity = this.emailInput.value;
- if (!this.emailInput.checkValidity()) {
+ if (!this.emailInput.value || !this.emailInput.checkValidity()) {
log('The email address is not valid.');
return;
}
@@ -287,8 +470,6 @@ class AxoManager {
// Authenticate the customer to get access to their profile.
log('Email is associated with a Connect profile or a PayPal member');
- // TODO : enter hideOtherGateways mode
-
const authResponse = await this.fastlane.identity.triggerAuthenticationFlow(lookupResponse.customerContextId);
log('AuthResponse', authResponse);
@@ -296,25 +477,18 @@ class AxoManager {
if (authResponse.authenticationState === 'succeeded') {
log(JSON.stringify(authResponse));
- this.el.allFields.show();
- this.el.paymentContainer.show();
-
-
- // document.querySelector(this.el.paymentContainer.selector).innerHTML =
- // 'Change card';
-
// Add addresses
this.setShipping(authResponse.profileData.shippingAddress);
// TODO : set billing
this.setCard(authResponse.profileData.card);
- this.isConnectProfile = true;
+ this.setStatus('validEmail', true);
+ this.setStatus('hasProfile', true);
+
this.hideGatewaySelection = true;
this.$('.wc_payment_methods label').hide();
- this.shippingView.activate();
- this.billingView.activate();
- this.cardView.activate();
+ this.rerender();
} else {
// authentication failed or canceled by the customer
@@ -326,14 +500,12 @@ class AxoManager {
// This is a guest customer.
log('No profile found with this email address.');
- this.el.allFields.show();
- this.el.paymentContainer.show();
-
- this.isNewProfile = true;
+ this.setStatus('validEmail', true);
+ this.setStatus('hasProfile', false);
this.cardComponent = await this.fastlane
.FastlaneCardComponent(MockData.cardComponent())
- .render(this.el.paymentContainer.selector);
+ .render(this.el.paymentContainer.selector + '-form');
}
}
diff --git a/modules/ppcp-axo/resources/js/Components/DomElementCollection.js b/modules/ppcp-axo/resources/js/Components/DomElementCollection.js
index d6840242a..8cc1deb1a 100644
--- a/modules/ppcp-axo/resources/js/Components/DomElementCollection.js
+++ b/modules/ppcp-axo/resources/js/Components/DomElementCollection.js
@@ -23,8 +23,15 @@ class DomElementCollection {
className: 'ppcp-axo-watermark-container'
});
- this.allFields = new DomElement({
- selector: '#customer_details .form-row, #customer_details .woocommerce-shipping-fields'
+ this.customerDetails = new DomElement({
+ selector: '#customer_details > *:not(#ppcp-axo-customer-details)'
+ });
+
+ this.axoCustomerDetails = new DomElement({
+ id: 'ppcp-axo-customer-details',
+ selector: '#ppcp-axo-customer-details',
+ className: 'ppcp-axo-customer-details',
+ anchorSelector: '#customer_details'
});
this.emailWidgetContainer = new DomElement({
@@ -36,15 +43,13 @@ class DomElementCollection {
this.shippingAddressContainer = new DomElement({
id: 'ppcp-axo-shipping-address-container',
selector: '#ppcp-axo-shipping-address-container',
- className: 'ppcp-axo-shipping-address-container',
- anchorSelector: '.woocommerce-shipping-fields'
+ className: 'ppcp-axo-shipping-address-container'
});
this.billingAddressContainer = new DomElement({
id: 'ppcp-axo-billing-address-container',
selector: '#ppcp-axo-billing-address-container',
- className: 'ppcp-axo-billing-address-container',
- anchorSelector: '.woocommerce-billing-fields__field-wrapper'
+ className: 'ppcp-axo-billing-address-container'
});
this.fieldBillingEmail = new DomElement({
diff --git a/modules/ppcp-axo/resources/js/Components/FormFieldGroup.js b/modules/ppcp-axo/resources/js/Components/FormFieldGroup.js
index d35b54349..c308bef3f 100644
--- a/modules/ppcp-axo/resources/js/Components/FormFieldGroup.js
+++ b/modules/ppcp-axo/resources/js/Components/FormFieldGroup.js
@@ -48,36 +48,40 @@ class MockData {
content.innerHTML = '';
+ if (!this.active) {
+ this.hideField(this.contentSelector);
+ } else {
+ this.showField(this.contentSelector);
+ }
+
Object.keys(this.fields).forEach((key) => {
const field = this.fields[key];
if (this.active) {
this.hideField(field.selector);
- //this.showField(this.contentSelector);
} else {
this.showField(field.selector);
- //this.hideField(this.contentSelector);
}
-
- if (typeof this.template === 'function') {
- content.innerHTML = this.template({
- value: (valueKey) => {
- return this.getDataValue(this.fields[valueKey].valuePath);
- },
- isEmpty: () => {
- let isEmpty = true;
- Object.values(this.fields).forEach((valueField) => {
- if (this.getDataValue(valueField.valuePath)) {
- isEmpty = false;
- return false;
- }
- });
- return isEmpty;
- }
- });
- }
-
});
+
+ if (typeof this.template === 'function') {
+ content.innerHTML = this.template({
+ value: (valueKey) => {
+ return this.getDataValue(this.fields[valueKey].valuePath);
+ },
+ isEmpty: () => {
+ let isEmpty = true;
+ Object.values(this.fields).forEach((valueField) => {
+ if (this.getDataValue(valueField.valuePath)) {
+ isEmpty = false;
+ return false;
+ }
+ });
+ return isEmpty;
+ }
+ });
+ }
+
}
showField(selector) {
diff --git a/modules/ppcp-axo/resources/js/Views/BillingView.js b/modules/ppcp-axo/resources/js/Views/BillingView.js
index 7e61388c3..4163c19c1 100644
--- a/modules/ppcp-axo/resources/js/Views/BillingView.js
+++ b/modules/ppcp-axo/resources/js/Views/BillingView.js
@@ -21,14 +21,14 @@ class BillingView {
if (data.isEmpty()) {
return `
-
Billing details Edit
+
Please fill in your billing details.
`;
}
return `
-
Billing details Edit
+
${data.value('email')}
${data.value('company')}
${data.value('firstName')} ${data.value('lastName')}
@@ -89,6 +89,10 @@ class BillingView {
});
}
+ isActive() {
+ return this.billingFormFields.active;
+ }
+
activate() {
this.billingFormFields.activate();
}
@@ -97,6 +101,10 @@ class BillingView {
this.billingFormFields.deactivate();
}
+ refresh() {
+ this.billingFormFields.refresh();
+ }
+
setData(data) {
this.billingFormFields.setData(data);
}
diff --git a/modules/ppcp-axo/resources/js/Views/CardView.js b/modules/ppcp-axo/resources/js/Views/CardView.js
index fd188d7c7..84a6555d2 100644
--- a/modules/ppcp-axo/resources/js/Views/CardView.js
+++ b/modules/ppcp-axo/resources/js/Views/CardView.js
@@ -20,19 +20,40 @@ class CardView {
if (data.isEmpty()) {
return `
-
Please fill in your card details.
-
+
+
Please fill in your card details.
+
+
${selectOtherPaymentMethod()}
`;
}
+
+ const expiry = data.value('expiry').split('-');
+
+ const cardIcons = {
+ 'VISA': 'visa-dark.svg',
+ 'MASTERCARD_CARD': 'mastercard-dark.svg',
+ 'AMEX': 'amex.svg',
+ 'DISCOVER': 'discover.svg',
+ };
+
return `
-
Card Details Edit
-
${data.value('name')}
-
${data.value('brand')}
-
${data.value('lastDigits') ? '************' + data.value('lastDigits'): ''}
-
${data.value('expiry')}
+
Card Details Edit
+
+
+
]})
+
+
${data.value('lastDigits') ? '**** **** **** ' + data.value('lastDigits'): ''}
+
${expiry[1]}/${expiry[0]}
+
${data.value('name')}
+
${selectOtherPaymentMethod()}
`;
diff --git a/modules/ppcp-axo/resources/js/Views/ShippingView.js b/modules/ppcp-axo/resources/js/Views/ShippingView.js
index ab154913a..24c95cf87 100644
--- a/modules/ppcp-axo/resources/js/Views/ShippingView.js
+++ b/modules/ppcp-axo/resources/js/Views/ShippingView.js
@@ -21,14 +21,14 @@ class ShippingView {
if (data.isEmpty()) {
return `
-
Shipping details Edit
+
Shipping Edit
Please fill in your shipping details.
`;
}
return `
-
Shipping details Edit
+
Shipping Edit
${data.value('company')}
${data.value('firstName')} ${data.value('lastName')}
${data.value('street1')}
@@ -85,6 +85,10 @@ class ShippingView {
});
}
+ isActive() {
+ return this.shippingFormFields.active;
+ }
+
activate() {
this.shippingFormFields.activate();
}
@@ -93,6 +97,10 @@ class ShippingView {
this.shippingFormFields.deactivate();
}
+ refresh() {
+ this.shippingFormFields.refresh();
+ }
+
setData(data) {
this.shippingFormFields.setData(data);
}
diff --git a/modules/ppcp-axo/src/Gateway/AxoGateway.php b/modules/ppcp-axo/src/Gateway/AxoGateway.php
index 32f9f83e9..d3ef227ed 100644
--- a/modules/ppcp-axo/src/Gateway/AxoGateway.php
+++ b/modules/ppcp-axo/src/Gateway/AxoGateway.php
@@ -214,12 +214,10 @@ class AxoGateway extends WC_Payment_Gateway {
//$this->add_paypal_meta( $wc_order, $order, $this->environment );
- // TODO: inject dependency
+ // TODO: inject dependency.
PPCP::container()->get( 'session.handler' )->replace_order( $order );
PPCP::container()->get( 'wcgateway.order-processor' )->process( $wc_order );
-
-
// $payment_source = array(
// 'oxxo' => array(
// 'name' => $wc_order->get_billing_first_name() . ' ' . $wc_order->get_billing_last_name(),