Une commande existe dans Shopify, le paiement est visible, mais l’ERP ne prépare rien. Ce blocage logistique reste invisible dans le dernier traitement de synchronisation, terminé sans erreur. Si votre collecte reprend après la date de la dernière commande reçue, le défaut peut tenir dans une seule seconde : plusieurs commandes partagent la même date affichée, et la suivante se retrouve hors du filtre de reprise.
La note Shopify du 19 octobre 2026 précise un changement des filtres temporels exclusifs en API 2026-10. Lorsqu’une borne > ne comporte pas de fraction de seconde, elle exclut désormais la seconde entière. Pour reprendre à partir d’un horodatage reçu sans perdre les autres objets de cette seconde, Shopify recommande >= et une déduplication par identifiant. Ce correctif de sélection doit s’accompagner d’une reprise durable jusqu’à l’ERP.
En pratique, la date de reprise ne doit avancer que sur des commandes durablement conservées, dont l’import ERP reste suivi séparément. Le diagnostic distingue la sélection, la réception et la confirmation métier. Un filtre inclusif ne protège pas un curseur enregistré trop tôt ; le cas fictif ci-dessous permet de reproduire cette perte, puis la reprise correcte après une panne entre deux pages.
Notre accompagnement en intégration API relie ces contrôles au fonctionnement du logiciel de gestion. Pour un raccordement Shopify à un ERP ou un WMS, le résultat attendu est une commande retrouvable et un import explicable, y compris après redémarrage du connecteur. Le prestataire ERP reste associé à la validation des documents, des réservations et des corrections métier.
Pour qui : les collecteurs concernés par la version 2026-10
Partir de la requête envoyée, pas de la version affichée dans un devis
Relevez la version appelée par le worker qui collecte les commandes, la chaîne de recherche réellement transmise et la provenance de son point de reprise. Un export manuel, un connecteur SaaS et une tâche interne peuvent employer trois versions différentes. L’inventaire doit couvrir chaque boutique et chaque processus ; vérifier uniquement la bibliothèque du site marchand ne prouve pas la configuration du middleware qui alimente l’entrepôt.
Selon le changelog officiel des filtres temporels, les applications en 2026-07 ou antérieur ne sont pas affectées par ce changement. Les opérateurs >=, < et <=, les dates sans heure et les bornes contenant une fraction de seconde restent inchangés. La vérification cible donc les bornes exclusives concernées ; elle ne justifie pas une réécriture aveugle de toutes les recherches.
Écarter les autres motifs d’absence avant de relancer
Demandez un identifiant de commande Shopify et recherchez-le dans les traces de collecte, la réception durable et le document ERP. Un mauvais périmètre de boutique, un filtre de statut trop restrictif, une autorisation insuffisante ou un rejet de mapping peuvent produire le même symptôme. La référence de la requête orders permet de vérifier les arguments de recherche et de tri utilisés ; elle ne remplace pas l’observation de votre requête.
Si le traitement ne fait que recevoir des webhooks, commencez par son journal de livraison et de traitement. La recherche temporelle par interrogation périodique, ou polling, peut aussi servir de rapprochement après webhook. Ajouter un nouveau collecteur sans clarifier la déduplication risque de transformer une commande absente en deux commandes ERP. Les deux chemins d’entrée doivent se rejoindre sur la même identité métier.
Vérifiez aussi la profondeur historique autorisée avant de rechercher des absences anciennes. La documentation de l’objet Order indique un accès aux soixante derniers jours par défaut ; l’accès à des commandes plus anciennes exige les autorisations prévues par Shopify. Un résultat vide sur une période inaccessible ne démontre donc pas que le filtre de reprise a perdu les commandes.
Comprendre la commande perdue dans la même seconde
Considérons trois commandes fictives A, B et C, créées respectivement à 12:00:02.100, 12:00:02.800 et 12:00:03.100 UTC. Le collecteur a déjà reçu A et conserve 12:00:02Z comme date de reprise, sans fraction. Ces fractions servent à expliquer la frontière du filtre ; votre connecteur ne doit pas supposer qu’il pourra les reconstruire à partir d’un champ reçu à la seconde.
| Recherche depuis 12:00:02Z | Résultat attendu dans ce modèle | Conséquence de traitement |
|---|---|---|
| Borne exclusive 2026-10 | C seulement | B ne peut pas être récupérée par cette reprise. |
| Borne inclusive | A, B et C | A revient volontairement ; B devient importable. |
| Borne inclusive, A déjà conservée | B et C deviennent de nouvelles réceptions | L’unicité locale absorbe la relecture de A. |
Paradoxalement, accepter davantage de lectures permet de réduire les commandes oubliées. Un doublon de lecture n’est pas encore un doublon de commande ERP. Si le connecteur sait reconnaître une réception déjà conservée, relire une frontière devient une protection. Si chaque ligne reçue crée immédiatement un document sans contrôle d’identité, la même protection révèle un second défaut qu’il faut traiter avant le déploiement.
Ne calculez pas le coût du défaut uniquement avec le nombre d’échecs techniques. Une commande jamais sélectionnée ne produit ni rejet ni ticket automatique. Dans un scénario illustratif de huit commandes retrouvées, vingt minutes d’enquête chacune représentent déjà deux heures quarante de rapprochement, avant les échanges clients et les frais de transport urgents. Ce calcul n’est pas un résultat client ; il montre les postes à mesurer sur votre propre incident.
Construire une fenêtre de collecte et paginer sans la déplacer
Conserver les bornes pendant tout le parcours
Pour une collecte de créations, fixez une borne basse inclusive L et une borne haute exclusive U. Conservez les deux pendant la pagination, avec la boutique, la version et le filtre complet. L’exemple ci-dessous parcourt une minute fictive. La borne haute est un choix de conception pour borner le travail, pas une garantie Shopify de photographie immuable ni une preuve que toutes les commandes sont déjà visibles dans la recherche.
query CollectOrders($after: String, $filter: String!) {
orders(first: 50, after: $after, sortKey: CREATED_AT, query: $filter) {
nodes { id createdAt updatedAt }
pageInfo { hasNextPage endCursor }
}
}
{
"after": null,
"filter": "created_at:>='2026-10-23T12:00:02Z' created_at:<'2026-10-23T12:01:00Z'"
}
La documentation de pagination GraphQL décrit l’emploi de endCursor comme argument after et de hasNextPage pour poursuivre la connexion. Le curseur est opaque : conservez sa valeur au lieu de la décoder pour inventer une date. Gardez aussi le filtre et le tri associés ; un curseur sorti de son contexte n’est pas un point de reprise autonome.
Ne pas confondre créations et modifications de commandes
Une collecte sur created_at répond à la question des nouvelles commandes. Elle ne suffit pas à suivre toutes les évolutions d’une commande déjà connue. Pour un flux de modifications, qualifiez séparément le filtre updated_at, son tri, les champs nécessaires et les règles d’application côté ERP. L’identifiant reste le même lorsque l’adresse ou l’état change ; ignorer pour toujours tout identifiant déjà vu supprimerait ces évolutions.
Pour les créations, une contrainte d’unicité sur le couple boutique et identifiant Shopify peut empêcher une deuxième création locale. Pour les mises à jour, il faut également décider quelle version d’état peut remplacer la précédente et quels effets sont autorisés. Un horodatage à la seconde n’est pas forcément une version totalement ordonnée. Lorsque l’ordre reste ambigu, une nouvelle lecture de l’objet et une comparaison métier sont plus prudentes qu’un classement inventé.
Séparer collecte durable et confirmation dans l’ERP
Nommer les états qui prouvent quelque chose
Une architecture possible conserve d’abord les commandes dans une boîte de réception durable, puis les importe avec un traitement distinct. Le journal de collecte contient les bornes, le curseur, les identifiants reçus et l’issue de stockage. Le journal métier contient les tentatives ERP, la référence du document créé et les rejets à corriger. Le premier peut avancer quand la réception est sûre ; il ne prétend pas que la logistique a déjà accepté chaque commande.
| État local proposé | Preuve attendue | Responsable de la suite |
|---|---|---|
| Collectée | Commande et identité conservées durablement | Traitement d’import du connecteur |
| Rejet ERP | Motif attribué à cette commande, sans effacement de la réception | Équipe métier ou administrateur du référentiel |
| Import incertain | Appel envoyé, confirmation non exploitable | Mainteneur avec rapprochement dans l’ERP |
| Import confirmé | Référence ERP retrouvable et associée à l’identifiant Shopify | Opérations commerciales et logistiques |
Adaptez les noms aux conventions de votre application, mais gardez cette séparation dans les tableaux de suivi. Un rejet d’article inconnu ne doit pas bloquer indéfiniment toute la collecte si la commande reste durablement conservée et assignée. En revanche, une perte de la réception durable doit empêcher de marquer la page comme acquise. Le choix dépend de ce qui peut être retrouvé après un arrêt complet du processus.
Protéger l’écriture qui suit la lecture
Une contrainte unique empêche deux workers d’insérer deux réceptions de la même création. Elle n’assure pas, seule, l’unicité de l’effet dans l’ERP. Si l’ERP a accepté la commande mais que sa réponse se perd, une nouvelle création peut doubler le document. Il faut une référence externe interrogeable, une opération idempotente réellement disponible ou une procédure de rapprochement avant relance, selon l’interface qualifiée avec l’intégrateur ERP.
Ne promettez pas une transaction commune entre Shopify, votre base et le logiciel de gestion. La transaction locale peut lier l’enregistrement d’une page et son curseur si les deux vivent dans la même base. La confirmation distante reste une autre frontière. Le contrat de raccordement doit expliquer laquelle de ces preuves autorise chaque transition, puis prévoir comment le support traite une confirmation absente.
Reprendre après une panne entre deux pages
Une panne peut arriver après la réception HTTP, pendant le stockage, après le stockage mais avant l’enregistrement du curseur, ou après l’écriture ERP. Ces situations ne demandent pas toutes la même relance. Le bon scénario de recette interrompt réellement le worker à ces frontières, puis vérifie ce qui subsiste. Un simple test du cas nominal avec trois commandes ne démontre pas cette propriété.
- Avant de lire, conserver le contexte de la fenêtre et son dernier état durable.
- Enregistrer les objets reçus avec leurs identifiants, puis valider le curseur associé dans la même transaction locale lorsque l’architecture le permet.
- Après une erreur réseau ou GraphQL, garder le dernier point confirmé et qualifier l’erreur avant de poursuivre.
- Si le curseur n’est plus exploitable, repartir du début de la fenêtre bornée et absorber les réceptions déjà connues.
- Clore la collecte lorsque toutes ses pages sont conservées, tout en gardant visibles les imports ERP encore rejetés ou incertains.
Cette politique accepte une relecture après crash, mais refuse de sauter une page dont la conservation n’est pas démontrée. Si le curseur est enregistré avant les objets, un arrêt crée un trou silencieux. Si les objets sont enregistrés avant le curseur sans atomicité, l’arrêt peut créer une relecture : c’est gérable uniquement si l’unicité locale fonctionne. Les deux séquences ne présentent donc pas le même risque.
Gardez un chevauchement de réconciliation dimensionné sur les retards observés, puis un contrôle plus profond pour les anomalies tardives. Aucune durée universelle n’est déduite du changement Shopify. Une marge de quelques minutes choisie sans mesure peut donner une confiance trompeuse. Documentez les retards observés, les limites de visibilité et le délai maximal acceptable pour retrouver une commande avant l’heure de préparation.
Exécuter les cas de frontière sur un jeu fictif
Le programme Python de démonstration reproduit localement les bornes décrites, la relecture d’une création et une interruption après la première page. Il utilise exclusivement des commandes fictives et ne contacte aucune boutique. Le modèle permet de vérifier le raisonnement de reprise ; il ne certifie ni le moteur de recherche Shopify ni les propriétés transactionnelles de votre ERP.
Exécutez python3 shopify_sync_boundaries.py avec Python 3.10 ou supérieur. Les assertions comparent les identifiants attendus, pas seulement le nombre de résultats. Le programme montre aussi le contre-exemple d’un curseur avancé avant stockage : une page disparaît lors de la reprise. Les données intermédiaires sont affichées afin qu’un mainteneur puisse rapprocher chaque résultat de la règle qu’il souhaite implémenter.
- La borne exclusive exclut les deux créations situées dans la seconde de départ.
- La borne inclusive relit A et conserve également B et C.
- Une deuxième lecture ne crée aucune réception supplémentaire pour les identifiants déjà conservés.
- Une panne après la première page laisse une fenêtre inachevée, puis une reprise complète retrouve l’ensemble attendu.
- Une commande exactement à la borne haute appartient à la fenêtre suivante.
- Le même identifiant dans deux boutiques reste deux identités locales distinctes.
Exemple concret de réception : dans le scénario A, B, C et D fourni avec le programme, le seuil d’acceptation est zéro identifiant perdu et zéro réception supplémentaire après rejeu. Le contrôle compare aussi la liste exacte : un total de trois dans la première fenêtre ne suffit pas si B manque et si C est comptée deux fois. D doit rester hors de cette fenêtre et être retrouvée à partir de la borne suivante. Si une assertion échoue, alors la modification du filtre reste à différer jusqu’à l’explication du résultat.
Pour passer du modèle à la recette, préparez plusieurs commandes dans une fenêtre resserrée, conservez les réponses réelles et comparez les parcours sur les versions effectivement accessibles. Rejouez ensuite le connecteur avec ses propres mécanismes de stockage et de reprise. Si la plateforme de recette ne permet pas de contrôler les fractions de seconde, ne prétendez pas les avoir testées : documentez cette limite et gardez le test déterministe local comme preuve du calcul, distincte de la preuve fournisseur.
Retrouver les commandes manquantes sans les réexpédier
Comparer des ensembles identifiables plutôt que deux totaux
Pour une boutique et une période définies, rapprochez les identifiants Shopify attendus, ceux conservés dans la réception et ceux reliés à un document ERP. Deux totaux identiques peuvent masquer une absence et un doublon. Un total de ventes peut aussi diverger pour des raisons de remboursements, de taxes ou de statuts. Commencez par la présence des commandes, puis comparez les montants sur un périmètre comptable explicite.
Classez chaque écart : absent de la collecte, présent mais rejeté, import incertain, confirmé sous une référence différente ou volontairement exclu par une règle métier. Cette classification évite de rejouer un document déjà préparé par l’entrepôt. Lorsqu’une correction manuelle a été réalisée, rattachez sa référence à la réception initiale avant de rouvrir les traitements automatiques. La trace de l’intervention fait partie de la résolution.
Surveiller les signaux que le taux de succès ne montre pas
Premier signal faible : les écarts se concentrent aux instants où le collecteur ferme ses pages ou actualise son point de reprise. Deuxième signal : les traitements restent verts, mais le service client signale des commandes qui n’existent dans aucune file de rejet. Un troisième apparaît lorsque les différences augmentent après le changement de version sans hausse des erreurs HTTP. Ces corrélations orientent l’enquête ; elles ne prouvent pas seules la cause temporelle.
Le monitoring expose l’ancienneté de la dernière fenêtre collectée, les identifiants absents au rapprochement et l’âge des imports ERP non confirmés. Attribuez au support la responsabilité de chaque file d’écarts ; un seuil lié à l’heure de préparation déclenche une décision avant le départ des colis. Le support reçoit une liste de commandes et une action attribuée, plutôt qu’un pourcentage global rassurant. Pour les journaux, limitez les données personnelles au nécessaire et protégez les accès ; un identifiant technique suffit souvent pour suivre la collecte sans recopier toute l’adresse du client.
Erreurs fréquentes : corriger la date sans corriger la reprise
Ajouter artificiellement une seconde à la dernière date reçue
Ce raccourci évite certains doublons apparents en sautant précisément la zone où une autre commande peut exister. La correction doit conserver une frontière relisible, pas fabriquer une progression à partir d’une précision absente. N’inventez pas davantage des millisecondes à partir du rang dans la page : le rang observé ne révèle pas l’instant de création interne.
Pour détecter ce défaut, journalisez la valeur reçue et la valeur réellement utilisée lors de la requête suivante. Un passage de 12:00:02Z à 12:00:03Z fabriqué par le connecteur doit apparaître explicitement. La recette conserve B dans les commandes attendues : sa disparition prouve que la transformation de la date a réduit le périmètre sans justification métier.
Déclarer la fenêtre terminée après une réponse partielle
Une réponse réseau valide peut encore porter des erreurs GraphQL ou un résultat inexploitable pour le traitement prévu. Le parseur doit vérifier les données attendues et l’issue complète de la page avant d’avancer. Après une limitation de débit, une attente bornée conserve le contexte de collecte. Relancer depuis une nouvelle date calculée à l’heure courante abandonnerait la période interrompue.
Le scénario de panne doit conserver un marqueur de page incomplète. La tentative suivante retrouve le filtre, les bornes et la dernière réception confirmée au lieu de créer une nouvelle fenêtre. Vérifiez aussi que les messages d’erreur sont rattachés à la boutique concernée : une file globale sans cette identité rend les relances difficiles à borner.
Utiliser la déduplication des créations pour supprimer les mises à jour
Une commande connue peut encore changer, mais une commande relue ne doit pas automatiquement être recréée. Séparez les opérations métier autorisées et leur identité : création, modification acceptée, annulation ou remboursement. La déduplication de réception protège le transport ; l’application des états et des effets demande un contrat supplémentaire. Cette distinction doit rester visible dans le code et dans les consignes de support.
Ajoutez deux cas distincts à la recette ERP : une relecture strictement identique, puis une commande connue dont un champ autorisé a changé. La première ne produit aucun nouveau document ; la seconde suit la règle de modification validée. Une règle unique « identifiant déjà vu, ignorer » réussirait le premier cas tout en échouant au second.
Plan d’action et preuves à demander avant la migration
Commencez par l’inventaire des collecteurs et des filtres, puis choisissez une boutique pilote représentative. Le mainteneur fournit la version, les bornes, le tri, la pagination et le stockage du point de reprise. Le responsable e-commerce fournit des commandes de référence et les heures limites de préparation. Le partenaire ERP vérifie les références externes et le comportement d’une nouvelle tentative après réponse perdue.
| Décision | Preuve requise | En cas d’échec |
|---|---|---|
| Autoriser le filtre inclusif | Relecture sans deuxième création et conservation de toutes les identités attendues | Corriger l’unicité avant d’augmenter les relances |
| Autoriser la reprise paginée | Arrêt du worker puis récupération des pages sans trou | Revoir l’atomicité du stockage et du curseur |
| Autoriser les imports après incident | Références ERP rapprochées, issues incertaines isolées | Suspendre seulement les commandes concernées |
| Étendre aux autres boutiques | Rapprochement expliqué, procédures exécutables par le support | Maintenir le pilote et qualifier les écarts |
Le contrat de reprise définit un repli compatible avec les données déjà écrites, sous la responsabilité du mainteneur du connecteur. La journalisation doit permettre de retrouver chaque fenêtre et chaque document ERP ; restaurer une ancienne date au hasard ne remplit pas cette condition. Conservez les fenêtres, réceptions et références ERP produites pendant le pilote. Si la nouvelle version doit être retirée, suspendez les nouvelles collectes du périmètre concerné, identifiez les écritures déjà confirmées et préparez une reprise qui conserve leurs identités. Une ancienne version du code peut être incompatible avec un journal transformé : cette compatibilité doit être vérifiée avant le pilote.
Chez Dawap, le cadrage de ce type de connecteur part des flux et des preuves disponibles, avec une recette partagée entre commerce, logistique et SI. Le livrable utile comprend une requête qualifiée, des scénarios de panne, un journal de rapprochement et une procédure de reprise attribuée. Le choix d’une orchestration ou d’un middleware vient ensuite ; aucun outil ne dispense de définir quand une commande peut être considérée comme acquise.
Prolonger le diagnostic vers webhooks, quotas et stock
Une signature invalide explique un autre type de commande absente
Si l’événement n’entre jamais dans le traitement, l’analyse Shopify : signature webhook et JSON réencodé examine la vérification du corps reçu. Il complète le rapprochement temporel lorsque le flux rapide par webhook et la collecte de contrôle ne présentent pas les mêmes commandes.
Conservez une commande présente dans la recherche mais absente des événements traités. Ce cas permet de suivre séparément la livraison du webhook et son traitement, sans attribuer au filtre temporel une perte située avant le journal de réception.
Une limitation de débit doit préserver la fenêtre interrompue
Le dossier Shopify GraphQL THROTTLED : isoler la boutique concernée traite la portée de la limitation et les files d’attente. Il aide à reprendre la bonne boutique sans déplacer ses bornes ni ralentir inutilement les autres raccordements.
Une limitation ne doit pas faire avancer le point de reprise ni déplacer les commandes vers une autre boutique. La reprise conserve le contexte initial ; le délai d’attente et les tentatives restent visibles pour déterminer si la collecte peut encore respecter la préparation logistique.
Un mouvement de stock demande une identité d’effet distincte
Le dossier reprendre un ajustement de stock Shopify sans double comptage examine les mutations et leur réponse incertaine. Une lecture répétée de commande et un ajustement de quantité répété n’ont pas les mêmes conséquences ; les deux protections doivent être qualifiées séparément.
Sources consultées le 23 octobre 2026 : le changelog Shopify du 19 octobre pour le changement de borne, la référence GraphQL orders pour les arguments et la documentation de pagination pour les curseurs. Les scénarios, tables de décision et règles de journalisation proposés ici sont des recommandations d’architecture à éprouver dans votre environnement, sans résultat client ni garantie fournisseur ajoutés aux sources.
Conclusion : avancer seulement sur une collecte démontrée
Une synchronisation fiable doit pouvoir expliquer ce qu’elle a collecté et ce qu’elle a laissé à traiter. La reprise inclusive conserve les commandes proches de la frontière ; la déduplication empêche que leur relecture devienne une nouvelle création. Ces protections se complètent, mais aucune ne remplace la confirmation de l’import dans le logiciel de gestion.
Avant la migration, concentrez la recette sur les endroits où le traitement peut s’interrompre : stockage de la page, enregistrement du curseur et écriture ERP. Le rapprochement par identifiants révèle les absences que le taux de succès des jobs ne voit pas. Les écarts doivent rester assignés jusqu’à leur résolution, même si la collecte suivante s’est terminée normalement.
Le modèle local rend ces arbitrages vérifiables sans accès marchand. La validation réelle doit encore éprouver les autorisations, les réponses, les limites de recherche et les effets ERP de votre connecteur. Garder cette distinction permet de savoir quelles preuves sont acquises et lesquelles conditionnent encore l’extension à d’autres boutiques. Une intégration Shopify reliée à votre ERP doit rendre ce rapprochement accessible au support, y compris après une interruption au milieu d’une page.
Dawap accompagne la conception et la reprise de vos intégrations API entre e-commerce et logiciels métier. Nous pouvons partir de commandes identifiées, reconstituer leur parcours et définir avec votre équipe SI une collecte, un import et un rapprochement exploitables au quotidien.