A custom payment gateway that works on the classic checkout can disappear completely when the store uses the block-based checkout. The gateway is enabled, the settings are saved, and nothing appears. This post covers what WooCommerce expects from a gateway before it will display it in the block version.
Why it disappears
The classic checkout renders gateways on the server using the gateway class. The block checkout is built on the client side, so it needs a JavaScript-side payment method registration as well as a PHP-side registration. A gateway that only has the PHP class is available on the server but has nothing to show in the block UI.
Step 1: Declare compatibility
Tell WooCommerce your plugin has been built for the cart and checkout blocks. Without this declaration, WooCommerce can flag the plugin as incompatible in the admin.
add_action( 'before_woocommerce_init', function () {
if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
'cart_checkout_blocks',
__FILE__,
true
);
}
} );
Only declare it once you have actually tested the block checkout. The declaration is a promise, not a switch that adds support.
Step 2: Register a block payment method on the PHP side
Create a class that extends WooCommerce Blocks' abstract payment method type, then register it when payment methods are being collected.
use Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType;
final class My_Gateway_Blocks_Support extends AbstractPaymentMethodType {
protected $name = 'my_gateway'; // Must match your gateway ID.
public function initialize() {
$this->settings = get_option( 'woocommerce_my_gateway_settings', array() );
}
public function is_active() {
return ! empty( $this->settings['enabled'] ) && 'yes' === $this->settings['enabled'];
}
public function get_payment_method_script_handles() {
wp_register_script(
'my-gateway-blocks',
plugins_url( 'build/blocks.js', __FILE__ ),
array( 'wc-blocks-registry', 'wp-element', 'wp-html-entities' ),
'1.0.0',
true
);
return array( 'my-gateway-blocks' );
}
public function get_payment_method_data() {
return array(
'title' => $this->settings['title'] ?? 'My Gateway',
'description' => $this->settings['description'] ?? '',
);
}
}
add_action( 'woocommerce_blocks_loaded', function () {
if ( class_exists( \Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType::class ) ) {
add_action(
'woocommerce_blocks_payment_method_type_registration',
function ( $registry ) {
$registry->register( new My_Gateway_Blocks_Support() );
}
);
}
} );
Treat this as a skeleton. Method names and data keys can change between versions, so check the current WooCommerce developer documentation for the exact signatures before shipping.
Step 3: Register the payment method on the JavaScript side
In the script you registered, call the registry function from the blocks registry, passing a name that matches the PHP side, a label, the content to show, an ariaLabel, and a canMakePayment callback that returns true when the method should be offered.
If canMakePayment returns false, or the script handle never loads, the method will not appear even though the PHP registration is correct.
Debugging checklist
- Does the gateway appear in the available list on the server? Use
WC()->payment_gateways()->get_available_payment_gateways() on staging to confirm. If it is absent, the problem is availability (currency, country, amount, settings), not blocks.
- Is the script handle loading? Open the Network tab and look for your blocks script on the checkout page.
- Any console errors? A failed registration usually logs one.
- Does the name match everywhere? The PHP
$name, the JavaScript registered name and the gateway ID should agree.
- Is something caching or delaying scripts? Exclude the checkout page from page caching and test with script delay and combine options turned off.
A fallback while you build it
If you need the gateway working today, replace the checkout block on the checkout page with a Shortcode block containing [woocommerce_checkout]. It switches the page to the classic checkout, which renders server-side gateways. Use it as a bridge, not a final answer.
For store owners reading this
If you are not the one writing the gateway, the practical version is: update the gateway plugin, check its documentation for block checkout support, and use the classic checkout temporarily if it has none.
I wrote a longer troubleshooting guide for store owners, covering setup gaps, currency limits, caching and plugin conflicts, here: https://amanurrahman.com/blog-post/woocommerce-payment-methods-not-showing-at-checkout
For a specific store, you can reach me at https://amanurrahman.com/hire-woocommerce-developer