Shopify Integration Guide
This guide shows you how to integrate HempData API with a Shopify store to display compliance badges on product pages and automatically respond to regulation changes.
What You Can Do
- Compliance badge on product pages — Show visitors whether your product is legal in their state
- Age gate enforcement — Automatically prompt for age verification when required
- Shipping restrictions — Block checkout for prohibited states
- Regulation change alerts — Get notified when a state changes its rules and update your store accordingly
Part 1: Add the Compliance Widget to Product Pages
Step 1: Edit Your Theme
In your Shopify admin, go to Online Store > Themes > Edit code.
Open the product.liquid or main-product.liquid template (depends on your theme).
Step 2: Add the Widget Container
Find the "Add to Cart" button section and add the widget just above it:
{% comment %} HempData Compliance Widget {% endcomment %}
<div id="hempdata-widget" style="margin-bottom: 16px;"></div>
<script
src="https://cdn.hempdataapi.com/widget/v1/hempdata-widget.js"
data-api-key="pk_live_your_public_key"
data-substance="{{ product.metafields.hempdata.substance | default: 'cbd' }}"
data-product-type="{{ product.metafields.hempdata.product_type | default: 'edibles' }}"
data-auto-detect-state="true"
></script>
Step 3: Set Product Metafields
For each product, set metafields to identify the substance and product type. In Shopify admin, go to Settings > Custom data > Products and add:
| Namespace | Key | Type |
|---|---|---|
hempdata | substance | Single line text |
hempdata | product_type | Single line text |
Then set values on each product:
hempdata.substance=delta-9-thchempdata.product_type=edibles
Step 4: Disable Add to Cart for Prohibited States
Add this script after the widget:
<script>
document.getElementById('hempdata-widget').addEventListener('hempdata:loaded', function(e) {
if (e.detail.legal_status === 'prohibited') {
// Disable the add to cart button
var cartBtn = document.querySelector('[name="add"]') || document.querySelector('.product-form__submit');
if (cartBtn) {
cartBtn.disabled = true;
cartBtn.textContent = 'Not Available in Your State';
cartBtn.style.opacity = '0.5';
cartBtn.style.cursor = 'not-allowed';
}
}
});
</script>
Step 5: Style to Match Your Theme
#hempdata-widget {
--hd-badge-font-family: var(--font-body-family, sans-serif);
--hd-badge-border-radius: 4px;
--hd-badge-max-width: 100%;
--hd-green-bg: #16a34a;
--hd-yellow-bg: #ca8a04;
--hd-red-bg: #dc2626;
}
Part 2: Block Shipping to Prohibited States
Use Shopify's carrier-calculated shipping or a shipping profile with HempData to block orders to states where your products are prohibited.
Using a Shopify Function (Shopify Plus)
If you are on Shopify Plus, create a Delivery Customization function:
// extensions/delivery-customization/src/index.js
import { HempDataClient } from '@hempdataapi/sdk';
const client = new HempDataClient({ apiKey: process.env.HEMPDATA_API_KEY });
export default async function deliveryCustomization(input) {
const state = input.cart.deliveryGroups[0]?.deliveryAddress?.provinceCode;
if (!state) return { operations: [] };
// Check each line item
const operations = [];
for (const group of input.cart.deliveryGroups) {
for (const item of group.cartLines) {
const substance = item.merchandise.product.metafield?.value;
if (!substance) continue;
const result = await client.regulations.list({
state,
substance,
product_type: item.merchandise.product.productType,
});
if (result.data[0]?.legal_status === 'prohibited') {
// Hide all delivery options for this group
for (const option of group.deliveryOptions) {
operations.push({
hide: { deliveryOptionHandle: option.handle },
});
}
}
}
}
return { operations };
}
Without Shopify Plus
For standard Shopify plans, maintain a list of blocked states and use Shopify's built-in shipping zones. Use the HempData API to keep this list updated:
// scripts/update-shipping-restrictions.js
// Run daily via cron or on webhook events
const { HempDataClient } = require('@hempdataapi/sdk');
const client = new HempDataClient({ apiKey: process.env.HEMPDATA_API_KEY });
async function getProhibitedStates(substance, productType) {
const states = await client.states.list();
const prohibited = [];
for (const state of states.data) {
const regs = await client.regulations.list({
state: state.code,
substance,
product_type: productType,
});
if (regs.data.some(r => r.legal_status === 'prohibited')) {
prohibited.push(state.code);
}
}
return prohibited;
}
// Get prohibited states for Delta-9 edibles
getProhibitedStates('delta-9-thc', 'edibles').then(states => {
console.log('Blocked states:', states);
// Update your Shopify shipping zones via Admin API
});
Part 3: Webhook Alerts for Regulation Changes
Set up webhooks (Enterprise tier) to automatically update your store when regulations change.
Register the Webhook
curl -X POST "https://api.hempdataapi.com/v1/webhooks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"endpoint_url": "https://your-shopify-app.herokuapp.com/webhooks/hempdata",
"filters": {
"substances": ["delta-9-thc", "delta-8-thc", "cbd"],
"event_types": ["legal_status_changed"]
},
"description": "Shopify store shipping restriction updates"
}'
Handle the Webhook
const express = require('express');
const crypto = require('crypto');
const Shopify = require('@shopify/shopify-api');
const app = express();
app.post('/webhooks/hempdata', express.raw({ type: 'application/json' }), async (req, res) => {
// Verify signature
const signature = req.headers['x-hempdata-signature'];
const expected = crypto.createHmac('sha256', process.env.HEMPDATA_WEBHOOK_SECRET)
.update(req.body, 'utf8').digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature, 'hex'), Buffer.from(expected, 'hex'))) {
return res.status(401).send('Invalid signature');
}
res.status(200).send('OK');
const event = JSON.parse(req.body);
if (event.event_type === 'legal_status_changed') {
const state = event.jurisdiction.state;
const newStatus = event.after.legal_status;
console.log(`${state} changed to ${newStatus} for ${event.substance} ${event.product_type}`);
// Notify your team
await sendSlackAlert(event);
// If a state just prohibited a product, update shipping zones
if (newStatus === 'prohibited') {
await addStateToBlockedShipping(state);
}
// If a state just legalized a product, consider opening it up
if (newStatus === 'legal' || newStatus === 'legal_with_restrictions') {
await reviewStateForShipping(state);
}
}
});
Architecture Overview
Shopify Product Page
|
+-- HempData Widget (client-side)
| - Checks compliance for visitor's state
| - Shows badge + age gate
| - Disables cart if prohibited
|
+-- Shipping Restriction (server-side)
| - Blocks delivery to prohibited states
| - Updated via webhooks or daily sync
|
+-- Webhook Handler (server-side)
- Receives regulation change alerts
- Updates shipping zones
- Notifies team via Slack
Testing
- Test the widget — Use
data-state="TX"to force a specific state and verify all three badge colors appear correctly for your products. - Test the age gate — Use a THC product with
data-state="CO"to trigger the age verification modal. - Test shipping blocks — Create a test order with a Texas shipping address for a prohibited product.
- Test webhooks — Check the HempData dashboard for delivery logs after registering your endpoint.