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:

MetaMask Payment Gateway for WooCommerce
This is what happens when you click Connect wallet (Place order) button on your WooCommerce checkout page.

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.

MetaMask payment gateway enabled for WooCommerce
To enable our MetaMask payment gateway please go to WooCommerce > Settings > Payments.

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

selecting metamask payment gateway on WooCommerce checkout page
This is how it looks like on WooCommerce default checkout page with StoreFront theme installed.

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:

Add Ether currency in WooCommerce settings
Just go to WooCommerce > Settings and scroll to the very bottom of the page.

Connect to wallet and send transaction

First things first – please make sure that you have MetaMask extension installed in your browser.

MetaMask extension in Google Chrome

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.

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

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

Follow me on X