Shopify

How the Shopify app gates checkout through a Checkout UI Extension, where the API key lives, how to scope which products are checked, and the order-level backstop.

Last updated: 2026-09-04

The Shopify app adds a verification step to checkout through a Checkout UI Extension, backed by the app's own server. The extension renders in Shopify's sandboxed checkout; the app server holds your API key and does all the talking to the verification API.

It is one of three integrations — see also WooCommerce and the JavaScript widget. They are alternatives; choose the one that matches your storefront.

How the pieces fit

A checkout extension runs sandboxed on Shopify's own domain and cannot be trusted with a secret. So the flow has three hops rather than two:

  1. The extension asks the app server to start a verification, authenticating with the Shopify session token Shopify issues it.
  2. The app server attaches your x-merchant-api-key and calls the eIDAS Pro API.
  3. The verdict comes back the same way: the app server reads the authenticated result endpoint and hands the extension a boolean.

Your key never enters the extension, the checkout page, or the shopper's browser. The storefront cart gate uses Shopify's App Proxy instead, which is same-origin, and the checkout extension uses the session-token path — two mechanisms because Shopify's sandbox blocks the extension from calling the proxy cross-origin.

1. Install the app

Install the app on your store from your Shopify Partner organisation, and open Apps → eIDAS Verification Settings in your Shopify admin.

2. Connect your API key

SettingWhat to put in it
Enable eIDAS VerificationThe master switch. Leave off until the rest is set.
Backend API URLThe verification API base URL, for example https://api.eidas-pro.com.
Merchant API KeyThe key from your merchant dashboard. Stored server-side against your shop.

See API keys for how to create and rotate one, and billing for why a genuine key can still be refused.

The settings banner reads a merchant-subscription endpoint

The settings screen summarises your plan by calling GET /api/merchant/subscription, which the production API serves. If it still shows "couldn't verify API key" for a key you know is good, judge the key by whether a verification call answers 401 instead, and read your plan and usage in the merchant dashboard, which is authoritative for both.

3. Choose which products are gated

Apply verification to takes one of three scopes:

  • All products — every checkout is gated.
  • Specific collections — only carts containing a product in the listed collections.
  • Specific product tags — only carts containing a product carrying one of the listed tags.

The scope check runs on the app server against Shopify's Admin API, and it fails safe: if the check cannot be completed — a malformed request, a transient Shopify error — the cart is treated as in scope and gated. You will see an unnecessary verification prompt before you ever see an ungated age-restricted order.

Collections and tags are the two scopes that let a store gate one product line without asking every shopper to verify, which is usually what you want.

4. Choose what happens around it

  • Verification method — which family of identity method to request. The eID option routes to bank or government electronic identity. The EU wallet option is a preview and is not a live capability.
  • Minimum age — 18, and only 18. The field is on the settings screen but disabled, and says so: the verification backend enforces a fixed 18-and-over threshold for every merchant and has no way to accept another value, so a number typed there would change nothing. The app's overview screen shows the threshold that is actually enforced for the same reason. A different threshold is a product question, not a setting.
  • Country restrictions — an optional allow or block list carried on the session.
  • Enforcement hold — see below.

As with every integration, whether a method can serve a request at all is a property of the deployment. Check it before launch:

curl https://api.eidas-pro.com/api/config

An empty supportedMethods array means no method is configured there and every session will fail closed. Note also that the implemented path serves age only; see how a verification works.

5. The order-level backstop

Client-side gates are best-effort. A form-submit checkout theme, a race during setup, or a determined buyer can get past one, so the app re-checks every order after it is created, server to server.

On orders/create the app reads the authenticated result endpoint for the session attached to the order and tags the order accordingly:

TagMeaning
age-verifiedThe result endpoint confirmed a pass.
age-verification-failedA session ran and did not pass.
age-verification-unverifiedNo session was attached, or its verdict could not be read at all.

That tag is the compliance record, because it was written by your server from the authoritative endpoint rather than by the browser.

Enforcement hold, when enabled, goes one step further: any order that is not tagged age-verified has its fulfilment orders placed on hold with a note, so it cannot ship until someone looks at it. Placing the hold is best-effort and never blocks the webhook; the tag is written either way.

6. Test before you launch

  1. Confirm supportedMethods is non-empty for your deployment.
  2. Add an in-scope product to a cart and reach checkout. The verification step should appear.
  3. Add an out-of-scope product only, and confirm no step appears.
  4. Complete a checkout and confirm the order carries the expected tag in the Shopify admin — that is the check that proves the server-side path works, not just the UI.

Troubleshooting maps the error codes the app surfaces back to their causes.

One of them is worth knowing about here. A build of the app from before the minimum-age field was retired sent that value to the verification API, which rejects a body carrying a property it does not accept — so on such a build every session answers 400 and step 2 above never gets past the prompt. Current builds do not send it. If you see that, you need a current build of the app rather than a change to your settings; see rejected request bodies.

What the app never receives

The verification API returns a status and two booleans and no personal data — no date of birth, no name, no country, no document number. The app stores its per-shop settings and the order tag; there is no attribute to store even if it wanted one.