Integration guide 7 min read

How to Verify GST Numbers on Shopify Checkout

Validate business customers’ GSTINs during Shopify checkout using checkout UI extensions and a verification API.

Written and reviewed by the GSTIN API team Last reviewed

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

Yes, using a Checkout UI extension to collect the GSTIN and an app proxy that forwards it to your own backend, which calls the verification API. The extension itself must never hold or call a keyed API directly, since its JavaScript runs in the customer's browser.
No. Checkout UI extensions for collecting additional information at checkout are available on all Shopify plans as of the current checkout extensibility model. Shopify Plus adds deeper checkout customisation (custom checkout pages, checkout.liquid-era flexibility on older setups), but a standard custom field plus validation does not require Plus.
An app proxy is a Shopify feature that forwards a request from the storefront or checkout to your own server under a URL on your store's domain. It lets the checkout extension call "your backend" without ever exposing your GST verification API key to the browser — the key stays server-side, on your app.
Yes — listen for the orders/create webhook, pull the GSTIN from order or customer metafields/note attributes, verify it server-side, and update the order or flag it for review. This is simpler to build than checkout-time validation but means a bad GSTIN is only caught after the sale, not before.
As a metafield on the order (and optionally mirrored onto the customer record), namespaced clearly, e.g. custom.verified_gstin and custom.verified_legal_name, so your invoice app or export can read it without parsing note attributes.

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 tool

Build it into your product

One REST call, JSON back. Get an API key and 20 free verification credits in under a minute.

Start free