laipower/wp-content/plugins/easy-digital-downloads/assets/js/frontend/gateways/paypal.js

285 lines
8.7 KiB
JavaScript
Raw Normal View History

/* global eddPayPalVars, edd_global_vars */
var EDD_PayPal = {
isMounted: false,
/**
* Initializes PayPal buttons and sets up some events.
*/
init: function() {
if ( document.getElementById( 'edd-paypal-container' ) ) {
this.initButtons( '#edd-paypal-container', 'checkout' );
}
jQuery( document.body ).on( 'edd_discount_applied', this.maybeRefreshPage );
jQuery( document.body ).on( 'edd_discount_removed', this.maybeRefreshPage );
},
/**
* Determines whether or not the selected gateway is PayPal.
* @returns {boolean}
*/
isPayPal: function() {
var chosenGateway = false;
if ( jQuery('select#edd-gateway, input.edd-gateway').length ) {
chosenGateway = jQuery("meta[name='edd-chosen-gateway']").attr('content');
}
if ( ! chosenGateway && edd_scripts.default_gateway ) {
chosenGateway = edd_scripts.default_gateway;
}
return 'paypal_commerce' === chosenGateway;
},
/**
* Refreshes the page when adding or removing a 100% discount.
*
* @param e
* @param {object} data
*/
maybeRefreshPage: function( e, data ) {
if ( 0 === data.total_plain && EDD_PayPal.isPayPal() ) {
window.location.reload();
} else if ( ! EDD_PayPal.isMounted && EDD_PayPal.isPayPal() && data.total_plain > 0 ) {
window.location.reload();
}
},
/**
* Sets the error HTML, depending on the context.
*
* @param {string|HTMLElement} container
* @param {string} context
* @param {string} errorHtml
*/
setErrorHtml: function( container, context, errorHtml ) {
// Format errors.
if ( 'checkout' === context && 'undefined' !== typeof edd_global_vars && edd_global_vars.checkout_error_anchor ) {
// Checkout errors.
var errorWrapper = document.getElementById( 'edd-paypal-errors-wrap' );
if ( errorWrapper ) {
errorWrapper.innerHTML = errorHtml;
}
} else if ( 'buy_now' === context ) {
// Buy Now errors
var form = container.closest( '.edd_download_purchase_form' );
var errorWrapper = form ? form.querySelector( '.edd-paypal-checkout-buy-now-error-wrapper' ) : false;
if ( errorWrapper ) {
errorWrapper.innerHTML = errorHtml;
}
}
jQuery( document.body ).trigger( 'edd_checkout_error', [ errorHtml ] );
},
/**
* Initializes PayPal buttons
*
* @param {string|HTMLElement} container Element to render the buttons in.
* @param {string} context Context for the button. Either `checkout` or `buy_now`.
*/
initButtons: function( container, context ) {
EDD_PayPal.isMounted = true;
paypal.Buttons( EDD_PayPal.getButtonArgs( container, context ) ).render( container );
document.dispatchEvent( new CustomEvent( 'edd_paypal_buttons_mounted' ) );
},
/**
* Retrieves the arguments used to build the PayPal button.
*
* @param {string|HTMLElement} container Element to render the buttons in.
* @param {string} context Context for the button. Either `checkout` or `buy_now`.
*/
getButtonArgs: function ( container, context ) {
var form = ( 'checkout' === context ) ? document.getElementById( 'edd_purchase_form' ) : container.closest( '.edd_download_purchase_form' );
var errorWrapper = ( 'checkout' === context ) ? form.querySelector( '#edd-paypal-errors-wrap' ) : form.querySelector( '.edd-paypal-checkout-buy-now-error-wrapper' );
var spinner = ( 'checkout' === context ) ? document.getElementById( 'edd-paypal-spinner' ) : form.querySelector( '.edd-paypal-spinner' );
var nonceEl = form.querySelector( 'input[name="edd_process_paypal_nonce"]' );
var tokenEl = form.querySelector( 'input[name="edd-process-paypal-token"]' );
var createFunc = ( 'subscription' === eddPayPalVars.intent ) ? 'createSubscription' : 'createOrder';
var buttonArgs = {
onApprove: function( data, actions ) {
var formData = new FormData();
formData.append( 'action', eddPayPalVars.approvalAction );
formData.append( 'edd_process_paypal_nonce', nonceEl.value );
formData.append( 'token', tokenEl.getAttribute('data-token') );
formData.append( 'timestamp', tokenEl.getAttribute('data-timestamp' ) );
if ( data.orderID ) {
formData.append( 'paypal_order_id', data.orderID );
}
if ( data.subscriptionID ) {
formData.append( 'paypal_subscription_id', data.subscriptionID );
}
return fetch( edd_scripts.ajaxurl, {
method: 'POST',
body: formData
} ).then( function( response ) {
return response.json();
} ).then( function( responseData ) {
if ( responseData.success && responseData.data.redirect_url ) {
window.location = responseData.data.redirect_url;
} else {
// Hide spinner.
spinner.style.display = 'none';
var errorHtml = responseData.data.message ? responseData.data.message : eddPayPalVars.defaultError;
EDD_PayPal.setErrorHtml( container, context, errorHtml );
// @link https://developer.paypal.com/docs/checkout/integration-features/funding-failure/
if ( responseData.data.retry ) {
return actions.restart();
}
}
} );
},
onError: function( error ) {
// Hide spinner.
spinner.style.display = 'none';
error.name = '';
EDD_PayPal.setErrorHtml( container, context, error );
},
onCancel: function( data ) {
// Hide spinner.
spinner.style.display = 'none';
const formData = new FormData();
formData.append( 'action', 'edd_cancel_paypal_order' );
return fetch( edd_scripts.ajaxurl, {
method: 'POST',
body: formData
} ).then( function ( response ) {
return response.json();
} ).then( function ( responseData ) {
if ( responseData.success ) {
const nonces = responseData.data.nonces;
Object.keys( nonces ).forEach( function ( key ) {
var gatewaySelector = document.getElementById( 'edd-gateway-' + key );
if ( gatewaySelector ) {
gatewaySelector.setAttribute( 'data-' + key + '-nonce', nonces[ key ] );
}
} );
}
} );
}
};
/*
* Add style if we have any
*
* @link https://developer.paypal.com/docs/checkout/integration-features/customize-button/
*/
if ( eddPayPalVars.style ) {
buttonArgs.style = eddPayPalVars.style;
}
/*
* Add the `create` logic. This gets added to `createOrder` for one-time purchases
* or `createSubscription` for recurring.
*/
buttonArgs[ createFunc ] = function ( data, actions ) {
// Show spinner.
spinner.style.display = 'block';
// Clear errors at the start of each attempt.
if ( errorWrapper ) {
errorWrapper.innerHTML = '';
}
// Submit the form via AJAX.
return fetch( edd_scripts.ajaxurl, {
method: 'POST',
body: new FormData( form )
} ).then( function( response ) {
return response.json();
} ).then( function( orderData ) {
if ( orderData.data && orderData.data.paypal_order_id ) {
// Add the nonce to the form so we can validate it later.
if ( orderData.data.nonce ) {
nonceEl.value = orderData.data.nonce;
}
// Add the token to the form so we can validate it later.
if ( orderData.data.token ) {
jQuery(tokenEl).attr( 'data-token', orderData.data.token );
jQuery(tokenEl).attr( 'data-timestamp', orderData.data.timestamp );
}
return orderData.data.paypal_order_id;
} else {
// Error message.
var errorHtml = eddPayPalVars.defaultError;
if ( orderData.data && 'string' === typeof orderData.data ) {
errorHtml = orderData.data;
} else if ( 'string' === typeof orderData ) {
errorHtml = orderData;
}
return new Promise( function( resolve, reject ) {
reject( errorHtml );
} );
}
} );
};
return buttonArgs;
}
};
/**
* Initialize on checkout.
*/
jQuery( document.body ).on( 'edd_gateway_loaded', function( e, gateway ) {
if ( 'paypal_commerce' !== gateway ) {
return;
}
EDD_PayPal.init();
} );
/**
* Initialize Buy Now buttons.
*/
jQuery( document ).ready( function( $ ) {
var buyButtons = document.querySelectorAll( '.edd-paypal-checkout-buy-now' );
for ( var i = 0; i < buyButtons.length; i++ ) {
var element = buyButtons[ i ];
// Skip if "Free Downloads" is enabled for this download.
if ( element.classList.contains( 'edd-free-download' ) ) {
continue;
}
var wrapper = element.closest( '.edd_purchase_submit_wrapper' );
if ( ! wrapper ) {
continue;
}
// Clear contents of the wrapper.
wrapper.innerHTML = '';
// Add error container after the wrapper.
var errorNode = document.createElement( 'div' );
errorNode.classList.add( 'edd-paypal-checkout-buy-now-error-wrapper' );
wrapper.before( errorNode );
// Add spinner container.
var spinnerWrap = document.createElement( 'span' );
spinnerWrap.classList.add( 'edd-paypal-spinner', 'edd-loading-ajax', 'edd-loading' );
spinnerWrap.style.display = 'none';
wrapper.after( spinnerWrap );
// Initialize button.
EDD_PayPal.initButtons( wrapper, 'buy_now' );
}
} );