Logo

Qu'est-ce qui a changé dans le mécanisme de rafraîchissement du token hors ligne de Shopify ?

avatar jayce 03 Sep 2026

Si vous maintenez récemment le code d’autorisation de l’application Shopify, cette mise à jour mérite un coup d’œil.

Le 10 décembre 2025, Shopify a précisé dans le changelog des développeurs : le token d’accès hors ligne prend désormais en charge l’expiration et le rafraîchissement. Au 20 mars 2026, un autre changelog a ajouté une phrase plus stricte : après le 1er avril 2026, les nouvelles applications publiques créées et appelant l’API Admin doivent utiliser un token d’accès hors ligne qui expirera.

Ce n’est pas un changement qui va immédiatement interrompre toutes les anciennes applications. Les applications publiques existantes, les applications personnalisées et celles créées par les commerçants dans le back-office ne sont pas concernées par cette règle du 1er avril. Mais si vous développez une nouvelle application ou si vous lancez une nouvelle application publique cette année, il est préférable d’intégrer cette logique de rafraîchissement dès la première version.

L’hypothèse de “installer et utiliser indéfiniment” a disparu

De nombreuses tâches de fond des applications Shopify dépendent du token hors ligne. Par exemple, la synchronisation des commandes, le traitement des webhooks, la récupération programmée des produits, et la génération de rapports pour la boutique. Lorsque le commerçant n’est pas en ligne, l’application doit pouvoir appeler l’API Admin, donc le token hors ligne a toujours été le choix par défaut.

Le traitement courant dans le code ancien est assez simple : le commerçant obtient le token lors de l’installation, puis le stocke dans la base de données ; ensuite, à chaque requête à l’API Admin, il l’insère dans X-Shopify-Access-Token. Tant que le commerçant ne désinstalle pas l’application, l’équipe suppose généralement que ce token peut encore être utilisé.

Le nouveau token hors ligne expirant a détruit cette hypothèse. La documentation officielle est maintenant très claire : la durée de vie d’un token d’accès hors ligne expirant est de 1 heure, et le champ expires_in dans la réponse est de 3600. Un refresh_token est également renvoyé, permettant à l’application d’obtenir un nouveau token d’accès sans déranger le commerçant.

Par exemple, un site indépendant vendant des fournitures pour animaux de compagnie, avec environ deux cents SKU, exécute une synchronisation des stocks toutes les 15 minutes. Auparavant, la tâche de synchronisation se contentait de lire le token hors ligne dans la table de la boutique. Maintenant, elle doit au moins vérifier deux champs supplémentaires : quand le token d’accès expire et si le refresh token est toujours valide. Sinon, la tâche de synchronisation de 1h du matin qui rencontre un 401 pour la première fois pourrait arrêter toute la synchronisation des stocks pour la nuit.

Le rafraîchissement n’est pas un nouveau processus d’installation

Un point clé de ce changement chez Shopify est que le rafraîchissement se produit au niveau de l’endpoint du token, sans que le commerçant ait besoin de réautoriser.

L’endpoint OAuth pour le token fourni par la documentation officielle est :

POST https://{shop}.myshopify.com/admin/oauth/access_token

Si vous utilisez l’échange de token, vous pouvez inclure requested_token_type=urn:shopify:params:oauth:token-type:offline-access-token lors de l’obtention du token hors ligne, et définir expiring à 1. Si vous utilisez le code d’autorisation, vous demandez également un token hors ligne expirant en passant expiring=1 lors de l’échange de code.

Dans la réponse, il ne suffit pas de sauvegarder access_token. Vous devez également sauvegarder ces éléments :

• expires_in : le nombre de secondes restantes pour le token d’accès actuel, qui est maintenant de 3600 secondes selon l’officiel.

• refresh_token : à utiliser pour le rafraîchissement du serveur suivant.

• refresh_token_expires_in : la durée de validité initiale du refresh token, qui est de 7776000 secondes, soit 90 jours selon l’officiel.

Ne codifiez pas 3600 en dur. L’officiel rappelle également que l’application doit lire expires_in dans la réponse, sans supposer que la durée de validité reste constante.

Le risque le plus courant est le rafraîchissement concurrent

La logique de rafraîchissement semble ordinaire, mais le véritable problème réside dans la rotation.

La documentation de Shopify est très détaillée : chaque rafraîchissement renvoie un nouveau token d’accès et un nouveau refresh token. L’application doit les stocker tous les deux, et lors du prochain rafraîchissement, utiliser le nouveau refresh token.

L’ancien refresh token ne devient pas immédiatement invalide au moment où Shopify émet un nouveau token. Il expirera au premier moment parmi plusieurs conditions : l’application a utilisé le nouveau refresh token ; l’application a à nouveau obtenu un nouveau token via l’échange de token ou le code d’autorisation ; l’ancien refresh token a été utilisé pour rafraîchir pour la première fois depuis 30 jours ; ou il a atteint son expiration initiale de 90 jours.

Cette règle a un impact direct sur l’implémentation. Supposons que votre worker de webhook et votre tâche planifiée découvrent tous deux que le token est sur le point d’expirer, et que les deux processus rafraîchissent en même temps. Ils écrivent tous deux le résultat dans la base de données, et celui qui écrit en dernier écrasera le précédent. La prochaine requête pourrait donc dépendre de la condition de concurrence pour savoir quel refresh token est utilisé.

Une approche plus stable consiste à verrouiller au niveau de la boutique, ou à effectuer une mise à jour conditionnelle dans la base de données : n’autoriser l’écriture d’un nouveau token que si le refresh token dans l’enregistrement actuel est toujours celui que vous venez de lire. En cas d’échec du rafraîchissement, relisez l’enregistrement une fois, sans renvoyer immédiatement le commerçant vers OAuth.

401 n’est pas le seul déclencheur

Ne rafraîchir qu’après avoir reçu un 401 peut sauver une partie des requêtes, mais les tâches de fond échoueront une fois de plus. Cela va bien pour les webhooks qui ont des tentatives de réexécution, mais pour les exports manuels ou les mises à jour en masse, l’expérience sera plus brutale.

La recommandation officielle est de rafraîchir quelques minutes à l’avance, et de compléter une branche de rafraîchissement lorsque vous recevez un 401. En pratique, vous pouvez sauvegarder expires_at pour chaque boutique, et vérifier avant la requête si elle est proche de l’expiration. Par exemple, si l’expiration est dans moins de 5 minutes, rafraîchissez d’abord avant de demander à l’API Admin.

Les échecs de rafraîchissement doivent également être signalés séparément. Les raisons peuvent être l’expiration du refresh token, le changement de secret client, la désinstallation de l’application par le commerçant, ou votre stockage qui n’a pas correctement sauvegardé le nouveau refresh token. Tous ces cas peuvent finalement se manifester par un 401, mais la manière de les traiter est différente.

Les anciennes applications peuvent prendre leur temps, mais ne continuez pas à accumuler des dettes techniques

L’exigence du 1er avril 2026 ne concerne que les nouvelles applications publiques. Shopify a également précisé que les applications publiques créées avant le 1er avril ne sont pas temporairement affectées.

Cependant, la documentation sur les tokens d’accès contient une autre échéance : les applications publiques doivent utiliser un token d’accès hors ligne expirant pour demander l’API Admin d’ici le 1er janvier 2027. Les applications personnalisées et celles créées par les commerçants ne sont pas concernées par cette règle.

Ainsi, les anciennes applications ne doivent pas migrer immédiatement, mais si vous êtes déjà en train de modifier la couche d’autorisation, il est préférable de préparer la structure de la table et le chemin de rafraîchissement. Au moins, supprimez d’abord les commentaires tels que “le token hors ligne n’expire jamais”, et ne classez plus les 401 dans les tâches de fond comme étant dues à la désinstallation par le commerçant.

Je n’ai pas encore essayé de vérifier ligne par ligne l’implémentation interne de la dernière bibliothèque dans un projet Shopify réel. L’officiel dit que si vous utilisez les modèles et bibliothèques d’applications Shopify, cette partie est déjà gérée. Pour les projets qui construisent leur propre OAuth, les anciennes applications Rails, ou celles qui ont modifié la couche d’autorisation du modèle, il est toujours conseillé de vérifier vous-même le stockage des tokens et le chemin de rafraîchissement.

Vous pouvez d’abord modifier ces quelques points

Pas besoin de réécrire l’ensemble de l’autorisation dès le départ. Commencez par examiner quatre points :

• Y a-t-il un emplacement dans la base de données pour stocker refresh_token, expires_at, refresh_token_expires_at ?

• Dans l’encapsulation des requêtes de l’API Admin, est-il possible de vérifier l’heure d’expiration avant la requête ?

• Les tâches de fond et les workers de webhook vont-ils rafraîchir simultanément le token de la même boutique ?

• Dans les journaux 401, pouvez-vous distinguer l’expiration du token, le manque de portée, ou la désinstallation de l’application ?

Si l’application utilise encore un token hors ligne non expirant, la nouvelle version peut d’abord ajouter expiring=1 lors de l’installation ou de l’échange de token, puis intégrer la logique de rafraîchissement dans un client API unifié. Ainsi, la synchronisation des produits, la synchronisation des commandes et les tâches de rapport n’auront pas besoin d’écrire chacune leur propre logique de rafraîchissement.

Ce changement n’est pas extravagant, mais il ressemble à Shopify qui standardise l’autorisation des applications vers un comportement OAuth plus standard. Les tâches de fond peuvent continuer à fonctionner, mais à l’avenir, elles ne pourront plus compter sur un token permanent pour soutenir tout le cycle de vie.

Sources officielles :

• https://shopify.dev/changelog/offline-access-tokens-now-support-expiry-and-refresh

• https://shopify.dev/changelog/expiring-offline-access-tokens-required-for-public-apps-april-1-2026

• https://shopify.dev/docs/apps/build/authentication-authorization/access-tokens

Book Free 30-Min Call