Skip to main content

How to use order metafields in your theme

Order metafields are not supported by the BigCommerce GraphQL Storefront API. The alternative is the REST Management API.

Do not call the Management API directly from the storefront because this could expose sensitive information to unauthorised users. The usual solution is a middleware service that accepts a metafield request with a current customer JWT and returns the order metafields to the theme.

Metafields Manager provides this middleware for subscribers.

Order metafields API

Subscribers can call an endpoint from the order detail page to fetch order metafields when the page loads.

Endpoint

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

Params

  • store_hash
    • Your store hash, visible in your BigCommerce admin URL.
  • jwt
  • order_id
    • The ID of the order whose metafields you want to load.

Example code

Add this JavaScript to templates/pages/account/orders/details.html:

info

Replace your-store-hash with your BigCommerce store hash.

<script type="text/javascript">
const storeHash = 'your-store-hash';
const appClientId = 'c0s7a28bku7ij79qte07ibtdedu619x'; // Metafields Manager client ID
const queryParams = new URLSearchParams(window.location.search);
const orderId = queryParams.get('order_id');

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

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

return await response.text();
}

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

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

return await response.json();
}

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

// 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 formattedMetafields = metafields.data.map(function (metafield) {
const capitalisedKey = metafield.key.charAt(0).toUpperCase() + metafield.key.slice(1);
const capitalisedKeyWithSpaces = capitalisedKey.replaceAll('_', ' ');
return `<dt class="definitionList-key">${capitalisedKeyWithSpaces}</dt>
<dd class="definitionList-value">${metafield.value}</dd>`
});

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

useOrderMetafields(storeHash, appClientId, orderId).catch(console.error);
</script>

Once this is working, you can move the code into a JavaScript file such as assets/js/theme/account.js. You may need small adjustments, including injecting the store hash and order ID into jsContext.