WooCommerce: Purchase Order Payment Gateway

Update: Version 1.1.5 released on 4th May 2021, on the plugin repository.

A recent project required the ability for customers on a client’s WooCommerce website to be able to request an invoice for their order (and thus pay offline) – but with the added twist that it required a Purchase Order number. This twist meant that simply changing the name of WooCommerce’s built-in “Offline” gateway was not enough.

I had a quick look around and found an existing plugin for WooCommerce that added this functionality, but as seems to be common when I do this, the functionality left a little bit to be desired.

First of all, the plugin required the customer to enter a postal address for the invoice (and curiously, didn’t automatically pull through the customer’s billing address) – I only needed a Purchase Order number field.

Additionally, it wasn’t very well internationalised – some strings were set as translated, but others – particularly in the HTML output that the plugin generated on the front-end and the admin back-end, were not.

So, I’ve taken it upon myself to learn a bit more about WooCommerce’s Payment Gateway API, and have written my own – which you can download below.

Plugin Features

  • Adds an offline payment gateway for WooCommerce with the name Purchase Order
  • Allows the administrator to set the plugin to ask for a Purchase Order number (or not) – and whether to make it mandatory if one is asked for
  • Has a setting that gets the plugin to ask for a postal address for the invoice to be sent to
  • Has another setting that, if an address is being asked for, will pre-fill the address with the customer’s billing address if they are logged in to WooCommerce during checkout
  • Adds the submitted Purchase Order details to the Edit Order screen in the WooCommerce back-end
  • Has full internationalisation (i18n) and localisation (l10n) support – so if you want to translate the plugin into your own language, please get in touch!


The gateway itself looks very straightforward – the screenshot below has the “ask for address” options turned off, though. When turned on, the plugin asks for a Contact Name, Company/Organisation, and an address (two lines, plus city, county and postcode).

In the WordPress back-end, Purchase Order information is shown under the General Details section on the Edit Order screen:


As with all WordPress plugins, you just need to drop the plugin folder into your wp-content/plugins folder and then activate the “GazChap’s WooCommerce Purchase Order Payment Gateway” plugin.


I’m using WordPress 4.9.4 and WooCommerce 3.2.6 – please let me know in the comments if it doesn’t work on other versions. I believe it requires at least WooCommerce 3.0.0.


Download the plugin from the WordPress Plugin Repository (5.2KiB Zip)


This plugin is open-source – view the source code on the GitHub repository.


How to enable checkbox lists for non-hierarchical taxonomies in WordPress


WooCommerce: getAddress.io Postcode Lookup


  1. Neil Coleclough


    Firstly, thank you for bringing your “Purchase Order Gateway” plugin to the World – it perfectly fits the bill for an ordering portal I’ve put together for some of our real-world customers to utilise. I wondered if you’d mind helping me out with something though. The end product of my portal is an email that lands with our sales team for keying into a standalone ERP system. I really need to find a way of including in that email, the customer’s purchase order number as entered in your plugin. Do you have any thoughts on how that might be achieved?

    Kind regards, and thanks again


    • gazchap

      Hi Neil – thanks for your kind words. This should be doable with a filter, similar to the one described here: https://docs.woocommerce.com/document/add-a-custom-field-in-an-order-to-the-emails/

      This should do it:

      add_filter( 'woocommerce_email_order_meta_fields', 'gazchap_purchase_order_gateway_email_order_meta_fields', 10, 3 );

      function gazchap_purchase_order_gateway_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
      ^t$po_data = maybe_unserialize( get_post_meta( $order->get_id(), '_gazchap_purchase_order', true ) );

      ^tif ( !empty( $po_data['number'] ) ) {
      ^t^t$fields['gazchap_po_number'] = array(
      ^t^t^t'label' => __( 'Purchase Order Number' ),
      ^t^t^t'value' => $po_data['number'],
      ^treturn $fields;

      I’ll also look at adding it to the plugin itself, good suggestion – thank you.

      • gazchap

        Replying to myself here, but the filter described in my comment below is no longer required as of the v1.1 update to the plugin just released.

        Ironically, because of a problem with the order in which I was saving the metadata to the order, the filter didn’t actually work in v1.0 anyway – at least, not until the order notification emails were resent through the admin panel.

        Thanks to Neil for making the request which led to this discovery, and the update that sprang from it.

  2. Reuben

    Hi there
    I’m surprised that there aren’t that many plugins that allow Woocommerce to purchase using a PO! Thanks for the plugin!

    I have an additional request! It really does make sense to have a PO gateway for off-line payment, and allow the buyer to UPLOAD THE PO. I have a client that sells to distributors, but they need the actual PO document to proceed with fulfilling the order. Is there a way to add a field to allow the buyer to use their PO number and also upload the actually PO? Thanks

    • gazchap

      Thanks for the feedback Reuben — that’s a great suggestion, I’ll see what I can do!

Leave a Reply

Your email address will not be published. Required fields are marked *

Privacy Policy & Powered by WordPress & Theme by Anders Norén