Creating MetaMask Payment Gateway for WooCommerce
Recently I really enjoyed creating a tutorial about signing in to WordPress with MetaMask, so I decided to continue with this topic and today I will show you how you can create a payment gateway for WooCommerce that allows to pay with MetaMask extension.
I also would like to remind that I already have a complete payment gateway tutorial and additionally a tutorial about paying with crypto. So you can check them out as well.
And this how it is going to work on our WooCommerce store:

If you need some help with custom development, me and my team are here for you.
1. Creating a WooCommerce Payment Gateway
Let’s begin with creating a very simple payment gateway plugin for WooCommerce. If you need more details, I have an additional tutorial for that.
Here is the code:
<?php
/*
* Plugin Name: MetaMask Payment Gateway
* Author: Misha Rudrastyh
* Author URI: http://rudrastyh.com
* Version: 1.0
*/
add_filter( 'woocommerce_payment_gateways', function( $gateways ) {
$gateways[] = 'WC_Rudr_MetaMask_Gateway';
return $gateways;
} );
add_action( 'plugins_loaded', function() {
class WC_Rudr_MetaMask_Gateway extends WC_Payment_Gateway {
public function __construct() {
$this->id = 'rudr_metamask';
$this->icon = plugin_dir_url( __FILE__ ) . 'assets/metamask.svg';
$this->method_title = 'MetaMask Gateway';
$this->method_description = 'Description of MetaMask payment gateway';
$this->supports = array( 'products' );
$this->order_button_text = 'Connect wallet';
$this->init_form_fields();
$this->init_settings();
$this->title = $this->get_option( 'title' );
$this->enabled = $this->get_option( 'enabled' );
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'payment_scripts' ) );
}
public function init_form_fields(){
$this->form_fields = array(
'enabled' => array(
'title' => 'Enable/Disable',
'label' => 'Enable MetaMask Gateway',
'type' => 'checkbox',
'description' => '',
'default' => 'no'
),
'title' => array(
'title' => 'Title',
'type' => 'text',
'description' => 'Some description maybe.',
'default' => 'Pay with MetaMask',
'desc_tip' => true,
),
);
}
function payment_scripts() {
wp_enqueue_script(
'metamask-checkout',
plugin_dir_url( __FILE__ ) . 'assets/script.js',
array(),
time(), // prevents caching, remove on live version or use filemtime()
true
);
}
}
} );
Once you create and activate this plugin on your WooCommerce store, a new payment gateway should appear in WooCommerce > Settings > Payments.

Once you enable it, it will also be available on the WooCommerce checkout page.

Of course nothing is working at this moment, so let’s continue to the next step.
2. Paying for Order with MetaMask
Dealing with Currency
Today I am going to show you how you can make transactions with ether. And for the simplicity of this tutorial we will add it as a new currency to our WooCommerce store.
If you don’t want to add any cryptocurrencies or maybe you are going to accept many of them plus fiat currency, then you need to do some work with exchange API. Creating API calls with WordPress HTTP API is not exactly what I was going to show you in this tutorial, so, we will just register Ether currency with a filter hook.
add_filter( 'woocommerce_currencies', function( $currencies ) {
$currencies[ 'ETH' ] = 'Ether';
return $currencies;
} );
// currency symbol
add_filter( 'woocommerce_currency_symbol', function( $symbol, $code ) {
// symbol Ξ is nowhere to be used!
return 'ETH' === $code ? $code : $symbol;
}, 10, 2 );
Then do not forget to choose it in your WooCommerce store settings:

Connect to wallet and send transaction
First things first – please make sure that you have MetaMask extension installed in your browser.

Then we are going to do some work with script.js
file we included in the step before.
async function web3PayForOrder() {
// this string is a shame, but I just want to show you an example!
let orderTotal = jQuery( '.order-total' ).find( 'bdi' ).text().slice(0,-3).trim()
// my recommendation for you is to get order total and recepient address from the server via AJAX
let address = ( await ethereum.request({ method: 'eth_requestAccounts' }) )[0];
await ethereum.request( {
method: 'eth_sendTransaction',
params: [
{
from: address,
to: '0x939063925dAC7217F643E6A04c16d595Bf364359',
//value: ethers.utils.hexlify( ethers.utils.parseUnits("4.00","ether") ),
value: ethers.utils.parseEther( orderTotal )._hex,
},
],
} )
.then( ( txHash ) => {
jQuery( 'form.checkout' ).append( '<input type="hidden" id="txhash" name="txhash" value="' + txHash + '">' )
// submit WooCommerce checkout form manually
jQuery( '#place_order' ).click()
})
.catch( ( error ) => {
// do something on error
console.error(error);
} );
}
jQuery( function( $ ){
$( 'form.checkout' ).on( 'checkout_place_order', function() {
if( $( '#payment_method_rudr_metamask' ).is( ':checked' ) && ! $( '#txhash' ).length ) {
web3PayForOrder()
return false
} else {
return true
}
});
} );
The code above is quite simple and not ready to be used on production environment, but it is working and it is enough to show you some key moments in this tutorial.
- You can see that I am using jQuery here which is totally ok because it is included on WooCommerce checkout page anyway.
- Once you insert this code as is, you could probably get an error “ReferenceError: ethers is not defined”, it is because you have to include ethers library, you can do it in your project by
npm i ethers
and thenrequire( 'ethers' )
or add it as a standalone script withwp_enqueue_script()
function. We need this library because we can not just pass a number on line 14, we have to pass a hexed value of order total in Wei. - Once the transaction is successful
etherium.request
will return the transaction hash which we can pass to the form and add to the order in the next step
Additional validation
In this step I also recommend to perform transaction_hash
validation in case MetaMask payment method is selected.
You can read more about checkout fields validation in this tutorial.
Process the order
The final step is to process the order and redirect to the Thank you page.
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
// record a transaction hash in order meta
$order->add_meta_data( 'tx_hash', $_POST[ 'txhash' ] );
$order->save_meta_data();
// decide what order status you need
$order->update_status( 'processing' );
// empty cart
WC()->cart->empty_cart();
$order->payment_complete();
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order ),
);
}
I tried to keep it super-simple just in order to show you some key moment how it is supposed to work. Of course if you create your own MetaMask payment plugin there are a lot of more things to keep in mind.
Anyway, if you need some Web3 development for WordPress, feel free to contact me.

Misha Rudrastyh
Hey guys and welcome to my website. For more than 10 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