How to use order metafields in your theme

Unfortunately, order metafields are not supported by BigCommerce GraphQL storefront API. The only way to access them is through the REST management API.  

You should not make requests directly to the Management API from the storefront because this would leak sensitive information to unauthorised users. The appropriate way to access order metafields would be to create a middleware service that accepted a request for metafields along with a current customer JWT and then ferried order metafields back to the theme.

This is a hassle, so we've built it for you. 

Our Order Metafields API

For Metafield Manager subscribers, our app now offers an endpoint so that you can add JavaScript to your order detail page to fetch these metafields on page load. 

Endpoint

https://metafields.space48apps.com/api/storefronts/{{store_hash}}/customers/{{jwt}}/orders/{{order_id}}/metafields

Params

  • store_hash
    • Your store identify, visible in the URL of your BigCommerce admin are
  • jwt
  • order_id
    • The ID of the order that you wish to load metafields for.

Example code

As an example, this JavaScript can be added to  templates/pages/account/orders/details.html

Replace me

Note that you will need to add your store hash to this code. Search for "REPLACE ME".

<script type="text/javascript">
    const store_hash = '%% REPLACE ME %%'; // Replace with your store hash
    const app_client_id = 'c0s7a28bku7ij79qte07ibtdedu619x'; // Metafields Manager Client ID
    const query_params = new URLSearchParams(window.location.search);
    const order_id = query_params.get('order_id');

    const fetchCustomerJWT = async (app_client_id) => {
        const response = await fetch('/customer/current.jwt?app_client_id=' + app_client_id);

        if (!response.ok) {
            if (response.status === 404) {
                return new Error('Customer not logged in.');
            }
            return new Error('Unable to identify customer');
        }

        return await response.text();
    }

    const fetchOrderMetafields = async (store_hash, jwt, order_id) => {
        const response = await fetch("https://metafields.space48apps.com/api/storefronts/" + store_hash + "/customers/" + jwt + "/orders/" + order_id + "/metafields");

        if (!response.ok) {
            if (response.status === 404) {
                return new Error(response?.data?.error || "Sorry, no match found.");
            } else if (response.status === 402) {
                return new Error(response?.data?.error || "A subscription to Metafields Manager is required to perform this action.");
            }
            return new Error('Unable to fetch metafields');
        }

        return await response.json();
    }

    const useOrderMetafields = async (store_hash, app_client_id, order_id) => {
        const jwt = await fetchCustomerJWT(app_client_id);
        if (!jwt.length) { throw new Error('Unable to fetch JWT'); }
        const metafields = await fetchOrderMetafields(store_hash, jwt, order_id);

        // Do whatever you would like to do with metafields here, e.g. add to the page.
        console.log("Metafields: \n");
        console.table(metafields.data);

        // For example, add them to the order details sidebar block.
        const formatted_metafields = metafields.data.map(function (metafield) {
            const capitalisedKey = metafield.key.charAt(0).toUpperCase() + metafield.key.slice(1);
            const capitalisedKeyWithSpaces = capitalisedKey.replace('_', ' ');
            return `<dt class="definitionList-key">${capitalisedKeyWithSpaces}</dt>
                    <dd class="definitionList-value">${metafield.value}</dd>`
        });

        const orderDetailsBlock = document.querySelector('.account-sidebar-block .definitionList');
        orderDetailsBlock.innerHTML += formatted_metafields.join("\n");
    }

    try {
        useOrderMetafields(store_hash, app_client_id, order_id);
    } catch (e) {
        console.log(e);
    }
</script>

Once this is working, it would be reasonable to want to move this code into the a JS file, e.g the assets/js/theme/account.js. It would likely need some small adjustments to achieve this. Notably, the injection of the store hash and order ID into the jsContext so these can be accessed.

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us