How to Verify GST Numbers on Shopify Checkout
Validate business customers’ GSTINs during Shopify checkout using checkout UI extensions and a verification API.
The correct way to verify GST numbers on Shopify is a Checkout UI extension that collects the GSTIN paired with an app proxy that forwards it to your own backend for the actual API call — never calling a keyed verification API directly from the browser. If checkout-time validation is more than you need right now, verifying post-purchase via an order webhook is a simpler fallback.
Never call a keyed API from the storefront
Any JavaScript that runs in a Checkout UI extension or a theme is visible to the customer, which means
any API key embedded in it is visible too. For a GSTIN verification
API, that key is tied to your billing and your rate limit, so exposing it in the browser lets anyone
who opens dev tools burn your API credits or worse. The fix is architectural, not a matter of obfuscating
the key: the browser only ever talks to Shopify's own infrastructure (the extension and the app proxy),
and the actual call to gstinapi.com happens from your server, where the
X-API-Key header never leaves your infrastructure.
Plus versus non-Plus checkout customisation
It is worth being precise here rather than repeating the common assumption that GST validation at checkout requires Shopify Plus. Under Shopify's current checkout extensibility model, Checkout UI extensions — including custom input fields and validation messages — are available to stores on standard plans, not only Plus. What Plus adds on top is deeper structural control over the checkout (custom branding at a finer grain, and more extension points in some configurations), which most GST-verification use cases do not actually need. If your store is still on an older, unmigrated checkout, some of this may not apply — check your admin's checkout settings to confirm which model you are on before building against either assumption.
A Checkout UI extension plus an app proxy
The extension side collects the field and shows validation feedback. It calls your app proxy URL —
something like /apps/gst-verify/check — which Shopify routes to your backend:
// checkout UI extension (React-based, simplified)
import { reactExtension, TextField, useApplyAttributeChange } from '@shopify/ui-extensions-react/checkout';
export default reactExtension('purchase.checkout.block.render', () => );
function GstinField() {
const applyAttributeChange = useApplyAttributeChange();
async function verify(gstin) {
const res = await fetch('/apps/gst-verify/check?gstin=' + encodeURIComponent(gstin));
const data = await res.json();
if (data.valid) {
await applyAttributeChange({
type: 'updateAttribute',
key: 'verified_gstin',
value: gstin,
});
}
return data;
}
return (
verify(value)}
/>
);
}
The app proxy endpoint on your backend is where the real call happens, key included:
// your app backend, handling the proxied request from Shopify
app.get('/gst-verify/check', async (req, res) => {
const gstin = String(req.query.gstin || '').toUpperCase();
const upstream = await fetch(
`https://gstinapi.com/api/get-taxpayer-info/${gstin}`,
{ headers: { 'X-API-Key': process.env.GSTINAPI_KEY } }
);
if (upstream.status === 404) {
return res.json({ valid: false, reason: 'not_found' });
}
if (upstream.status !== 200) {
return res.status(502).json({ valid: false, reason: 'upstream_error' });
}
const data = await upstream.json();
return res.json({
valid: data.status === 'Active',
legalName: data.legalName,
status: data.status,
});
});
Storing the verified GSTIN in a metafield
Once the order lands, copy the verified GSTIN and legal name from the checkout attribute into a proper order metafield (and onto the customer record, if the buyer is a repeat B2B account), rather than leaving it only as a note attribute:
mutation {
metafieldsSet(metafields: [
{
ownerId: "gid://shopify/Order/1234567890",
namespace: "custom",
key: "verified_gstin",
type: "single_line_text_field",
value: "27AAACR5055K1Z7"
},
{
ownerId: "gid://shopify/Order/1234567890",
namespace: "custom",
key: "verified_legal_name",
type: "single_line_text_field",
value: "Reliance Industries Limited"
}
]) {
userErrors { field message }
}
}
Metafields are what your invoicing app, a Flow automation, or a CSV export will actually read from, so this step is what turns a one-off checkout validation into data you can build a B2B GST invoicing workflow on top of.
The alternative: verify after purchase via webhook
Checkout-time validation is the stronger pattern because it blocks a bad GSTIN before payment, but it is
also the more involved build — an extension, an app proxy, and metafield writes. A simpler alternative
that many smaller stores use instead is to collect the GSTIN as a plain checkout note attribute or a
post-purchase form, then verify it asynchronously when the orders/create webhook fires:
app.post('/webhooks/orders-create', async (req, res) => {
const order = req.body;
const gstin = order.note_attributes?.find(a => a.name === 'gstin')?.value;
if (gstin) {
const upstream = await fetch(
`https://gstinapi.com/api/get-taxpayer-info/${gstin}`,
{ headers: { 'X-API-Key': process.env.GSTINAPI_KEY } }
);
// write result to order metafields, flag for review if not Active
}
res.sendStatus(200);
});
The trade-off is honest: this catches a bad GSTIN after the sale, not before it, so it suits invoicing and record-keeping accuracy more than fraud prevention at the point of sale. It is also considerably faster to ship if you are not ready to build a checkout extension yet.
Which approach fits your store
Choose checkout-time verification when GSTIN correctness must block the order — high-value B2B sales where a bad number means a rejected invoice and a payment dispute. Choose the post-purchase webhook when you mainly need accurate records for GST invoicing and are comfortable following up manually on the rare mismatch. Either approach benefits from checking your existing customer base in bulk first — see the bulk GSTIN verification guide — and from understanding how to handle rate limits and retries if your store runs high order volumes.
Frequently asked questions
A note on accuracy. GST rules change often. This article reflects our understanding as of 30 August 2026 and is general information, not tax or legal advice. For the authoritative position, check gst.gov.in and cbic-gst.gov.in, or speak to a qualified tax professional about your specific situation.
Check a GSTIN right now, free
Five lookups a day, no account required. Status, filing history, e-invoicing and jurisdiction.
Free GST search toolBuild it into your product
One REST call, JSON back. Get an API key and 20 free verification credits in under a minute.
Start freeMore on developer integration guides
Browse every guide in the GST API blog.