Skip to content

Instantly share code, notes, and snippets.

@senadir
Last active April 8, 2024 12:31
Show Gist options
  • Save senadir/08161ef030c7e4daf2b2e6cbc3fb6dac to your computer and use it in GitHub Desktop.
Save senadir/08161ef030c7e4daf2b2e6cbc3fb6dac to your computer and use it in GitHub Desktop.
Add a field to Checkout block that can adds a fee to an order realtime.
let selectedValue = null;
wp.data.subscribe( () => {
// This is only needed for fields registered in Contact or Additional, address fields are always pushed and you can use other hooks.
const additionalFields = wp.data
.select( 'wc/store/checkout' )
.getAdditionalFields();
// Use the same id you used to register your field.
const donationAmount = additionalFields[ 'my-plugin/donation' ];
// We only want to update the cart when the value changes.
if ( donationAmount !== selectedValue ) {
// The default value is "", we want to use 0 if the field is empty.
selectedValue = donationAmount ?? 0;
// Use the same namespace you used in woocommerce_store_api_register_update_callback.
wc.blocksCheckout.extensionCartUpdate( {
namespace: 'my-plugin',
data: {
donation: selectedValue,
},
} );
}
}, 'wc/store/checkout' );
<?php
add_action(
'woocommerce_blocks_loaded',
function () {
// This will react to extensionCartUpdate and register the fee for the order (or remove it).
woocommerce_store_api_register_update_callback(
array(
'namespace' => 'my-plugin',
'callback' => function ( $data ) {
$donation = intval( sanitize_text_field( $data['donation'] ) );
wc()->session->set( 'my-plugin/donation', $donation );
},
)
);
add_action(
'woocommerce_cart_calculate_fees',
function () {
$donation = wc()->session->get( 'my-plugin/donation' );
if ( ! is_int( $donation ) ) {
return;
}
wc()->cart->add_fee( 'Donation', $donation );
}
);
// This will register a select at the Additional step, values are predefined here, you can also use a text field.
__experimental_woocommerce_blocks_register_checkout_field(
array(
'id' => 'my-plugin/donation',
'label' => 'Donate an amount?',
'location' => 'additional',
'type' => 'select',
'options' => array(
array(
'value' => '5',
'label' => '$5.00',
),
array(
'value' => '10',
'label' => '$10.00',
),
array(
'value' => '15',
'label' => '$15.00',
),
),
)
);
add_action(
'woocommerce_blocks_checkout_block_registration',
function () {
// Update the file path to the correct one.
wp_enqueue_script( 'my-plugin-donation-field', plugins_url( 'frontend.js', __FILE__ ), array( 'wp-data', 'wc-blocks-checkout' ), '1.0.0', true );
},
10,
0
);
// This makes sure that if the customer refresh the checkout page or tries to place an order again in the same session, no the same value is used.
add_action(
'woocommerce_blocks_checkout_enqueue_data',
function () {
wc()->session->set( 'my-plugin/donation', null );
}
);
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment