How to Integrate Custom Payment Gateways with WooCommerce Checkout Block
On my blog you can find a complete tutorial about creating a WooCommerce payment gateway but in the latest versions of WooCommerce (since 8.3 I guess) you may notice that your custom payment method isn’t available in the Checkout block.
For example if you try to deactivate all the payment methods except your custom one on your store, you’ll probably get an error message like this:

But for sure everything is working great when you’re using a legacy [woocommerce_checkout] shortcode.
Yes, it seems like my complete payment gateway tutorial isn’t that complete anymore, but we’re about to change it today by this extra tutorial where I guide you step by step what you should do in order to add the compatibility of your custom WooCommerce payment method for the WooCommerce Cart and Checkout blocks.
That’s what we’re going to achieve by end of this tutorial:

Sure thing, I will also show you some neat extra stuff like adding a custom icon for your payment method.
Server-Side Integration
First things first, let’s begin with the server-side integration, I am pretty sure that many of you guys feel more comfortable developing with PHP than JavaScript + React, so let’s start with simple things.
Registering a block support PHP class
“Block support PHP class” is the PHP class in addition to the main payment gateway class. We are about to register it with the simple code snippet below, kind of similar to what we did when registered our main gateway class in woocommerce_payment_gateways hook.
add_action( 'woocommerce_blocks_loaded', 'rudr_gateway_block_support' );
function rudr_gateway_block_support() {
// if( ! class_exists( 'Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType' ) ) {
// return;
// }
// here we're including our "gateway block support class"
require_once __DIR__ . '/includes/class-wc-misha-gateway-blocks-support.php';
// registering the PHP class we have just included
add_action(
'woocommerce_blocks_payment_method_type_registration',
function( Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry ) {
$payment_method_registry->register( new WC_Misha_Gateway_Blocks_Support );
}
);
}Keep in mind the following:
- I commented
class_exists()condition because we don’t need it anymore since the checkout block is a part of WooCommerce now and not a standalone plugin. - Our block support PHP class itself is going to be in a separate file which is
class-wc-misha-gateway-blocks-support.phpand we’ll take a look at it in the next step.
Block support PHP class
In this part I am creating a WC_Misha_Gateway_Blocks_Support PHP class which extends the the WooCommerce class AbstractPaymentMethodType. At the same time don’t forget that we already have WC_Misha_Gateway which extends WC_Payment_Gateway.
In my case I put it into includes/class-wc-misha-gateway-blocks-support.php.
<?php
use Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType;
final class WC_Misha_Gateway_Blocks_Support extends AbstractPaymentMethodType {
private $gateway;
protected $name = 'misha'; // payment gateway id
public function initialize() {
// get payment gateway settings
$this->settings = get_option( "woocommerce_{$this->name}_settings", array() );
// you can also initialize your payment gateway here
// $gateways = WC()->payment_gateways->payment_gateways();
// $this->gateway = $gateways[ $this->name ];
}
public function is_active() {
return ! empty( $this->settings[ 'enabled' ] ) && 'yes' === $this->settings[ 'enabled' ];
}
public function get_payment_method_script_handles() {
wp_register_script(
'wc-misha-blocks-integration',
plugin_dir_url( __DIR__ ) . 'build/index.js',
array(
'wc-blocks-registry',
'wc-settings',
'wp-element',
'wp-html-entities',
),
null, // or time() or filemtime( ... ) to skip caching
true
);
return array( 'wc-misha-blocks-integration' );
}
public function get_payment_method_data() {
return array(
'title' => $this->get_setting( 'title' ),
// almost the same way:
// 'title' => isset( $this->settings[ 'title' ] ) ? $this->settings[ 'title' ] : 'Default value';
'description' => $this->get_setting( 'description' ),
// if $this->gateway was initialized on line 15
// 'supports' => array_filter( $this->gateway->supports, [ $this->gateway, 'supports' ] ),
// example of getting a public key
// 'publicKey' => $this->get_publishable_key(),
);
}
//private function get_publishable_key() {
// $test_mode = ( ! empty( $this->settings[ 'testmode' ] ) && 'yes' === $this->settings[ 'testmode' ] );
// $setting_key = $test_mode ? 'test_publishable_key' : 'publishable_key';
// return ! empty( $this->settings[ $setting_key ] ) ? $this->settings[ $setting_key ] : '';
//}
}First of all let’s take a look at class properties and methods.
Properties:
$name– this is a payment gateway ID from this step.$gateway– we can store an instance of the payment gateway object here, but it is not like a required thing, so I commented this part in my code.
Methods:
is_active(),get_payment_method_script_handles()– that’s where we include a JavaScript file which contains the client-side part of the integration.get_payment_method_data()– provide all the necessary data you’re going to use on the front-end as an associative array.
You can also use index.asset.php to get a script version and dependencies from.
public function get_payment_method_script_handles() {
$asset_path = plugin_dir_path( __DIR__ ) . 'build/index.asset.php';
$version = null;
$dependencies = array();
if( file_exists( $asset_path ) ) {
$asset = require $asset_path;
$version = isset( $asset[ 'version' ] ) ? $asset[ 'version' ] : $version;
$dependencies = isset( $asset[ 'dependencies' ] ) ? $asset[ 'dependencies' ] : $dependencies;
}
wp_register_script(
'wc-misha-blocks-integration',
plugin_dir_url( __DIR__ ) . 'build/index.js',
$dependencies,
$version,
true
);
return array( 'wc-misha-blocks-integration' );
}Declare compatibility
This part is usually useful when you would like to let your users know that your payment method is not compatible with the WooCommerce Checkout block.
Users will be notified about it when they try to edit the Checkout page in Gutenberg:

And here is how to do that:
add_action( 'before_woocommerce_init', 'rudr_cart_checkout_blocks_compatibility' );
function rudr_cart_checkout_blocks_compatibility() {
if( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
'cart_checkout_blocks',
__FILE__,
false // true (compatible, default) or false (not compatible)
);
}
}Client-Side Integration
Setting up a project
Once again, I would like to keep the things super-simple in this tutorial, so I am just going to use @wordpress/scripts and that’s all.
In our build for sure you can go further and configure WooCommerce hybrid build, so you can use import { registerPaymentMethod } from ....
That’s how my folder structure looks like:

Register a custom payment method for WooCommerce Checkout Block
Below is the /src/index.js file in case you have doubts.
import { decodeEntities } from '@wordpress/html-entities';
const { registerPaymentMethod } = window.wc.wcBlocksRegistry
const { getSetting } = window.wc.wcSettings
const settings = getSetting( 'misha_data', {} )
const label = decodeEntities( settings.title )
const Content = () => {
return decodeEntities( settings.description || '' )
}
const Label = ( props ) => {
const { PaymentMethodLabel } = props.components
return <PaymentMethodLabel text={ label } />
}
registerPaymentMethod( {
name: "misha",
label: <Label />,
content: <Content />,
edit: <Content />,
canMakePayment: () => true,
ariaLabel: label,
supports: {
features: settings.supports,
}
} )Probably it’d be a great idea to talk about registerPaymentMethod() in details and also about registerExpressPaymentMethod(), but I think we’re going to take a deeper look on a specific examples in the next tutorials on my blog.
Finally! 🎉

In case you’re wondering where the payment method title and description come from:

Add a payment method icon
Since I promised you more examples and probably you don’t want to wait till the next tutorials, so let’s start with this one.
My goal right now is to display an icon near my custom payment gateway title in the WooCommerce Checkout block:

First of all let’s modify our block support PHP class, specifically its get_payment_method_data(), we’re just about to provide one more parameter there:
public function get_payment_method_data() {
return array(
'title' => $this->get_setting( 'title' ),
'description' => $this->get_setting( 'description' ),
'icon' => plugin_dir_url( __DIR__ ) . 'assets/icon.png',
...Then I recommend to create another React component for it:
const Icon = () => {
return settings.icon
? <img src={settings.icon} style={{ float: 'right', marginRight: '20px' }} />
: ''
}
const Label = () => {
return (
<span style={{ width: '100%' }}>
{label}
<Icon />
</span>
)
}If the icon image URL isn’t provided, <img> tag won’t be displayed, great!
Misha Rudrastyh
Hey guys and welcome to my website. For more than 15 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me
the latest update confused me a lot , thanks for sharing.
Great tutorial, help me a lot in my study. If wasn’t you I will be lost.
Very nice tutorial, helped me a lot… but.. can you please expand on the front-end project setup? I am not familiar with React so I struggled a lot to set up that project. Also, you say you use @wordpress/scripts, but in the code I see you use @wordpress/html-entities?
Hi Steve, you can just start doing it step by step and you will figure it out
Great tutorial, thanks!!!
Do you have the complete source for I take a look?
Haven’t started yet. But the topic is fireeee, as I needed. Thanks a lot.
Great tutorial, thanks!!!
Great tutorial,
How to do single product checkout in woocommerce programmatically
I mean add checkout fields (name, address, phone), payment options and place order button to the single product page
Thanks
Hi, thanks for the tutorial
i want to know if have option to handle the validation of the checkout with blocks
or way to show errors of the payment gateway on the blocks checkout
now when have error its show some custom message like this “Something went wrong. Please contact us to get assistance.”
This is a bug that should be fixed soon, Ideally you should do validation on your process_payment function.
https://github.com/woocommerce/woocommerce/issues/46926
Hi! Great tutorial, but I have a problem to add to Block form with credit card number field. Can we get to this via Gutenberg?
Assuming you got the above code working fine, you should be able to still render whatever fields you want using React.
Yeah, that’s about right. But I can’t get the custom field data to be included in the post request when the “Place Order” button is clicked.
Hey Misha! Great article.
Are you planning to post a full article mixing the WC_Misha_Gateway in the other article and this one?
Would be nice to have the whole process or a repo to follow and create the Payment Gateway and use it also with blocks!
Thank you.
Hey Daniel, thank you!
Maybe;)
Hey Misha! Great article.
I was wondering if we can add custom field too with blocks! I want to pass some custom input value from user to payment gateway. Is it possible?
You can render any field you want within “const Content = () => { //here };”.
Currently, I can display custom fields on the checkout page but I’m struggling to pass the values to the POST request so I can process them further. I have all name, id attributes on my inputs but still no luck. Did anyone try this?
Hi David,
Thanks for respond. Yes I’ve tried similar, like you said getting same issue while trying to fetch value from custom field. I’ve tried $_REQUEST, $_POST as well pass value to add_action functions and tries to get $data. Getting null value for all of them. Still no luck :(
Do you have an update on this? thanks
Hello, can we get a full plugin code example ?
I try to follow your guide without success.
I cant have Woocommerce block compatibility :(
Thanks
Hello Seb,
Thank you for your comment! Currently there is no code example on GitHub or something.
Hello Misha, thank you for responding.
My displayed payment method is still not compatible with the Woocommerce block.
I’ve already included the line to declare compatibility.
Is there another important parameter to declare?
Finally, i find this dummy example which help me : https://github.com/woocommerce/woocommerce-gateway-dummy/tree/master
I was good in the last tutorial, but here I got lost after the part where the index.asset.php file is created
I didn’t understand about including React, the payment gateway doesn’t work either, it says it doesn’t exist
Has anyone figured out a way to pass values from an input field to the server side? I have a phone number that I would like to pass to the backend, but not sure as my code won’t work.
Hi,
Thanks for sharing your works!
I don’t understand how you generate the build/index.js file and what it contains?
Thanks for your help
Thanks but hard to find the latest documentation for woocommerce checkout block js components. Any idea where it is because i need to find the function to get the selected payment method when using the checkout block?
Hi Misha,
I hope you’re doing well.
I’ve been following your blog as always—your posts are incredibly insightful, thank you for sharing your knowledge so generously.
I’m currently looking into converting a classic WooCommerce payment gateway to the new block-based checkout system. Specifically, I’m not referring to redirect-based gateways, but rather a self-hosted credit card checkout that works directly within the block-based flow.
I’ve gone through the WooCommerce documentation and reviewed the Stripe block integration, but I’m still struggling to get a clear understanding of how to make an existing payment gateway compatible with the blocks system.
Have you worked on something like this before or do you happen to have an example you could share? I’d really appreciate any guidance or direction.
Looking forward to your response!
Hey Ahir,
Thank you for your question! At this moment our team is handling all the stuff with payment gateways for clients. I had some experience as well, however, couldn’t find time yet to wrap it all in a course or a tutorial…
Nice tutorial, very helpful… Thank you