diff --git a/includes/class-donations.php b/includes/class-donations.php index f731845086..f8d4ba6fb0 100644 --- a/includes/class-donations.php +++ b/includes/class-donations.php @@ -66,7 +66,11 @@ class Donations { public static function init() { self::$donation_product_name = __( 'Donate', 'newspack-plugin' ); - add_action( 'wp_loaded', [ __CLASS__, 'process_donation_form' ], 99 ); + // Process donation request. + add_action( 'wp_ajax_modal_checkout_request', [ __CLASS__, 'process_donation_request' ] ); + add_action( 'wp_ajax_nopriv_modal_checkout_request', [ __CLASS__, 'process_donation_request' ] ); + add_action( 'wp_loaded', [ __CLASS__, 'process_donation_request' ], 99 ); + add_action( 'woocommerce_checkout_update_order_meta', [ __CLASS__, 'woocommerce_checkout_update_order_meta' ] ); add_filter( 'woocommerce_billing_fields', [ __CLASS__, 'woocommerce_billing_fields' ] ); add_filter( 'pre_option_woocommerce_enable_guest_checkout', [ __CLASS__, 'disable_guest_checkout' ] ); @@ -649,8 +653,8 @@ public static function is_platform_other() { /** * Handle submission of the donation form. */ - public static function process_donation_form() { - if ( is_admin() ) { + public static function process_donation_request() { + if ( is_admin() && ! defined( 'DOING_AJAX' ) ) { return; } @@ -777,8 +781,16 @@ function ( $item ) { ); // Redirect to checkout. - \wp_safe_redirect( apply_filters( 'newspack_donation_checkout_url', $checkout_url, $donation_value, $donation_frequency ) ); - exit; + $checkout_url = apply_filters( 'newspack_donation_checkout_url', $checkout_url, $donation_value, $donation_frequency ); + + if ( defined( 'DOING_AJAX' ) ) { + echo wp_json_encode( [ 'url' => $checkout_url ] ); + exit; + } else { + // Redirect to checkout. + \wp_safe_redirect( $checkout_url ); + exit; + } } /** diff --git a/includes/class-magic-link.php b/includes/class-magic-link.php index 80036eb188..ca8351416f 100644 --- a/includes/class-magic-link.php +++ b/includes/class-magic-link.php @@ -35,14 +35,7 @@ final class Magic_Link { const OTP_AUTH_ACTION = 'np_otp_auth'; const OTP_HASH_COOKIE = 'np_otp_hash'; const ACCEPTED_PARAMS = [ - 'newspack_modal_checkout', - 'type', - 'layout', - 'frequency', - 'amount', - 'other', - 'product_id', - 'variation_id', + 'checkout', ]; /** diff --git a/includes/data-events/class-woo-user-registration.php b/includes/data-events/class-woo-user-registration.php index 41389119f7..08df749253 100644 --- a/includes/data-events/class-woo-user-registration.php +++ b/includes/data-events/class-woo-user-registration.php @@ -47,7 +47,7 @@ public static function init() { public static function checkout_process() { /** - * On Newspack\Donations::process_donation_form(), we add these values to the cart. + * On Newspack\Donations::process_donation_request(), we add these values to the cart. * * Later, we add them to the order (Newspack\Donations::checkout_create_order_line_item()) and use it to send the metadata to Newspack on donation events. * diff --git a/includes/plugins/wc-memberships/class-memberships.php b/includes/plugins/wc-memberships/class-memberships.php index e83d3fac0d..c06b1e5662 100644 --- a/includes/plugins/wc-memberships/class-memberships.php +++ b/includes/plugins/wc-memberships/class-memberships.php @@ -770,7 +770,7 @@ public static function render_js() { window.newspackRAS = window.newspackRAS || []; window.newspackRAS.push( function( ras ) { ras.on( 'reader', function( ev ) { - if ( ev.detail.authenticated && ! window?.newspackReaderActivation?.isPendingCheckout() ) { + if ( ev.detail.authenticated && ! window?.newspackReaderActivation?.getPendingCheckout() ) { if ( ras.overlays.get().length ) { ras.on( 'overlay', function( ev ) { if ( ! ev.detail.overlays.length ) { diff --git a/src/reader-activation-auth/auth-form.js b/src/reader-activation-auth/auth-form.js index bcee6e8bb4..d3f4ccb127 100644 --- a/src/reader-activation-auth/auth-form.js +++ b/src/reader-activation-auth/auth-form.js @@ -4,7 +4,7 @@ * Internal dependencies. */ import { domReady, formatTime } from '../utils'; -import { getCheckoutRedirectUrl } from '../reader-activation/checkout'; +import { getPendingCheckout } from '../reader-activation/checkout'; import { openNewslettersSignupModal } from '../reader-activation-newsletters/newsletters-modal'; import './google-oauth'; @@ -219,11 +219,11 @@ window.newspackRAS.push( function ( readerActivation ) { body.set( 'reader-activation-auth-form', 1 ); body.set( 'npe', emailInput.value ); body.set( 'action', 'link' ); - if ( readerActivation.isPendingCheckout() ) { - const redirectUrl = getCheckoutRedirectUrl(); - if ( redirectUrl ) { - body.set( 'redirect_url', redirectUrl ); - } + const pendingCheckout = getPendingCheckout(); + if ( pendingCheckout ) { + const url = new URL( window.location.href ); + url.searchParams.set( 'checkout', 1 ); + body.set( 'redirect_url', url.toString() ); } fetch( form.getAttribute( 'action' ) || window.location.pathname, { method: 'POST', @@ -372,11 +372,11 @@ window.newspackRAS.push( function ( readerActivation ) { if ( ! body.has( 'npe' ) || ! body.get( 'npe' ) ) { return form.endLoginFlow( newspack_reader_activation_labels.invalid_email, 400 ); } - if ( readerActivation.isPendingCheckout() ) { - const redirectUrl = getCheckoutRedirectUrl(); - if ( redirectUrl ) { - body.set( 'redirect_url', redirectUrl ); - } + const pendingCheckout = getPendingCheckout(); + if ( pendingCheckout ) { + const url = new URL( window.location.href ); + url.searchParams.set( 'checkout', 1 ); + body.set( 'redirect_url', url.toString() ); } if ( 'otp' === action ) { readerActivation diff --git a/src/reader-activation/checkout.js b/src/reader-activation/checkout.js index 50230577fd..8726bd415c 100644 --- a/src/reader-activation/checkout.js +++ b/src/reader-activation/checkout.js @@ -9,85 +9,20 @@ import Store from './store.js'; export const store = Store(); /** - * Get the current checkout. + * Set the pending checkout URL. * - * @return {Object} Checkout data. + * @param {string|false} url */ -export function getCheckout() { - return store.get( 'checkout' ) || {}; -} - -/** - * Set the current checkout data. - * - * @param {Object} data Checkout data. Optional. - * If empty or not provided, the checkout data will be cleared. - */ -export function setCheckoutData( data = {} ) { - store.set( 'checkout', data, false ); +export function setPendingCheckout( url = false ) { + store.set( 'pending_checkout', url, false ); emit( EVENTS.reader, getReader() ); } /** - * Get the reader checkout data. - * - * @param {string} key Checkout data key. Optional. - * - * @return {any} Reader checkout data. - */ -export function getCheckoutData( key ) { - const checkout = getCheckout(); - if ( ! key ) { - return checkout; - } - return checkout?.[ key ]; -} - -/** - * Whether checkout is pending. - * - * @return {boolean} Whether checkout is pending. - */ -export function isPendingCheckout() { - const checkout = getCheckout(); - if ( Object.keys( checkout ).length ) { - return true; - } - return false; -} - -/** - * Reset the reader checkout data. - */ -export function resetCheckoutData() { - setCheckoutData(); -} - -/** - * Get a checkout redirect URL. + * Get the pending checkout URL. * - * @return {string} A checkout redirect URL if checkout data is present. - * Otherwise, an empty string + * @return {string|false} Pending checkout URL. */ -export function getCheckoutRedirectUrl() { - const checkoutType = getCheckoutData( 'type' ); - if ( ! checkoutType ) { - return ''; - } - const redirectUrl = new URL( window.location.href ); - redirectUrl.searchParams.set( 'newspack_modal_checkout', 1 ); - redirectUrl.searchParams.set( 'type', checkoutType ); - // Add checkout button params. - if ( checkoutType === 'checkout_button' ) { - redirectUrl.searchParams.set( 'product_id', getCheckoutData( 'product_id' ) ?? '' ); - redirectUrl.searchParams.set( 'variation_id', getCheckoutData( 'variation_id' ) ?? '' ); - } - // Add donate params. - if ( checkoutType === 'donate' ) { - redirectUrl.searchParams.set( 'layout', getCheckoutData( 'layout' ) ?? '' ); - redirectUrl.searchParams.set( 'frequency', getCheckoutData( 'frequency' ?? '' ) ); - redirectUrl.searchParams.set( 'amount', getCheckoutData( 'amount' ) ?? '' ); - redirectUrl.searchParams.set( 'other', getCheckoutData( 'other' ) ?? '' ); - } - return redirectUrl.href; +export function getPendingCheckout() { + return store.get( 'pending_checkout' ) || false; } diff --git a/src/reader-activation/index.js b/src/reader-activation/index.js index a361633e02..96320f9ab4 100644 --- a/src/reader-activation/index.js +++ b/src/reader-activation/index.js @@ -3,7 +3,7 @@ window.newspack_ras_config = window.newspack_ras_config || {}; import Store from './store.js'; -import { isPendingCheckout, setCheckoutData, getCheckoutData, resetCheckoutData } from './checkout.js'; +import { getPendingCheckout, setPendingCheckout } from './checkout.js'; import { EVENTS, on, off, emit } from './events.js'; import { getCookie, setCookie, generateID } from './utils.js'; import overlays from './overlays.js'; @@ -429,10 +429,8 @@ const readerActivation = { authenticateOTP, setAuthStrategy, getAuthStrategy, - setCheckoutData, - getCheckoutData, - isPendingCheckout, - resetCheckoutData, + setPendingCheckout, + getPendingCheckout, ...( newspack_ras_config.is_ras_enabled && { openAuthModal } ) };