Company
A stable external ID, derived when the buyer applies rather than when you approve. Shopify does not enforce unique company names — without it, a double-clicked Approve silently creates two.
A buyer applies. A human reads it. On approval, B2B Triage writes native Shopify objects — Company, location, contact, catalog, payment terms, tax exemption. Not a tag. Not a note. The objects Shopify's own B2B engine runs on.
$20/month. Native Shopify B2B is on every paid plan — it stopped being Plus-only in April 2026.
The common approach ends at a customer record with the answers pasted into a note. B2B Triage creates what Shopify's B2B engine actually reads.
A stable external ID, derived when the buyer applies rather than when you approve. Shopify does not enforce unique company names — without it, a double-clicked Approve silently creates two.
Including the second one Shopify auto-creates behind your back, carrying no terms, no exemption and no catalog. It is the one buyers pick, and it sells at retail. We detect and reconcile it.
The buyer, attached to the location, using the assignment mutation that works when the customer already exists — which is always.
Their price list, asserted ACTIVE on read-back rather than assumed. Shopify can silently force it to ARCHIVED.
Net 30 resolved from the template to a typed integer — never parsed out of the display string, which breaks on the first French store.
The jurisdiction-correct value from Shopify's 75. Canada alone has six kinds. A blanket boolean is not the same thing.
Nine steps, each recorded on the application's own timeline. When Shopify refuses one, you get Shopify's own words — not an error code we invented.
Every app wants your data. Almost none will tell you what happens to it the day you leave.
Shopify records no app-ownership link on a Company, a location, a contact, a catalog assignment, payment terms or a tax exemption. Metafields do have a reserved $app: namespace, and an uninstall severs those. Companies have no such field. There is nothing for an uninstall to take away.
Stated precisely, because this is the kind of claim that deserves it: what is proven is the mechanism, and it holds whoever created the objects. Our live uninstall run wrote them with an independent Admin API credential rather than the app's own token — we would rather show you the seam than sand it down.
We build apps that structure your data and track ROI. It shows up in an unglamorous place: where the answers go.
The common approach stores registration answers as a delimited plaintext blob inside the customer's Notes field. Any staff member can edit it or wipe it, and no report, segment or query can reach inside it. The data is on the record without being data.
B2B Triage writes typed, namespaced metafields. A number is a number.
We write tags too, as a compatibility bridge for tools that cannot read metafields (Klaviyo's native Shopify sync reads tags, not metafields). The metafields are the truth. The tags are a courtesy.
VIES is the EU's VAT registry. It answers HTTP 200 when it is broken, and reports its own outages as isValid: false. The actual reason hides in a different field.
On 16 July 2026 we asked it about IE6388047V — Google Ireland's real, live VAT number. For 21 minutes it came back invalid, because Ireland's member-state service was down. Then, without anything changing at Google, it came back valid.
| Time (UTC) | isValid | userError | The naive reading |
|---|---|---|---|
| 05:14 | false | MS_UNAVAILABLE | "Invalid" — fraud-flagged |
| 05:35 | true | VALID | GOOGLE IRELAND LIMITED |
We never read isValid. We read the error code as an allowlist: exactly one value means "not registered". Everything else — including codes the EC ships next year — means "we could not check right now", which is a different sentence and gets a different word on screen.
And we never reject anyone because a government registry blinked. There is no branch in our code that 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.
"Validated" and "checked against the registry" are not the same word. So we use both, and we tell you which one you got.
Conditional logic is usually the thing you upgrade for. Ours does nested AND/OR groups — not a single global "match all / match any" switch, which by construction cannot express that line above. At $20.
Show the resale certificate field when the country is Canada and the province is Québec — or whenever they picked "distributor", wherever they are. That is one rule.
Hidden means absent, and it is enforced on our side: the server re-evaluates every condition before it accepts anything, so a crafted POST cannot smuggle a value your logic never showed. The same module runs the editor preview and the submission.
Your storefront's speed is your SEO and your conversion rate. An app that taxes every page to serve one form is not free — you just do not get the invoice.
Billed by Shopify, on your existing invoice.
| Capability | B2B Triage $20/month Everything above. | + RetailNot built yet $35/month Everything in $20, plus three things that do not exist yet. |
|---|---|---|
| Registration forms — multi-step, custom fields, nested AND/OR logic | Included | Included |
| Approval queue — manual, automatic, or auto-approve on an email domain | Included | Included |
| Native Company, location, contact, catalog, terms, tax exemption on approval | Included | Included |
| Typed metafields + tags for compatibility | Included | Included |
| Tax ID validation, and EU VAT checked live against VIES | Included | Included |
| CSV export with Shopify GIDs as join keys | Included | Included |
| Shopify Flow trigger carrying typed application data | Included | Included |
| Point of sale — B2B prices at the counter | Not included | Not built yet |
| Public API | Not included | Not built yet |
| Klaviyo integration | Not included | Not built yet |
The three retail rows are in development, and listed here so the roadmap is not a secret. Do not buy the $35 plan for them today — buy the $20 plan, and we will tell you when this one is real.
Native Shopify B2B is available on every paid Shopify plan — it has not been Plus-only since April 2026. A few pieces of Shopify's own B2B are still Plus-gated, and we are specific about which in the FAQ.
Native Shopify B2B objects: a Company, a CompanyLocation, a CompanyContact, a catalog assignment, payment terms and a jurisdiction-correct tax exemption — plus typed metafields on the customer, and tags for tools that only read tags. They are ordinary Shopify records: your staff can edit them, your other apps can read them, and Shopify's B2B engine uses them directly because they are its own.
No. Shopify's native B2B has been on every paid plan since April 2026 — the "B2B is Plus-only" rule is real history and out of date. Three things are still Plus-gated by Shopify, not by us: assigning a catalog directly to a company, having more than three catalogs (non-Plus caps at three), and partial payments or deposits. Our own store is Plus, and we have not yet watched a non-Plus install pass or fail — if you are on one and something is wrong, we want to be the ones who find out.
They stay. Shopify records no app-ownership link on a Company, a location, a contact, a catalog assignment, payment terms or a tax exemption — unlike metafields, which live under a reserved $app: namespace that an uninstall does sever. There is nothing for our removal to take away. Precisely: what is proven is that mechanism, and it holds whoever created the objects — our live uninstall run wrote them with an independent Admin API credential, not the app's own token.
A honeypot field, an IP rate limit, and the approval queue — the real backstop, because no application becomes a company until a human reads it. We do not ship a CAPTCHA: we had one, it caused more problems than it solved, and we removed it rather than leave a control that lies. Spam can cost you attention and a database row. It cannot cost you money, and it cannot create anything on your store. If a CAPTCHA is a hard requirement for you, that is a real gap.
It stays in your Shopify store and in our database, nowhere else. Tax IDs and VAT numbers are private to the storefront — never readable from your theme. No PII in logs, none in URLs. Applicant personal data is anonymised automatically 730 days after the application is decided. Approved companies are never touched by that — they are your records, not ours.
Human After All, a Shopify agency in Montréal. We build B2B on Shopify for a living, and made this because the tools we needed either did not exist or built a parallel system beside the store instead of using the store. Argue with an engineering decision on this page and you will get an engineer.
A real person reads these. If you have a question about a claim on this page, ask it — we would rather be corrected than believed.