---
title: "B2B Triage — Wholesale Registration & Approval for Shopify B2B | Human After All"
description: "B2B Triage is a Shopify app by Human After All: wholesale applications become native Shopify B2B accounts. Approval writes Company, location, contact, catalog assignment, payment terms, and tax exemption — not a tag, not a note. Launching on the Shopify App Store."
url: "https://humanafterall.ca/shopify-apps/b2b-triage/"
language: "en"
updated: "2026-07-24"
markdown_index: "https://humanafterall.ca/api/md/index.md"
---

Labs — Shopify App

# B2B Triage: Wholesale Registration & Approval for Shopify B2B

Wholesale applications become real Shopify companies.

B2B Triage is a Shopify app by Human After All that turns wholesale sign-ups into native Shopify B2B accounts. A buyer applies through a form on your storefront, a person reviews the application, and approval writes real Shopify objects — Company, location, contact, catalog assignment, payment terms, tax exemption. Not a tag. Not a note. The records Shopify's own B2B engine runs on.

[Talk to us →](https://humanafterall.ca/contact/) [See what approval creates →](#bt-objects)

Launching on the Shopify App Store · Works on every paid Shopify plan

Last updated: July 24, 2026

Applications 3

Alpine Supply Co.

Denver, CO

VAT — not checked Approve Decline

Coolblue B.V.

Rotterdam, NL

VAT confirmed — COOLBLUE B.V. Approve Decline

Dépôt Rive-Sud

Longueuil, QC

Registry unavailable Approve Decline

Nothing becomes a company until a person says so.

01 — The object graph

## What does B2B Triage create when you _approve_ a buyer?

Approving one application writes six native Shopify objects: a Company, a company location, a company contact, a catalog assignment, payment terms, and a tax exemption. Most registration apps stop at a customer record — the buyer's answers pasted into the Notes field as a text blob, a tag or two, and a password. B2B Triage ends at the object graph Shopify's B2B engine actually reads. The Company is created with a stable external ID, derived when the buyer applies, so a double-clicked Approve button cannot silently create duplicates. The location is assigned to one of your existing catalogs; the app never creates catalogs, so yours stay yours. Payment terms are resolved from Shopify's own template to a typed integer. The tax exemption is the jurisdiction-correct value from Shopify's 75 — Canada alone has six kinds. Every step is recorded on the application's own timeline. When Shopify refuses one, you read Shopify's words — not an error code we invented.

One approval. Six native objects.

01

### Company

Created with a stable external ID, derived when the buyer applies. Shopify does not enforce unique company names; without the ID, a double-clicked Approve silently creates two.

02

### Company location

Including the second one Shopify auto-creates in the background — no terms, no exemption, no catalog. Buyers tend to pick that one and pay retail. The app detects and reconciles it.

03

### Company contact

The buyer, attached to the location using the assignment mutation that works when the customer already exists — which, in practice, is always.

04

### Catalog assignment

The buyer’s location is assigned to a catalog you already built, so many buyers share the same tiered catalogs. The app never creates a catalog — yours stay yours.

05

### Payment terms

Net terms resolved from Shopify’s own template to a typed integer — never parsed out of a display string, which breaks on the first French-language store.

06

### Tax exemption

The jurisdiction-correct value from Shopify’s 75 exemptions. Canada alone has six kinds. A blanket yes/no boolean is not the same thing.

02 — Your data

## Why native Shopify objects instead of _tags and notes_?

Because a note is not data and a tag is not a number. The common pattern stores registration answers as a delimited plaintext blob inside the customer's Notes field — editable by any staff member, unreachable by any report, segment, or query. B2B Triage writes typed, namespaced metafields instead. net\_terms\_days = 30 is an integer, so it supports "greater than 30". The tag net30 is a string: it collides with net300 and supports nothing. Metafields reach ShopifyQL as a GROUP BY dimension, so you can genuinely report on your wholesale program. Tags have no analytics dimension at all. Namespaces separate cleanly too: everything the app writes lands under b2b\_triage, while tags share one flat namespace with every app on your store — two apps writing "wholesale" collide in silence. We still write tags, as a compatibility bridge for tools that only read tags, such as Klaviyo's native Shopify sync. The metafields are the truth; the tags are a courtesy.

| Property | Why it matters |
| --- | --- |
| Reportable | Metafields reach ShopifyQL as a GROUP BY dimension. Tags have no analytics dimension at all — you cannot report on a tag. (Shopify does not offer admin-list filtering on customer metafields; that answer comes from analytics and the export, not the customer list.) |
| Typed | net\_terms\_days = 30 supports "greater than 30". The tag net30 string-collides with net300 and supports nothing. |
| Namespaced | Everything lands under b2b\_triage. Tags are one flat global namespace shared with every app on your store — two apps writing "wholesale" collide in silence. |
| Exportable | CSV with Shopify GIDs as join keys, so the row matches your CRM instead of approximating it. Values are normalised at input. |

03 — Ownership

## What happens to your companies if you _uninstall_?

They stay. Shopify records no app-ownership link on a Company, a company location, a contact, a catalog assignment, payment terms, or a tax exemption — so there is nothing for an uninstall to take away. Metafields are the one exception: they carry a reserved $app: namespace, and uninstalling an app genuinely severs those. Companies have no such field. The accounts B2B Triage approves are ordinary Shopify records. Your staff can edit them. Your other apps can read them. They behave exactly as if your team had created them by hand in the admin. Stated precisely, because the claim deserves it: what is proven is the mechanism, and the mechanism holds no matter who created the objects. Contrast that with wholesale apps that keep registration data and pricing in their own database — leave, and your program leaves with them. This is the design philosophy in one sentence: we own the interface, Shopify owns the engine.

04 — Tax IDs

## What happens when the EU VAT registry _goes down_?

On 16 July 2026 we asked VIES, the EU's VAT registry, about IE6388047V — Google Ireland's real VAT number. For 21 minutes the registry called it invalid; Ireland's member-state service was down. Then, with nothing changed at Google, it came back valid.

That is the trap. VIES sometimes reports its own outages as "invalid": technically, an HTTP 200 with isValid: false, while the reason hides in a different field.

| Time (UTC) | isValid | userError | The naive reading |
| --- | --- | --- | --- |
| 05:14 | false | MS\_UNAVAILABLE | "Invalid" — fraud-flagged |
| 05:35 | true | VALID | GOOGLE IRELAND LIMITED |

B2B Triage never reads isValid. It reads the error code as an allowlist: exactly one value means "not registered". Everything else — even codes the European Commission ships next year — means "we could not check right now", which gets a different word on screen.

The app never rejects an applicant because a registry blinked. No branch in our code turns a registry's bad day into a rejection — not a policy we promise, a branch that does not exist. "Never checked", "checked and found nothing" and "the check failed" are three different facts; a boolean would collapse them into a lie.

05 — Performance

## Does B2B Triage slow down your _storefront_?

No, and the numbers are measured rather than promised. The registration form ships as a theme app block, not an app embed. It loads only on the pages where you place it; an embed executes on every page of your store, including the ones with no form. The block makes zero third-party requests — no tracker, no CDN font, no analytics pixel, nothing that phones anywhere except your own storefront. It measures under 13 KB gzipped, enforced by a build step that fails when it grows. The form works with JavaScript disabled entirely; any tax-registry lookup runs on our server, never in your buyer's browser. Input handling follows the same discipline. Postal codes normalise per country — h9b2g9 becomes H9B 2G9. Phone numbers store as E.164. And 244 countries get province and state dropdowns built from Shopify's own zone data, which is not ISO 3166-2.

06 — Labs

## How does B2B Triage fit with _B2B Protocol_ and our other B2B work?

B2B Triage is the first Labs product we are taking to the Shopify App Store — self-serve, installable, and deliberately scoped to one job: wholesale registration and approval on Shopify's native B2B. The rest of our Labs work is client-exclusive. [B2B Protocol](https://humanafterall.ca/shopify-apps/b2b-protocol/) is the Shopify Plus B2B accelerator we deploy for manufacturers and distributors — ERP middleware, buyer segment routing, corporate spend control. Its POS module put [B2B contract pricing on Shopify POS](https://humanafterall.ca/shopify-pos-b2b/) for the first time. The philosophy is identical across all of them: never build a parallel system beside Shopify. Create and assign the platform's own objects, so merchants keep everything if they ever leave. If your wholesale program needs more than an approval flow — ERP-connected pricing, multi-segment routing, or a full [Shopify Plus implementation](https://humanafterall.ca/shopify-plus/) — that is our agency practice, and the [contact form](https://humanafterall.ca/contact/) is the door.

## Wholesale applications, _triaged_.

B2B Triage is launching on the Shopify App Store. The full product story lives on this page, and every claim on it is checked against the code, not recalled. If a question survives the FAQ, talk to us directly about your wholesale registration flow.

[Talk to us →](https://humanafterall.ca/contact/) [Read the FAQ →](#bt-faq)

B2B Triage is built by Human After All — a B2B eCommerce and AI consultancy specializing in Shopify Plus implementations for manufacturers and distributors. Shopify Plus Partner. Forbes Agency Council member.

## Frequently asked questions

What is B2B Triage and how does it work?

B2B Triage is a Shopify app by Human After All that handles wholesale registration and approval on top of Shopify’s native B2B. You build a registration form — multi-step, with nested AND/OR conditional logic — and place it on your storefront as a theme app block. Wholesale buyers apply. Every application lands in a triage queue where a person reads it — the queue that gives the app its name. Nothing becomes an account until a human decides. On approval, the app writes native Shopify objects: a Company, a company location, a company contact, a catalog assignment, payment terms, and a jurisdiction-correct tax exemption, plus typed metafields and compatibility tags on the customer. The result is a wholesale account that Shopify’s own B2B engine runs directly, visible in your admin like any record your staff created by hand. B2B Triage is launching on the Shopify App Store and works on every paid Shopify plan.

Do I need Shopify Plus to use B2B Triage?

No. Shopify’s native B2B stopped being Plus-only in April 2026. It is now included on every paid Shopify plan, and that change is exactly why B2B Triage exists. For years, wholesale apps on non-Plus stores had no choice but tags and workarounds, because the real B2B objects were locked behind Plus. That constraint is gone, so the app writes the real objects on Basic, Grow, and Advanced too. Three capabilities remain Plus-gated by Shopify itself, not by us: assigning a catalog directly to a company, running more than three catalogs (non-Plus plans cap at three), and partial payments or deposits. When Shopify refuses a step for plan reasons, B2B Triage reports Shopify’s own error and marks the step skipped rather than failing the whole approval. If you want the full Plus feature set behind your wholesale program, that is what our Shopify Plus practice is for.

What happens to my companies if I uninstall B2B Triage?

They stay. Shopify records no app-ownership link on a Company, a company location, a contact, a catalog assignment, payment terms, or a tax exemption. Metafields are different: they live under a reserved $app: namespace that an uninstall genuinely severs. Companies carry no such field, so there is nothing for our removal to take away. Every account B2B Triage approves is an ordinary Shopify record: your staff can edit it, your other apps can read it, and Shopify’s B2B engine keeps running it whether or not we are installed. Stated precisely, because a claim like this deserves precision: what is proven is the mechanism, and it holds no matter who created the objects. Contrast that with wholesale apps that keep registration answers and negotiated pricing in their own off-platform database — cancel, and the program leaves with them. Merchant-owned data is the entire point of building on native objects.

How does B2B Triage validate tax IDs and VAT numbers?

In two distinct steps, and it tells you which one ran. First, offline validation: EU VAT, UK VAT, Australian ABN, India GST, and US EIN formats are checked with real check-digit arithmetic, not a regex, so an obvious typo never reaches a government registry. Second, a live registry check: EU VAT numbers are verified against VIES, the European Commission’s registry — and that is the whole list, stated plainly rather than implying five. VIES sometimes reports its own outages as “invalid” — technically, an HTTP 200 with isValid: false — so a naive integration fraud-flags legitimate businesses whenever a member state blinks. We watched it call Google Ireland’s real VAT number invalid for 21 minutes. B2B Triage reads the error code instead. It distinguishes “not registered” from “could not check right now”, and it never auto-rejects an applicant because a registry had a bad day. The merchant decides; the app informs.

How is B2B Triage different from B2B Protocol?

They solve different problems at different scales. B2B Triage is a self-serve Shopify App Store app with one deliberately narrow job: wholesale registration and approval into Shopify’s native B2B objects. You install it, build a form, and approve applications — no agency engagement required, on any paid Shopify plan. B2B Protocol is the opposite shape: a client-exclusive Shopify Plus accelerator that Human After All deploys and configures — ERP-connected pricing, buyer segment routing, approval workflows, corporate spend control, and the module that put B2B contract pricing on Shopify POS. Both are built on the same conviction: create and assign Shopify’s own objects instead of running a parallel system beside the store. If your wholesale program starts with “how do buyers apply and get approved?”, B2B Triage answers it. If it starts with “how does my ERP price every channel?”, that conversation is B2B Protocol.
