Pour les agences Shopify
Construire un portail B2B Shopify sur les comptes clients : ce qu'il faut savoir d'abord
Par Jahangir Alam · 22 septembre 2026 · 15 min de lecture
- Dernière vérification
- API Shopify
- 2026-07
- Public
- Agences Shopify, développeurs et architectes solution qui construisent le côté acheteur d'une boutique B2B
- Périmètre
- Comptes clients actuels, extensions d'interface de compte client (cibles, capacités, le plafond de 64/128 Ko), les surfaces portail hébergé et headless, les demandes de compte d'entreprise et les commandes provisoires de la Customer Account API en API 2026-07 ; l'axe des comptes hérités est abandonné comme obsolète
Un portail acheteur B2B sur Shopify se construit sur les comptes clients de Shopify pour les acheteurs qui en ont un, et sur une surface à part pour ceux qui n'en ont pas. C'est toute la décision. La question que les agences posent encore - nouveaux comptes clients ou comptes hérités ? - a cessé d'en être une le 26 février 2026, quand Shopify a déprécié les comptes hérités ; et elle n'a jamais été une question B2B, parce que le B2B n'a jamais fonctionné dessus. Ce qui reste à décider, c'est laquelle des quatre surfaces porte chaque partie du portail, et la réponse tient à deux faits sur l'acheteur : a-t-il un compte client, et ce compte est-il rattaché à un site d'entreprise.
Cette page s'adresse à l'agence qui cadre le côté acheteur d'un projet B2B : ce que sont les comptes clients aujourd'hui et ce qu'un acheteur B2B connecté obtient déjà sans aucune application ; les quatre surfaces qu'un portail peut utiliser et ce que chacune porte, avec les limites de plateforme qui tranchent ; ce qu'une extension de compte client peut et ne peut pas faire ; où placer les acheteurs invités ; ce que le headless change ; si un acheteur peut voir une commande provisoire ; et les modes de défaillance qui viennent d'un modèle de compte mal compris. Là où elle décrit comment QuotWay met les devis dans le compte, il s'agit d'une implémentation, signalée comme telle.
Tout ce qui concerne Shopify ci-dessous a été vérifié sur les pages de Shopify le 22 septembre 2026, en version d'API 2026-07 ; les sources sont en fin de page.
Ce que sont les comptes clients aujourd'hui
Shopify a un système de comptes clients pour les nouvelles boutiques et un système déprécié. Les comptes actuels connectent l'acheteur avec une adresse e-mail et un code à usage unique envoyé à cette adresse - « aucun mot de passe n'est requis » - et en B2B l'e-mail est celui d'un site d'entreprise, si bien que la connexion est aussi le contrôle d'entreprise. Un acheteur rattaché à plusieurs sites choisit celui pour lequel il achète avant que quoi que ce soit n'entre dans le panier. Le compte peut vivre sur un sous-domaine du domaine de la boutique, par exemple account.votreboutique.fr, et une boutique peut brancher son propre fournisseur d'identité en OAuth 2.0 ou OpenID Connect ; l'Edition Spring '26 a ajouté la synchronisation de profil et de tags depuis Auth0, Ping Identity et Azure ID, et des sessions allant jusqu'à 365 jours.
Les comptes clients hérités sont dépréciés depuis le 26 février 2026 - plus disponibles pour les nouvelles boutiques, plus de mises à jour, une date d'arrêt « annoncée plus tard en 2026 » - et la documentation B2B de Shopify est explicite : « vous ne pouvez pas utiliser les comptes clients hérités pour les clients et commandes B2B ». Tout plan de construction qui garde une branche héritée planifie pour une boutique qui ne peut pas exister.
Ce qu'un acheteur B2B connecté obtient du compte sans aucune application est plus qu'un projet ne le suppose parfois :
| Dans le compte aujourd'hui | Détail |
|---|---|
| Commandes | Historique des commandes sur les sites de l'acheteur, suivi, nouvelle commande par duplication d'une commande passée, demandes de retour |
| Conditions de paiement | Sur une commande à échéance, un bouton Payer maintenant, la date d'échéance, et une mention En retard une fois le délai passé ; l'acheteur peut payer à tout moment avant l'échéance |
| Acomptes | Le montant de l'acompte et la date d'échéance du solde, affichés au paiement, sur la page de remerciement et dans le compte (les acomptes sont une capacité Plus) |
| Entreprise | Informations d'entreprise et de site, moyens de paiement enregistrés ; modifier les adresses demande la permission Administrateur du site |
| Permissions | Commande uniquement voit ses propres commandes ; Administrateur du site voit toutes les commandes du site et modifie les adresses |
Ce qu'il n'a pas, c'est quoi que ce soit sur un devis : ni demande, ni proposition, ni versions, ni contre-offre, ni validation. C'est le vide qu'un portail comble, et les quatre surfaces ci-dessous sont les endroits où il peut le faire.
Les quatre surfaces
La matrice, avec la limite qui tranche chaque ligne :
| Compte client standard | Extension d'interface de compte | Portail hébergé (app) | Vitrine headless | |
|---|---|---|---|---|
| Qui peut l'utiliser | Les clients connectés ; comportement B2B seulement s'ils sont rattachés à un site d'entreprise | Idem - les extensions se rendent dans le compte | Toute personne avec le lien : invités, acheteurs sans compte, boutiques sans comptes actuels | Les acheteurs que la vitrine connecte via la Customer Account API |
| Connexion | E-mail + code unique ; fournisseur OIDC en option | Celle de Shopify, déjà faite | Celle de l'app : un lien magique, un code vers la même boîte | Flux d'autorisation de la Customer Account API |
| Où elle vit | Hébergée par Shopify, ou account.votreboutique.fr |
Dans le compte ; une page entière a une entrée de menu et sa propre route | Le domaine de l'app | Votre domaine |
| Contrôle de l'interface | Aucun au-delà de l'éditeur | Composants web Shopify uniquement ; s'exécute dans un worker isolé ; 64 Ko par extension, 128 Ko pour une page entière | Total | Total |
| Image de marque | Thème du compte de la boutique | Thème du compte ; l'extension en hérite | Celle de l'app, avec le logo et les couleurs de la boutique si elle le permet | La vôtre |
| Données accessibles à une app | - | Lectures Storefront API (produits, collections, métaobjets) avec api_access ; le backend de l'app avec network_access + un jeton de session ; purchasingCompany sur le compte authentifié |
Ce que le backend de l'app détient | Customer Account API + Storefront API avec contexte acheteur |
| Ce que l'acheteur voit nativement | Commandes, conditions, acomptes, nouvelle commande, retours, données d'entreprise | Tout cela, plus ce que l'extension ajoute | Seulement ce que l'app rend | Seulement ce que vous rendez |
| Commandes provisoires / factures | Via le lien de facture ; les commandes à échéance ont Payer maintenant | La Customer Account API expose draftOrders avec invoiceUrl, une page peut donc les lister |
Ce vers quoi l'app renvoie | La même API que l'extension |
| Devis | Non | Oui, depuis le backend de l'app | Oui | Oui, si vous le construisez |
| Surface de défaillance | Celle de Shopify | Le plafond du bundle, les règles de cibles, CORS et la vérification du jeton | Délivrabilité des e-mails, un second domaine | Tout, connexion comprise |
Lisez les colonnes comme une répartition du travail, pas comme des rivales. Un projet qui sert des acheteurs d'entreprise met les pages de devis dans le compte, parce que c'est là que ces acheteurs paient déjà leurs factures ; le même projet garde une surface hébergée, parce qu'un invité, un acheteur dont le compte n'est pas encore rattaché à une entreprise et une boutique qui n'est pas passée aux comptes actuels sont tous hors de portée de l'extension. Le headless remplace les deux premières colonnes pour les boutiques qui possèdent leur vitrine, et ne remplace rien de la troisième.
Ce qu'une extension de compte peut et ne peut pas faire
L'extension est la surface que la plupart des projets sous-estiment dans les deux sens : elle peut plus qu'un lien dans le menu, et moins qu'une page.
Où elle peut se rendre. Une page entière (customer-account.page.render, « non liée à une commande précise ») que les marchands ajoutent à la navigation du compte ; une page liée à une commande pour des flux comme les retours ; des blocs et des annonces sur l'index des commandes et la page de statut de commande ; une action de commande qui s'ouvre dans une fenêtre modale ; des blocs de profil, dont des blocs spécifiques au B2B qui se rendent après les détails de l'entreprise, les adresses du site, les moyens de paiement du site et la liste du personnel du site ; un emplacement de pied de page. La règle de Shopify : « les cibles de page entière ne peuvent pas être combinées avec d'autres cibles dans une seule extension ». Une page de devis plus un lien « voir mes devis » sur la page des commandes font donc deux extensions, et si la boutique doit pouvoir les ajouter ensemble depuis l'éditeur, une collection d'extensions d'éditeur - qui exige au moins deux extensions - les regroupe.
Dans quoi elle s'exécute. « Un bac à sable isolé, séparé de la page du compte client et des autres extensions d'interface » - un Web Worker - qui rend les composants web de Shopify, « des éléments d'interface natifs qui suivent le système de design de Shopify », pas votre HTML et CSS. Le bundle compilé « ne peut pas dépasser 64 Ko, ou 128 Ko pour les extensions de page entière ». L'extension n'a pas accès aux « informations de paiement sensibles ni à la page du compte client elle-même ». Ces trois contraintes font de l'extension un client léger : l'état du devis, ses règles et ses documents vivent dans le backend, et la page récupère et rend.
Ce qu'elle peut atteindre. Avec api_access, la Storefront API en « lecture non authentifiée des produits, collections, tags de produits, plans de vente et métaobjets » - assez pour lire les données produit et tout métaobjet appartenant à l'app, comme des libellés par boutique ou un slug de route. Avec network_access, le backend de l'app, sous deux conditions que Shopify énonce clairement : les réponses doivent porter Access-Control-Allow-Origin: *, et « les requêtes peuvent provenir de n'importe où sur Internet » - le jeton de session prouve l'identité du client, pas que l'appel vient de Shopify, donc le backend vérifie le jeton à chaque requête et traite l'origine comme non fiable. Du compte authentifié, l'extension obtient le client et, pour un acheteur professionnel, purchasingCompany ; pour tous les autres cette valeur est undefined, et c'est le test « est-ce un acheteur d'entreprise, oui ou non ».
Ce qu'elle ne peut pas faire. Se rendre pour un invité. Se styler hors des jetons de Shopify. Porter un gros client. Lire le DOM de la page du compte. Exister sur les comptes hérités. Chacun de ces points est une raison pour laquelle la colonne hébergée survit dans la matrice.
Devis invités et acheteurs hors entreprise
Deux sortes d'acheteurs sont invisibles pour l'extension, et un plan de portail doit dire où ils vont.
La première est l'invité : un acheteur qui demande un devis depuis une page produit sans se connecter. Shopify n'a pas d'objet pour cette demande, ni de page de compte où l'afficher. La voie native pour faire de cet acheteur une entreprise est la demande de compte d'entreprise : un formulaire Shopify Forms, en ligne ou en popup, dont l'envoi « crée automatiquement » une entreprise, un site d'entreprise et un client dans l'admin, mis en attente sous « Commande non approuvée » jusqu'à ce que le marchand les approuve - et d'ici là ils « ne peuvent pas passer de commande dans votre boutique en ligne ni accéder aux prix B2B ». C'est la bonne voie pour un acheteur qui veut un compte. C'est la mauvaise voie à imposer à un acheteur qui veut un prix pour vendredi, et c'est pourquoi la couche de devis a besoin d'une surface qui fonctionne avec une seule adresse e-mail.
La seconde est l'acheteur connecté mais non rattaché à un site d'entreprise. L'aide de Shopify est directe : un tel client est traité comme un particulier même connecté. purchasingCompany est undefined, les catalogues ne s'appliquent pas, et les blocs de profil B2B ne se rendent pas. Une extension peut encore lister les devis de cet acheteur par identifiant client, mais rien n'existe pour lui en matière de prix d'entreprise ou de conditions tant qu'un administrateur ne l'a pas rattaché à un site.
La réponse de QuotWay aux deux, signalée comme une implémentation : la proposition d'un invité part vers un portail hébergé par un lien magique valable sept jours par défaut, protégé par un code unique envoyé à la même boîte qui expire au bout d'une heure ; un invité qui a un compte plus tard peut y rattacher le devis avec un code à usage unique ; et l'e-mail qui annonce une proposition ne renvoie vers la page du compte que si la boutique utilise les comptes clients actuels et si l'acheteur est un client connecté, sinon vers le portail. Les deux surfaces portent les mêmes actions - accepter, contre-proposer, refuser, écrire, validations côté acheteur - sur tous les forfaits.
Le headless change la connexion, pas le modèle
Sur Hydrogen ou une vitrine sur mesure, l'acheteur s'authentifie via la Customer Account API, et le contexte B2B est quelque chose que la vitrine porte explicitement : elle interroge les contacts d'entreprise du client pour trouver les sites pour lesquels il peut acheter, propose un sélecteur quand il y en a plusieurs, puis envoie companyLocationId avec le jeton d'accès client dans @inContext(buyer: …) sur les requêtes Storefront API - c'est ainsi que reviennent les prix contextuels, les règles de quantité et la tarification par volume pour ce site - et dans cartCreate ou cartBuyerIdentityUpdate comme buyerIdentity du panier. Deux mises en garde de la page de Shopify : changer l'identité acheteur d'un panier existant peut retirer des produits non publiés pour cet acheteur, et le jeton d'accès Customer Account « ne peut servir qu'à mettre à jour l'identité acheteur d'un panier », pas à interroger le client via la Storefront API.
Pour le portail, cela signifie que la colonne extension de compte disparaît - il n'y a pas de compte rendu par Shopify à étendre - et que l'interface de devis est la vôtre, avec le même contrat backend qu'une extension utiliserait et le même contrôle d'identité : le site que l'acheteur a sélectionné est le site du devis, et le prix de départ est celui que renvoie le contexte acheteur.
Un acheteur peut-il voir une commande provisoire ?
Un devis converti est une commande provisoire jusqu'au paiement de l'acheteur, donc la question revient à chaque cadrage. Le compte standard montre les commandes ; une commande provisoire atteint l'acheteur par le lien de facture que Shopify envoie, et une fois devenue commande à échéance elle apparaît avec Payer maintenant et une date d'échéance. En dessous, la Customer Account API expose customer.draftOrders - chacune avec status, l'invoiceUrl « envoyée au client dans l'e-mail de facture », la purchasingEntity, le deposit et les lignes - si bien qu'une page d'extension ou une vitrine headless peut lister les commandes provisoires ouvertes d'un acheteur à côté de ses devis et renvoyer directement au paiement. Que l'interface de compte de Shopify liste elle-même les commandes provisoires en section n'est pas ce que disent ses pages d'aide ; un projet qui a besoin de la liste doit donc prévoir de la rendre depuis l'API plutôt que de supposer que la page standard l'a.
Décider la surface
| Si | Alors |
|---|---|
| Les acheteurs sont des contacts d'entreprise qui paient déjà leurs factures dans le compte | Les devis vont dans le compte : une extension de page entière dans le menu, un bloc sur l'index des commandes qui y renvoie |
| Certains acheteurs demandent des devis avant d'avoir un compte, ou avant que l'entreprise soit approuvée | Une surface hébergée atteinte par e-mail, et une étape de rattachement une fois le compte créé |
| La boutique n'est pas passée aux comptes clients actuels | La surface hébergée est la seule ; le passage est un réglage Shopify, pas un projet |
| La vitrine est headless | La Customer Account API pour la connexion, companyLocationId sur chaque requête et le panier, votre propre interface de devis sur le même backend |
| Le portail doit ressembler à la marque, pas à Shopify | La surface hébergée ou headless ; l'extension hérite du thème du compte |
| Une interface acheteur riche et avec état est exigée | La garder hors de l'extension (64 / 128 Ko, composants Shopify seulement) ; l'extension est l'entrée, le backend l'état |
| Les acheteurs doivent créer un compte d'entreprise en libre-service | La demande de compte d'entreprise de Shopify Forms, avec l'étape d'approbation budgétée dans l'onboarding |
Modes de défaillance
| Mode de défaillance | Ce qui se passe | Conception |
|---|---|---|
| Une branche héritée dans le plan | Effort dépensé sur une surface que le B2B ne peut pas utiliser et que Shopify arrête | Supprimer la branche ; traiter « pas de comptes actuels » comme « surface hébergée seulement » |
| Invités planifiés en « inscrivez-vous d'abord » | La demande se perd au mur d'inscription | Une surface qui fonctionne avec une adresse e-mail ; rattachement plus tard |
| Acheteur connecté mais non rattaché traité comme B2B | purchasingCompany est undefined, les prix catalogue ne s'appliquent pas, les conditions n'existent pas |
Tester purchasingCompany et router ; faire du rattachement à un site la tâche d'onboarding |
| Page entière et bloc dans une seule extension | Refusé par la règle de plateforme | Extensions sœurs plus une collection d'extensions d'éditeur |
| Client riche dans l'extension | Au-dessus du plafond de 64 / 128 Ko, ou en lutte avec le jeu de composants | Client léger ; l'état dans le backend |
| Le backend fait confiance à l'origine | N'importe qui peut appeler le point de terminaison ; Shopify dit que la requête peut venir de n'importe où | Vérifier le jeton de session à chaque appel ; CORS * est obligatoire, donc l'autorisation est le jeton, jamais l'origine |
| Un acheteur multi-sites demande un devis pour le mauvais site | La proposition est chiffrée contre un catalogue sous lequel l'acheteur ne paiera pas | Prendre le site sélectionné dans le compte (ou le sélecteur headless) au moment de la demande et le porter sur le devis |
| E-mail de lien magique dans les spams | L'invité n'atteint jamais le portail | SPF et DKIM sur le domaine d'envoi ; renvoi du code depuis le portail lui-même |
| Un portail sur un second domaine surprend l'acheteur | La confiance baisse ; le support demande « c'est bien vous ? » | Logo et couleurs de la boutique sur le portail ; des e-mails qui ne montrent que le nom, jamais les prix |
Comment QuotWay fait
Une implémentation, pour que les contraintes ci-dessus puissent être vérifiées contre quelque chose de construit. QuotWay livre trois extensions de compte client : une page entière « Mes devis » sur customer-account.page.render, un bloc « Voir mes devis » sur l'index des commandes qui renvoie vers la route /account/pages/… propre à la boutique (le slug est lu via api_access dans un métaobjet appartenant à l'app), et une collection d'extensions d'éditeur qui permet au marchand d'ajouter les deux en une étape - la séparation est la règle de plateforme ci-dessus, pas une préférence. La page appelle le backend de l'app avec le jeton de session dans l'en-tête Authorization sous network_access ; un acheteur connecté y liste ses devis, lit une proposition, accepte, contre-propose, refuse, écrit, agit sur une étape de validation côté acheteur, rattache des devis invités et passe une commande rapide. Les invités, les acheteurs des boutiques sans comptes actuels et tous ceux que la règle de routage exclut reçoivent le portail hébergé par lien magique avec les mêmes actions, sur tous les forfaits. Le compte rendu côté marchand est sur la page de la fonctionnalité portail acheteur et dans la documentation sur les devis invités et le rattachement au compte ; les forfaits sur la page des tarifs ; les tests de lancement pour les comptes, sites et connexion dans le plan de test en 50 points.
Les faits Shopify de cet article sont tenus à jour dans la référence Shopify B2B.
Questions fréquentes
Shopify B2B fonctionne-t-il avec les comptes clients hérités ?
Non, et il n'a jamais fonctionné avec : la documentation B2B de Shopify indique que les comptes clients hérités ne peuvent pas être utilisés pour les clients et commandes B2B. Les comptes hérités sont dépréciés depuis le 26 février 2026, avec une date d'arrêt annoncée plus tard en 2026. Un projet B2B vise les comptes clients actuels ; une boutique encore sur les comptes hérités bascule dans les réglages avant même de pouvoir utiliser le B2B.
Les acheteurs B2B peuvent-ils se connecter avec un mot de passe ?
Pas sur les comptes clients de Shopify. Un acheteur se connecte avec l'adresse e-mail de son site d'entreprise et un code unique envoyé à cette adresse ; il n'y a pas de mot de passe. Une boutique qui a son propre fournisseur d'identité peut le connecter en OAuth 2.0 ou OpenID Connect, et les sessions peuvent durer jusqu'à 365 jours.
Une application peut-elle ajouter une page aux comptes clients Shopify ?
Oui. Une extension d'interface de compte client avec la cible de page entière crée une page que le marchand ajoute au menu du compte, et d'autres cibles ajoutent des blocs aux pages commandes, statut de commande et profil. L'extension s'exécute dans un bac à sable, rend les composants de Shopify, est plafonnée à 64 Ko (128 Ko pour une page entière) et atteint le backend de l'app par un jeton de session. Une page entière ne peut pas partager une extension avec d'autres cibles.
Un acheteur peut-il demander un devis sans compte Shopify ?
Shopify n'a pas d'objet de demande, c'est donc entièrement le travail de la couche de devis. Un invité peut être servi par une page hébergée atteinte par e-mail - un lien magique plus un code unique - et rattacher ensuite le devis à un compte. La voie native pour transformer un invité en acheteur d'entreprise est le formulaire de demande de compte d'entreprise, qui crée l'entreprise, le site et le client pour que le marchand les approuve.
Un acheteur peut-il voir une commande provisoire dans son compte ?
Par le lien de facture, et par l'API. La Customer Account API expose les commandes provisoires du client avec leur statut, l'URL de facture, l'entité acheteuse, l'acompte et les lignes, si bien qu'une extension ou une vitrine headless peut les lister. Les commandes à conditions de paiement apparaissent dans le compte avec un bouton Payer maintenant et une date d'échéance.
Faut-il Shopify Plus pour un portail acheteur B2B ?
Non. Le B2B est sur tous les forfaits Shopify, les comptes clients actuels sur tous les forfaits, et les extensions d'interface de compte fonctionnent sur toute boutique qui les a. Plus ajoute les acomptes, les catalogues actifs illimités et l'affectation directe des catalogues - rien dont le portail lui-même dépende.
Sources
Pages Shopify, toutes lues le 22 septembre 2026 en version d'API 2026-07 sauf date contraire :
- Connexion et comptes clients en B2B et configurer les conditions de paiement en B2B
- Demandes de compte d'entreprise et contacts d'entreprise et permissions
- Configurer et gérer les comptes clients
- Extensions d'interface de compte client, leurs cibles et capacités ; l'Authenticated Account API et la Session Token API
- Customer Account API : Customer et DraftOrder
- Headless avec B2B et la Customer Account API avec Hydrogen
- Dépréciation des comptes hérités et ajouts d'identité de Spring '26 : la référence Shopify B2B, vérifiée le 20 septembre 2026
Les extensions, le routage et le comportement du portail de QuotWay sont décrits d'après leur code source (configuration des extensions, client API de l'extension et résolveur de lien acheteur) et la documentation liée ci-dessus.
Articles liés
- Pour les agences ShopifyMigrer des clients grossistes vers les entreprises Shopify : le playbook d'agence14 min de lecture
- Pour les agences ShopifyIntégration ERP, CRM et PIM pour les devis B2B Shopify : les patterns qui tiennent18 min de lecture
- Pour les agences ShopifyCe qui casse entre le devis et la conversion : 17 modes de défaillance de la conversion d'un devis Shopify B2B16 minutes de lecture
Découvrez comment QuotWay gère cela sur votre boutique.