Calling the Shopify Storefront API from a WordPress Plugin

Shopify and WordPress are great 3rd party hosting providers. Shopify lets you quickly stand up a retail Website and WordPress is solid for putting together content oriented ones, like this one. So of course from time to time, if you use both, you will want to make a deeper integration between the two. In this post, I am going to cover the basics for exactly that; setting up a WordPress plugin that interacts with the Shopify Storefront API; this plugin will let you make custom retail experiences on your WordPress site that go well beyond what liquid, Shopify’s template engine, can support while at the same time still leveraging Shopify for inventory and order management.

A WordPress plugin is where you want to do this kind of integration work. It is possible to bake this functionality directly into a theme, though, that doesn’t make a lot of sense in my opinion. It is just easier to encapsulate these kinds of integrations as plugins and then you can use them in any WordPress theme you choose.

Step 1: Setup your dev environment

To follow along here, you will need a Shopify development site. You can create as many of those for free. You can add some products to its catalog if you want but that is entirely optional for this tutorial. Doing so, however, will let you better explore the functionality of the Storefront API so it isn’t a bad idea once you have completed the steps here.

Next you should setup a development instance of WordPress. You can do that remotely with a hosting provider or you can setup WordPress locally. Local setup is my preference; you can just do things a lot faster locally. I use a Mac for development so my setup involves a MAMP environment. WordPress has instructions for that here. It is largely straightforward. Once you have MAMP up and running, download and install WordPress in the directory that your MAMP environment uses for hosting content. This tutorial is written for version 5.3.

Step 2: Create a WordPress plugin

WordPress plugin development is fortunately very easy. It can certainly get complex in a hurry, though, that is more related to the functionality that you may want to incorporate. Plugins really just boil down to some PHP with a touch of organization. The documentation is here but you can look at it later. We’re going to make a simple plugin called hello-tech. I would typically go for the standard hello-world but someone has already published a plugin with that name to the WordPress marketplace.

In your WordPress install directory, create a new plugin directory:
wp-content/plugins/hello-tech

The directory wp-content/plugins should already exist. If it doesn’t, you might be looking in the wrong spot in your WordPress install or there is something wrong with your install. hello-tech is the name of your plugin. In this new directory, create a new file call hello-tech.php. It is a good practice to name your PHP file after your plugin. In order for this file to be recognized as a plugin it needs to start with a WordPress plugin header. This header can have information about the plugin, its maintainers, and its license. However, for this tutorial let’s keep it simple and use with the following:

<?php
/**
 * Plugin Name: Hello Tech
 */

That is all your plugin needs for you to see it in the WordPress admin dashboard. It doesn’t have any functionality but you can still activate it; do that now by clicking on activate. Now we’re ready to add some functionality. Update hello-tech.php to be the following:

<?php
/**
 * Plugin Name: Hello Tech
 */
function helloTech() {
    return '<strong>hello tech</strong>'; 
}
add_shortcode('hello-tech', 'helloTech');

The above snippet does 2 things. First it creates a function called helloTech that returns an HTML snippet. Second it registers a new shortcode, hello-tech, that uses it. Shortcodes are a quick way to incorporate plugin functionality into a WordPress site. If you add [hello-tech] to the contents of any page on your site, you will see hello tech appear. There are other methods for triggering plugin functionality but we are going to stick with shortcodes for now.

Step 3: Create a Storefront Access token

You need an access token to send Storefront requests. The steps for generating a token are here.

Essentially you need to create a new private app that at least has read access to some of your store data. For this tutorial, I set the private app name to be Hello Tech. You don’t need to worry about Admin API access; you can disable all of those permissions. At the bottom of the private app settings page is where you will find the Storefront API options. Don’t forget to enable access.

Step 4: Send a Storefront API request

With the access token you can now issue Storefront API requests. Update your plugin to look like the following. Swap STORE_NAME and ACCESS_TOKEN for your Shopify store name and Storefront access token:

<?php
/**
 * Plugin Name: Hello Tech
 */
function helloTech() {
    $store_name = 'STORE_NAME';
    $access_token = 'ACCESS_TOKEN';
    $query = <<<'GRAPHQL'
    query {
        shop {
            name
            primaryDomain {
                url
                host
            }
        }
    }
    GRAPHQL;
    
    $storefront_response = wp_remote_post(
        'https://'.$store_name.'.myshopify.com/api/2019-07/graphql.json', 
        array(
            'method' => 'POST',
            'timeout' => 30,
            'blocking' => true,
            'httpversion' => '1.1',
            'headers' => array(
                'Accept' => 'application/json',
                'Content-Type' => 'application/json; charset=utf-8', 
                'X-Shopify-Storefront-Access-Token' => $access_token
            ),
            'body' => json_encode(['query' => $query, 'variables' => '']),
        )
    );

    $storefront_json = json_decode($storefront_response['body'], true);
    return '<strong>hello tech</strong><br /><br />'. 
        '<code>'.$storefront_response['body'].'</code><br /><br />'.
        '<code>'.$storefront_json['data']['shop']['name'].'</code>'; 
}
add_shortcode('hello-tech', 'helloTech');

The above plugin issues a request to get your store name, URl, and host. It is basically a hello world Storefront query that you can use to make sure your access token and plugin are working. For more information on the Storefront API and to develop queries that meet your use cases, have a look at the reference documentation.

Step 5: Move the Storefront API key into plugin settings

Our plugin now issues Storefront API requests and displays the results on a page via shortcode. Our store name and access token, however, are hard coded into the plugin. Let’s do a final touch and move those configurations to a custom settings page.

First, let’s create a separate PHP file to contain our custom settings page. Update hello-tech.php to have these 2 lines at the top to require a new file called hello-tech-settings.php:

define( 'HELLO_TECH__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );

require_once( HELLO_TECH__PLUGIN_DIR . 'hello-tech-settings.php' );

In the hello-tech plugin directory, create the file hello-tech-settings.php. Forewarning, these custom settings pages are a little verbose. The WordPress Codex provides a decent tutorial on them and you can also look at the reference documentation. They do suggest using arrays to store key/values if you are dealing with a lot of options but since we only have two, we’re going to skip that optimization. Set the contents of hello-tech-settings.php to the following:

<?php

function hello_tech_plugin_admin_init(){
    register_setting( 'hello_tech_options', 'hello_tech_shopify_store_name', 'noop_validator' );
    register_setting( 'hello_tech_options', 'hello_tech_storefront_access_token', 'noop_validator' );
    add_settings_section('hello_tech_main', 'Shopify Settings', 'hello_tech_shopify_section_text', 'hello_tech_plugin');
    add_settings_field('hello_tech_shopify_store_name', 'Shopify Store Name', 'hello_tech_shopify_store_name_setting', 'hello_tech_plugin', 'hello_tech_main');
    add_settings_field('hello_tech_storefront_access_token', 'Storefront Access Token', 'hello_tech_storefront_access_token_setting', 'hello_tech_plugin', 'hello_tech_main');
}
add_action('admin_init', 'hello_tech_plugin_admin_init');

function hello_tech_shopify_section_text() {
    echo '<p>Please set the Shopify store name and Storefront access token.</p>';
}

function hello_tech_shopify_store_name_setting() {
    $shopify_store_name = get_option('hello_tech_shopify_store_name');
    echo "<input id='hello_tech_shopify_store_name' name='hello_tech_shopify_store_name' size='40' type='text' value='{$shopify_store_name}' />";
}

function hello_tech_storefront_access_token_setting() {
    $storefront_access_token = get_option('hello_tech_storefront_access_token');
    echo "<input id='hello_tech_storefront_access_token' name='hello_tech_storefront_access_token' size='40' type='text' value='{$storefront_access_token}' />";
}

function noop_validator($input) {
    return $input;
}

function hello_tech_plugin_menu() {
	add_options_page('Hello Tech Options', 'Hello Tech', 'manage_options', 'hello-tech-settings', 'hello_tech_options');
}
add_action('admin_menu', 'hello_tech_plugin_menu');

function hello_tech_options() {
	if ( !current_user_can('manage_options') )  {
		wp_die(__('You do not have sufficient permissions to access this page.'));
    }
?>
	<div class="wrap">
        <h2>Hello Tech</h2>
        <form action="options.php" method="post">
<?php
    settings_fields('hello_tech_options');
    do_settings_sections('hello_tech_plugin');
 ?>
            <input name="Submit" type="submit" value="<?php esc_attr_e('Save Changes') ?>" />
        </form>
	</div>
<?php
}

If you look in Settings in the admin dashboard, you should see a new entry for “Hello Tech”. Click it and you will see a basic settings page with a two field form asking for your Shopify store name and Storefront access token. Enter in those values and click “Save Changes”.

Next update your plugin to use those two options with the get_option function instead of the hard coded values. hello-tech.php should look like the following:

<?php
/**
 * Plugin Name: Hello Tech
 */

define( 'HELLO_TECH__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );

require_once( HELLO_TECH__PLUGIN_DIR . 'hello-tech-settings.php' );

function helloTech() {
    $store_name = get_option('hello_tech_shopify_store_name');
    $access_token = get_option('hello_tech_storefront_access_token');
    $query = <<<'GRAPHQL'
    query {
        shop {
            name
            primaryDomain {
                url
                host
            }
        }
    }
    GRAPHQL;
    
    $storefront_response = wp_remote_post(
        'https://'.$store_name.'.myshopify.com/api/2019-07/graphql.json', 
        array(
            'method' => 'POST',
            'timeout' => 30,
            'blocking' => true,
            'httpversion' => '1.1',
            'headers' => array(
                'Accept' => 'application/json',
                'Content-Type' => 'application/json; charset=utf-8', 
                'X-Shopify-Storefront-Access-Token' => $access_token
            ),
            'body' => json_encode(['query' => $query, 'variables' => '']),
        )
    );

    $storefront_json = json_decode($storefront_response['body'], true);
    return '<strong>hello tech</strong><br /><br />'. 
        '<code>'.$storefront_response['body'].'</code><br /><br />'.
        '<code>'.$storefront_json['data']['shop']['name'].'</code>'; 
}
add_shortcode('hello-tech', 'helloTech');

Closing thoughts

This tutorial walks you through creating a WordPress plugin that makes calls to Shopify’s Storefront API. You can also use it as a template for making other plugins that issue REST calls to a 3rd party API with relatively little effort. Once you can make that all important request and get back a response, then all you have to do is work it into a reasonable UX for your users.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: