woocommerce-paypal-payments/modules/ppcp-onboarding/resources/js/onboarding.js

493 lines
13 KiB
JavaScript

const ppcp_onboarding = {
BUTTON_SELECTOR: '[data-paypal-onboard-button]',
PAYPAL_JS_ID: 'ppcp-onboarding-paypal-js',
_timeout: false,
STATE_START: 'start',
STATE_ONBOARDED: 'onboarded',
init() {
document.addEventListener( 'DOMContentLoaded', this.reload );
},
reload() {
const buttons = document.querySelectorAll(
ppcp_onboarding.BUTTON_SELECTOR
);
if ( buttons.length > 0 ) {
// Add event listeners to buttons preventing link clicking if PayPal init failed.
buttons.forEach( ( element ) => {
if ( element.hasAttribute( 'data-ppcp-button-initialized' ) ) {
return;
}
element.addEventListener( 'click', ( e ) => {
if (
! element.hasAttribute(
'data-ppcp-button-initialized'
) ||
'undefined' === typeof window.PAYPAL
) {
e.preventDefault();
}
} );
} );
// Clear any previous PayPal scripts.
[ ppcp_onboarding.PAYPAL_JS_ID, 'signup-js', 'biz-js' ].forEach(
( scriptID ) => {
const scriptTag = document.getElementById( scriptID );
if ( scriptTag ) {
scriptTag.parentNode.removeChild( scriptTag );
}
if ( 'undefined' !== typeof window.PAYPAL ) {
delete window.PAYPAL;
}
}
);
// Load PayPal scripts.
const paypalScriptTag = document.createElement( 'script' );
paypalScriptTag.id = ppcp_onboarding.PAYPAL_JS_ID;
paypalScriptTag.src = PayPalCommerceGatewayOnboarding.paypal_js_url;
document.body.appendChild( paypalScriptTag );
if ( ppcp_onboarding._timeout ) {
clearTimeout( ppcp_onboarding._timeout );
}
ppcp_onboarding._timeout = setTimeout( () => {
buttons.forEach( ( element ) => {
element.setAttribute(
'data-ppcp-button-initialized',
'true'
);
} );
if ( 'undefined' !== window.PAYPAL.apps.Signup ) {
window.PAYPAL.apps.Signup.render();
}
}, 1000 );
}
const $onboarding_inputs = function () {
return jQuery( '*[data-onboarding-option]' );
};
const onboarding_options = function () {
const options = {};
$onboarding_inputs().each( ( index, el ) => {
const opt = jQuery( el ).data( 'onboardingOption' );
options[ opt ] = el.checked;
} );
return options;
};
const disable_onboarding_options = function () {
$onboarding_inputs().each( ( index, el ) => {
el.setAttribute( 'disabled', 'disabled' );
} );
};
const enable_onboarding_options = function () {
$onboarding_inputs().each( ( index, el ) => {
el.removeAttribute( 'disabled' );
} );
};
const update_onboarding_options = function () {
const spinner =
'<span class="spinner is-active" style="float: none;"></span>';
disable_onboarding_options();
buttons.forEach( ( element ) => {
element.removeAttribute( 'href' );
element.setAttribute( 'disabled', 'disabled' );
jQuery( spinner ).insertAfter( element );
} );
fetch(
PayPalCommerceGatewayOnboarding.update_signup_links_endpoint,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'same-origin',
body: JSON.stringify( {
nonce: PayPalCommerceGatewayOnboarding.update_signup_links_nonce,
settings: onboarding_options(),
} ),
}
)
.then( ( res ) => {
return res.json();
} )
.then( ( data ) => {
if ( ! data.success ) {
alert(
'Could not update signup buttons: ' +
JSON.stringify( data )
);
return;
}
buttons.forEach( ( element ) => {
for ( let [ key, value ] of Object.entries(
data.data.signup_links
) ) {
key = 'connect-to' + key.replace( /-/g, '' );
if ( key === element.id ) {
element.setAttribute( 'href', value );
element.removeAttribute( 'disabled' );
document.querySelector( '.spinner' ).remove();
}
}
} );
enable_onboarding_options();
} );
};
$onboarding_inputs().on( 'click', ( event ) => {
event.preventDefault();
update_onboarding_options();
} );
},
loginSeller( env, authCode, sharedId ) {
fetch( PayPalCommerceGatewayOnboarding.endpoint, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify( {
authCode,
sharedId,
nonce: PayPalCommerceGatewayOnboarding.nonce,
env,
acceptCards: document.querySelector(
'#ppcp-onboarding-accept-cards'
).checked,
} ),
} );
},
};
window.ppcp_onboarding_sandboxCallback = function ( ...args ) {
return ppcp_onboarding.loginSeller( 'sandbox', ...args );
};
window.ppcp_onboarding_productionCallback = function ( ...args ) {
return ppcp_onboarding.loginSeller( 'production', ...args );
};
( () => {
const productionCredentialElementsSelectors = [
'#field-merchant_email_production',
'#field-merchant_id_production',
'#field-client_id_production',
'#field-client_secret_production',
];
const sandboxCredentialElementsSelectors = [
'#field-merchant_email_sandbox',
'#field-merchant_id_sandbox',
'#field-client_id_sandbox',
'#field-client_secret_sandbox',
];
const updateOptionsState = () => {
const cardsChk = document.querySelector(
'#ppcp-onboarding-accept-cards'
);
if ( ! cardsChk ) {
return;
}
document
.querySelectorAll( '#ppcp-onboarding-dcc-options input' )
.forEach( ( input ) => {
input.disabled = ! cardsChk.checked;
} );
document.querySelector(
'.ppcp-onboarding-cards-options'
).style.display = ! cardsChk.checked ? 'none' : '';
const basicRb = document.querySelector( '#ppcp-onboarding-dcc-basic' );
const isExpress = ! cardsChk.checked || basicRb.checked;
const expressButtonSelectors = [
'#field-ppcp_onboarding_production_express',
'#field-ppcp_onboarding_sandbox_express',
];
const ppcpButtonSelectors = [
'#field-ppcp_onboarding_production_ppcp',
'#field-ppcp_onboarding_sandbox_ppcp',
];
document
.querySelectorAll( expressButtonSelectors.join() )
.forEach(
( element ) =>
( element.style.display = isExpress ? '' : 'none' )
);
document
.querySelectorAll( ppcpButtonSelectors.join() )
.forEach(
( element ) =>
( element.style.display = ! isExpress ? '' : 'none' )
);
const screemImg = document.querySelector(
'#ppcp-onboarding-cards-screen-img'
);
if ( screemImg ) {
const currentRb =
Array.from(
document.querySelectorAll(
'#ppcp-onboarding-dcc-options input[type="radio"]'
)
).filter( ( rb ) => rb.checked )[ 0 ] ?? null;
const imgUrl = currentRb.getAttribute( 'data-screen-url' );
screemImg.src = imgUrl;
}
};
const updateManualInputControls = (
shown,
isSandbox,
isAnyEnvOnboarded
) => {
const productionElementsSelectors =
productionCredentialElementsSelectors;
const sandboxElementsSelectors = sandboxCredentialElementsSelectors;
const otherElementsSelectors = [ '.woocommerce-save-button' ];
if ( ! isAnyEnvOnboarded ) {
otherElementsSelectors.push( '#field-sandbox_on' );
}
document
.querySelectorAll( productionElementsSelectors.join() )
.forEach( ( element ) => {
element.classList.remove( 'hide', 'show' );
element.classList.add( shown && ! isSandbox ? 'show' : 'hide' );
} );
document
.querySelectorAll( sandboxElementsSelectors.join() )
.forEach( ( element ) => {
element.classList.remove( 'hide', 'show' );
element.classList.add( shown && isSandbox ? 'show' : 'hide' );
} );
document
.querySelectorAll( otherElementsSelectors.join() )
.forEach(
( element ) => ( element.style.display = shown ? '' : 'none' )
);
};
const updateEnvironmentControls = ( isSandbox ) => {
const productionElementsSelectors = [
'#field-ppcp_disconnect_production',
'#field-credentials_production_heading',
];
const sandboxElementsSelectors = [
'#field-ppcp_disconnect_sandbox',
'#field-credentials_sandbox_heading',
];
document
.querySelectorAll( productionElementsSelectors.join() )
.forEach(
( element ) =>
( element.style.display = ! isSandbox ? '' : 'none' )
);
document
.querySelectorAll( sandboxElementsSelectors.join() )
.forEach(
( element ) =>
( element.style.display = isSandbox ? '' : 'none' )
);
};
let isDisconnecting = false;
const disconnect = ( event ) => {
event.preventDefault();
const fields = event.target.classList.contains( 'production' )
? productionCredentialElementsSelectors
: sandboxCredentialElementsSelectors;
document
.querySelectorAll( fields.map( ( f ) => f + ' input' ).join() )
.forEach( ( element ) => {
element.value = '';
} );
sandboxSwitchElement.checked = ! sandboxSwitchElement.checked;
isDisconnecting = true;
const saveButton = document.querySelector( '.woocommerce-save-button' );
saveButton.removeAttribute( 'disabled' );
saveButton.click();
};
// Prevent the message about unsaved checkbox/radiobutton when reloading the page.
// (WC listens for changes on all inputs and sets dirty flag until form submission)
const preventDirtyCheckboxPropagation = ( event ) => {
event.preventDefault();
event.stopPropagation();
const value = event.target.checked;
setTimeout( () => {
event.target.checked = value;
}, 1 );
};
const sandboxSwitchElement = document.querySelector( '#ppcp-sandbox_on' );
sandboxSwitchElement?.addEventListener( 'click', () => {
document
.querySelector( '.woocommerce-save-button' )
?.removeAttribute( 'disabled' );
} );
const validate = () => {
const selectors = sandboxSwitchElement.checked
? sandboxCredentialElementsSelectors
: productionCredentialElementsSelectors;
const values = selectors
.map( ( s ) => document.querySelector( s + ' input' ) )
.map( ( el ) => el.value );
const errors = [];
if ( values.some( ( v ) => ! v ) ) {
errors.push(
PayPalCommerceGatewayOnboarding.error_messages.no_credentials
);
}
return errors;
};
const isAnyEnvOnboarded =
PayPalCommerceGatewayOnboarding.sandbox_state ===
ppcp_onboarding.STATE_ONBOARDED ||
PayPalCommerceGatewayOnboarding.production_state ===
ppcp_onboarding.STATE_ONBOARDED;
document.querySelectorAll( '.ppcp-disconnect' ).forEach( ( button ) => {
button.addEventListener( 'click', disconnect );
} );
document
.querySelectorAll( '.ppcp-onboarding-options input' )
.forEach( ( element ) => {
element.addEventListener( 'click', ( event ) => {
updateOptionsState();
preventDirtyCheckboxPropagation( event );
} );
} );
const isSandboxInBackend =
PayPalCommerceGatewayOnboarding.current_env === 'sandbox';
if ( sandboxSwitchElement?.checked !== isSandboxInBackend ) {
sandboxSwitchElement.checked = isSandboxInBackend;
}
updateOptionsState();
const settingsContainer = document.querySelector( '#mainform .form-table' );
const markCurrentOnboardingState = ( isOnboarded ) => {
settingsContainer.classList.remove(
'ppcp-onboarded',
'ppcp-onboarding'
);
settingsContainer.classList.add(
isOnboarded ? 'ppcp-onboarded' : 'ppcp-onboarding'
);
};
markCurrentOnboardingState(
PayPalCommerceGatewayOnboarding.current_state ===
ppcp_onboarding.STATE_ONBOARDED
);
const manualInputToggleButton = document.querySelector(
'#field-toggle_manual_input button'
);
let isManualInputShown =
PayPalCommerceGatewayOnboarding.current_state ===
ppcp_onboarding.STATE_ONBOARDED;
manualInputToggleButton.addEventListener( 'click', ( event ) => {
event.preventDefault();
isManualInputShown = ! isManualInputShown;
updateManualInputControls(
isManualInputShown,
sandboxSwitchElement.checked,
isAnyEnvOnboarded
);
} );
sandboxSwitchElement.addEventListener( 'click', ( event ) => {
const isSandbox = sandboxSwitchElement.checked;
if ( isAnyEnvOnboarded ) {
const onboardingState = isSandbox
? PayPalCommerceGatewayOnboarding.sandbox_state
: PayPalCommerceGatewayOnboarding.production_state;
const isOnboarded =
onboardingState === ppcp_onboarding.STATE_ONBOARDED;
markCurrentOnboardingState( isOnboarded );
isManualInputShown = isOnboarded;
}
updateManualInputControls(
isManualInputShown,
isSandbox,
isAnyEnvOnboarded
);
updateEnvironmentControls( isSandbox );
preventDirtyCheckboxPropagation( event );
} );
updateManualInputControls(
isManualInputShown,
sandboxSwitchElement.checked,
isAnyEnvOnboarded
);
updateEnvironmentControls( sandboxSwitchElement.checked );
document.querySelector( '#mainform' ).addEventListener( 'submit', ( e ) => {
if ( isDisconnecting ) {
return;
}
const errors = validate();
if ( errors.length ) {
e.preventDefault();
const errorLabel = document.querySelector(
'#ppcp-form-errors-label'
);
errorLabel.parentElement.parentElement.classList.remove( 'hide' );
errorLabel.innerHTML = errors.join( '<br/>' );
errorLabel.scrollIntoView();
window.scrollBy( 0, -120 ); // WP + WC floating header
}
} );
// Onboarding buttons.
ppcp_onboarding.init();
} )();