ADR-0033 — La connexion Shopify principale est une Custom App merchant-owned
BoostEcom n'est pas seulement un lecteur de catalogue. @Atlas doit pouvoir observer et, avec les autorisations internes requises, agir sur l'ensemble de l'admin Shopify que le marchand choisit de lui ouvrir.
Statut
Accepté · 2026-09-22
Piliers : integrations, app-shell, ai-platform
Contexte
BoostEcom n'est pas seulement un lecteur de catalogue. @Atlas doit pouvoir observer et, avec les autorisations internes requises, agir sur l'ensemble de l'admin Shopify que le marchand choisit de lui ouvrir.
Deux modeles ont ete melanges dans le depot :
- une public app Shopify, distribuee par BoostEcom et installee via OAuth ;
- une Custom App merchant-owned, creee par le marchand dans son propre Dev Dashboard, configuree pour sa propre organisation puis reliee a BoostEcom avec son Client ID et son Client Secret.
Le premier donne l'installation la plus courte. Il place en revanche BoostEcom dans le regime de distribution/review d'une app publique, notamment pour des donnees client protegees et certains scopes restreints.
Le second demande quelques actions manuelles au marchand mais laisse
l'application et son grant dans son organisation Shopify. Shopify documente le
client_credentials grant pour une app et un store de la meme organisation :
le Client ID + Client Secret donnent un access token de 24 h, renouvelable en
rejouant le meme echange.
Une ancienne tache, integrations/0599, concluait qu'il fallait abandonner
ce modele avant le 1er janvier 2027. Sa premisse est fausse : Shopify dit
explicitement que l'obligation 2027 sur les offline tokens expirants concerne
les public apps et ne s'applique pas aux custom apps ni aux apps creees par
les marchands.
Sources verifiees le 2026-09-22 :
- https://shopify.dev/docs/apps/build/dev-dashboard/create-apps-using-dev-dashboard
- https://shopify.dev/docs/apps/build/authentication-authorization/client-credentials-grant
- https://shopify.dev/docs/apps/build/authentication-authorization/access-tokens
- https://shopify.dev/changelog/expiring-offline-access-tokens-required-for-all-public-apps-as-of-january-1-2027
- https://shopify.dev/docs/apps/launch/protected-customer-data
- https://shopify.dev/docs/api/usage/access-scopes
Décision
La connexion Shopify par defaut d'une boutique existante est une Custom App merchant-owned creee dans le Dev Dashboard du marchand.
Le marchand :
- cree l'app dans son organisation Shopify ;
- choisit les permissions ;
- release et installe l'app sur sa boutique ;
- fournit a BoostEcom le Client ID et le Client Secret.
BoostEcom :
- chiffre ces credentials au repos ;
- obtient un access token via
client_credentials; - lit
expires_inet renouvelle le token sans intervention humaine ; - lit le grant reel retourne par Shopify ;
- derive de ce grant les capacites accessibles ;
- accepte une connexion partielle et explique ce qui manque.
La public app OAuth Shopify reste un chemin secondaire, utile si un jour le produit choisit consciemment de privilegier une installation 1-clic en acceptant ses contraintes de distribution et de review. Son existence ne change pas la source d'autorite du chemin principal.
Le MCP BoostEcom est en aval : il expose des capacites que BoostEcom possede deja. Il ne remplace jamais l'authentification Shopify.
La promesse produit n'est pas « toutes les APIs Shopify sans limite ». Elle est :
Tout ce que le marchand nous accorde et que Shopify rend disponible pour cette boutique doit etre exploitable par BoostEcom ; aucune limite supplementaire ne doit venir d'une liste de scopes incomplete ou d'un connecteur artificiellement etroit.
La capacite effective est donc l'intersection du grant Shopify reel, des restrictions Shopify/plan, de l'implementation BoostEcom et des autorisations BoostEcom de l'appelant.
Alternatives écartées
| Option | Pourquoi non |
|---|---|
| Public app OAuth comme chemin principal | Meilleur onboarding, mais fait de la distribution/review Shopify une dependance de la couverture fonctionnelle. Pour un produit dont la contrainte premiere est la profondeur d'acces, ce compromis est inverse. |
Token shpat_ colle par le marchand | Nouveau parcours obsolet : les apps merchant-owned modernes du Dev Dashboard donnent Client ID + Client Secret et BoostEcom doit obtenir/renouveler le token lui-meme. Le chemin token ne reste que pour le legacy. |
| MCP Shopify comme auth du store | MCP est une surface d'outils, pas le grant Admin API qui autorise la lecture/ecriture du store. |
| Automatiser le Dev Dashboard du marchand par navigateur | Fragile, opaque sur une operation de securite, et supprimerait precisement le consentement explicite que le modele merchant-owned cherche a conserver. |
| Refuser un grant partiel | Un marchand prudent doit pouvoir connecter son store. Le produit doit degrader ses capacites explicitement, pas transformer une permission refusee en echec d'onboarding. |
Conséquences
Le prix accepte est de l'UX : le marchand doit quitter BoostEcom quelques minutes pour creer/configurer son app. Ce prix se paie dans un wizard guide, pas dans une migration vers une public app par defaut.
Le Client Secret devient un credential durable tres sensible. Il est chiffre,
jamais logge, et sa rotation doit etre un chemin explicite de reconnexion.
L'access token de client_credentials est court (24 h) et doit etre renouvelle
par le backend.
Les restrictions Shopify restent reelles. Certaines capacites peuvent dependre du plan, d'une approbation Shopify ou d'un produit specialise. Elles sont affichees comme telles et mesurees sur le grant reel ; elles ne sont jamais cachees derriere « connexion reussie ».
Le cas des commandes historiques doit etre connection-type-aware. La
documentation generique de read_all_orders decrit le modele Partner, tandis
que Shopify Staff a confirme en 2026 qu'une merchant-owned custom app du Dev
Dashboard peut obtenir l'historique complet avec read_orders. Cette
propriete doit etre testee sur une vraie boutique avant d'etre consideree comme
un invariant BoostEcom.
Le signal pour revisiter cette decision serait un changement Shopify qui retire le modele merchant-owned/client-credentials, ou des donnees montrant que la friction Dev Dashboard rend l'acquisition non viable malgre un wizard guide.
Comment c'est appliqué
Deja en place :
src/app/api/integrations/shopify/custom-app/route.tssrc/features/shopify/sdk/token.ts- metadata
authMethod: "client_credentials" shopifyCapabilityGaps+ rendu des gaps dans l'onboarding
A terminer et garder comme item executif unique :
backlog/integrations/2951-shopify-custom-app-merchant-owned-onboarding-permissions-maximales.md
integrations/0599 est archivé comme remplacé : son calendrier 2027
s'appliquait au mauvais type d'app.