woocommerce-paypal-payments/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js
2024-08-06 17:13:51 +02:00

337 lines
9 KiB
JavaScript

import CheckoutActionHandler from '../ActionHandler/CheckoutActionHandler';
import { setVisible, setVisibleByClass } from '../Helper/Hiding';
import {
getCurrentPaymentMethod,
isSavedCardSelected,
ORDER_BUTTON_SELECTOR,
PaymentMethods,
} from '../Helper/CheckoutMethodState';
import BootstrapHelper from '../Helper/BootstrapHelper';
import {
ButtonEvents,
dispatchButtonEvent,
} from '../Helper/PaymentButtonHelpers';
class CheckoutBootstap {
constructor( gateway, renderer, spinner, errorHandler ) {
this.gateway = gateway;
this.renderer = renderer;
this.spinner = spinner;
this.errorHandler = errorHandler;
this.standardOrderButtonSelector = ORDER_BUTTON_SELECTOR;
this.renderer.onButtonsInit(
this.gateway.button.wrapper,
() => {
this.handleButtonStatus();
},
true
);
}
init() {
this.render();
this.handleButtonStatus();
// Unselect saved card.
// WC saves form values, so with our current UI it would be a bit weird
// if the user paid with saved, then after some time tries to pay again,
// but wants to enter a new card, and to do that they have to choose “Select payment” in the list.
jQuery( '#saved-credit-card' ).val(
jQuery( '#saved-credit-card option:first' ).val()
);
jQuery( document.body ).on( 'updated_checkout', () => {
this.render();
this.handleButtonStatus();
if (
this.shouldShowMessages() &&
document.querySelector( this.gateway.messages.wrapper )
) {
// currently we need amount only for Pay Later
fetch( this.gateway.ajax.cart_script_params.endpoint, {
method: 'GET',
credentials: 'same-origin',
} )
.then( ( result ) => result.json() )
.then( ( result ) => {
if ( ! result.success ) {
return;
}
jQuery( document.body ).trigger(
'ppcp_checkout_total_updated',
[ result.data.amount ]
);
} );
}
} );
jQuery( document.body ).on(
'updated_checkout payment_method_selected',
() => {
this.invalidatePaymentMethods();
this.updateUi();
}
);
jQuery( document ).on( 'hosted_fields_loaded', () => {
jQuery( '#saved-credit-card' ).on( 'change', () => {
this.updateUi();
} );
} );
jQuery( document ).on( 'ppcp_should_show_messages', ( e, data ) => {
if ( ! this.shouldShowMessages() ) {
data.result = false;
}
} );
this.updateUi();
}
handleButtonStatus() {
BootstrapHelper.handleButtonStatus( this );
}
shouldRender() {
if ( document.querySelector( this.gateway.button.cancel_wrapper ) ) {
return false;
}
return (
document.querySelector( this.gateway.button.wrapper ) !== null ||
document.querySelector( this.gateway.hosted_fields.wrapper ) !==
null
);
}
shouldEnable() {
return BootstrapHelper.shouldEnable( this );
}
render() {
if ( ! this.shouldRender() ) {
return;
}
if (
document.querySelector(
this.gateway.hosted_fields.wrapper + '>div'
)
) {
document
.querySelector( this.gateway.hosted_fields.wrapper + '>div' )
.setAttribute( 'style', '' );
}
const actionHandler = new CheckoutActionHandler(
PayPalCommerceGateway,
this.errorHandler,
this.spinner
);
if (
PayPalCommerceGateway.data_client_id.has_subscriptions &&
PayPalCommerceGateway.data_client_id.paypal_subscriptions_enabled
) {
let subscription_plan_id =
PayPalCommerceGateway.subscription_plan_id;
if (
PayPalCommerceGateway.variable_paypal_subscription_variation_from_cart !==
''
) {
subscription_plan_id =
PayPalCommerceGateway.variable_paypal_subscription_variation_from_cart;
}
this.renderer.render(
actionHandler.subscriptionsConfiguration(
subscription_plan_id
),
{},
actionHandler.configuration()
);
if ( ! PayPalCommerceGateway.subscription_product_allowed ) {
this.gateway.button.is_disabled = true;
this.handleButtonStatus();
}
return;
}
if (
PayPalCommerceGateway.is_free_trial_cart &&
PayPalCommerceGateway.vault_v3_enabled
) {
this.renderer.render(
actionHandler.addPaymentMethodConfiguration(),
{},
actionHandler.configuration()
);
return;
}
this.renderer.render(
actionHandler.configuration(),
{},
actionHandler.configuration()
);
}
invalidatePaymentMethods() {
/**
* Custom JS event to notify other modules that the payment button on the checkout page
* has become irrelevant or invalid.
*/
dispatchButtonEvent( { event: ButtonEvents.INVALIDATE } );
}
updateUi() {
const currentPaymentMethod = getCurrentPaymentMethod();
const isPaypal = currentPaymentMethod === PaymentMethods.PAYPAL;
const isCard = currentPaymentMethod === PaymentMethods.CARDS;
const isSeparateButtonGateway = [ PaymentMethods.CARD_BUTTON ].includes(
currentPaymentMethod
);
const isGooglePayMethod =
currentPaymentMethod === PaymentMethods.GOOGLEPAY;
const isSavedCard = isCard && isSavedCardSelected();
const isNotOurGateway =
! isPaypal &&
! isCard &&
! isSeparateButtonGateway &&
! isGooglePayMethod;
const isFreeTrial = PayPalCommerceGateway.is_free_trial_cart;
const hasVaultedPaypal =
PayPalCommerceGateway.vaulted_paypal_email !== '';
const paypalButtonWrappers = {
...Object.entries( PayPalCommerceGateway.separate_buttons ).reduce(
( result, [ k, data ] ) => {
return { ...result, [ data.id ]: data.wrapper };
},
{}
),
};
setVisibleByClass(
this.standardOrderButtonSelector,
( isPaypal && isFreeTrial && hasVaultedPaypal ) ||
isNotOurGateway ||
isSavedCard,
'ppcp-hidden'
);
setVisible( '.ppcp-vaulted-paypal-details', isPaypal );
setVisible(
this.gateway.button.wrapper,
isPaypal && ! ( isFreeTrial && hasVaultedPaypal )
);
setVisible(
this.gateway.hosted_fields.wrapper,
isCard && ! isSavedCard
);
for ( const [ gatewayId, wrapper ] of Object.entries(
paypalButtonWrappers
) ) {
setVisible( wrapper, gatewayId === currentPaymentMethod );
}
if ( isCard ) {
if ( isSavedCard ) {
this.disableCreditCardFields();
} else {
this.enableCreditCardFields();
}
}
/**
* Custom JS event that is observed by the relevant payment gateway.
*
* Dynamic part of the event name is the payment method ID, for example
* "ppcp-credit-card-gateway" or "ppcp-googlepay"
*/
dispatchButtonEvent( {
event: ButtonEvents.RENDER,
paymentMethod: currentPaymentMethod,
} );
document.body.dispatchEvent( new Event( 'ppcp_checkout_rendered' ) );
}
shouldShowMessages() {
// hide when another method selected only if messages are near buttons
const messagesWrapper = document.querySelector(
this.gateway.messages.wrapper
);
if (
getCurrentPaymentMethod() !== PaymentMethods.PAYPAL &&
messagesWrapper &&
jQuery( messagesWrapper ).closest( '.ppc-button-wrapper' ).length
) {
return false;
}
return ! PayPalCommerceGateway.is_free_trial_cart;
}
disableCreditCardFields() {
jQuery( 'label[for="ppcp-credit-card-gateway-card-number"]' ).addClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( '#ppcp-credit-card-gateway-card-number' ).addClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( 'label[for="ppcp-credit-card-gateway-card-expiry"]' ).addClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( '#ppcp-credit-card-gateway-card-expiry' ).addClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( 'label[for="ppcp-credit-card-gateway-card-cvc"]' ).addClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( '#ppcp-credit-card-gateway-card-cvc' ).addClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( 'label[for="vault"]' ).addClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( '#ppcp-credit-card-vault' ).addClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( '#ppcp-credit-card-vault' ).attr( 'disabled', true );
this.renderer.disableCreditCardFields();
}
enableCreditCardFields() {
jQuery(
'label[for="ppcp-credit-card-gateway-card-number"]'
).removeClass( 'ppcp-credit-card-gateway-form-field-disabled' );
jQuery( '#ppcp-credit-card-gateway-card-number' ).removeClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery(
'label[for="ppcp-credit-card-gateway-card-expiry"]'
).removeClass( 'ppcp-credit-card-gateway-form-field-disabled' );
jQuery( '#ppcp-credit-card-gateway-card-expiry' ).removeClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( 'label[for="ppcp-credit-card-gateway-card-cvc"]' ).removeClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( '#ppcp-credit-card-gateway-card-cvc' ).removeClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( 'label[for="vault"]' ).removeClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( '#ppcp-credit-card-vault' ).removeClass(
'ppcp-credit-card-gateway-form-field-disabled'
);
jQuery( '#ppcp-credit-card-vault' ).attr( 'disabled', false );
this.renderer.enableCreditCardFields();
}
}
export default CheckoutBootstap;