Skip to content

Instantly share code, notes, and snippets.

@mikejolley
Last active November 4, 2024 01:41
Show Gist options
  • Save mikejolley/f185f73f0046353f05773843bd153a9a to your computer and use it in GitHub Desktop.
Save mikejolley/f185f73f0046353f05773843bd153a9a to your computer and use it in GitHub Desktop.
WooCommerce Block Checkout Example to listen for payment method change and add a fee server side
<?php
// Reset payment method in session
add_action('woocommerce_checkout_init', function(){
if( ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || ( defined( 'DOING_AJAX') && DOING_AJAX ) || !WC() || !WC()->session || is_admin() ) {
return;
}
// Get first payment method and store it
// Since payment method selection is not persistent, on page load always the first one will be selected
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
$first_payment_method = key($available_gateways);
WC()->session->set('test_plugin_selected_payment_method', $first_payment_method);
});
// Update callback to store the posted payment method for later usage.
add_action( 'woocommerce_blocks_loaded', function() {
woocommerce_store_api_register_update_callback([
'namespace' => 'test-plugin-namespace',
'callback' => function( $data ) {
if ( isset( $data['payment_method'] ) ) {
WC()->session->set('test_plugin_selected_payment_method', $data['payment_method']);
}
}
]);
});
// Add fee logic.
add_action( 'woocommerce_cart_calculate_fees', function() {
$chosen_payment_method_id = WC()->session->get('test_plugin_selected_payment_method');
if ( 'bacs' === $chosen_payment_method_id ) {
WC()->cart->add_fee( 'Additional Fee', 10 );
}
});
// Move to dedicated script. Used here as quick example.
add_action( 'wp_footer', function() {
?>
<script>
document.addEventListener("DOMContentLoaded", function() {
wp.hooks.addAction(
// This is the action hook.
'experimental__woocommerce_blocks-checkout-set-active-payment-method',
// This is your unique plugin namespace.
'test-plugin-namespace',
function( payment_method ) {
// Log to console to demonstrate it working.
console.log(payment_method);
// Trigger API call.
window.wc.blocksCheckout.extensionCartUpdate( {
namespace: 'test-plugin-namespace',
data: {
payment_method: payment_method.value
}
} );
}
);
});
</script>
<?php
});
@senadir
Copy link

senadir commented Jul 2, 2024

Subscribing to the wc/store/payment is better than set-active-payment-method because it's also called on mount.

@senadir
Copy link

senadir commented Jul 2, 2024

Weirdly, the set-active-payment-method filter would give different payload depending if you selected a regular payment method (value) or a saved payment method paymentMethodSlug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment