Skip to content

Instantly share code, notes, and snippets.

@xlplugins
Created July 10, 2026 11:40
Show Gist options
  • Select an option

  • Save xlplugins/faf9a8ac018dce9eb03520a1c81035a7 to your computer and use it in GitHub Desktop.

Select an option

Save xlplugins/faf9a8ac018dce9eb03520a1c81035a7 to your computer and use it in GitHub Desktop.
Express Wallets - Single Button
<?php
/**
* Plugin Name: Express Wallets - Single Button (Apple > Google, hide PayPal)
* Description: Show only ONE express wallet button — Apple Pay if the device supports
* it, else Google Pay — and hide the PayPal EXPRESS button whenever a
* Stripe wallet is available. Works on product, cart and checkout.
*
* We do NOT re-detect wallet support and we do NOT pre-hide anything. FunnelKit Stripe
* already runs the wallet check and renders the buttons; we only step in AFTER it has
* finished and hide the ones we don't want. So the worst case is "all buttons show"
* (the original behaviour) — never "no button".
*
* Scope: only the PayPal EXPRESS buttons (product / cart / checkout-top / slide-cart)
* are hidden. The PayPal payment-method button (#angelleye_ppcp_checkout, shown when a
* shopper selects PayPal in the checkout payment methods) is left completely alone.
*
* Signals we read (all from FunnelKit Stripe):
* - data-fkwcs-available="yes" on a wallet's wrapper when it is ready,
* - window._fkwcs_gpay_ready_state === true for native Google Pay,
* - the `fkwcs_smart_buttons_showed` event (fired when detection is done).
*
* Priority: Apple Pay > Google Pay. PayPal express hidden whenever a wallet is available.
*
* Note on the layout jump: because we hide the extras after they've painted there can
* be a small reflow. That is the safe trade-off — pre-hiding off-screen can stop a
* wallet from ever becoming available, which is worse.
*
* Lives in mu-plugins; the plugins themselves are never edited.
*/
defined( 'ABSPATH' ) || exit;
add_action( 'wp_head', 'ewsb_head', 1 );
function ewsb_head() {
if ( is_admin() ) {
return;
}
echo '<style id="ewsb-style">.ewsb-hide{display:none !important;}</style>' . "\n";
}
add_action( 'wp_footer', 'ewsb_footer', 99 );
function ewsb_footer() {
if ( is_admin() ) {
return;
}
?>
<script id="ewsb-js">
( function ( $ ) {
if ( ! $ ) { return; }
var APPLE = '.fkwcs_express_smart_button_wrapper.fkwcs_apple_pay_button, #wfacp_smart_button_fkwcs_apple_pay, #fkcart_fkwcs_smart_button_apple_pay';
var GOOGLE = '.fkwcs_express_smart_button_wrapper.fkwcs_google_pay_button, #wfacp_smart_button_fkwcs_stripe_google_pay, #wfacp_smart_button_fkwcs_google_pay, #fkcart_fkwcs_smart_button_google_pay, #fkcart_fkwcs_smart_button_gpay';
// PayPal EXPRESS placements only. The checkout payment-method button is
// #angelleye_ppcp_checkout — deliberately NOT listed here, so choosing PayPal
// as a payment method still renders its button normally.
var PAYPAL_EXPRESS_IDS = '#angelleye_ppcp_product, #angelleye_ppcp_product_shortcode, #angelleye_ppcp_cart, #angelleye_ppcp_cart_shortcode, #angelleye_ppcp_cart_top, #angelleye_ppcp_checkout_top, #angelleye_ppcp_fkcart';
function hide( sel ) { $( sel ).addClass( 'ewsb-hide' ); }
function hidePaypalExpress() {
// Hide the express button container around each express placement...
$( PAYPAL_EXPRESS_IDS ).closest( '.angelleye_ppcp-button-container' ).addClass( 'ewsb-hide' );
// ...and the express fieldset wrapper on checkout (incl. its "OR" divider).
$( '.wc_ppcp_express_checkout_gateways' ).addClass( 'ewsb-hide' );
}
// A group is "available" only when Stripe has flagged one of its wrappers ready.
function available( sel ) {
return $( sel ).filter( '[data-fkwcs-available="yes"]' ).length > 0
|| $( sel ).find( '[data-fkwcs-available="yes"]' ).length > 0;
}
function apply() {
var appleOn = available( APPLE );
var googleOn = window._fkwcs_gpay_ready_state === true || available( GOOGLE );
// Only ever hide things once a wallet is actually confirmed available.
// If nothing is confirmed we leave every button exactly as Stripe left it.
if ( appleOn ) {
hide( GOOGLE ); // Apple wins over Google
hidePaypalExpress();
} else if ( googleOn ) {
hidePaypalExpress(); // Google wins over PayPal
}
}
$( document.body ).on(
'fkwcs_smart_buttons_showed fkwcs_new_express_smart_buttons_showed fkwcs_express_google_ready_pay fkwcs_express_google_not_ready_pay updated_cart_totals wc_fragments_refreshed fkcart_fragments_refreshed updated_checkout',
apply
);
// A couple of safety re-runs in case the event fired before this bound.
$( apply );
setTimeout( apply, 1500 );
setTimeout( apply, 3500 );
} )( window.jQuery );
</script>
<?php
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment