{
  "brand": "Kevmi",
  "version": "2026-10-23.15",
  "updatedAt": "2026-10-23",
  "articles": [
    {
      "id": "quickstart",
      "title": "Démarrage rapide",
      "summary": "Explorez votre espace de travail, configurez votre boutique et voyez une facture telle que votre client la verra. Ce guide vous fait parcourir les principales étapes dans l'ordre.",
      "group": "start",
      "url": "/docs/quickstart",
      "tags": [
        "démarrer",
        "configurer",
        "premier paiement",
        "démarrage rapide"
      ],
      "sections": [
        {
          "id": "explore",
          "title": "1. Explorez le produit",
          "paragraphs": [
            "Ouvrez l'espace de travail de démonstration pour créer une commande de test, explorer les liens de paiement et vérifier un calcul de frais. La démonstration utilise des données de test distinctes. Elle ne crée pas de paiement bancaire ni ne transfère de fonds vers un portefeuille."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Ouvrir l'espace de travail de démonstration",
              "href": "/demo/index.html"
            },
            {
              "label": "Aperçu du paiement",
              "href": "/pay/demo"
            }
          ]
        },
        {
          "id": "account",
          "title": "2. Créez un compte avec Telegram",
          "paragraphs": [
            "Après la connexion via Telegram, le compte marchand s'ouvre. L'intégration sur le site se fait à /account#applications ; le formulaire et le suivi individuel à /account#applications/{id} restent dans l'application.",
            "Un nouveau paiement et une intention de carte nécessitent l'approbation de la dernière demande de revue du site du marchand. L'approbation seule ne connecte pas la passerelle de paiement. Si la revue change après l'envoi, l'opération existante reste disponible pour la lecture des statuts, le rapprochement et un code bancaire demandé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Ouvrir votre compte",
              "href": "/account"
            }
          ]
        },
        {
          "id": "settings",
          "title": "3. Configurez votre boutique",
          "paragraphs": [],
          "bullets": [],
          "steps": [
            "Choisissez un nom de boutique que votre client reconnaîtra.",
            "Choisissez une règle de TVA par défaut. Chaque nouvelle facture accepte séparément les parts de frais client et de TVA de 0 à 100%.",
            "Sélectionnez les notifications que vous souhaitez recevoir dans Telegram.",
            "Utilisez le calculateur pour vérifier un montant de commande typique."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Calculer les frais et la TVA",
              "href": "/pricing"
            }
          ]
        },
        {
          "id": "invoice",
          "title": "4. Préparez un lien de paiement",
          "paragraphs": [
            "Saisissez un titre de commande clair, un montant et une devise. Le client obtient une page dédiée avec les détails de l'achat et le total dû. Une facture existante conserve ses conditions d'origine lorsque les paramètres de votre boutique changent."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Guide des liens de paiement",
              "href": "/docs/payment-links"
            }
          ]
        },
        {
          "id": "activate",
          "title": "5. Vérifiez la disponibilité du paiement",
          "paragraphs": [
            "Gérez les factures, les clés API, les widgets et les webhooks depuis votre compte. Avant le paiement, Kevmi vérifie la configuration de la passerelle, l'approbation du marchand, le montant et les conditions de la facture. Si la méthode sélectionnée est indisponible, le paiement explique pourquoi.",
            "Les factures du nouvel espace de travail utilisent un prix de base en USD et Any propose les quatre méthodes. SBP convertit en RUB au taux de référence gelé de la Banque de Russie ; la crypto utilise la règle de facturation explicite 1:1 USD/USDT. La tarification native héritée reste disponible pour les anciennes factures et les demandes API sans pricingMode=universal. Voir la section multi-boutiques et tarification USD ci-dessous.",
            "Pour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "Créer une facture, une clé ou une demande ne facture pas d'argent. La création de paiement via l'API est indisponible ; les conditions de retrait sont couvertes dans un guide séparé.",
          "links": [
            {
              "label": "Exigences d'intégration de la passerelle",
              "href": "/docs/gateway"
            }
          ]
        },
        {
          "id": "stores-usd",
          "title": "Plusieurs boutiques et un prix de base USD unique",
          "paragraphs": [
            "Choisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.",
            "Les factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.",
            "Le taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.",
            "Créez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.",
            "Pour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "1. Explorez le produit\n\nOuvrez l'espace de travail de démonstration pour créer une commande de test, explorer les liens de paiement et vérifier un calcul de frais. La démonstration utilise des données de test distinctes. Elle ne crée pas de paiement bancaire ni ne transfère de fonds vers un portefeuille.\n\nOuvrir l'espace de travail de démonstration\n\nAperçu du paiement\n\n2. Créez un compte avec Telegram\n\nAprès la connexion via Telegram, le compte marchand s'ouvre. L'intégration sur le site se fait à /account#applications ; le formulaire et le suivi individuel à /account#applications/{id} restent dans l'application.\n\nUn nouveau paiement et une intention de carte nécessitent l'approbation de la dernière demande de revue du site du marchand. L'approbation seule ne connecte pas la passerelle de paiement. Si la revue change après l'envoi, l'opération existante reste disponible pour la lecture des statuts, le rapprochement et un code bancaire demandé.\n\nOuvrir votre compte\n\n3. Configurez votre boutique\n\nChoisissez un nom de boutique que votre client reconnaîtra.\n\nChoisissez une règle de TVA par défaut. Chaque nouvelle facture accepte séparément les parts de frais client et de TVA de 0 à 100%.\n\nSélectionnez les notifications que vous souhaitez recevoir dans Telegram.\n\nUtilisez le calculateur pour vérifier un montant de commande typique.\n\nCalculer les frais et la TVA\n\n4. Préparez un lien de paiement\n\nSaisissez un titre de commande clair, un montant et une devise. Le client obtient une page dédiée avec les détails de l'achat et le total dû. Une facture existante conserve ses conditions d'origine lorsque les paramètres de votre boutique changent.\n\nGuide des liens de paiement\n\n5. Vérifiez la disponibilité du paiement\n\nGérez les factures, les clés API, les widgets et les webhooks depuis votre compte. Avant le paiement, Kevmi vérifie la configuration de la passerelle, l'approbation du marchand, le montant et les conditions de la facture. Si la méthode sélectionnée est indisponible, le paiement explique pourquoi.\n\nLes factures du nouvel espace de travail utilisent un prix de base en USD et Any propose les quatre méthodes. SBP convertit en RUB au taux de référence gelé de la Banque de Russie ; la crypto utilise la règle de facturation explicite 1:1 USD/USDT. La tarification native héritée reste disponible pour les anciennes factures et les demandes API sans pricingMode=universal. Voir la section multi-boutiques et tarification USD ci-dessous.\n\nPour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA.\n\nCréer une facture, une clé ou une demande ne facture pas d'argent. La création de paiement via l'API est indisponible ; les conditions de retrait sont couvertes dans un guide séparé.\n\nExigences d'intégration de la passerelle\n\nPlusieurs boutiques et un prix de base USD unique\n\nChoisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.\n\nLes factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.\n\nLe taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.\n\nCréez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.\n\nPour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé.",
      "readMinutes": 3
    },
    {
      "id": "overview",
      "title": "Comment fonctionne Kevmi",
      "summary": "Kevmi réunit les factures individuelles, les méthodes de paiement et les règles de tarification dans un seul espace de travail. Chaque commande est payée séparément. Il n'y a ni abonnements ni frais récurrents automatiques.",
      "group": "start",
      "url": "/docs/overview",
      "tags": [
        "aperçu",
        "paiements uniques",
        "espace de travail",
        "pas d'abonnements"
      ],
      "sections": [
        {
          "id": "roles",
          "title": "Le marchand et le client",
          "paragraphs": [
            "Le marchand définit un titre de commande, un prix de base, une devise et une répartition fiscale. Le client ouvre une page de paiement dédiée, choisit une méthode disponible et voit le total avant de confirmer.",
            "Le client n'a pas besoin d'accéder à l'espace de travail du marchand. Le paiement expose les détails d'une seule commande, pas le solde de la boutique, les paramètres ou d'autres dossiers clients."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "channels",
          "title": "Quatre canaux de paiement",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Méthode",
              "Public",
              "Frais d'acceptation"
            ],
            "rows": [
              [
                "Cartes internationales",
                "Clients internationaux",
                "10% + 0,50 $ ; TVA de 16%"
              ],
              [
                "SBP",
                "Clients en Russie",
                "8% ; pas de TVA"
              ],
              [
                "Alipay",
                "Clients en Chine",
                "10% + 0,50 $ ; TVA de 16%"
              ],
              [
                "Cryptomonnaie",
                "Paiements crypto",
                "4% ; pas de TVA"
              ]
            ]
          },
          "code": null,
          "note": "Visa et Mastercard sont disponibles dans plus de 190 pays, à l'exception des restrictions publiées. La cryptomonnaie est disponible dans tous les pays.",
          "links": [
            {
              "label": "Pays et restrictions",
              "href": "/docs/geography"
            }
          ]
        },
        {
          "id": "workspace",
          "title": "Dans votre espace de travail",
          "paragraphs": [
            "Les enregistrements du serveur appartiennent au compte vérifié. La démonstration est séparée et ne peut pas créer de paiements en direct ni de solde retirable."
          ],
          "bullets": [
            "Liens de paiement et conditions de commande : /account#links.",
            "Demandes de site et suivi individuel : /account#applications.",
            "Clés API, webhooks, widget et événements : /account#keys, #webhooks, #widget, #events.",
            "Tarification, calculateur, carte des pays et documentation complète : /account#knowledge.",
            "Les paramètres du magasin, les notifications Telegram et les demandes d'assistance restent dans le même compte."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "money",
          "title": "Comprendre les montants",
          "paragraphs": [
            "Le prix de base est le prix des biens ou services avant répartition des coûts. Les frais et la TVA utilisent cette base indépendamment. Les parts client sont ajoutées au paiement ; les parts marchand sont déduites du prix de base. La TVA pour les cartes et Alipay est de 16 %, avec une répartition des frais et de la TVA contrôlée séparément.",
            "La commission de plateforme de Kevmi est déjà incluse dans les frais publiés. Il n'y a pas de surcharge supplémentaire de 5 %. Un versement USDT TRC20 comporte des frais distincts basés sur la source des fonds et une offre de conversion explicite."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Tous les frais",
              "href": "/pricing"
            }
          ]
        },
        {
          "id": "availability",
          "title": "Accès aux fonctionnalités",
          "paragraphs": [
            "La documentation, la calculatrice et l'assistant de documentation sont disponibles sans connexion. Les paramètres du magasin, les liens de paiement et les demandes d'assistance privées nécessitent un compte. La disponibilité financière est vérifiée séparément, et un canal de paiement indisponible est signalé avant toute facturation."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "Le marchand et le client\n\nLe marchand définit un titre de commande, un prix de base, une devise et une répartition fiscale. Le client ouvre une page de paiement dédiée, choisit une méthode disponible et voit le total avant de confirmer.\n\nLe client n'a pas besoin d'accéder à l'espace de travail du marchand. Le paiement expose les détails d'une seule commande, pas le solde de la boutique, les paramètres ou d'autres dossiers clients.\n\nQuatre canaux de paiement\n\nMéthode · Public · Frais d'acceptation\nCartes internationales · Clients internationaux · 10% + 0,50 $ ; TVA de 16%\nSBP · Clients en Russie · 8% ; pas de TVA\nAlipay · Clients en Chine · 10% + 0,50 $ ; TVA de 16%\nCryptomonnaie · Paiements crypto · 4% ; pas de TVA\n\nVisa et Mastercard sont disponibles dans plus de 190 pays, à l'exception des restrictions publiées. La cryptomonnaie est disponible dans tous les pays.\n\nPays et restrictions\n\nDans votre espace de travail\n\nLes enregistrements du serveur appartiennent au compte vérifié. La démonstration est séparée et ne peut pas créer de paiements en direct ni de solde retirable.\n\nLiens de paiement et conditions de commande : /account#links.\n\nDemandes de site et suivi individuel : /account#applications.\n\nClés API, webhooks, widget et événements : /account#keys, #webhooks, #widget, #events.\n\nTarification, calculateur, carte des pays et documentation complète : /account#knowledge.\n\nLes paramètres du magasin, les notifications Telegram et les demandes d'assistance restent dans le même compte.\n\nComprendre les montants\n\nLe prix de base est le prix des biens ou services avant répartition des coûts. Les frais et la TVA utilisent cette base indépendamment. Les parts client sont ajoutées au paiement ; les parts marchand sont déduites du prix de base. La TVA pour les cartes et Alipay est de 16 %, avec une répartition des frais et de la TVA contrôlée séparément.\n\nLa commission de plateforme de Kevmi est déjà incluse dans les frais publiés. Il n'y a pas de surcharge supplémentaire de 5 %. Un versement USDT TRC20 comporte des frais distincts basés sur la source des fonds et une offre de conversion explicite.\n\nTous les frais\n\nAccès aux fonctionnalités\n\nLa documentation, la calculatrice et l'assistant de documentation sont disponibles sans connexion. Les paramètres du magasin, les liens de paiement et les demandes d'assistance privées nécessitent un compte. La disponibilité financière est vérifiée séparément, et un canal de paiement indisponible est signalé avant toute facturation.",
      "readMinutes": 3
    },
    {
      "id": "fees",
      "title": "Frais de paiement et de versement",
      "summary": "Les frais d'acceptation dépendent du mode de paiement et utilisent le prix de base de la commande. La commission de Kevmi est incluse. La TVA et les frais de versement sont affichés séparément.",
      "group": "payments",
      "url": "/docs/fees",
      "tags": [
        "frais",
        "tarification",
        "coût",
        "versement",
        "commission"
      ],
      "sections": [
        {
          "id": "incoming",
          "title": "Accepter un paiement",
          "paragraphs": [
            "Additionnez les composantes en pourcentage et fixes. Pour une commande par carte de $5, les frais sont de $0.50 + $0.50 = $1. La TVA est de $0.80 et est distincte de ces frais.",
            "La part de plateforme, environ 5 % en moyenne, est déjà intégrée à ces conditions. N'ajoutez pas de deuxième pourcentage de plateforme."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Méthode",
              "Pourcentage",
              "Frais fixes",
              "VAT"
            ],
            "rows": [
              [
                "Cartes internationales",
                "10%",
                "$0.50",
                "16 % du prix de base"
              ],
              [
                "Alipay",
                "10%",
                "$0.50",
                "16 % du prix de base"
              ],
              [
                "SBP",
                "8%",
                "Aucun",
                "Aucun"
              ],
              [
                "Cryptomonnaie",
                "4%",
                "Aucun",
                "Aucun"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "payout",
          "title": "Retirer des fonds",
          "paragraphs": [
            "La source des fonds et le réseau de versement sont des paramètres distincts. Utiliser TRC20 ne rend pas tous les frais de versement identiques. Les frais de versement sont distincts des frais d'acceptation.",
            "Conservez les frais fixes dans leur devise indiquée. Ne déduisez pas 400 RUB d'un montant en USD et ne supposez pas que $3 équivaut à 3 USDT. Le versement final nécessite une offre de conversion explicite."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Source des fonds",
              "Frais de versement",
              "Destination"
            ],
            "rows": [
              [
                "Cartes",
                "4%",
                "USDT TRC20"
              ],
              [
                "Alipay",
                "4%",
                "USDT TRC20"
              ],
              [
                "SBP",
                "5 % + 400 RUB",
                "USDT TRC20"
              ],
              [
                "Cryptomonnaie",
                "0% + $3",
                "USDT TRC20"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "rounding",
          "title": "Précision du calcul",
          "paragraphs": [
            "Le montant de facture en unités mineures est un entier : 500 signifie 5,00 USD, RUB ou USDT dans la devise explicitement indiquée. Ce sont des unités de calcul de facture ; USD et USDT ne sont pas automatiquement convertis. Les frais et la TVA utilisent un arrondi séparé au demi supérieur.",
            "Pour un transfert crypto, utilisez le montant exact en décimales de pièce et le réseau renvoyés par l'opération créée. Ne dérivez pas le montant du transfert du prix de facture arrondi. Un calcul ne peut pas produire un produit marchand négatif."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "Formula",
            "code": "feeMinor = roundHalfUp(baseMinor × rate / 100) + fixedMinor\nvatMinor = roundHalfUp(baseMinor × 16 / 100)\n// For SBP and cryptocurrency, vatMinor = 0"
          },
          "note": "",
          "links": []
        },
        {
          "id": "before-pay",
          "title": "Vérifiez avant de payer",
          "paragraphs": [],
          "bullets": [
            "Le montant et la devise d'origine de la commande.",
            "Le mode de paiement, qui détermine les frais et si la TVA s'applique.",
            "Le payeur de TVA enregistré avec la facture.",
            "Le total client et le crédit marchand attendu."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Calculez votre montant",
              "href": "/pricing"
            },
            {
              "label": "Comprendre la TVA",
              "href": "/docs/vat"
            }
          ]
        }
      ],
      "body": "Accepter un paiement\n\nAdditionnez les composantes en pourcentage et fixes. Pour une commande par carte de $5, les frais sont de $0.50 + $0.50 = $1. La TVA est de $0.80 et est distincte de ces frais.\n\nLa part de plateforme, environ 5 % en moyenne, est déjà intégrée à ces conditions. N'ajoutez pas de deuxième pourcentage de plateforme.\n\nMéthode · Pourcentage · Frais fixes · VAT\nCartes internationales · 10% · $0.50 · 16 % du prix de base\nAlipay · 10% · $0.50 · 16 % du prix de base\nSBP · 8% · Aucun · Aucun\nCryptomonnaie · 4% · Aucun · Aucun\n\nRetirer des fonds\n\nLa source des fonds et le réseau de versement sont des paramètres distincts. Utiliser TRC20 ne rend pas tous les frais de versement identiques. Les frais de versement sont distincts des frais d'acceptation.\n\nConservez les frais fixes dans leur devise indiquée. Ne déduisez pas 400 RUB d'un montant en USD et ne supposez pas que $3 équivaut à 3 USDT. Le versement final nécessite une offre de conversion explicite.\n\nSource des fonds · Frais de versement · Destination\nCartes · 4% · USDT TRC20\nAlipay · 4% · USDT TRC20\nSBP · 5 % + 400 RUB · USDT TRC20\nCryptomonnaie · 0% + $3 · USDT TRC20\n\nPrécision du calcul\n\nLe montant de facture en unités mineures est un entier : 500 signifie 5,00 USD, RUB ou USDT dans la devise explicitement indiquée. Ce sont des unités de calcul de facture ; USD et USDT ne sont pas automatiquement convertis. Les frais et la TVA utilisent un arrondi séparé au demi supérieur.\n\nPour un transfert crypto, utilisez le montant exact en décimales de pièce et le réseau renvoyés par l'opération créée. Ne dérivez pas le montant du transfert du prix de facture arrondi. Un calcul ne peut pas produire un produit marchand négatif.\n\nfeeMinor = roundHalfUp(baseMinor × rate / 100) + fixedMinor\nvatMinor = roundHalfUp(baseMinor × 16 / 100)\n// For SBP and cryptocurrency, vatMinor = 0\n\nVérifiez avant de payer\n\nLe montant et la devise d'origine de la commande.\n\nLe mode de paiement, qui détermine les frais et si la TVA s'applique.\n\nLe payeur de TVA enregistré avec la facture.\n\nLe total client et le crédit marchand attendu.\n\nCalculez votre montant\n\nComprendre la TVA",
      "readMinutes": 3
    },
    {
      "id": "vat",
      "title": "TVA et répartition des coûts",
      "summary": "La TVA est de 16 % du prix de base de la commande pour les cartes internationales et Alipay. Le marchand définit une part client de 0 à 100 % et couvre le reste à partir des revenus. SBP et les cryptomonnaies n'ont pas de TVA selon ces conditions publiées.",
      "group": "payments",
      "url": "/docs/vat",
      "tags": [
        "VAT",
        "taxe",
        "client",
        "marchand",
        "cinq dollars"
      ],
      "sections": [
        {
          "id": "base",
          "title": "Une seule base pour les frais et la taxe",
          "paragraphs": [
            "Le prix de base est le montant de la commande saisi par le magasin. Les frais de 10 % + $0.50 et la TVA de 16 % sont calculés indépendamment de ce prix. Les frais ne s'appliquent pas à la TVA ajoutée par-dessus.",
            "Avec un prix de base de $5, les frais sont de $1 et la TVA est de $0.80. Changer le payeur modifie la répartition, pas le taux de taxe ni sa base de calcul."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "customer",
          "title": "Le client paie la TVA",
          "paragraphs": [
            "Il s'agit de la règle de TVA par défaut : une part client de 100 %, équivalente à la valeur client héritée. Le marchand couvre la totalité des frais dans cet exemple. La TVA est ajoutée au prix de base. Le paiement affiche le prix de la commande, la TVA et le total dû.",
            "Seuls les frais d'acceptation sont déduits du prix de base. Pour une commande de $5, le client paie $5.80 et le marchand reçoit $4."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "Formula",
            "code": "customerTotalMinor = baseMinor + vatMinor\nmerchantNetMinor = baseMinor - feeMinor"
          },
          "note": "",
          "links": []
        },
        {
          "id": "merchant",
          "title": "Le marchand paie la TVA",
          "paragraphs": [
            "Dans cet exemple, les parts client sont de 0 % pour la TVA et les frais. La valeur marchand de TVA héritée correspond à une part client de TVA nulle ; le marchand couvre les deux coûts à partir du prix de base.",
            "Pour une commande de $5, le client paie $5, les frais sont de $1, la TVA est de $0.80 et le marchand reçoit $3.20. La TVA reste de 16 % du prix de base ; ne remplacez pas cette règle par une formule 16/116."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "Formula",
            "code": "customerTotalMinor = baseMinor\nmerchantNetMinor = baseMinor - feeMinor - vatMinor"
          },
          "note": "",
          "links": []
        },
        {
          "id": "comparison",
          "title": "Un exemple côte à côte",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Montant",
              "Le client paie la TVA",
              "Le marchand paie la TVA"
            ],
            "rows": [
              [
                "Prix de base de la commande",
                "$5.00",
                "$5.00"
              ],
              [
                "Frais d'acceptation",
                "$1.00",
                "$1.00"
              ],
              [
                "VAT",
                "$0.80",
                "$0.80"
              ],
              [
                "Le client paie",
                "$5.80",
                "$5.00"
              ],
              [
                "Le marchand reçoit",
                "$4.00",
                "$3.20"
              ]
            ]
          },
          "code": null,
          "note": "Les deux colonnes supposent une part de frais de traitement client de 0 %. Des parts de TVA intermédiaires et une répartition distincte des frais sont disponibles dans le calculateur.",
          "links": []
        },
        {
          "id": "snapshot",
          "title": "Lorsque le paramètre s'applique",
          "paragraphs": [
            "La préférence du magasin fournit la répartition initiale. L'interface et l'API enregistrent des parts indépendantes de TVA client et de frais de traitement entières de 0 à 100 pour chaque facture. Les modifications des paramètres du magasin ne recalculent pas les factures émises.",
            "Pour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA.",
            "Créez un nouveau lien pour des conditions différentes. La TVA est nulle pour SBP et les cryptomonnaies."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Paramètres du magasin",
              "href": "/docs/settings"
            },
            {
              "label": "Vérifiez le calcul",
              "href": "/pricing"
            },
            {
              "label": "Répartir les frais de traitement et la TVA",
              "href": "/docs/cost-sharing"
            }
          ]
        }
      ],
      "body": "Une seule base pour les frais et la taxe\n\nLe prix de base est le montant de la commande saisi par le magasin. Les frais de 10 % + $0.50 et la TVA de 16 % sont calculés indépendamment de ce prix. Les frais ne s'appliquent pas à la TVA ajoutée par-dessus.\n\nAvec un prix de base de $5, les frais sont de $1 et la TVA est de $0.80. Changer le payeur modifie la répartition, pas le taux de taxe ni sa base de calcul.\n\nLe client paie la TVA\n\nIl s'agit de la règle de TVA par défaut : une part client de 100 %, équivalente à la valeur client héritée. Le marchand couvre la totalité des frais dans cet exemple. La TVA est ajoutée au prix de base. Le paiement affiche le prix de la commande, la TVA et le total dû.\n\nSeuls les frais d'acceptation sont déduits du prix de base. Pour une commande de $5, le client paie $5.80 et le marchand reçoit $4.\n\ncustomerTotalMinor = baseMinor + vatMinor\nmerchantNetMinor = baseMinor - feeMinor\n\nLe marchand paie la TVA\n\nDans cet exemple, les parts client sont de 0 % pour la TVA et les frais. La valeur marchand de TVA héritée correspond à une part client de TVA nulle ; le marchand couvre les deux coûts à partir du prix de base.\n\nPour une commande de $5, le client paie $5, les frais sont de $1, la TVA est de $0.80 et le marchand reçoit $3.20. La TVA reste de 16 % du prix de base ; ne remplacez pas cette règle par une formule 16/116.\n\ncustomerTotalMinor = baseMinor\nmerchantNetMinor = baseMinor - feeMinor - vatMinor\n\nUn exemple côte à côte\n\nMontant · Le client paie la TVA · Le marchand paie la TVA\nPrix de base de la commande · $5.00 · $5.00\nFrais d'acceptation · $1.00 · $1.00\nVAT · $0.80 · $0.80\nLe client paie · $5.80 · $5.00\nLe marchand reçoit · $4.00 · $3.20\n\nLes deux colonnes supposent une part de frais de traitement client de 0 %. Des parts de TVA intermédiaires et une répartition distincte des frais sont disponibles dans le calculateur.\n\nLorsque le paramètre s'applique\n\nLa préférence du magasin fournit la répartition initiale. L'interface et l'API enregistrent des parts indépendantes de TVA client et de frais de traitement entières de 0 à 100 pour chaque facture. Les modifications des paramètres du magasin ne recalculent pas les factures émises.\n\nPour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA.\n\nCréez un nouveau lien pour des conditions différentes. La TVA est nulle pour SBP et les cryptomonnaies.\n\nParamètres du magasin\n\nVérifiez le calcul\n\nRépartir les frais de traitement et la TVA",
      "readMinutes": 4
    },
    {
      "id": "geography",
      "title": "Pays et méthodes de paiement",
      "summary": "Visa et Mastercard couvrent plus de 190 pays, sauf restrictions publiées. SBP dessert la Russie, Alipay dessert la Chine et les cryptomonnaies sont disponibles dans le monde entier.",
      "group": "payments",
      "url": "/docs/geography",
      "tags": [
        "pays",
        "couverture",
        "190+",
        "Russie",
        "Chine",
        "Îles Åland",
        "Albanie",
        "Algérie",
        "Samoa américaines",
        "Andorre",
        "Angola",
        "Anguilla",
        "Antigua-et-Barbuda",
        "Argentine",
        "Arménie",
        "Aruba",
        "Australie",
        "Autriche",
        "Azerbaïdjan",
        "Bahamas",
        "Bahreïn",
        "Bangladesh",
        "Barbade",
        "Belgique",
        "Belize",
        "Bénin",
        "Bermudes",
        "Bhoutan",
        "Bolivie",
        "Pays-Bas caribéens",
        "Bosnie-Herzégovine",
        "Botswana",
        "Île Bouvet",
        "Brésil",
        "Territoire britannique de l'océan Indien",
        "Brunei",
        "Bulgarie",
        "Burkina Faso",
        "Cap-Vert",
        "Cambodge",
        "Cameroun",
        "Canada",
        "Îles Caïmans",
        "Chili",
        "Chine",
        "Île Christmas",
        "Îles Cocos (Keeling)",
        "Colombie",
        "Comores",
        "Îles Cook",
        "Costa Rica",
        "Croatie",
        "Curaçao",
        "Chypre",
        "Tchéquie",
        "Côte d’Ivoire",
        "Danemark",
        "Djibouti",
        "Dominique",
        "République dominicaine",
        "Équateur",
        "Égypte",
        "Salvador",
        "Guinée équatoriale",
        "Estonie",
        "Eswatini",
        "Éthiopie",
        "Îles Malouines",
        "Îles Féroé",
        "Micronésie",
        "Fidji",
        "Finlande",
        "France",
        "Guyane française",
        "Polynésie française",
        "Terres australes françaises",
        "Gabon",
        "Gambie",
        "Géorgie",
        "Allemagne",
        "Ghana",
        "Gibraltar",
        "Grèce",
        "Groenland",
        "Grenade",
        "Guadeloupe",
        "Guam",
        "Guatemala",
        "Guernesey",
        "Guinée",
        "Guinée-Bissau",
        "Guyana",
        "Îles Heard-et-MacDonald",
        "Cité du Vatican",
        "Honduras",
        "RAS de Hong Kong, Chine",
        "Hongrie",
        "Islande",
        "Inde",
        "Indonésie",
        "Irlande",
        "Île de Man",
        "Israël",
        "Italie",
        "Jamaïque",
        "Japon",
        "Jersey",
        "Jordanie",
        "Kazakhstan",
        "Kenya",
        "Kiribati",
        "Koweït",
        "Kirghizistan",
        "Laos",
        "Lettonie",
        "Liban",
        "Lesotho",
        "Libéria",
        "Liechtenstein",
        "Lituanie",
        "Luxembourg",
        "Région administrative spéciale de Macao, Chine",
        "Madagascar",
        "Malawi",
        "Malaisie",
        "Maldives",
        "Malte",
        "Îles Marshall",
        "Martinique",
        "Mauritanie",
        "Maurice",
        "Mayotte",
        "Mexique",
        "Moldavie",
        "Monaco",
        "Mongolie",
        "Monténégro",
        "Montserrat",
        "Maroc",
        "Mozambique",
        "Namibie",
        "Nauru",
        "Népal",
        "Pays-Bas",
        "Nouvelle-Calédonie",
        "Nouvelle-Zélande",
        "Niger",
        "Nigéria",
        "Nioué",
        "Île Norfolk",
        "Macédoine du Nord",
        "Îles Mariannes du Nord",
        "Norvège",
        "Oman",
        "Pakistan",
        "Palaos",
        "Panama",
        "Papouasie-Nouvelle-Guinée",
        "Paraguay",
        "Pérou",
        "Philippines",
        "Îles Pitcairn",
        "Pologne",
        "Portugal",
        "Porto Rico",
        "Qatar",
        "Roumanie",
        "Rwanda",
        "La Réunion",
        "Saint-Barthélemy",
        "Sainte-Hélène",
        "Saint-Kitts-et-Nevis",
        "Sainte-Lucie",
        "Saint-Martin",
        "Saint-Pierre-et-Miquelon",
        "Saint-Vincent-et-les-Grenadines",
        "Samoa",
        "Saint-Marin",
        "Sao Tomé-et-Principe",
        "Arabie saoudite",
        "Sénégal",
        "Serbie",
        "Seychelles",
        "Sierra Leone",
        "Singapour",
        "Saint-Martin (partie néerlandaise)",
        "Slovaquie",
        "Slovénie",
        "Îles Salomon",
        "Afrique du Sud",
        "Géorgie du Sud-et-les Îles Sandwich du Sud",
        "Corée du Sud",
        "Espagne",
        "Sri Lanka",
        "Territoires palestiniens",
        "Suriname",
        "Svalbard et Jan Mayen",
        "Suède",
        "Suisse",
        "Taïwan",
        "Tadjikistan",
        "Tanzanie",
        "Thaïlande",
        "Timor oriental",
        "Togo",
        "Tokelau",
        "Tonga",
        "Trinité-et-Tobago",
        "Tunisie",
        "Turkménistan",
        "Îles Turques-et-Caïques",
        "Tuvalu",
        "Türkiye",
        "Ouganda",
        "Ukraine",
        "Émirats arabes unis",
        "Royaume-Uni",
        "Îles mineures éloignées des États-Unis",
        "États-Unis",
        "Uruguay",
        "Ouzbékistan",
        "Vanuatu",
        "Vietnam",
        "Îles Vierges britanniques",
        "Îles Vierges des États-Unis",
        "Wallis-et-Futuna",
        "Sahara occidental",
        "Zambie"
      ],
      "sections": [
        {
          "id": "coverage",
          "title": "Couverture par canal",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Canal",
              "Couverture",
              "Conditions"
            ],
            "rows": [
              [
                "Cartes internationales",
                "Plus de 190 pays",
                "Sauf la liste de restrictions et cinq régions d'Ukraine"
              ],
              [
                "SBP",
                "Russie",
                "La disponibilité dépend de la banque et de la transaction"
              ],
              [
                "Alipay",
                "Chine",
                "La disponibilité dépend du compte et de la transaction"
              ],
              [
                "Cryptomonnaie",
                "Tous les pays",
                "Choisissez une pièce et un réseau pris en charge"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "map",
          "title": "La carte interactive",
          "paragraphs": [
            "La page Géographie contient une carte du monde en deux dimensions. Les filtres mettent en évidence les pays de cartes internationales publiés, la Russie pour SBP et la Chine pour Alipay. Recherchez par nom de pays ou code ISO pour voir ses méthodes et ses notes.",
            "Le hachurage marque l'Ukraine car cinq régions sont exclues des cartes. Le reste de l'Ukraine est disponible. Les restrictions de cartes ne s'appliquent pas aux cryptomonnaies, disponibles dans tous les pays."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Ouvrir la carte",
              "href": "/countries"
            }
          ]
        },
        {
          "id": "cards",
          "title": "Ce que couvre la liste",
          "paragraphs": [
            "La liste complète ci-dessous décrit la couverture des cartes internationales. Les pays d'enregistrement des marchands et les destinations de paiement ont des conditions distinctes.",
            "L'approbation dépend du pays émetteur, de la banque, du type de carte et des vérifications du canal de paiement. Le fait qu'un pays soit répertorié ne garantit pas l'approbation pour chaque carte ou transaction."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "restrictions",
          "title": "Restrictions Visa et Mastercard",
          "paragraphs": [
            "Les cartes sont indisponibles en Crimée, à Donetsk, à Louhansk, à Kherson et à Zaporijjia. Le reste de l'Ukraine est disponible.",
            "Tous les autres pays sont disponibles. Les Antilles néerlandaises sont conservées comme entrée historique de la liste du fournisseur ; elles ne bloquent pas tous les territoires caribéens modernes."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Code",
              "Pays ou territoire"
            ],
            "rows": [
              [
                "AF",
                "Afghanistan"
              ],
              [
                "AQ",
                "Antarctique"
              ],
              [
                "BY",
                "Biélorussie"
              ],
              [
                "MM",
                "Birmanie (Myanmar)"
              ],
              [
                "BI",
                "Burundi"
              ],
              [
                "CF",
                "République centrafricaine"
              ],
              [
                "TD",
                "Tchad"
              ],
              [
                "CU",
                "Cuba"
              ],
              [
                "CD",
                "République démocratique du Congo"
              ],
              [
                "CG",
                "République du Congo"
              ],
              [
                "ER",
                "Érythrée"
              ],
              [
                "HT",
                "Haïti"
              ],
              [
                "IR",
                "Iran"
              ],
              [
                "IQ",
                "Irak"
              ],
              [
                "LY",
                "Libye"
              ],
              [
                "ML",
                "Mali"
              ],
              [
                "NI",
                "Nicaragua"
              ],
              [
                "KP",
                "Corée du Nord"
              ],
              [
                "RU",
                "Russie"
              ],
              [
                "SO",
                "Somalie"
              ],
              [
                "SS",
                "Soudan du Sud"
              ],
              [
                "SD",
                "Soudan"
              ],
              [
                "SY",
                "Syrie"
              ],
              [
                "VE",
                "Venezuela"
              ],
              [
                "YE",
                "Yémen"
              ],
              [
                "ZW",
                "Zimbabwe"
              ],
              [
                "UA-43",
                "Crimée (région d'Ukraine)"
              ],
              [
                "UA-14",
                "Donetsk (région d'Ukraine)"
              ],
              [
                "UA-65",
                "Kherson (région d'Ukraine)"
              ],
              [
                "UA-09",
                "Louhansk (région d'Ukraine)"
              ],
              [
                "UA-23",
                "Zaporijjia (région d'Ukraine)"
              ],
              [
                "AN",
                "Antilles néerlandaises"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "card-list",
          "title": "Répertoire des pays et territoires",
          "paragraphs": [
            "Les noms, les codes ISO et les marqueurs proviennent du registre commun des pays. Ces notes s'appliquent aux cartes internationales."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "ISO",
              "Pays ou territoire",
              "Note"
            ],
            "rows": [
              [
                "AX",
                "Îles Åland",
                "—"
              ],
              [
                "AL",
                "Albanie",
                "—"
              ],
              [
                "DZ",
                "Algérie",
                "—"
              ],
              [
                "AS",
                "Samoa américaines",
                "—"
              ],
              [
                "AD",
                "Andorre",
                "—"
              ],
              [
                "AO",
                "Angola",
                "—"
              ],
              [
                "AI",
                "Anguilla",
                "—"
              ],
              [
                "AG",
                "Antigua-et-Barbuda",
                "—"
              ],
              [
                "AR",
                "Argentine",
                "—"
              ],
              [
                "AM",
                "Arménie",
                "—"
              ],
              [
                "AW",
                "Aruba",
                "—"
              ],
              [
                "AU",
                "Australie",
                "—"
              ],
              [
                "AT",
                "Autriche",
                "—"
              ],
              [
                "AZ",
                "Azerbaïdjan",
                "—"
              ],
              [
                "BS",
                "Bahamas",
                "—"
              ],
              [
                "BH",
                "Bahreïn",
                "—"
              ],
              [
                "BD",
                "Bangladesh",
                "—"
              ],
              [
                "BB",
                "Barbade",
                "—"
              ],
              [
                "BE",
                "Belgique",
                "—"
              ],
              [
                "BZ",
                "Belize",
                "—"
              ],
              [
                "BJ",
                "Bénin",
                "—"
              ],
              [
                "BM",
                "Bermudes",
                "—"
              ],
              [
                "BT",
                "Bhoutan",
                "—"
              ],
              [
                "BO",
                "Bolivie",
                "—"
              ],
              [
                "BQ",
                "Pays-Bas caribéens",
                "—"
              ],
              [
                "BA",
                "Bosnie-Herzégovine",
                "—"
              ],
              [
                "BW",
                "Botswana",
                "—"
              ],
              [
                "BV",
                "Île Bouvet",
                "—"
              ],
              [
                "BR",
                "Brésil",
                "—"
              ],
              [
                "IO",
                "Territoire britannique de l'océan Indien",
                "—"
              ],
              [
                "BN",
                "Brunei",
                "—"
              ],
              [
                "BG",
                "Bulgarie",
                "—"
              ],
              [
                "BF",
                "Burkina Faso",
                "—"
              ],
              [
                "CV",
                "Cap-Vert",
                "—"
              ],
              [
                "KH",
                "Cambodge",
                "—"
              ],
              [
                "CM",
                "Cameroun",
                "—"
              ],
              [
                "CA",
                "Canada",
                "—"
              ],
              [
                "KY",
                "Îles Caïmans",
                "—"
              ],
              [
                "CL",
                "Chili",
                "—"
              ],
              [
                "CN",
                "Chine",
                "—"
              ],
              [
                "CX",
                "Île Christmas",
                "—"
              ],
              [
                "CC",
                "Îles Cocos (Keeling)",
                "—"
              ],
              [
                "CO",
                "Colombie",
                "—"
              ],
              [
                "KM",
                "Comores",
                "—"
              ],
              [
                "CK",
                "Îles Cook",
                "—"
              ],
              [
                "CR",
                "Costa Rica",
                "—"
              ],
              [
                "HR",
                "Croatie",
                "—"
              ],
              [
                "CW",
                "Curaçao",
                "—"
              ],
              [
                "CY",
                "Chypre",
                "—"
              ],
              [
                "CZ",
                "Tchéquie",
                "—"
              ],
              [
                "CI",
                "Côte d’Ivoire",
                "—"
              ],
              [
                "DK",
                "Danemark",
                "—"
              ],
              [
                "DJ",
                "Djibouti",
                "—"
              ],
              [
                "DM",
                "Dominique",
                "—"
              ],
              [
                "DO",
                "République dominicaine",
                "—"
              ],
              [
                "EC",
                "Équateur",
                "—"
              ],
              [
                "EG",
                "Égypte",
                "—"
              ],
              [
                "SV",
                "Salvador",
                "—"
              ],
              [
                "GQ",
                "Guinée équatoriale",
                "—"
              ],
              [
                "EE",
                "Estonie",
                "—"
              ],
              [
                "SZ",
                "Eswatini",
                "—"
              ],
              [
                "ET",
                "Éthiopie",
                "—"
              ],
              [
                "FK",
                "Îles Malouines",
                "—"
              ],
              [
                "FO",
                "Îles Féroé",
                "—"
              ],
              [
                "FM",
                "Micronésie",
                "—"
              ],
              [
                "FJ",
                "Fidji",
                "—"
              ],
              [
                "FI",
                "Finlande",
                "—"
              ],
              [
                "FR",
                "France",
                "—"
              ],
              [
                "GF",
                "Guyane française",
                "—"
              ],
              [
                "PF",
                "Polynésie française",
                "—"
              ],
              [
                "TF",
                "Terres australes françaises",
                "—"
              ],
              [
                "GA",
                "Gabon",
                "—"
              ],
              [
                "GM",
                "Gambie",
                "—"
              ],
              [
                "GE",
                "Géorgie",
                "—"
              ],
              [
                "DE",
                "Allemagne",
                "—"
              ],
              [
                "GH",
                "Ghana",
                "—"
              ],
              [
                "GI",
                "Gibraltar",
                "—"
              ],
              [
                "GR",
                "Grèce",
                "—"
              ],
              [
                "GL",
                "Groenland",
                "—"
              ],
              [
                "GD",
                "Grenade",
                "—"
              ],
              [
                "GP",
                "Guadeloupe",
                "—"
              ],
              [
                "GU",
                "Guam",
                "—"
              ],
              [
                "GT",
                "Guatemala",
                "—"
              ],
              [
                "GG",
                "Guernesey",
                "—"
              ],
              [
                "GN",
                "Guinée",
                "—"
              ],
              [
                "GW",
                "Guinée-Bissau",
                "—"
              ],
              [
                "GY",
                "Guyana",
                "—"
              ],
              [
                "HM",
                "Îles Heard-et-MacDonald",
                "—"
              ],
              [
                "VA",
                "Cité du Vatican",
                "—"
              ],
              [
                "HN",
                "Honduras",
                "—"
              ],
              [
                "HK",
                "RAS de Hong Kong, Chine",
                "—"
              ],
              [
                "HU",
                "Hongrie",
                "—"
              ],
              [
                "IS",
                "Islande",
                "—"
              ],
              [
                "IN",
                "Inde",
                "—"
              ],
              [
                "ID",
                "Indonésie",
                "—"
              ],
              [
                "IE",
                "Irlande",
                "—"
              ],
              [
                "IM",
                "Île de Man",
                "—"
              ],
              [
                "IL",
                "Israël",
                "—"
              ],
              [
                "IT",
                "Italie",
                "—"
              ],
              [
                "JM",
                "Jamaïque",
                "—"
              ],
              [
                "JP",
                "Japon",
                "—"
              ],
              [
                "JE",
                "Jersey",
                "—"
              ],
              [
                "JO",
                "Jordanie",
                "—"
              ],
              [
                "KZ",
                "Kazakhstan",
                "—"
              ],
              [
                "KE",
                "Kenya",
                "—"
              ],
              [
                "KI",
                "Kiribati",
                "—"
              ],
              [
                "KW",
                "Koweït",
                "—"
              ],
              [
                "KG",
                "Kirghizistan",
                "—"
              ],
              [
                "LA",
                "Laos",
                "—"
              ],
              [
                "LV",
                "Lettonie",
                "—"
              ],
              [
                "LB",
                "Liban",
                "—"
              ],
              [
                "LS",
                "Lesotho",
                "—"
              ],
              [
                "LR",
                "Libéria",
                "—"
              ],
              [
                "LI",
                "Liechtenstein",
                "—"
              ],
              [
                "LT",
                "Lituanie",
                "—"
              ],
              [
                "LU",
                "Luxembourg",
                "—"
              ],
              [
                "MO",
                "Région administrative spéciale de Macao, Chine",
                "—"
              ],
              [
                "MG",
                "Madagascar",
                "—"
              ],
              [
                "MW",
                "Malawi",
                "—"
              ],
              [
                "MY",
                "Malaisie",
                "—"
              ],
              [
                "MV",
                "Maldives",
                "—"
              ],
              [
                "MT",
                "Malte",
                "—"
              ],
              [
                "MH",
                "Îles Marshall",
                "—"
              ],
              [
                "MQ",
                "Martinique",
                "—"
              ],
              [
                "MR",
                "Mauritanie",
                "—"
              ],
              [
                "MU",
                "Maurice",
                "—"
              ],
              [
                "YT",
                "Mayotte",
                "—"
              ],
              [
                "MX",
                "Mexique",
                "—"
              ],
              [
                "MD",
                "Moldavie",
                "—"
              ],
              [
                "MC",
                "Monaco",
                "—"
              ],
              [
                "MN",
                "Mongolie",
                "—"
              ],
              [
                "ME",
                "Monténégro",
                "—"
              ],
              [
                "MS",
                "Montserrat",
                "—"
              ],
              [
                "MA",
                "Maroc",
                "—"
              ],
              [
                "MZ",
                "Mozambique",
                "—"
              ],
              [
                "NA",
                "Namibie",
                "—"
              ],
              [
                "NR",
                "Nauru",
                "—"
              ],
              [
                "NP",
                "Népal",
                "—"
              ],
              [
                "NL",
                "Pays-Bas",
                "—"
              ],
              [
                "NC",
                "Nouvelle-Calédonie",
                "—"
              ],
              [
                "NZ",
                "Nouvelle-Zélande",
                "—"
              ],
              [
                "NE",
                "Niger",
                "—"
              ],
              [
                "NG",
                "Nigéria",
                "—"
              ],
              [
                "NU",
                "Nioué",
                "—"
              ],
              [
                "NF",
                "Île Norfolk",
                "—"
              ],
              [
                "MK",
                "Macédoine du Nord",
                "—"
              ],
              [
                "MP",
                "Îles Mariannes du Nord",
                "—"
              ],
              [
                "NO",
                "Norvège",
                "—"
              ],
              [
                "OM",
                "Oman",
                "—"
              ],
              [
                "PK",
                "Pakistan",
                "—"
              ],
              [
                "PW",
                "Palaos",
                "—"
              ],
              [
                "PA",
                "Panama",
                "—"
              ],
              [
                "PG",
                "Papouasie-Nouvelle-Guinée",
                "—"
              ],
              [
                "PY",
                "Paraguay",
                "—"
              ],
              [
                "PE",
                "Pérou",
                "—"
              ],
              [
                "PH",
                "Philippines",
                "—"
              ],
              [
                "PN",
                "Îles Pitcairn",
                "—"
              ],
              [
                "PL",
                "Pologne",
                "—"
              ],
              [
                "PT",
                "Portugal",
                "—"
              ],
              [
                "PR",
                "Porto Rico",
                "—"
              ],
              [
                "QA",
                "Qatar",
                "—"
              ],
              [
                "RO",
                "Roumanie",
                "—"
              ],
              [
                "RW",
                "Rwanda",
                "—"
              ],
              [
                "RE",
                "La Réunion",
                "—"
              ],
              [
                "BL",
                "Saint-Barthélemy",
                "—"
              ],
              [
                "SH",
                "Sainte-Hélène",
                "—"
              ],
              [
                "KN",
                "Saint-Kitts-et-Nevis",
                "—"
              ],
              [
                "LC",
                "Sainte-Lucie",
                "—"
              ],
              [
                "MF",
                "Saint-Martin",
                "—"
              ],
              [
                "PM",
                "Saint-Pierre-et-Miquelon",
                "—"
              ],
              [
                "VC",
                "Saint-Vincent-et-les-Grenadines",
                "—"
              ],
              [
                "WS",
                "Samoa",
                "—"
              ],
              [
                "SM",
                "Saint-Marin",
                "—"
              ],
              [
                "ST",
                "Sao Tomé-et-Principe",
                "—"
              ],
              [
                "SA",
                "Arabie saoudite",
                "—"
              ],
              [
                "SN",
                "Sénégal",
                "—"
              ],
              [
                "RS",
                "Serbie",
                "—"
              ],
              [
                "SC",
                "Seychelles",
                "—"
              ],
              [
                "SL",
                "Sierra Leone",
                "—"
              ],
              [
                "SG",
                "Singapour",
                "—"
              ],
              [
                "SX",
                "Saint-Martin (partie néerlandaise)",
                "—"
              ],
              [
                "SK",
                "Slovaquie",
                "—"
              ],
              [
                "SI",
                "Slovénie",
                "—"
              ],
              [
                "SB",
                "Îles Salomon",
                "—"
              ],
              [
                "ZA",
                "Afrique du Sud",
                "—"
              ],
              [
                "GS",
                "Géorgie du Sud-et-les Îles Sandwich du Sud",
                "—"
              ],
              [
                "KR",
                "Corée du Sud",
                "—"
              ],
              [
                "ES",
                "Espagne",
                "—"
              ],
              [
                "LK",
                "Sri Lanka",
                "—"
              ],
              [
                "PS",
                "Territoires palestiniens",
                "—"
              ],
              [
                "SR",
                "Suriname",
                "—"
              ],
              [
                "SJ",
                "Svalbard et Jan Mayen",
                "—"
              ],
              [
                "SE",
                "Suède",
                "—"
              ],
              [
                "CH",
                "Suisse",
                "—"
              ],
              [
                "TW",
                "Taïwan",
                "—"
              ],
              [
                "TJ",
                "Tadjikistan",
                "—"
              ],
              [
                "TZ",
                "Tanzanie",
                "—"
              ],
              [
                "TH",
                "Thaïlande",
                "—"
              ],
              [
                "TL",
                "Timor oriental",
                "—"
              ],
              [
                "TG",
                "Togo",
                "—"
              ],
              [
                "TK",
                "Tokelau",
                "—"
              ],
              [
                "TO",
                "Tonga",
                "—"
              ],
              [
                "TT",
                "Trinité-et-Tobago",
                "—"
              ],
              [
                "TN",
                "Tunisie",
                "—"
              ],
              [
                "TM",
                "Turkménistan",
                "—"
              ],
              [
                "TC",
                "Îles Turques-et-Caïques",
                "—"
              ],
              [
                "TV",
                "Tuvalu",
                "—"
              ],
              [
                "TR",
                "Türkiye",
                "—"
              ],
              [
                "UG",
                "Ouganda",
                "—"
              ],
              [
                "UA",
                "Ukraine**",
                "Les cartes sont indisponibles en Crimée, à Donetsk, à Louhansk, à Kherson et à Zaporijjia. Le reste de l'Ukraine est disponible."
              ],
              [
                "AE",
                "Émirats arabes unis",
                "—"
              ],
              [
                "GB",
                "Royaume-Uni",
                "—"
              ],
              [
                "UM",
                "Îles mineures éloignées des États-Unis",
                "—"
              ],
              [
                "US",
                "États-Unis",
                "—"
              ],
              [
                "UY",
                "Uruguay",
                "—"
              ],
              [
                "UZ",
                "Ouzbékistan",
                "—"
              ],
              [
                "VU",
                "Vanuatu",
                "—"
              ],
              [
                "VN",
                "Vietnam",
                "—"
              ],
              [
                "VG",
                "Îles Vierges britanniques",
                "—"
              ],
              [
                "VI",
                "Îles Vierges des États-Unis",
                "—"
              ],
              [
                "WF",
                "Wallis-et-Futuna",
                "—"
              ],
              [
                "EH",
                "Sahara occidental",
                "—"
              ],
              [
                "ZM",
                "Zambie",
                "—"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "crypto",
          "title": "Pièces et réseaux de paiement",
          "paragraphs": [
            "Le catalogue contient 16 pièces et 31 paires pièce/réseau. Une pièce peut être acceptée sur plusieurs réseaux : USDT sur Tron et USDT sur Ethereum sont des options de transfert différentes. La liste complète apparaît ci-dessous.",
            "Les options disponibles pour une facture spécifique et leurs limites proviennent de GET /api/checkout/{token}/crypto-services. Cette page décrit les combinaisons prises en charge ; la réponse actuelle de la passerelle détermine si un paiement peut être créé. Une entrée de référence seule ne rend pas une paire indisponible payable.",
            "Le marchand crée une facture crypto en USDT, et le client choisit une pièce et un réseau disponibles. L'opération de passerelle créée fournit le montant exact de la pièce, l'adresse, le code QR et l'expiration. Le prix d'une facture USDT ne fige pas le taux de change du BTC, de l'ETH ou d'une autre pièce, et n'implique pas un taux de 1:1. Transférez le montant décimal exact selon les instructions de paiement sans arrondir ni calculer vous-même une conversion.",
            "USDT TRC20 est un terme distinct de paiement au marchand. Il ne restreint pas les paiements entrants à Tron et ne signifie pas que la création de paiements est disponible via le compte ou l'API. Le guide des paiements explique les conditions et restrictions de retrait."
          ],
          "bullets": [],
          "steps": [
            "Ouvrez la facture et choisissez la cryptomonnaie comme méthode de paiement.",
            "Choisissez une pièce et un réseau disponible. Le réseau du portefeuille de l'expéditeur doit correspondre au réseau indiqué dans les instructions de paiement Kevmi.",
            "Créez les instructions de paiement et vérifiez le montant exact, l'adresse complète et l'expiration. Copiez l'adresse et le montant, ou utilisez le code QR approprié.",
            "Envoyez le montant spécifié sur le réseau sélectionné. Tenez compte des frais de portefeuille ou de réseau afin que le destinataire reçoive le montant complet indiqué dans les instructions.",
            "Attendez un statut confirmé lors du paiement. L'envoi d'un transfert de portefeuille seul ne complète pas la commande : Kevmi vérifie le résultat via la passerelle."
          ],
          "table": {
            "headers": [
              "Pièce",
              "Nom",
              "Réseaux et codes de passerelle"
            ],
            "rows": [
              [
                "AVAX",
                "Avalanche",
                "Avalanche C-Chain (avalanche)"
              ],
              [
                "BCH",
                "Bitcoin Cash",
                "Bitcoin Cash (bch)"
              ],
              [
                "BNB",
                "BNB",
                "BNB Smart Chain (bsc)"
              ],
              [
                "BTC",
                "Bitcoin",
                "Bitcoin (btc)"
              ],
              [
                "DAI",
                "Dai",
                "BNB Smart Chain (bsc), Ethereum (eth), Polygon PoS (polygon)"
              ],
              [
                "DASH",
                "Dash",
                "Dash (dash)"
              ],
              [
                "DOGE",
                "Dogecoin",
                "Dogecoin (doge)"
              ],
              [
                "ETH",
                "Ethereum",
                "Ethereum (eth), Arbitrum One (arbitrum), BNB Smart Chain (bsc)"
              ],
              [
                "GRAM",
                "Gram",
                "TON (ton)"
              ],
              [
                "LTC",
                "Litecoin",
                "Litecoin (ltc)"
              ],
              [
                "POL",
                "Polygon",
                "Ethereum (eth), Polygon PoS (polygon)"
              ],
              [
                "SHIB",
                "Shiba Inu",
                "Ethereum (eth)"
              ],
              [
                "TRX",
                "TRON",
                "TRON (tron)"
              ],
              [
                "USDC",
                "USD Coin",
                "Arbitrum One (arbitrum), BNB Smart Chain (bsc), Polygon PoS (polygon), Ethereum (eth), Avalanche C-Chain (avalanche)"
              ],
              [
                "USDT",
                "Tether",
                "TRON (tron), Avalanche C-Chain (avalanche), BNB Smart Chain (bsc), TON (ton), Polygon PoS (polygon), Arbitrum One (arbitrum), Ethereum (eth)"
              ],
              [
                "XMR",
                "Monero",
                "Monero (xmr)"
              ]
            ]
          },
          "code": null,
          "note": "N'utilisez pas d'anciennes instructions de paiement après expiration. Si vous avez déjà envoyé des fonds, vérifiez la même opération et contactez le support si nécessaire ; ne créez pas un second paiement pour vérifier le premier.",
          "links": [
            {
              "label": "Paiement",
              "href": "/docs/checkout#method"
            },
            {
              "label": "Conditions de paiement",
              "href": "/docs/payouts"
            }
          ]
        },
        {
          "id": "specific",
          "title": "Vérification d'un pays spécifique",
          "paragraphs": [
            "L'assistant peut trouver un pays par son nom russe ou anglais ou son code ISO et expliquer son indicateur publié. Pour les pays **, précisez l'emplacement dont vous avez besoin. Pour la Chine *, demandez des informations sur votre carte.",
            "Si un pays est absent de la liste, cette base de connaissances ne peut pas confirmer la couverture internationale des cartes. Incluez le pays, la banque et la méthode souhaitée dans une demande de support. N'envoyez pas de numéro de carte complet ni de secrets de paiement."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Géographie",
              "href": "/countries"
            },
            {
              "label": "Demander au support",
              "href": "/?support=open"
            }
          ]
        }
      ],
      "body": "Couverture par canal\n\nCanal · Couverture · Conditions\nCartes internationales · Plus de 190 pays · Sauf la liste de restrictions et cinq régions d'Ukraine\nSBP · Russie · La disponibilité dépend de la banque et de la transaction\nAlipay · Chine · La disponibilité dépend du compte et de la transaction\nCryptomonnaie · Tous les pays · Choisissez une pièce et un réseau pris en charge\n\nLa carte interactive\n\nLa page Géographie contient une carte du monde en deux dimensions. Les filtres mettent en évidence les pays de cartes internationales publiés, la Russie pour SBP et la Chine pour Alipay. Recherchez par nom de pays ou code ISO pour voir ses méthodes et ses notes.\n\nLe hachurage marque l'Ukraine car cinq régions sont exclues des cartes. Le reste de l'Ukraine est disponible. Les restrictions de cartes ne s'appliquent pas aux cryptomonnaies, disponibles dans tous les pays.\n\nOuvrir la carte\n\nCe que couvre la liste\n\nLa liste complète ci-dessous décrit la couverture des cartes internationales. Les pays d'enregistrement des marchands et les destinations de paiement ont des conditions distinctes.\n\nL'approbation dépend du pays émetteur, de la banque, du type de carte et des vérifications du canal de paiement. Le fait qu'un pays soit répertorié ne garantit pas l'approbation pour chaque carte ou transaction.\n\nRestrictions Visa et Mastercard\n\nLes cartes sont indisponibles en Crimée, à Donetsk, à Louhansk, à Kherson et à Zaporijjia. Le reste de l'Ukraine est disponible.\n\nTous les autres pays sont disponibles. Les Antilles néerlandaises sont conservées comme entrée historique de la liste du fournisseur ; elles ne bloquent pas tous les territoires caribéens modernes.\n\nCode · Pays ou territoire\nAF · Afghanistan\nAQ · Antarctique\nBY · Biélorussie\nMM · Birmanie (Myanmar)\nBI · Burundi\nCF · République centrafricaine\nTD · Tchad\nCU · Cuba\nCD · République démocratique du Congo\nCG · République du Congo\nER · Érythrée\nHT · Haïti\nIR · Iran\nIQ · Irak\nLY · Libye\nML · Mali\nNI · Nicaragua\nKP · Corée du Nord\nRU · Russie\nSO · Somalie\nSS · Soudan du Sud\nSD · Soudan\nSY · Syrie\nVE · Venezuela\nYE · Yémen\nZW · Zimbabwe\nUA-43 · Crimée (région d'Ukraine)\nUA-14 · Donetsk (région d'Ukraine)\nUA-65 · Kherson (région d'Ukraine)\nUA-09 · Louhansk (région d'Ukraine)\nUA-23 · Zaporijjia (région d'Ukraine)\nAN · Antilles néerlandaises\n\nRépertoire des pays et territoires\n\nLes noms, les codes ISO et les marqueurs proviennent du registre commun des pays. Ces notes s'appliquent aux cartes internationales.\n\nISO · Pays ou territoire · Note\nAX · Îles Åland · —\nAL · Albanie · —\nDZ · Algérie · —\nAS · Samoa américaines · —\nAD · Andorre · —\nAO · Angola · —\nAI · Anguilla · —\nAG · Antigua-et-Barbuda · —\nAR · Argentine · —\nAM · Arménie · —\nAW · Aruba · —\nAU · Australie · —\nAT · Autriche · —\nAZ · Azerbaïdjan · —\nBS · Bahamas · —\nBH · Bahreïn · —\nBD · Bangladesh · —\nBB · Barbade · —\nBE · Belgique · —\nBZ · Belize · —\nBJ · Bénin · —\nBM · Bermudes · —\nBT · Bhoutan · —\nBO · Bolivie · —\nBQ · Pays-Bas caribéens · —\nBA · Bosnie-Herzégovine · —\nBW · Botswana · —\nBV · Île Bouvet · —\nBR · Brésil · —\nIO · Territoire britannique de l'océan Indien · —\nBN · Brunei · —\nBG · Bulgarie · —\nBF · Burkina Faso · —\nCV · Cap-Vert · —\nKH · Cambodge · —\nCM · Cameroun · —\nCA · Canada · —\nKY · Îles Caïmans · —\nCL · Chili · —\nCN · Chine · —\nCX · Île Christmas · —\nCC · Îles Cocos (Keeling) · —\nCO · Colombie · —\nKM · Comores · —\nCK · Îles Cook · —\nCR · Costa Rica · —\nHR · Croatie · —\nCW · Curaçao · —\nCY · Chypre · —\nCZ · Tchéquie · —\nCI · Côte d’Ivoire · —\nDK · Danemark · —\nDJ · Djibouti · —\nDM · Dominique · —\nDO · République dominicaine · —\nEC · Équateur · —\nEG · Égypte · —\nSV · Salvador · —\nGQ · Guinée équatoriale · —\nEE · Estonie · —\nSZ · Eswatini · —\nET · Éthiopie · —\nFK · Îles Malouines · —\nFO · Îles Féroé · —\nFM · Micronésie · —\nFJ · Fidji · —\nFI · Finlande · —\nFR · France · —\nGF · Guyane française · —\nPF · Polynésie française · —\nTF · Terres australes françaises · —\nGA · Gabon · —\nGM · Gambie · —\nGE · Géorgie · —\nDE · Allemagne · —\nGH · Ghana · —\nGI · Gibraltar · —\nGR · Grèce · —\nGL · Groenland · —\nGD · Grenade · —\nGP · Guadeloupe · —\nGU · Guam · —\nGT · Guatemala · —\nGG · Guernesey · —\nGN · Guinée · —\nGW · Guinée-Bissau · —\nGY · Guyana · —\nHM · Îles Heard-et-MacDonald · —\nVA · Cité du Vatican · —\nHN · Honduras · —\nHK · RAS de Hong Kong, Chine · —\nHU · Hongrie · —\nIS · Islande · —\nIN · Inde · —\nID · Indonésie · —\nIE · Irlande · —\nIM · Île de Man · —\nIL · Israël · —\nIT · Italie · —\nJM · Jamaïque · —\nJP · Japon · —\nJE · Jersey · —\nJO · Jordanie · —\nKZ · Kazakhstan · —\nKE · Kenya · —\nKI · Kiribati · —\nKW · Koweït · —\nKG · Kirghizistan · —\nLA · Laos · —\nLV · Lettonie · —\nLB · Liban · —\nLS · Lesotho · —\nLR · Libéria · —\nLI · Liechtenstein · —\nLT · Lituanie · —\nLU · Luxembourg · —\nMO · Région administrative spéciale de Macao, Chine · —\nMG · Madagascar · —\nMW · Malawi · —\nMY · Malaisie · —\nMV · Maldives · —\nMT · Malte · —\nMH · Îles Marshall · —\nMQ · Martinique · —\nMR · Mauritanie · —\nMU · Maurice · —\nYT · Mayotte · —\nMX · Mexique · —\nMD · Moldavie · —\nMC · Monaco · —\nMN · Mongolie · —\nME · Monténégro · —\nMS · Montserrat · —\nMA · Maroc · —\nMZ · Mozambique · —\nNA · Namibie · —\nNR · Nauru · —\nNP · Népal · —\nNL · Pays-Bas · —\nNC · Nouvelle-Calédonie · —\nNZ · Nouvelle-Zélande · —\nNE · Niger · —\nNG · Nigéria · —\nNU · Nioué · —\nNF · Île Norfolk · —\nMK · Macédoine du Nord · —\nMP · Îles Mariannes du Nord · —\nNO · Norvège · —\nOM · Oman · —\nPK · Pakistan · —\nPW · Palaos · —\nPA · Panama · —\nPG · Papouasie-Nouvelle-Guinée · —\nPY · Paraguay · —\nPE · Pérou · —\nPH · Philippines · —\nPN · Îles Pitcairn · —\nPL · Pologne · —\nPT · Portugal · —\nPR · Porto Rico · —\nQA · Qatar · —\nRO · Roumanie · —\nRW · Rwanda · —\nRE · La Réunion · —\nBL · Saint-Barthélemy · —\nSH · Sainte-Hélène · —\nKN · Saint-Kitts-et-Nevis · —\nLC · Sainte-Lucie · —\nMF · Saint-Martin · —\nPM · Saint-Pierre-et-Miquelon · —\nVC · Saint-Vincent-et-les-Grenadines · —\nWS · Samoa · —\nSM · Saint-Marin · —\nST · Sao Tomé-et-Principe · —\nSA · Arabie saoudite · —\nSN · Sénégal · —\nRS · Serbie · —\nSC · Seychelles · —\nSL · Sierra Leone · —\nSG · Singapour · —\nSX · Saint-Martin (partie néerlandaise) · —\nSK · Slovaquie · —\nSI · Slovénie · —\nSB · Îles Salomon · —\nZA · Afrique du Sud · —\nGS · Géorgie du Sud-et-les Îles Sandwich du Sud · —\nKR · Corée du Sud · —\nES · Espagne · —\nLK · Sri Lanka · —\nPS · Territoires palestiniens · —\nSR · Suriname · —\nSJ · Svalbard et Jan Mayen · —\nSE · Suède · —\nCH · Suisse · —\nTW · Taïwan · —\nTJ · Tadjikistan · —\nTZ · Tanzanie · —\nTH · Thaïlande · —\nTL · Timor oriental · —\nTG · Togo · —\nTK · Tokelau · —\nTO · Tonga · —\nTT · Trinité-et-Tobago · —\nTN · Tunisie · —\nTM · Turkménistan · —\nTC · Îles Turques-et-Caïques · —\nTV · Tuvalu · —\nTR · Türkiye · —\nUG · Ouganda · —\nUA · Ukraine** · Les cartes sont indisponibles en Crimée, à Donetsk, à Louhansk, à Kherson et à Zaporijjia. Le reste de l'Ukraine est disponible.\nAE · Émirats arabes unis · —\nGB · Royaume-Uni · —\nUM · Îles mineures éloignées des États-Unis · —\nUS · États-Unis · —\nUY · Uruguay · —\nUZ · Ouzbékistan · —\nVU · Vanuatu · —\nVN · Vietnam · —\nVG · Îles Vierges britanniques · —\nVI · Îles Vierges des États-Unis · —\nWF · Wallis-et-Futuna · —\nEH · Sahara occidental · —\nZM · Zambie · —\n\nPièces et réseaux de paiement\n\nLe catalogue contient 16 pièces et 31 paires pièce/réseau. Une pièce peut être acceptée sur plusieurs réseaux : USDT sur Tron et USDT sur Ethereum sont des options de transfert différentes. La liste complète apparaît ci-dessous.\n\nLes options disponibles pour une facture spécifique et leurs limites proviennent de GET /api/checkout/{token}/crypto-services. Cette page décrit les combinaisons prises en charge ; la réponse actuelle de la passerelle détermine si un paiement peut être créé. Une entrée de référence seule ne rend pas une paire indisponible payable.\n\nLe marchand crée une facture crypto en USDT, et le client choisit une pièce et un réseau disponibles. L'opération de passerelle créée fournit le montant exact de la pièce, l'adresse, le code QR et l'expiration. Le prix d'une facture USDT ne fige pas le taux de change du BTC, de l'ETH ou d'une autre pièce, et n'implique pas un taux de 1:1. Transférez le montant décimal exact selon les instructions de paiement sans arrondir ni calculer vous-même une conversion.\n\nUSDT TRC20 est un terme distinct de paiement au marchand. Il ne restreint pas les paiements entrants à Tron et ne signifie pas que la création de paiements est disponible via le compte ou l'API. Le guide des paiements explique les conditions et restrictions de retrait.\n\nOuvrez la facture et choisissez la cryptomonnaie comme méthode de paiement.\n\nChoisissez une pièce et un réseau disponible. Le réseau du portefeuille de l'expéditeur doit correspondre au réseau indiqué dans les instructions de paiement Kevmi.\n\nCréez les instructions de paiement et vérifiez le montant exact, l'adresse complète et l'expiration. Copiez l'adresse et le montant, ou utilisez le code QR approprié.\n\nEnvoyez le montant spécifié sur le réseau sélectionné. Tenez compte des frais de portefeuille ou de réseau afin que le destinataire reçoive le montant complet indiqué dans les instructions.\n\nAttendez un statut confirmé lors du paiement. L'envoi d'un transfert de portefeuille seul ne complète pas la commande : Kevmi vérifie le résultat via la passerelle.\n\nPièce · Nom · Réseaux et codes de passerelle\nAVAX · Avalanche · Avalanche C-Chain (avalanche)\nBCH · Bitcoin Cash · Bitcoin Cash (bch)\nBNB · BNB · BNB Smart Chain (bsc)\nBTC · Bitcoin · Bitcoin (btc)\nDAI · Dai · BNB Smart Chain (bsc), Ethereum (eth), Polygon PoS (polygon)\nDASH · Dash · Dash (dash)\nDOGE · Dogecoin · Dogecoin (doge)\nETH · Ethereum · Ethereum (eth), Arbitrum One (arbitrum), BNB Smart Chain (bsc)\nGRAM · Gram · TON (ton)\nLTC · Litecoin · Litecoin (ltc)\nPOL · Polygon · Ethereum (eth), Polygon PoS (polygon)\nSHIB · Shiba Inu · Ethereum (eth)\nTRX · TRON · TRON (tron)\nUSDC · USD Coin · Arbitrum One (arbitrum), BNB Smart Chain (bsc), Polygon PoS (polygon), Ethereum (eth), Avalanche C-Chain (avalanche)\nUSDT · Tether · TRON (tron), Avalanche C-Chain (avalanche), BNB Smart Chain (bsc), TON (ton), Polygon PoS (polygon), Arbitrum One (arbitrum), Ethereum (eth)\nXMR · Monero · Monero (xmr)\n\nN'utilisez pas d'anciennes instructions de paiement après expiration. Si vous avez déjà envoyé des fonds, vérifiez la même opération et contactez le support si nécessaire ; ne créez pas un second paiement pour vérifier le premier.\n\nPaiement\n\nConditions de paiement\n\nVérification d'un pays spécifique\n\nL'assistant peut trouver un pays par son nom russe ou anglais ou son code ISO et expliquer son indicateur publié. Pour les pays **, précisez l'emplacement dont vous avez besoin. Pour la Chine *, demandez des informations sur votre carte.\n\nSi un pays est absent de la liste, cette base de connaissances ne peut pas confirmer la couverture internationale des cartes. Incluez le pays, la banque et la méthode souhaitée dans une demande de support. N'envoyez pas de numéro de carte complet ni de secrets de paiement.\n\nGéographie\n\nDemander au support",
      "readMinutes": 15
    },
    {
      "id": "payment-links",
      "title": "Liens de paiement",
      "summary": "Un lien de paiement ouvre une page de commande dédiée. Les clients voient le vendeur, la description de l'achat, les méthodes disponibles et le total dû sur leur téléphone ou leur ordinateur.",
      "group": "payments",
      "url": "/docs/payment-links",
      "tags": [
        "lien de paiement",
        "facture",
        "paiement",
        "pause",
        "commande",
        "Toute",
        "sélection de méthode"
      ],
      "sections": [
        {
          "id": "contents",
          "title": "Ce que comprend une facture",
          "paragraphs": [
            "Les factures du nouvel espace de travail utilisent un prix de base en USD et Any propose les quatre méthodes. SBP convertit en RUB au taux de référence gelé de la Banque de Russie ; la crypto utilise la règle de facturation explicite 1:1 USD/USDT. La tarification native héritée reste disponible pour les anciennes factures et les demandes API sans pricingMode=universal. Voir la section multi-boutiques et tarification USD ci-dessous.",
            "N'incluez jamais de mots de passe, de clés API, de données de carte ou de codes bancaires dans les descriptions publiques. Utilisez un titre de commande et une référence que le client reconnaît."
          ],
          "bullets": [
            "Nom du magasin, titre de commande jusqu'à 120 caractères et description jusqu'à 500 caractères.",
            "Montant de base et devise explicite USD, RUB ou USDT.",
            "Méthodes compatibles, frais séparés et parts de TVA, référence de commande et expiration du lien.",
            "Les réponses du propriétaire incluent link.payment avec l'état enregistré d'une opération existante ; cela est distinct de l'état de disponibilité du lien."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "any",
          "title": "N’importe lequel — le client choisit",
          "paragraphs": [
            "N’importe lequel sélectionne toutes les méthodes compatibles avec la devise de la facture : cartes et Alipay pour USD, SBP pour RUB, et crypto pour USDT. L’API prend un tableau de méthodes concret plutôt que la chaîne any. Chaque méthode a sa propre citation.",
            "Les factures du nouvel espace de travail utilisent un prix de base en USD et Any propose les quatre méthodes. SBP convertit en RUB au taux de référence gelé de la Banque de Russie ; la crypto utilise la règle de facturation explicite 1:1 USD/USDT. La tarification native héritée reste disponible pour les anciennes factures et les demandes API sans pricingMode=universal. Voir la section multi-boutiques et tarification USD ci-dessous.",
            "Pour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Envoyer les méthodes via l’API",
              "href": "/docs/payment-links-api#methods"
            }
          ]
        },
        {
          "id": "create",
          "title": "Créer un lien",
          "paragraphs": [],
          "bullets": [],
          "steps": [
            "Ouvrez les liens de paiement dans votre compte.",
            "Saisissez un titre, un montant, une devise et une description. Définissez les parts de frais et de TVA avec les deux commandes.",
            "Gardez N’importe lequel pour laisser le client choisir, ou sélectionnez des méthodes spécifiques. Définissez l’expiration.",
            "Comparez le total pour chaque méthode et visualisez le paiement.",
            "Recevez le lien de paiement prêt immédiatement après la création, puis copiez-le pour votre client ou widget."
          ],
          "table": null,
          "code": null,
          "note": "Si l’acceptation du paiement est indisponible, le paiement le signale avant la confirmation. Créer une facture ne débite pas d’argent.",
          "links": []
        },
        {
          "id": "fixed",
          "title": "Les conditions restent avec la facture",
          "paragraphs": [
            "Une facture enregistrée ne change pas lorsque les paramètres de la boutique changent. Son prix, sa devise, ses parts de frais et de TVA, sa référence de commande et ses métadonnées appartiennent à cette commande. Cela maintient le total cohérent pour un client qui a déjà ouvert le lien.",
            "Créez un nouveau lien et mettez l’ancien en pause lorsque le prix, la description ou la répartition des coûts change. Modifier un montant d’URL ne peut pas changer le calcul serveur."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "public",
          "title": "Une page de paiement dédiée",
          "paragraphs": [
            "Les liens serveur sont enregistrés dans la base de données et s’ouvrent sur tous les appareils à /pay/… sans accès au compte marchand. Un client n’a pas besoin de s’inscrire pour voir une facture. Les soldes de boutique, paramètres et autres dossiers clients restent privés.",
            "L’exemple /pay/demo montre l’expérience sans débiter d’argent. Les liens de démo navigateur sont des données de test et ne doivent pas être présentés comme de vraies factures."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Aperçu du paiement",
              "href": "/pay/demo"
            },
            {
              "label": "États de paiement",
              "href": "/docs/checkout"
            }
          ]
        },
        {
          "id": "control",
          "title": "Gestion de la disponibilité",
          "paragraphs": [
            "Mettre en pause, annuler ou faire expirer un lien bloque une nouvelle opération. Cela ne masque pas un paiement envoyé : le statut, le rapprochement et un code bancaire demandé restent disponibles. La disponibilité du lien et l’état financier sont vérifiés séparément.",
            "La reprise lève une pause sans modifier les conditions. L’annulation est définitive, et un lien expiré ne peut pas être prolongé. Créez une nouvelle facture pour une nouvelle commande ou des conditions modifiées, pas pour réessayer un débit dont le résultat est inconnu."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "stores-usd",
          "title": "Plusieurs boutiques et un prix de base USD unique",
          "paragraphs": [
            "Choisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.",
            "Les factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.",
            "Le taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.",
            "Créez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.",
            "Pour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "Ce que comprend une facture\n\nLes factures du nouvel espace de travail utilisent un prix de base en USD et Any propose les quatre méthodes. SBP convertit en RUB au taux de référence gelé de la Banque de Russie ; la crypto utilise la règle de facturation explicite 1:1 USD/USDT. La tarification native héritée reste disponible pour les anciennes factures et les demandes API sans pricingMode=universal. Voir la section multi-boutiques et tarification USD ci-dessous.\n\nN'incluez jamais de mots de passe, de clés API, de données de carte ou de codes bancaires dans les descriptions publiques. Utilisez un titre de commande et une référence que le client reconnaît.\n\nNom du magasin, titre de commande jusqu'à 120 caractères et description jusqu'à 500 caractères.\n\nMontant de base et devise explicite USD, RUB ou USDT.\n\nMéthodes compatibles, frais séparés et parts de TVA, référence de commande et expiration du lien.\n\nLes réponses du propriétaire incluent link.payment avec l'état enregistré d'une opération existante ; cela est distinct de l'état de disponibilité du lien.\n\nN’importe lequel — le client choisit\n\nN’importe lequel sélectionne toutes les méthodes compatibles avec la devise de la facture : cartes et Alipay pour USD, SBP pour RUB, et crypto pour USDT. L’API prend un tableau de méthodes concret plutôt que la chaîne any. Chaque méthode a sa propre citation.\n\nLes factures du nouvel espace de travail utilisent un prix de base en USD et Any propose les quatre méthodes. SBP convertit en RUB au taux de référence gelé de la Banque de Russie ; la crypto utilise la règle de facturation explicite 1:1 USD/USDT. La tarification native héritée reste disponible pour les anciennes factures et les demandes API sans pricingMode=universal. Voir la section multi-boutiques et tarification USD ci-dessous.\n\nPour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA.\n\nEnvoyer les méthodes via l’API\n\nCréer un lien\n\nOuvrez les liens de paiement dans votre compte.\n\nSaisissez un titre, un montant, une devise et une description. Définissez les parts de frais et de TVA avec les deux commandes.\n\nGardez N’importe lequel pour laisser le client choisir, ou sélectionnez des méthodes spécifiques. Définissez l’expiration.\n\nComparez le total pour chaque méthode et visualisez le paiement.\n\nRecevez le lien de paiement prêt immédiatement après la création, puis copiez-le pour votre client ou widget.\n\nSi l’acceptation du paiement est indisponible, le paiement le signale avant la confirmation. Créer une facture ne débite pas d’argent.\n\nLes conditions restent avec la facture\n\nUne facture enregistrée ne change pas lorsque les paramètres de la boutique changent. Son prix, sa devise, ses parts de frais et de TVA, sa référence de commande et ses métadonnées appartiennent à cette commande. Cela maintient le total cohérent pour un client qui a déjà ouvert le lien.\n\nCréez un nouveau lien et mettez l’ancien en pause lorsque le prix, la description ou la répartition des coûts change. Modifier un montant d’URL ne peut pas changer le calcul serveur.\n\nUne page de paiement dédiée\n\nLes liens serveur sont enregistrés dans la base de données et s’ouvrent sur tous les appareils à /pay/… sans accès au compte marchand. Un client n’a pas besoin de s’inscrire pour voir une facture. Les soldes de boutique, paramètres et autres dossiers clients restent privés.\n\nL’exemple /pay/demo montre l’expérience sans débiter d’argent. Les liens de démo navigateur sont des données de test et ne doivent pas être présentés comme de vraies factures.\n\nAperçu du paiement\n\nÉtats de paiement\n\nGestion de la disponibilité\n\nMettre en pause, annuler ou faire expirer un lien bloque une nouvelle opération. Cela ne masque pas un paiement envoyé : le statut, le rapprochement et un code bancaire demandé restent disponibles. La disponibilité du lien et l’état financier sont vérifiés séparément.\n\nLa reprise lève une pause sans modifier les conditions. L’annulation est définitive, et un lien expiré ne peut pas être prolongé. Créez une nouvelle facture pour une nouvelle commande ou des conditions modifiées, pas pour réessayer un débit dont le résultat est inconnu.\n\nPlusieurs boutiques et un prix de base USD unique\n\nChoisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.\n\nLes factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.\n\nLe taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.\n\nCréez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.\n\nPour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé.",
      "readMinutes": 5
    },
    {
      "id": "checkout",
      "title": "Paiement",
      "summary": "Le paiement montre au client ce qu’il achète, comment il peut payer et le montant dû avant la confirmation. Il est séparé de l’espace de travail marchand.",
      "group": "payments",
      "url": "/docs/checkout",
      "tags": [
        "paiement",
        "client",
        "payer",
        "facture",
        "erreur de paiement"
      ],
      "sections": [
        {
          "id": "review",
          "title": "Vérifier la commande",
          "paragraphs": [
            "Vérifiez le nom de la boutique, l’achat, le prix de base et la devise. S’ils diffèrent de votre accord avec le vendeur, demandez une facture corrigée avant de continuer.",
            "Une facture publique ne nécessite que son adresse ; l’accès au compte du vendeur n’est pas requis. Une page de démo est clairement marquée et ne collecte pas les détails de carte pour un débit réel."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "method",
          "title": "Choisir une méthode",
          "paragraphs": [
            "Les factures du nouvel espace de travail utilisent un prix de base en USD et Any propose les quatre méthodes. SBP convertit en RUB au taux de référence gelé de la Banque de Russie ; la crypto utilise la règle de facturation explicite 1:1 USD/USDT. La tarification native héritée reste disponible pour les anciennes factures et les demandes API sans pricingMode=universal. Voir la section multi-boutiques et tarification USD ci-dessous.",
            "Carte : le navigateur chiffre les détails de paiement avec la clé publique de la passerelle. Kevmi relaie l’enveloppe chiffrée ; son serveur n’accepte ni ne stocke les numéros de carte en clair, les CVV ni les codes bancaires à usage unique. Un formulaire de code bancaire demandé n’apparaît que si le défi de la passerelle est valide.",
            "Alipay : le client fournit un nom et reçoit un code QR. SBP ouvre l’URL de paiement bancaire ; un QR fourni par la passerelle peut aussi être utilisé. Une expiration est affichée lorsque la passerelle en fournit une.",
            "Crypto : choisissez une pièce, puis un réseau disponible dans le catalogue actuel. Après avoir créé une opération, le paiement affiche le montant décimal exact, l’adresse du destinataire et deux modes QR : adresse seule, ou adresse et montant. Le réseau du portefeuille doit correspondre au réseau choisi. Le prix d’une facture USDT ne verrouille pas le taux de change d’une autre pièce : utilisez le montant fourni par la passerelle. Les instructions expirées sont masquées pendant que le rapprochement continue pour le même paiement.",
            "Pour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "states",
          "title": "États de paiement",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "État",
              "Signification",
              "Prochaine étape"
            ],
            "rows": [
              [
                "Actif",
                "La facture est disponible à la consultation",
                "Vérifiez le total et la disponibilité de la méthode sélectionnée"
              ],
              [
                "En pause / expiré / annulé",
                "Aucun nouveau paiement ne peut démarrer via le lien",
                "Contactez le vendeur ; une opération d’origine est vérifiée séparément"
              ],
              [
                "Introuvable",
                "L’adresse est invalide ou indisponible",
                "Vérifiez l’adresse complète"
              ],
              [
                "Paiement indisponible",
                "Une nouvelle opération est bloquée par la configuration, la méthode, la limite, la répartition ou la revue marchande",
                "Suivez le message affiché ; les conditions de la facture enregistrée ne changent pas"
              ],
              [
                "En attente / action requise",
                "L’opération d’origine existe ou nécessite une confirmation",
                "Terminez l’étape actuelle ou vérifiez son statut"
              ],
              [
                "Résultat en cours de vérification",
                "Un résultat confirmé n’est pas encore disponible",
                "Vérifiez l’opération d’origine ; ne créez pas de deuxième débit"
              ]
            ]
          },
          "code": null,
          "note": "Une erreur réseau ou une réponse manquante ne prouve pas qu’aucun débit n’a eu lieu. Une opération déjà envoyée reste lisible même si le lien n’accepte plus de nouveaux paiements.",
          "links": []
        },
        {
          "id": "confirmation",
          "title": "Ce qui confirme le paiement",
          "paragraphs": [
            "Le paiement est confirmé par le rapprochement serveur de l’opération exacte de la passerelle. succeeded exige fulfillment_ready=true, verification=provider_confirmed, aucun litige et une correspondance exacte entre le montant payé et le total approuvé. Crypto exige en plus une preuve de règlement confirmée.",
            "Une redirection, un message de widget, un code bancaire accepté ou une observation navigateur ne confirme pas l’argent. Après un délai d’attente, lisez le statut de l’opération d’origine ; une tentative de remplacement n’est jamais créée automatiquement.",
            "Un nouveau paiement et une intention de carte nécessitent l'approbation de la dernière demande de revue du site du marchand. L'approbation seule ne connecte pas la passerelle de paiement. Si la revue change après l'envoi, l'opération existante reste disponible pour la lecture des statuts, le rapprochement et un code bancaire demandé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "help",
          "title": "Obtenir de l’aide",
          "paragraphs": [
            "Envoyez au vendeur la référence ou l’adresse de la facture, l’heure de la tentative et l’erreur affichée. N’envoyez pas de CVV, de mot de passe bancaire, de code de confirmation ou de phrase de récupération au support. L’assistant de documentation peut expliquer les termes mais ne peut pas confirmer indépendamment un crédit."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Aide au paiement",
              "href": "/?support=open"
            },
            {
              "label": "Calcul de la TVA",
              "href": "/docs/vat"
            }
          ]
        }
      ],
      "body": "Vérifier la commande\n\nVérifiez le nom de la boutique, l’achat, le prix de base et la devise. S’ils diffèrent de votre accord avec le vendeur, demandez une facture corrigée avant de continuer.\n\nUne facture publique ne nécessite que son adresse ; l’accès au compte du vendeur n’est pas requis. Une page de démo est clairement marquée et ne collecte pas les détails de carte pour un débit réel.\n\nChoisir une méthode\n\nLes factures du nouvel espace de travail utilisent un prix de base en USD et Any propose les quatre méthodes. SBP convertit en RUB au taux de référence gelé de la Banque de Russie ; la crypto utilise la règle de facturation explicite 1:1 USD/USDT. La tarification native héritée reste disponible pour les anciennes factures et les demandes API sans pricingMode=universal. Voir la section multi-boutiques et tarification USD ci-dessous.\n\nCarte : le navigateur chiffre les détails de paiement avec la clé publique de la passerelle. Kevmi relaie l’enveloppe chiffrée ; son serveur n’accepte ni ne stocke les numéros de carte en clair, les CVV ni les codes bancaires à usage unique. Un formulaire de code bancaire demandé n’apparaît que si le défi de la passerelle est valide.\n\nAlipay : le client fournit un nom et reçoit un code QR. SBP ouvre l’URL de paiement bancaire ; un QR fourni par la passerelle peut aussi être utilisé. Une expiration est affichée lorsque la passerelle en fournit une.\n\nCrypto : choisissez une pièce, puis un réseau disponible dans le catalogue actuel. Après avoir créé une opération, le paiement affiche le montant décimal exact, l’adresse du destinataire et deux modes QR : adresse seule, ou adresse et montant. Le réseau du portefeuille doit correspondre au réseau choisi. Le prix d’une facture USDT ne verrouille pas le taux de change d’une autre pièce : utilisez le montant fourni par la passerelle. Les instructions expirées sont masquées pendant que le rapprochement continue pour le même paiement.\n\nPour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA.\n\nÉtats de paiement\n\nÉtat · Signification · Prochaine étape\nActif · La facture est disponible à la consultation · Vérifiez le total et la disponibilité de la méthode sélectionnée\nEn pause / expiré / annulé · Aucun nouveau paiement ne peut démarrer via le lien · Contactez le vendeur ; une opération d’origine est vérifiée séparément\nIntrouvable · L’adresse est invalide ou indisponible · Vérifiez l’adresse complète\nPaiement indisponible · Une nouvelle opération est bloquée par la configuration, la méthode, la limite, la répartition ou la revue marchande · Suivez le message affiché ; les conditions de la facture enregistrée ne changent pas\nEn attente / action requise · L’opération d’origine existe ou nécessite une confirmation · Terminez l’étape actuelle ou vérifiez son statut\nRésultat en cours de vérification · Un résultat confirmé n’est pas encore disponible · Vérifiez l’opération d’origine ; ne créez pas de deuxième débit\n\nUne erreur réseau ou une réponse manquante ne prouve pas qu’aucun débit n’a eu lieu. Une opération déjà envoyée reste lisible même si le lien n’accepte plus de nouveaux paiements.\n\nCe qui confirme le paiement\n\nLe paiement est confirmé par le rapprochement serveur de l’opération exacte de la passerelle. succeeded exige fulfillment_ready=true, verification=provider_confirmed, aucun litige et une correspondance exacte entre le montant payé et le total approuvé. Crypto exige en plus une preuve de règlement confirmée.\n\nUne redirection, un message de widget, un code bancaire accepté ou une observation navigateur ne confirme pas l’argent. Après un délai d’attente, lisez le statut de l’opération d’origine ; une tentative de remplacement n’est jamais créée automatiquement.\n\nUn nouveau paiement et une intention de carte nécessitent l'approbation de la dernière demande de revue du site du marchand. L'approbation seule ne connecte pas la passerelle de paiement. Si la revue change après l'envoi, l'opération existante reste disponible pour la lecture des statuts, le rapprochement et un code bancaire demandé.\n\nObtenir de l’aide\n\nEnvoyez au vendeur la référence ou l’adresse de la facture, l’heure de la tentative et l’erreur affichée. N’envoyez pas de CVV, de mot de passe bancaire, de code de confirmation ou de phrase de récupération au support. L’assistant de documentation peut expliquer les termes mais ne peut pas confirmer indépendamment un crédit.\n\nAide au paiement\n\nCalcul de la TVA",
      "readMinutes": 5
    },
    {
      "id": "payments",
      "title": "Paiements et statuts",
      "summary": "Une facture décrit une commande. Un paiement est une tentative spécifique de la régler. Une tentative de paiement et la disponibilité de son lien sont des états distincts.",
      "group": "payments",
      "url": "/docs/payments",
      "tags": [
        "paiement",
        "statut",
        "en attente",
        "réussi",
        "échoué"
      ],
      "sections": [
        {
          "id": "record",
          "title": "L'enregistrement du paiement",
          "paragraphs": [
            "La facture stocke les conditions de la commande ; le paiement identifie son opération de passerelle. Le premier lancement réserve une liaison durable et une clé d'idempotence serveur. Après le début de l'envoi, une autre méthode ne peut pas créer un second débit sur la même facture.",
            "GET /api/payment-links et GET /api/v1/payments renvoient link.payment au propriétaire. Le statut actif/en pause/annulé/expiré du lien est distinct de l'état du paiement. Un client ne peut lire son opération que via le jeton de paiement aléatoire."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Données",
              "Objectif"
            ],
            "rows": [
              [
                "Identifiant et commande",
                "Associer la tentative à un achat"
              ],
              [
                "Montant de base et devise",
                "La base de calcul"
              ],
              [
                "Méthode de paiement",
                "Frais et taxes applicables"
              ],
              [
                "Assujetti à la TVA",
                "Qui prend en charge la taxe"
              ],
              [
                "Frais, TVA et totaux",
                "Calcul enregistré"
              ],
              [
                "Statut et heure",
                "État actuel de la transaction"
              ],
              [
                "Référence d'événement de la passerelle",
                "Source de confirmation serveur"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "statuses",
          "title": "États d'opération en direct",
          "paragraphs": [
            "La démo utilise des enregistrements de test distincts. Modifier un état de démo ne confirme pas un paiement réel et ne modifie pas les enregistrements financiers."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Statut",
              "Signification"
            ],
            "rows": [
              [
                "en attente",
                "Opération créée ; en attente d'une action ou d'un résultat"
              ],
              [
                "requires_action",
                "Un code bancaire ou une confirmation du client est requis"
              ],
              [
                "processing",
                "Le fournisseur confirme encore le résultat"
              ],
              [
                "réussi",
                "Le serveur a vérifié le paiement exact"
              ],
              [
                "échoué",
                "Tentative terminée sans paiement confirmé"
              ],
              [
                "expired",
                "Instructions expirées ; le rapprochement reste disponible"
              ],
              [
                "review_required",
                "Un examen supplémentaire est nécessaire ; ne payez pas à nouveau"
              ],
              [
                "partially_paid",
                "Seule une partie du montant a été reçue ; ne créez pas un autre paiement"
              ],
              [
                "partially_refunded",
                "Une partie du paiement a été remboursée"
              ],
              [
                "refunded",
                "Remboursement confirmé"
              ],
              [
                "disputed",
                "L'opération est contestée"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "authority",
          "title": "La source de vérité",
          "paragraphs": [
            "Un webhook signé déclenche une lecture authentifiée de l'opération exacte de la passerelle. Les identifiants, la commande, la devise, la méthode, les montants de base et finaux, le mode réel et la version monotone sont validés. Un simple nom d'événement entrant n'est pas une preuve d'argent.",
            "L'état, le reçu et l'événement marchand sont validés de manière atomique. Les réponses plus anciennes ne peuvent pas écraser une version plus récente ; les doublons ne sont pas exécutés deux fois, et « en attente » ne peut pas remplacer un paiement confirmé. Ces enregistrements ne créent pas automatiquement un solde retirable ni un paiement."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "uncertain",
          "title": "Lorsque le résultat est inconnu",
          "paragraphs": [],
          "bullets": [],
          "steps": [
            "Conservez la facture d'origine et l'identifiant de l'opération.",
            "Lisez GET /api/checkout/{token}/status ; cela ne crée pas de débit.",
            "Utilisez POST /api/checkout/{token}/reconcile lorsqu'un rapprochement explicite est nécessaire.",
            "Ne modifiez pas la méthode, le montant ou la clé d'idempotence après un résultat incertain."
          ],
          "table": null,
          "code": null,
          "note": "Un délai d'attente n'est pas un refus. Une réponse perdue est récupérée par la clé serveur d'origine ; aucune tentative de remplacement n'est créée automatiquement.",
          "links": []
        },
        {
          "id": "stores-usd",
          "title": "Plusieurs boutiques et un prix de base USD unique",
          "paragraphs": [
            "Choisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.",
            "Les factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.",
            "Le taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.",
            "Créez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.",
            "Pour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "L'enregistrement du paiement\n\nLa facture stocke les conditions de la commande ; le paiement identifie son opération de passerelle. Le premier lancement réserve une liaison durable et une clé d'idempotence serveur. Après le début de l'envoi, une autre méthode ne peut pas créer un second débit sur la même facture.\n\nGET /api/payment-links et GET /api/v1/payments renvoient link.payment au propriétaire. Le statut actif/en pause/annulé/expiré du lien est distinct de l'état du paiement. Un client ne peut lire son opération que via le jeton de paiement aléatoire.\n\nDonnées · Objectif\nIdentifiant et commande · Associer la tentative à un achat\nMontant de base et devise · La base de calcul\nMéthode de paiement · Frais et taxes applicables\nAssujetti à la TVA · Qui prend en charge la taxe\nFrais, TVA et totaux · Calcul enregistré\nStatut et heure · État actuel de la transaction\nRéférence d'événement de la passerelle · Source de confirmation serveur\n\nÉtats d'opération en direct\n\nLa démo utilise des enregistrements de test distincts. Modifier un état de démo ne confirme pas un paiement réel et ne modifie pas les enregistrements financiers.\n\nStatut · Signification\nen attente · Opération créée ; en attente d'une action ou d'un résultat\nrequires_action · Un code bancaire ou une confirmation du client est requis\nprocessing · Le fournisseur confirme encore le résultat\nréussi · Le serveur a vérifié le paiement exact\néchoué · Tentative terminée sans paiement confirmé\nexpired · Instructions expirées ; le rapprochement reste disponible\nreview_required · Un examen supplémentaire est nécessaire ; ne payez pas à nouveau\npartially_paid · Seule une partie du montant a été reçue ; ne créez pas un autre paiement\npartially_refunded · Une partie du paiement a été remboursée\nrefunded · Remboursement confirmé\ndisputed · L'opération est contestée\n\nLa source de vérité\n\nUn webhook signé déclenche une lecture authentifiée de l'opération exacte de la passerelle. Les identifiants, la commande, la devise, la méthode, les montants de base et finaux, le mode réel et la version monotone sont validés. Un simple nom d'événement entrant n'est pas une preuve d'argent.\n\nL'état, le reçu et l'événement marchand sont validés de manière atomique. Les réponses plus anciennes ne peuvent pas écraser une version plus récente ; les doublons ne sont pas exécutés deux fois, et « en attente » ne peut pas remplacer un paiement confirmé. Ces enregistrements ne créent pas automatiquement un solde retirable ni un paiement.\n\nLorsque le résultat est inconnu\n\nConservez la facture d'origine et l'identifiant de l'opération.\n\nLisez GET /api/checkout/{token}/status ; cela ne crée pas de débit.\n\nUtilisez POST /api/checkout/{token}/reconcile lorsqu'un rapprochement explicite est nécessaire.\n\nNe modifiez pas la méthode, le montant ou la clé d'idempotence après un résultat incertain.\n\nUn délai d'attente n'est pas un refus. Une réponse perdue est récupérée par la clé serveur d'origine ; aucune tentative de remplacement n'est créée automatiquement.\n\nPlusieurs boutiques et un prix de base USD unique\n\nChoisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.\n\nLes factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.\n\nLe taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.\n\nCréez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.\n\nPour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé.",
      "readMinutes": 3
    },
    {
      "id": "payouts",
      "title": "Paiements USDT TRC20",
      "summary": "Les conditions de paiement précisent l'USDT sur TRC20, avec des frais basés sur la source des fonds. Ce guide couvre les frais, les exigences de devis et les restrictions : la création de paiement via le compte et l'API est indisponible.",
      "group": "payments",
      "url": "/docs/payouts",
      "tags": [
        "versement",
        "retrait",
        "USDT",
        "TRC20",
        "portefeuille",
        "taux de change"
      ],
      "sections": [
        {
          "id": "tariffs",
          "title": "Frais par source",
          "paragraphs": [
            "Les frais d'acceptation sont déjà inclus dans le crédit du commerçant. Un paiement est une opération distincte avec ses propres frais. N'appliquez pas les frais d'acceptation au solde une seconde fois."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Source",
              "Frais"
            ],
            "rows": [
              [
                "Cartes et Alipay",
                "4%"
              ],
              [
                "SBP",
                "5 % + 400 RUB"
              ],
              [
                "Cryptomonnaie",
                "0% + $3"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "quote",
          "title": "Devis et devises",
          "paragraphs": [
            "Les montants en USD et en RUB doivent être comptabilisés séparément. Ne les additionnez pas sans taux de change. L'USD est une monnaie fiduciaire et l'USDT est un actif numérique ; un taux de change automatique de 1:1 n'est pas supposé.",
            "Un devis doit indiquer la devise source et le montant, les frais, la sortie en USDT et l'expiration. Toute modification du montant ou du portefeuille nécessite une nouvelle vérification des conditions."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "address",
          "title": "Adresse du destinataire",
          "paragraphs": [
            "Utilisez une adresse TRC20 appartenant au destinataire. La validation du format de l'adresse peut détecter certaines fautes de frappe mais ne peut pas vérifier le propriétaire ni garantir la livraison.",
            "Vérifiez l'adresse complète et le réseau avant l'envoi. Le serveur doit valider le montant, le solde disponible et le devis indépendamment du formulaire client."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "flow",
          "title": "Le processus de paiement",
          "paragraphs": [
            "La démo utilise un devis saisi manuellement pour le calcul uniquement. Un paiement de test réserve des fonds de démo et ne transfère pas d'actifs."
          ],
          "bullets": [],
          "steps": [
            "Choisissez la source des fonds et le montant à débiter.",
            "Saisissez une adresse TRC20.",
            "Obtenez un devis actuel et examinez les frais.",
            "Confirmez les conditions exactes de la demande.",
            "Attendez un résultat confirmé par le serveur."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "availability",
          "title": "Disponibilité des paiements",
          "paragraphs": [
            "La création de paiements via le compte et /api/payouts est indisponible. Les frais publiés et un calcul de frais ne créent pas de demande de transfert ni n'en confirment l'exécution.",
            "Les paiements vérifiés, les reçus et les événements sont conservés dans l'historique. Ces enregistrements ne constituent pas un solde retirable. L'exécution d'un paiement nécessite un registre de fonds distinct, un devis actuel, une validation de destination et une confirmation de transfert."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Intégration de la passerelle",
              "href": "/docs/gateway"
            }
          ]
        }
      ],
      "body": "Frais par source\n\nLes frais d'acceptation sont déjà inclus dans le crédit du commerçant. Un paiement est une opération distincte avec ses propres frais. N'appliquez pas les frais d'acceptation au solde une seconde fois.\n\nSource · Frais\nCartes et Alipay · 4%\nSBP · 5 % + 400 RUB\nCryptomonnaie · 0% + $3\n\nDevis et devises\n\nLes montants en USD et en RUB doivent être comptabilisés séparément. Ne les additionnez pas sans taux de change. L'USD est une monnaie fiduciaire et l'USDT est un actif numérique ; un taux de change automatique de 1:1 n'est pas supposé.\n\nUn devis doit indiquer la devise source et le montant, les frais, la sortie en USDT et l'expiration. Toute modification du montant ou du portefeuille nécessite une nouvelle vérification des conditions.\n\nAdresse du destinataire\n\nUtilisez une adresse TRC20 appartenant au destinataire. La validation du format de l'adresse peut détecter certaines fautes de frappe mais ne peut pas vérifier le propriétaire ni garantir la livraison.\n\nVérifiez l'adresse complète et le réseau avant l'envoi. Le serveur doit valider le montant, le solde disponible et le devis indépendamment du formulaire client.\n\nLe processus de paiement\n\nLa démo utilise un devis saisi manuellement pour le calcul uniquement. Un paiement de test réserve des fonds de démo et ne transfère pas d'actifs.\n\nChoisissez la source des fonds et le montant à débiter.\n\nSaisissez une adresse TRC20.\n\nObtenez un devis actuel et examinez les frais.\n\nConfirmez les conditions exactes de la demande.\n\nAttendez un résultat confirmé par le serveur.\n\nDisponibilité des paiements\n\nLa création de paiements via le compte et /api/payouts est indisponible. Les frais publiés et un calcul de frais ne créent pas de demande de transfert ni n'en confirment l'exécution.\n\nLes paiements vérifiés, les reçus et les événements sont conservés dans l'historique. Ces enregistrements ne constituent pas un solde retirable. L'exécution d'un paiement nécessite un registre de fonds distinct, un devis actuel, une validation de destination et une confirmation de transfert.\n\nIntégration de la passerelle",
      "readMinutes": 3
    },
    {
      "id": "telegram-login",
      "title": "Connectez-vous et inscrivez-vous via Telegram",
      "summary": "Telegram vérifie votre identité. Kevmi crée votre compte lors de la première connexion et l'ouvre lors des visites suivantes. Un mot de passe Kevmi séparé n'est pas requis.",
      "group": "account",
      "url": "/docs/telegram-login",
      "tags": [
        "Telegram",
        "se connecter",
        "connexion",
        "s'inscrire",
        "compte",
        "bot"
      ],
      "sections": [
        {
          "id": "steps",
          "title": "Connexion",
          "paragraphs": [
            "La demande dure cinq minutes. Lancez une nouvelle demande si elle expire. Une ancienne demande ne peut pas être réutilisée pour obtenir une session."
          ],
          "bullets": [],
          "steps": [
            "Ouvrez Connexion ou Créer un compte et sélectionnez Continuer avec Telegram.",
            "Suivez le lien du bot créé par ce navigateur.",
            "Comparez le code à six chiffres sur le site Web et dans le message du bot.",
            "Confirmez dans le chat privé.",
            "Revenez au navigateur d'origine. Votre compte s'ouvre après la vérification."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "browser",
          "title": "Pourquoi le navigateur d'origine compte",
          "paragraphs": [
            "Le lien Telegram est lié à un cookie protégé dans le navigateur qui a lancé la connexion. Un challengeId ou un lien transféré seul ne peut pas créer une session sur un autre appareil.",
            "Vous pouvez confirmer dans Telegram sur un autre appareil, mais le compte s'ouvre dans le navigateur où la connexion a commencé. Ne confirmez pas une demande que vous n'avez pas lancée."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "session",
          "title": "Sessions et déconnexion",
          "paragraphs": [
            "Une session dure jusqu'à 24 heures. Son jeton aléatoire est stocké dans un cookie Secure HttpOnly et ne peut pas être lu par JavaScript. La déconnexion du site met fin à la session actuelle.",
            "La commande du bot /logout met fin à toutes les sessions du compte et annule les confirmations inutilisées. Une nouvelle connexion nécessite une nouvelle demande."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "trouble",
          "title": "Dépannage de la connexion",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Situation",
              "Action"
            ],
            "rows": [
              [
                "Le lien a expiré",
                "Lancez une nouvelle demande sur le site Web"
              ],
              [
                "Un navigateur différent est ouvert",
                "Revenez à l'onglet où la connexion a commencé"
              ],
              [
                "Les codes diffèrent",
                "Ne confirmez pas ; recommencez"
              ],
              [
                "Connexion indisponible",
                "Réessayez plus tard ou contactez l'assistance"
              ],
              [
                "Erreur réseau temporaire",
                "Attendez la prochaine vérification ou réessayez la connexion"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "privacy",
          "title": "Informations utilisées pour la connexion",
          "paragraphs": [
            "Le serveur reçoit un identifiant Telegram vérifié et les champs de profil disponibles pour créer le compte. Un nom d'utilisateur public seul ne prouve pas l'identité.",
            "Le bot ne demande pas votre mot de passe Telegram, vos codes bancaires, votre CVV, votre phrase de récupération ni vos clés privées."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "API d'authentification",
              "href": "/docs/auth-api"
            },
            {
              "label": "Se connecter",
              "href": "/login"
            }
          ]
        }
      ],
      "body": "Connexion\n\nLa demande dure cinq minutes. Lancez une nouvelle demande si elle expire. Une ancienne demande ne peut pas être réutilisée pour obtenir une session.\n\nOuvrez Connexion ou Créer un compte et sélectionnez Continuer avec Telegram.\n\nSuivez le lien du bot créé par ce navigateur.\n\nComparez le code à six chiffres sur le site Web et dans le message du bot.\n\nConfirmez dans le chat privé.\n\nRevenez au navigateur d'origine. Votre compte s'ouvre après la vérification.\n\nPourquoi le navigateur d'origine compte\n\nLe lien Telegram est lié à un cookie protégé dans le navigateur qui a lancé la connexion. Un challengeId ou un lien transféré seul ne peut pas créer une session sur un autre appareil.\n\nVous pouvez confirmer dans Telegram sur un autre appareil, mais le compte s'ouvre dans le navigateur où la connexion a commencé. Ne confirmez pas une demande que vous n'avez pas lancée.\n\nSessions et déconnexion\n\nUne session dure jusqu'à 24 heures. Son jeton aléatoire est stocké dans un cookie Secure HttpOnly et ne peut pas être lu par JavaScript. La déconnexion du site met fin à la session actuelle.\n\nLa commande du bot /logout met fin à toutes les sessions du compte et annule les confirmations inutilisées. Une nouvelle connexion nécessite une nouvelle demande.\n\nDépannage de la connexion\n\nSituation · Action\nLe lien a expiré · Lancez une nouvelle demande sur le site Web\nUn navigateur différent est ouvert · Revenez à l'onglet où la connexion a commencé\nLes codes diffèrent · Ne confirmez pas ; recommencez\nConnexion indisponible · Réessayez plus tard ou contactez l'assistance\nErreur réseau temporaire · Attendez la prochaine vérification ou réessayez la connexion\n\nInformations utilisées pour la connexion\n\nLe serveur reçoit un identifiant Telegram vérifié et les champs de profil disponibles pour créer le compte. Un nom d'utilisateur public seul ne prouve pas l'identité.\n\nLe bot ne demande pas votre mot de passe Telegram, vos codes bancaires, votre CVV, votre phrase de récupération ni vos clés privées.\n\nAPI d'authentification\n\nSe connecter",
      "readMinutes": 3
    },
    {
      "id": "settings",
      "title": "Paramètres du magasin",
      "summary": "Paramètres : associez le nom de votre boutique, la règle de TVA et les notifications à votre compte vérifié. Les modifications sont enregistrées sur le serveur pour l'utilisateur actuel.",
      "group": "account",
      "url": "/docs/settings",
      "tags": [
        "paramètres",
        "boutique",
        "Assujetti à la TVA",
        "thème",
        "notifications"
      ],
      "sections": [
        {
          "id": "name",
          "title": "Nom de la boutique",
          "paragraphs": [
            "Choisissez un nom court et reconnaissable que votre client s'attend à voir sur la commande. Le nom doit contenir 1 à 80 caractères après suppression des espaces environnants.",
            "Un nom d'affichage ne remplace pas les informations juridiques ni votre accord client. Conservez les secrets, les identifiants de paiement et les informations personnelles d'autrui hors de ce champ."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "vat",
          "title": "Assujetti à la TVA",
          "paragraphs": [
            "Le payeur par défaut est le client. La TVA s'applique uniquement aux cartes et à Alipay. La modification de ce paramètre ne change pas les totaux SBP ni ceux des cryptomonnaies.",
            "Les factures existantes conservent leurs conditions enregistrées. Lors de la création d'une facture, la TVA du client et les parts de frais indépendantes de 0 à 100 % peuvent remplacer les valeurs par défaut. La préférence de la boutique ne fournit qu'une valeur par défaut pour les factures futures.",
            "Une préférence enregistrée n'étend pas les capacités des passerelles. Les canaux actuels de carte en direct et d'Alipay exigent 100 % de TVA client et 0 % de frais de traitement client ; les autres répartitions enregistrées restent des calculs."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Valeur",
              "Règle pour une nouvelle facture"
            ],
            "rows": [
              [
                "client",
                "La TVA est ajoutée au prix de base du client"
              ],
              [
                "marchand",
                "Le marchand couvre la TVA à partir du prix de base"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "notifications",
          "title": "Notifications Telegram",
          "paragraphs": [
            "Sélectionnez les catégories paiement, versement, assistance et sécurité. Choisir une catégorie contrôle les notifications ; cela n'active pas un canal de paiement ni ne génère d'événements financiers.",
            "Un message de test vérifie la livraison vers le chat privé lié. Son statut apparaît dans le centre de notifications et dans GET /api/notifications. Un message en file d'attente n'est pas encore livré ; vérifiez aussi Telegram."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Guide des notifications",
              "href": "/docs/notifications"
            }
          ]
        },
        {
          "id": "saving",
          "title": "Enregistrement et erreurs",
          "paragraphs": [
            "Le formulaire confirme un enregistrement réussi. Si le réseau échoue, vos saisies restent disponibles pour une nouvelle tentative ; appuyer sur Enregistrer seul ne prouve pas que la modification a été stockée.",
            "Connectez-vous à nouveau lorsque votre session expire. Le serveur identifie le compte à partir de la session et n'accepte pas un autre identifiant de propriétaire de boutique depuis le navigateur."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "local",
          "title": "Thème et données de démonstration",
          "paragraphs": [
            "Le thème d'affichage est enregistré localement sur l'appareil. L'espace de démonstration utilise des données de navigateur distinctes et ne modifie pas le compte serveur.",
            "La réinitialisation de la démonstration supprime uniquement les enregistrements de test dans ce navigateur. Une exportation de démonstration n'est pas un relevé bancaire ni une preuve de paiement."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "stores-usd",
          "title": "Plusieurs boutiques et un prix de base USD unique",
          "paragraphs": [
            "Choisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.",
            "Les factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.",
            "Le taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.",
            "Créez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.",
            "Pour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "Nom de la boutique\n\nChoisissez un nom court et reconnaissable que votre client s'attend à voir sur la commande. Le nom doit contenir 1 à 80 caractères après suppression des espaces environnants.\n\nUn nom d'affichage ne remplace pas les informations juridiques ni votre accord client. Conservez les secrets, les identifiants de paiement et les informations personnelles d'autrui hors de ce champ.\n\nAssujetti à la TVA\n\nLe payeur par défaut est le client. La TVA s'applique uniquement aux cartes et à Alipay. La modification de ce paramètre ne change pas les totaux SBP ni ceux des cryptomonnaies.\n\nLes factures existantes conservent leurs conditions enregistrées. Lors de la création d'une facture, la TVA du client et les parts de frais indépendantes de 0 à 100 % peuvent remplacer les valeurs par défaut. La préférence de la boutique ne fournit qu'une valeur par défaut pour les factures futures.\n\nUne préférence enregistrée n'étend pas les capacités des passerelles. Les canaux actuels de carte en direct et d'Alipay exigent 100 % de TVA client et 0 % de frais de traitement client ; les autres répartitions enregistrées restent des calculs.\n\nValeur · Règle pour une nouvelle facture\nclient · La TVA est ajoutée au prix de base du client\nmarchand · Le marchand couvre la TVA à partir du prix de base\n\nNotifications Telegram\n\nSélectionnez les catégories paiement, versement, assistance et sécurité. Choisir une catégorie contrôle les notifications ; cela n'active pas un canal de paiement ni ne génère d'événements financiers.\n\nUn message de test vérifie la livraison vers le chat privé lié. Son statut apparaît dans le centre de notifications et dans GET /api/notifications. Un message en file d'attente n'est pas encore livré ; vérifiez aussi Telegram.\n\nGuide des notifications\n\nEnregistrement et erreurs\n\nLe formulaire confirme un enregistrement réussi. Si le réseau échoue, vos saisies restent disponibles pour une nouvelle tentative ; appuyer sur Enregistrer seul ne prouve pas que la modification a été stockée.\n\nConnectez-vous à nouveau lorsque votre session expire. Le serveur identifie le compte à partir de la session et n'accepte pas un autre identifiant de propriétaire de boutique depuis le navigateur.\n\nThème et données de démonstration\n\nLe thème d'affichage est enregistré localement sur l'appareil. L'espace de démonstration utilise des données de navigateur distinctes et ne modifie pas le compte serveur.\n\nLa réinitialisation de la démonstration supprime uniquement les enregistrements de test dans ce navigateur. Une exportation de démonstration n'est pas un relevé bancaire ni une preuve de paiement.\n\nPlusieurs boutiques et un prix de base USD unique\n\nChoisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.\n\nLes factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.\n\nLe taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.\n\nCréez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.\n\nPour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé.",
      "readMinutes": 3
    },
    {
      "id": "notifications",
      "title": "Notifications du site et de Telegram",
      "summary": "Les événements de compte apparaissent sous la cloche dans la barre supérieure. Lisez les notifications, vérifiez la livraison Telegram et ouvrez la partie pertinente de votre espace de travail.",
      "group": "account",
      "url": "/docs/notifications",
      "tags": [
        "notifications",
        "Telegram",
        "cloche",
        "lire",
        "livraison"
      ],
      "sections": [
        {
          "id": "inbox",
          "title": "Centre de notifications",
          "paragraphs": [
            "Le badge compte les événements de compte non lus. Les messages sont regroupés par date ; Charger plus récupère les enregistrements plus anciens. Les visiteurs sont invités à se connecter.",
            "L'état de lecture est stocké sur le serveur. Les pages visibles se rafraîchissent automatiquement et les onglets ouverts synchronisent les marques de lecture. Les événements plus récents que le dernier message affiché ne sont pas marqués comme lus avec les plus anciens."
          ],
          "bullets": [],
          "steps": [
            "Sélectionnez la cloche dans la barre supérieure.",
            "Choisissez tous les événements ou uniquement les non lus.",
            "Ouvrez la page concernée ou marquez un message comme lu.",
            "Utilisez Tout marquer comme lu pour les événements déjà chargés."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "types",
          "title": "Catégories d'événements",
          "paragraphs": [
            "L'assistance et la sécurité sont activées pour un nouveau compte ; les catégories de paiement sont sélectionnées par l'utilisateur. Le centre affiche les événements enregistrés pour les catégories activées. Les événements de démonstration du navigateur ne sont pas de véritables notifications de fonds."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Catégorie",
              "Contenu"
            ],
            "rows": [
              [
                "Paiements",
                "Événements de paiement confirmés"
              ],
              [
                "Versements",
                "Événements de versement confirmés"
              ],
              [
                "Assistance",
                "Demandes d'assistance et mises à jour de l'étape de candidature"
              ],
              [
                "Sécurité",
                "Nouvelle connexion vérifiée"
              ],
              [
                "Test",
                "Vérification de livraison vers votre Telegram"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "setup",
          "title": "Configuration de la livraison",
          "paragraphs": [
            "Les tests sont limités à trois par compte et par heure. Un test ne modifie pas un solde ni ne crée un paiement. Mettre un message en file d'attente ne prouve pas la livraison."
          ],
          "bullets": [],
          "steps": [
            "Connectez-vous avec Telegram et ouvrez Compte → Notifications.",
            "Activez les catégories souhaitées et enregistrez.",
            "Sélectionnez Tester la livraison.",
            "Vérifiez le statut du centre et le chat privé du bot."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Paramètres de notification",
              "href": "/account#notifications"
            }
          ]
        },
        {
          "id": "statuses",
          "title": "Livraison et état de lecture sont distincts",
          "paragraphs": [
            "La livraison dépend de la disponibilité de Telegram et des autorisations de l'utilisateur. Une réponse perdue peut entraîner un message répété, mais pas une opération financière répétée.",
            "Si la livraison échoue, vérifiez que le bot est joignable et non bloqué. Les nouvelles tentatives de notification de l'application s'exécutent également dans des tâches en arrière-plan ; les interactions de service peuvent déclencher d'autres livraisons en file d'attente. Consultez le centre de notifications pour connaître l'état actuel."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Statut",
              "Signification"
            ],
            "rows": [
              [
                "en attente",
                "En file d'attente pour traitement"
              ],
              [
                "envoi",
                "Le serveur tente la livraison"
              ],
              [
                "envoyé",
                "Telegram a confirmé l'envoi"
              ],
              [
                "échoué",
                "Échec de la livraison"
              ]
            ]
          },
          "code": null,
          "note": "L'état de livraison du message fait référence à Telegram. Marquer une notification comme lue sur le site web ne signifie pas qu'elle a été lue dans Telegram et ne change pas la livraison.",
          "links": []
        },
        {
          "id": "feedback",
          "title": "Confirmations d'action",
          "paragraphs": [
            "Le site web affiche une brève notification après une sauvegarde terminée, un nouveau lien ou une action similaire. Elle se ferme automatiquement et reste plus longtemps lorsqu'elle est survolée ou focalisée.",
            "Cela confirme l'action de l'interface. Cela ne remplace pas un statut financier confirmé ni ne crée d'enregistrement de paiement. Les erreurs de champ restent à côté du formulaire."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "api",
          "title": "Lecture et marquage via l'API",
          "paragraphs": [
            "GET /api/notifications renvoie jusqu'à 30 événements de compte, unreadCount et nextCursor. Passez nextCursor inchangé comme curseur pour charger une autre page. unread=1 sélectionne les entrées non lues. L'ordre de tri est createdAt décroissant, puis id décroissant.",
            "PATCH /api/notifications/read accepte soit 1–100 identifiants, soit all:true avec before défini sur l'horodatage en millisecondes du dernier événement affiché. Une session, Origin et X-CSRF-Token sont requis. Le client ne peut pas définir le propriétaire de l'enregistrement.",
            "La réponse contient updated, readAt et unreadCount. Lire un événement déjà lu conserve son readAt d'origine. Lister les événements ne les marque pas comme lus ; le statut Telegram et sentAt restent inchangés."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JSON · mark selected",
            "code": "{\n  \"ids\": [\"ntf_46d94180-492e-4c28-b15f-a70049161a63\"]\n}"
          },
          "note": "",
          "links": [
            {
              "label": "Référence API",
              "href": "/docs/api-reference"
            }
          ]
        },
        {
          "id": "commands",
          "title": "Commandes du bot",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Commande",
              "Action"
            ],
            "rows": [
              [
                "/notifications",
                "Gérer les catégories"
              ],
              [
                "/stop",
                "Désactiver les notifications"
              ],
              [
                "/help",
                "Lister les commandes disponibles"
              ],
              [
                "/logout",
                "Terminer toutes les sessions de compte"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "availability",
          "title": "Disponibilité des fonctionnalités",
          "paragraphs": [
            "Le centre de notifications nécessite une connexion. Les messages Telegram sont envoyés au chat privé vérifié du bot. Si la livraison est indisponible, vérifiez les autorisations du bot et le statut du message.",
            "Une notification de paiement ou de versement est basée sur un événement serveur confirmé. La sélection d'une catégorie modifie les préférences de livraison, pas la disponibilité des transactions."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "Centre de notifications\n\nLe badge compte les événements de compte non lus. Les messages sont regroupés par date ; Charger plus récupère les enregistrements plus anciens. Les visiteurs sont invités à se connecter.\n\nL'état de lecture est stocké sur le serveur. Les pages visibles se rafraîchissent automatiquement et les onglets ouverts synchronisent les marques de lecture. Les événements plus récents que le dernier message affiché ne sont pas marqués comme lus avec les plus anciens.\n\nSélectionnez la cloche dans la barre supérieure.\n\nChoisissez tous les événements ou uniquement les non lus.\n\nOuvrez la page concernée ou marquez un message comme lu.\n\nUtilisez Tout marquer comme lu pour les événements déjà chargés.\n\nCatégories d'événements\n\nL'assistance et la sécurité sont activées pour un nouveau compte ; les catégories de paiement sont sélectionnées par l'utilisateur. Le centre affiche les événements enregistrés pour les catégories activées. Les événements de démonstration du navigateur ne sont pas de véritables notifications de fonds.\n\nCatégorie · Contenu\nPaiements · Événements de paiement confirmés\nVersements · Événements de versement confirmés\nAssistance · Demandes d'assistance et mises à jour de l'étape de candidature\nSécurité · Nouvelle connexion vérifiée\nTest · Vérification de livraison vers votre Telegram\n\nConfiguration de la livraison\n\nLes tests sont limités à trois par compte et par heure. Un test ne modifie pas un solde ni ne crée un paiement. Mettre un message en file d'attente ne prouve pas la livraison.\n\nConnectez-vous avec Telegram et ouvrez Compte → Notifications.\n\nActivez les catégories souhaitées et enregistrez.\n\nSélectionnez Tester la livraison.\n\nVérifiez le statut du centre et le chat privé du bot.\n\nParamètres de notification\n\nLivraison et état de lecture sont distincts\n\nLa livraison dépend de la disponibilité de Telegram et des autorisations de l'utilisateur. Une réponse perdue peut entraîner un message répété, mais pas une opération financière répétée.\n\nSi la livraison échoue, vérifiez que le bot est joignable et non bloqué. Les nouvelles tentatives de notification de l'application s'exécutent également dans des tâches en arrière-plan ; les interactions de service peuvent déclencher d'autres livraisons en file d'attente. Consultez le centre de notifications pour connaître l'état actuel.\n\nStatut · Signification\nen attente · En file d'attente pour traitement\nenvoi · Le serveur tente la livraison\nenvoyé · Telegram a confirmé l'envoi\néchoué · Échec de la livraison\n\nL'état de livraison du message fait référence à Telegram. Marquer une notification comme lue sur le site web ne signifie pas qu'elle a été lue dans Telegram et ne change pas la livraison.\n\nConfirmations d'action\n\nLe site web affiche une brève notification après une sauvegarde terminée, un nouveau lien ou une action similaire. Elle se ferme automatiquement et reste plus longtemps lorsqu'elle est survolée ou focalisée.\n\nCela confirme l'action de l'interface. Cela ne remplace pas un statut financier confirmé ni ne crée d'enregistrement de paiement. Les erreurs de champ restent à côté du formulaire.\n\nLecture et marquage via l'API\n\nGET /api/notifications renvoie jusqu'à 30 événements de compte, unreadCount et nextCursor. Passez nextCursor inchangé comme curseur pour charger une autre page. unread=1 sélectionne les entrées non lues. L'ordre de tri est createdAt décroissant, puis id décroissant.\n\nPATCH /api/notifications/read accepte soit 1–100 identifiants, soit all:true avec before défini sur l'horodatage en millisecondes du dernier événement affiché. Une session, Origin et X-CSRF-Token sont requis. Le client ne peut pas définir le propriétaire de l'enregistrement.\n\nLa réponse contient updated, readAt et unreadCount. Lire un événement déjà lu conserve son readAt d'origine. Lister les événements ne les marque pas comme lus ; le statut Telegram et sentAt restent inchangés.\n\n{\n  \"ids\": [\"ntf_46d94180-492e-4c28-b15f-a70049161a63\"]\n}\n\nRéférence API\n\nCommandes du bot\n\nCommande · Action\n/notifications · Gérer les catégories\n/stop · Désactiver les notifications\n/help · Lister les commandes disponibles\n/logout · Terminer toutes les sessions de compte\n\nDisponibilité des fonctionnalités\n\nLe centre de notifications nécessite une connexion. Les messages Telegram sont envoyés au chat privé vérifié du bot. Si la livraison est indisponible, vérifiez les autorisations du bot et le statut du message.\n\nUne notification de paiement ou de versement est basée sur un événement serveur confirmé. La sélection d'une catégorie modifie les préférences de livraison, pas la disponibilité des transactions.",
      "readMinutes": 4
    },
    {
      "id": "support",
      "title": "Chat d'assistance et demandes",
      "summary": "L'assistant explique les conditions de Kevmi, trouve la bonne page et aide avec les paramètres. Ouvrez le chat à l'aide du bouton rond en bas à droite. Utilisez une demande privée pour une question spécifique au compte.",
      "group": "account",
      "url": "/docs/support",
      "tags": [
        "support",
        "aide",
        "AI",
        "assistant",
        "documentation",
        "demande",
        "chat"
      ],
      "sections": [
        {
          "id": "chat",
          "title": "Aide sur la page actuelle",
          "paragraphs": [
            "Sur téléphone, le chat s'ouvre dans un panneau compact. Vous pouvez le réduire et le rouvrir ; un badge apparaît si une réponse arrive pendant qu'il est fermé.",
            "Le support s'ouvre sur la page actuelle. L'ancienne adresse /help redirige vers la page d'accueil avec le chat ouvert."
          ],
          "bullets": [],
          "steps": [
            "Sélectionnez le bouton de support rond en bas à droite ou Posez votre question.",
            "Ouvrez une conversation existante ou commencez-en une nouvelle. Choisissez une suggestion ou saisissez une question : Entrée envoie ; Maj + Entrée ajoute une ligne.",
            "Lisez la réponse et suivez ses sources de documentation.",
            "Réduisez le chat pour continuer à travailler. Les messages et le brouillon restent dans ce navigateur."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Ouvrir le chat de support",
              "href": "/?support=open"
            }
          ]
        },
        {
          "id": "history",
          "title": "Conversations, brouillons et historique",
          "paragraphs": [
            "Gardez chaque sujet dans une conversation séparée. Recherchez dans l'historique par titre ou texte, renommez une conversation et épinglez celles qui sont importantes. Une nouvelle conversation préserve les chats antérieurs, et chacune garde son propre brouillon.",
            "Restaurez une conversation depuis Supprimé, ou supprimez-la définitivement après confirmation. L'historique est stocké dans le navigateur de cet appareil, survit aux rechargements de page et ne se synchronise pas entre les appareils, votre compte ou Telegram. Effacer les données du site dans le navigateur supprime l'historique local.",
            "Si le stockage du navigateur est indisponible, le chat continue dans la mémoire de la page ouverte. Les conversations locales sont séparées des demandes de support privées, qui sont stockées sur le serveur après connexion."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "knowledge",
          "title": "Sur quoi les réponses sont basées",
          "paragraphs": [
            "Le site web et le bot utilisent une base de connaissances versionnée. Le serveur fournit des guides publiés, des tarifs structurés, des faits sur les allocations et les pays, le catalogue de pages et l'état réel des fonctionnalités à l'assistant génératif. La base inclut les applications, les clés API, les widgets et les webhooks.",
            "Les sources de réponses se réfèrent uniquement aux articles de cette base. Lorsque les informations confirmées sont insuffisantes, l'assistant le dit et suggère une question plus spécifique ou une demande de support. Il n'invente pas de pays, de délais de versement, de limites ou d'obligations fiscales."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "context",
          "title": "Questions de suivi et contexte",
          "paragraphs": [
            "La question suivante inclut les trois dernières paires question-réponse de la conversation sélectionnée, ce qui aide pour les suivis comme « Et si le marchand paie la TVA ? ». L'autre historique local n'est pas automatiquement joint à la demande.",
            "Un court libellé de section, comme Tarifs ou Paiement, est également envoyé. L'URL, les paramètres de requête et le jeton de facture sont exclus. Les messages antérieurs sont un contexte non fiable et sont vérifiés par rapport à la base de connaissances."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "modes",
          "title": "IA et recherche de documentation",
          "paragraphs": [
            "Le mode IA utilise un fournisseur configuré, un stockage serveur et un quota disponible. /api/config signale l'état de préparation ; la connectivité du modèle est vérifiée lors d'une demande. Une génération indisponible, un quota épuisé ou une réponse invalide retombe sur la recherche de documentation étiquetée.",
            "La recherche fonctionne aussi sans modèle externe. L'assistant ne peut pas lire les comptes privés, les soldes, les demandes ou les données de paiement. Il ne peut pas prélever des fonds, créer des versements ni modifier les paramètres."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Mode",
              "Comportement"
            ],
            "rows": [
              [
                "ai",
                "Écrit une réponse à partir de l'ensemble des connaissances publiées et lie les guides pertinents"
              ],
              [
                "recherche",
                "Renvoie la documentation publiée correspondante"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "question",
          "title": "Poser une question utile",
          "paragraphs": [
            "Par exemple : « Une commande de carte de 5 $, avec TVA payée par le commerçant. Que reçoit le commerçant ? » Vérifiez les chiffres exacts dans la calculatrice publiée.",
            "Le champ de discussion accepte jusqu'à 1 800 caractères. Si la connexion échoue, la question reste dans le champ pour une nouvelle tentative."
          ],
          "bullets": [
            "Nommez la méthode : carte, SBP, Alipay ou cryptomonnaie.",
            "Pour un calcul, donnez le montant de base et les deux parts payées par le client : frais et TVA.",
            "Pour une erreur, nommez la page, l'action et le message affiché.",
            "N'envoyez pas de mots de passe, codes de connexion, jetons, CVV ou phrases de récupération."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "request",
          "title": "Questionner via l'API",
          "paragraphs": [
            "POST /api/support/ask accepte une question de 2 à 2 000 caractères après suppression des espaces. L'historique facultatif contient jusqu'à six messages avec role=user ou role=assistant. Les messages utilisateur acceptent 1 à 1 800 caractères et les messages assistant 1 à 3 000.",
            "pageContext facultatif est une étiquette de section de 1 à 80 caractères, sans URL, jetons, paramètres de requête ni sauts de ligne. locale facultatif est ru, en, es, de ou fr et sélectionne la langue de réponse. L'anglais est la valeur par défaut ; les sources techniques complètes sont disponibles en russe et en anglais. L'API n'accepte pas de messages système, d'outils ni d'instructions arbitraires du fournisseur.",
            "La limite du corps JSON est de 65 536 octets. La réponse contient mode, answer, sources, knowledgeVersion et needsHuman, avec aiUnavailable:true lorsque la génération est indisponible. Aucune session utilisateur n'est nécessaire ; un Origin fourni doit correspondre à l'application."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Contrat API",
              "href": "/docs/api-reference"
            }
          ]
        },
        {
          "id": "ticket",
          "title": "Demandes de support privées",
          "paragraphs": [
            "Après la connexion, créez une demande avec un objet de 1 à 120 caractères et un message de 5 à 4 000 caractères. Elle est stockée dans votre compte et n'est pas visible par un autre utilisateur.",
            "La liste affiche les 30 dernières demandes. Vous pouvez clore votre propre demande. Conservez sa référence pour vous renseigner sur le statut ; le délai de résolution dépend du problème."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Mes demandes de support",
              "href": "/account#support"
            }
          ]
        }
      ],
      "body": "Aide sur la page actuelle\n\nSur téléphone, le chat s'ouvre dans un panneau compact. Vous pouvez le réduire et le rouvrir ; un badge apparaît si une réponse arrive pendant qu'il est fermé.\n\nLe support s'ouvre sur la page actuelle. L'ancienne adresse /help redirige vers la page d'accueil avec le chat ouvert.\n\nSélectionnez le bouton de support rond en bas à droite ou Posez votre question.\n\nOuvrez une conversation existante ou commencez-en une nouvelle. Choisissez une suggestion ou saisissez une question : Entrée envoie ; Maj + Entrée ajoute une ligne.\n\nLisez la réponse et suivez ses sources de documentation.\n\nRéduisez le chat pour continuer à travailler. Les messages et le brouillon restent dans ce navigateur.\n\nOuvrir le chat de support\n\nConversations, brouillons et historique\n\nGardez chaque sujet dans une conversation séparée. Recherchez dans l'historique par titre ou texte, renommez une conversation et épinglez celles qui sont importantes. Une nouvelle conversation préserve les chats antérieurs, et chacune garde son propre brouillon.\n\nRestaurez une conversation depuis Supprimé, ou supprimez-la définitivement après confirmation. L'historique est stocké dans le navigateur de cet appareil, survit aux rechargements de page et ne se synchronise pas entre les appareils, votre compte ou Telegram. Effacer les données du site dans le navigateur supprime l'historique local.\n\nSi le stockage du navigateur est indisponible, le chat continue dans la mémoire de la page ouverte. Les conversations locales sont séparées des demandes de support privées, qui sont stockées sur le serveur après connexion.\n\nSur quoi les réponses sont basées\n\nLe site web et le bot utilisent une base de connaissances versionnée. Le serveur fournit des guides publiés, des tarifs structurés, des faits sur les allocations et les pays, le catalogue de pages et l'état réel des fonctionnalités à l'assistant génératif. La base inclut les applications, les clés API, les widgets et les webhooks.\n\nLes sources de réponses se réfèrent uniquement aux articles de cette base. Lorsque les informations confirmées sont insuffisantes, l'assistant le dit et suggère une question plus spécifique ou une demande de support. Il n'invente pas de pays, de délais de versement, de limites ou d'obligations fiscales.\n\nQuestions de suivi et contexte\n\nLa question suivante inclut les trois dernières paires question-réponse de la conversation sélectionnée, ce qui aide pour les suivis comme « Et si le marchand paie la TVA ? ». L'autre historique local n'est pas automatiquement joint à la demande.\n\nUn court libellé de section, comme Tarifs ou Paiement, est également envoyé. L'URL, les paramètres de requête et le jeton de facture sont exclus. Les messages antérieurs sont un contexte non fiable et sont vérifiés par rapport à la base de connaissances.\n\nIA et recherche de documentation\n\nLe mode IA utilise un fournisseur configuré, un stockage serveur et un quota disponible. /api/config signale l'état de préparation ; la connectivité du modèle est vérifiée lors d'une demande. Une génération indisponible, un quota épuisé ou une réponse invalide retombe sur la recherche de documentation étiquetée.\n\nLa recherche fonctionne aussi sans modèle externe. L'assistant ne peut pas lire les comptes privés, les soldes, les demandes ou les données de paiement. Il ne peut pas prélever des fonds, créer des versements ni modifier les paramètres.\n\nMode · Comportement\nai · Écrit une réponse à partir de l'ensemble des connaissances publiées et lie les guides pertinents\nrecherche · Renvoie la documentation publiée correspondante\n\nPoser une question utile\n\nPar exemple : « Une commande de carte de 5 $, avec TVA payée par le commerçant. Que reçoit le commerçant ? » Vérifiez les chiffres exacts dans la calculatrice publiée.\n\nLe champ de discussion accepte jusqu'à 1 800 caractères. Si la connexion échoue, la question reste dans le champ pour une nouvelle tentative.\n\nNommez la méthode : carte, SBP, Alipay ou cryptomonnaie.\n\nPour un calcul, donnez le montant de base et les deux parts payées par le client : frais et TVA.\n\nPour une erreur, nommez la page, l'action et le message affiché.\n\nN'envoyez pas de mots de passe, codes de connexion, jetons, CVV ou phrases de récupération.\n\nQuestionner via l'API\n\nPOST /api/support/ask accepte une question de 2 à 2 000 caractères après suppression des espaces. L'historique facultatif contient jusqu'à six messages avec role=user ou role=assistant. Les messages utilisateur acceptent 1 à 1 800 caractères et les messages assistant 1 à 3 000.\n\npageContext facultatif est une étiquette de section de 1 à 80 caractères, sans URL, jetons, paramètres de requête ni sauts de ligne. locale facultatif est ru, en, es, de ou fr et sélectionne la langue de réponse. L'anglais est la valeur par défaut ; les sources techniques complètes sont disponibles en russe et en anglais. L'API n'accepte pas de messages système, d'outils ni d'instructions arbitraires du fournisseur.\n\nLa limite du corps JSON est de 65 536 octets. La réponse contient mode, answer, sources, knowledgeVersion et needsHuman, avec aiUnavailable:true lorsque la génération est indisponible. Aucune session utilisateur n'est nécessaire ; un Origin fourni doit correspondre à l'application.\n\nContrat API\n\nDemandes de support privées\n\nAprès la connexion, créez une demande avec un objet de 1 à 120 caractères et un message de 5 à 4 000 caractères. Elle est stockée dans votre compte et n'est pas visible par un autre utilisateur.\n\nLa liste affiche les 30 dernières demandes. Vous pouvez clore votre propre demande. Conservez sa référence pour vous renseigner sur le statut ; le délai de résolution dépend du problème.\n\nMes demandes de support",
      "readMinutes": 6
    },
    {
      "id": "api-reference",
      "title": "Référence API",
      "summary": "L'API serveur prend en charge les comptes, factures, paiement sécurisé, statuts et webhooks. OpenAPI décrit les routes, champs et erreurs. Démarrer un paiement nécessite une passerelle configurée, un commerçant approuvé et des conditions de facture prises en charge.",
      "group": "developers",
      "url": "/docs/api-reference",
      "tags": [
        "API",
        "OpenAPI",
        "point de terminaison",
        "référence",
        "JSON"
      ],
      "sections": [
        {
          "id": "base",
          "title": "URL de base et format",
          "paragraphs": [
            "The base URL is https://kevmi.one. Request and response bodies use JSON. Money values are integer minor units. Account and support dates are Unix timestamps in milliseconds.",
            "Les réponses API utilisent Cache-Control: no-store. Le /openapi.json public peut être mis en cache pendant cinq minutes. Ne placez pas de cookies ni de secrets dans une URL."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "cURL",
            "code": "curl 'https://kevmi.one/api/config'\n\ncurl 'https://kevmi.one/openapi.json'"
          },
          "note": "",
          "links": []
        },
        {
          "id": "session",
          "title": "Autorisation des requêtes",
          "paragraphs": [
            "Le compte web utilise un cookie de session HttpOnly. GET /api/auth/me renvoie l'utilisateur actuel et csrfToken. Les mutations exigent X-CSRF-Token et une requête de même origine.",
            "Les clés commerçant Kevmi à portée limitée autorisent /api/v1/payments, /api/v1/payment-links et /api/v1/events. Elles ne remplacent pas le cookie de session pour les paramètres du compte ni les routes administratives."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JavaScript · website browser",
            "code": "const me = await fetch('/api/auth/me').then(r => r.json());\nif (!me.authenticated) throw new Error('Sign in required');\nconst response = await fetch('/api/account/settings', {\n  method: 'PATCH',\n  headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': me.csrfToken },\n  body: JSON.stringify({ vatPayer: 'merchant' })\n});\nif (!response.ok) throw new Error('Settings were not saved');\nconst updated = await response.json();"
          },
          "note": "",
          "links": []
        },
        {
          "id": "groups",
          "title": "Groupes de points de terminaison",
          "paragraphs": [
            "GET /api/config signale la présence de la configuration serveur. GET /api/checkout/{token} renvoie la disponibilité de la facture pour la méthode sélectionnée, y compris l'approbation du commerçant et les conditions enregistrées. Ces vérifications n'établissent pas la connectivité du fournisseur ni le succès du paiement : le résultat provient de l'opération de passerelle vérifiée."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Groupe",
              "Objectif"
            ],
            "rows": [
              [
                "Configuration et santé",
                "Disponibilité du service public et du stockage"
              ],
              [
                "Authentification",
                "Défis et sessions Telegram"
              ],
              [
                "Compte",
                "Paramètres et application commerçant privée"
              ],
              [
                "/api/v1/payments",
                "Création et lecture de factures serveur à portée limitée ; ne lance pas de débit"
              ],
              [
                "/api/v1/events",
                "Journal d'événements serveur avec events:read"
              ],
              [
                "Intégrations",
                "Administration des clés et des points de terminaison webhook authentifiés par session"
              ],
              [
                "Applications et modération",
                "Soumissions possédées, suivi du statut et autorisations de modérateur distinctes"
              ],
              [
                "Paiement",
                "Facture publique, demande de carte chiffrée, opération concrète, code bancaire, statut et rapprochement"
              ],
              [
                "Entrée de passerelle",
                "Notifications v3 signées et vérification d'opération authentifiée"
              ],
              [
                "Support et notifications",
                "Questions, demandes privées, événements et état de lecture"
              ],
              [
                "Telegram",
                "Webhook de bot vérifié"
              ],
              [
                "Routes monétaires non prises en charge",
                "Les /api/payments et /api/payouts directs hérités ne créent pas de débit ni de paiement"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "support-example",
          "title": "Une demande de connaissance publique",
          "paragraphs": [
            "La réponse comprend mode, answer, sources, knowledgeVersion et needsHuman. Un Origin fourni doit correspondre à l'origine de l'application. Un agent de documentation côté serveur peut omettre Origin."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "cURL",
            "code": "curl 'https://kevmi.one/api/support/ask' \\\n  -H 'Content-Type: application/json' \\\n  --data '{\"question\":\"Who pays VAT?\",\"locale\":\"en\"}'"
          },
          "note": "",
          "links": []
        },
        {
          "id": "errors",
          "title": "Erreurs et limites",
          "paragraphs": [
            "Une erreur comprend un code lisible par machine et un message. Les champs de requête inconnus sont rejetés. Les corps JSON standard permettent 16 384 octets ; /api/support/ask et le webhook Telegram permettent 65 536.",
            "429 indique une limite de débit. 503 peut indiquer une intégration indisponible, pas un paiement refusé. Lisez error.code et ne modifiez pas un statut financier sur la seule base d'un statut HTTP."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Codes d'erreur",
              "href": "/docs/errors"
            },
            {
              "label": "Spécification OpenAPI complète",
              "href": "/openapi.json"
            }
          ]
        },
        {
          "id": "stores-usd",
          "title": "Plusieurs boutiques et un prix de base USD unique",
          "paragraphs": [
            "Choisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.",
            "Les factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.",
            "Le taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.",
            "Créez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.",
            "Pour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "json",
            "code": "{\n  \"pricingMode\": \"universal\",\n  \"title\": \"Order 1042\",\n  \"amountMinor\": 1000,\n  \"currency\": \"USD\",\n  \"methods\": [\n    \"card\",\n    \"alipay\",\n    \"sbp\",\n    \"crypto\"\n  ],\n  \"vatCustomerPercent\": 100,\n  \"feeCustomerPercent\": 0\n}"
          },
          "note": "",
          "links": []
        }
      ],
      "body": "URL de base et format\n\nThe base URL is https://kevmi.one. Request and response bodies use JSON. Money values are integer minor units. Account and support dates are Unix timestamps in milliseconds.\n\nLes réponses API utilisent Cache-Control: no-store. Le /openapi.json public peut être mis en cache pendant cinq minutes. Ne placez pas de cookies ni de secrets dans une URL.\n\ncurl 'https://kevmi.one/api/config'\n\ncurl 'https://kevmi.one/openapi.json'\n\nAutorisation des requêtes\n\nLe compte web utilise un cookie de session HttpOnly. GET /api/auth/me renvoie l'utilisateur actuel et csrfToken. Les mutations exigent X-CSRF-Token et une requête de même origine.\n\nLes clés commerçant Kevmi à portée limitée autorisent /api/v1/payments, /api/v1/payment-links et /api/v1/events. Elles ne remplacent pas le cookie de session pour les paramètres du compte ni les routes administratives.\n\nconst me = await fetch('/api/auth/me').then(r => r.json());\nif (!me.authenticated) throw new Error('Sign in required');\nconst response = await fetch('/api/account/settings', {\n  method: 'PATCH',\n  headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': me.csrfToken },\n  body: JSON.stringify({ vatPayer: 'merchant' })\n});\nif (!response.ok) throw new Error('Settings were not saved');\nconst updated = await response.json();\n\nGroupes de points de terminaison\n\nGET /api/config signale la présence de la configuration serveur. GET /api/checkout/{token} renvoie la disponibilité de la facture pour la méthode sélectionnée, y compris l'approbation du commerçant et les conditions enregistrées. Ces vérifications n'établissent pas la connectivité du fournisseur ni le succès du paiement : le résultat provient de l'opération de passerelle vérifiée.\n\nGroupe · Objectif\nConfiguration et santé · Disponibilité du service public et du stockage\nAuthentification · Défis et sessions Telegram\nCompte · Paramètres et application commerçant privée\n/api/v1/payments · Création et lecture de factures serveur à portée limitée ; ne lance pas de débit\n/api/v1/events · Journal d'événements serveur avec events:read\nIntégrations · Administration des clés et des points de terminaison webhook authentifiés par session\nApplications et modération · Soumissions possédées, suivi du statut et autorisations de modérateur distinctes\nPaiement · Facture publique, demande de carte chiffrée, opération concrète, code bancaire, statut et rapprochement\nEntrée de passerelle · Notifications v3 signées et vérification d'opération authentifiée\nSupport et notifications · Questions, demandes privées, événements et état de lecture\nTelegram · Webhook de bot vérifié\nRoutes monétaires non prises en charge · Les /api/payments et /api/payouts directs hérités ne créent pas de débit ni de paiement\n\nUne demande de connaissance publique\n\nLa réponse comprend mode, answer, sources, knowledgeVersion et needsHuman. Un Origin fourni doit correspondre à l'origine de l'application. Un agent de documentation côté serveur peut omettre Origin.\n\ncurl 'https://kevmi.one/api/support/ask' \\\n  -H 'Content-Type: application/json' \\\n  --data '{\"question\":\"Who pays VAT?\",\"locale\":\"en\"}'\n\nErreurs et limites\n\nUne erreur comprend un code lisible par machine et un message. Les champs de requête inconnus sont rejetés. Les corps JSON standard permettent 16 384 octets ; /api/support/ask et le webhook Telegram permettent 65 536.\n\n429 indique une limite de débit. 503 peut indiquer une intégration indisponible, pas un paiement refusé. Lisez error.code et ne modifiez pas un statut financier sur la seule base d'un statut HTTP.\n\nCodes d'erreur\n\nSpécification OpenAPI complète\n\nPlusieurs boutiques et un prix de base USD unique\n\nChoisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.\n\nLes factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.\n\nLe taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.\n\nCréez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.\n\nPour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé.\n\n{\n  \"pricingMode\": \"universal\",\n  \"title\": \"Order 1042\",\n  \"amountMinor\": 1000,\n  \"currency\": \"USD\",\n  \"methods\": [\n    \"card\",\n    \"alipay\",\n    \"sbp\",\n    \"crypto\"\n  ],\n  \"vatCustomerPercent\": 100,\n  \"feeCustomerPercent\": 0\n}",
      "readMinutes": 4
    },
    {
      "id": "payment-links-api",
      "title": "API de liens de paiement et clés API",
      "summary": "Créez une facture depuis votre backend et recevez checkoutUrl immédiatement. L'API prend en charge les clés à portée limitée, les nouvelles tentatives idempotentes, les parts de frais et TVA indépendantes, une référence de commande et des métadonnées privées.",
      "tags": [
        "API",
        "lien de paiement",
        "idempotence",
        "paiement",
        "pagination",
        "clé API",
        "périmètre",
        "métadonnées"
      ],
      "sections": [
        {
          "id": "create",
          "title": "Une requête serveur renvoie un lien prêt à l’emploi",
          "paragraphs": [
            "POST /api/v1/payments et /api/v1/payment-links créent le même type de facture. Le nom de la route payments n’implique pas de débit : le résultat est une facture persistée avec ses conditions et une checkoutUrl pour le client.",
            "Envoyez Authorization: Bearer <key>, Content-Type: application/json et Idempotency-Key. Les clés d’idempotence contiennent 16 à 100 lettres, chiffres, tirets ou underscores. Persistez une clé pour chaque création logique de commande."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "cURL · server only",
            "code": "curl 'https://kevmi.maxeevmax1.chatgpt.site/api/v1/payments' \\\n  -H \"Authorization: Bearer $KEVMI_API_KEY\" \\\n  -H 'Content-Type: application/json' \\\n  -H 'Idempotency-Key: order-1042-create-v1' \\\n  --data '{\"title\":\"Design project · order 1042\",\"description\":\"One-time payment for the agreed design work\",\"amountMinor\":500,\"currency\":\"USD\",\"methods\":[\"card\",\"alipay\"],\"vatCustomerPercent\":100,\"feeCustomerPercent\":0,\"orderId\":\"order-1042\",\"metadata\":{\"campaign\":\"autumn\"}}'"
          },
          "note": "La réponse contient link, checkoutUrl et replayed. Transmettez checkoutUrl au client ou au widget ; conservez la clé API sur votre serveur.",
          "links": []
        },
        {
          "id": "keys",
          "title": "Périmètres et expiration des clés API",
          "paragraphs": [
            "Créez une clé à /account#keys dans votre compte marchand vérifié. Sa valeur complète n’apparaît qu’une fois ; seul un hash est stocké. Les clés durent 90 jours par défaut, avec une durée de vie autorisée de 1 à 365 jours et jusqu’à dix clés actives par compte.",
            "Accordez uniquement les périmètres requis. La révocation ou l’expiration bloque l’accès. Une clé ne remplace pas la session navigateur pour les paramètres du compte, l’administration des endpoints, les applications ou la modération. Ne la placez pas dans les widgets, les URL, les dépôts publics ou les messages d’assistance.",
            "Le site web utilise /api/payment-links avec son cookie de session, l’Origin exact et X-CSRF-Token. Ces routes opèrent sur les mêmes factures possédées."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Périmètre",
              "Objectif"
            ],
            "rows": [
              [
                "invoices:read",
                "Lire les factures possédées et leur liste"
              ],
              [
                "invoices:write",
                "Créer des factures et modifier la disponibilité des liens"
              ],
              [
                "events:read",
                "Lire le journal d’événements du serveur"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Clés API dans votre compte",
              "href": "/account#keys"
            }
          ]
        },
        {
          "id": "methods",
          "title": "Any et méthodes API concrètes",
          "paragraphs": [
            "Any est un mode de sélection d’interface. Les nouvelles factures acceptent les méthodes : [\"card\", \"alipay\"] ou un sous-ensemble non vide pour USD ; [\"sbp\"] pour RUB ; [\"crypto\"] pour USDT. La valeur any n’est pas une méthode de paiement API.",
            "Pour une nouvelle facture dans l'interface, USD propose les cartes et Alipay ; RUB propose SBP ; USDT propose la crypto. L'API peut également enregistrer USD + crypto pour compatibilité, mais son paiement crypto en direct est bloqué avec crypto_requires_usdt. USD et USDT sont distincts, sans conversion automatique ni taux de 1:1 supposé. Un paiement crypto nécessite une facture USDT séparée.",
            "Pour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Any dans l’interface du compte",
              "href": "/docs/payment-links#any"
            },
            {
              "label": "Paiement",
              "href": "/docs/checkout"
            }
          ]
        },
        {
          "id": "snapshot",
          "title": "Champs et conditions persistées",
          "paragraphs": [
            "La facture enregistre le nom du marchand, le prix, la devise, les méthodes, les deux parts de coûts et les devis calculés. Les métadonnées sont renvoyées au propriétaire et dans les événements serveur, mais pas via le checkout public. N’y stockez pas de secrets de paiement.",
            "Si les parts sont omises, le marchand couvre les frais ; la TVA hérite de vatPayer ou du paramètre du compte. Une répartition partielle peut renvoyer vatPayer=shared. Le titre, orderId et la description sont publics."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Champ",
              "Règle"
            ],
            "rows": [
              [
                "title / description",
                "1 à 120 / 0 à 500 caractères"
              ],
              [
                "amountMinor",
                "Entier de 1 à 10 000 000 000 ; 500 signifie 5,00 $ en USD"
              ],
              [
                "currency / methods",
                "USD : card, alipay ; RUB : sbp ; USDT : crypto. Liste unique non vide."
              ],
              [
                "vatCustomerPercent / feeCustomerPercent",
                "Parts client entières indépendantes de 0 à 100"
              ],
              [
                "vatPayer",
                "Hérité customer ou merchant ; ne peut pas entrer en conflit avec la part de TVA"
              ],
              [
                "orderId",
                "Facultatif, jusqu’à 100 caractères ; visible par le client"
              ],
              [
                "métadonnées",
                "Jusqu’à dix entrées de chaîne ; clé de 1 à 40 lettres/chiffres/_/- ; valeur jusqu’à 500 caractères ; total jusqu’à 3000 octets UTF-8"
              ],
              [
                "expiresAt",
                "Unix ms futur dans les 90 jours ; sept jours par défaut"
              ]
            ]
          },
          "code": null,
          "note": "Par compatibilité, l’API enregistre aussi USD + crypto, mais l’exécution crypto en direct est bloquée avec crypto_requires_usdt. Utilisez USDT pour les nouvelles factures crypto ; aucune conversion automatique n’est effectuée.",
          "links": [
            {
              "label": "Formules de répartition des coûts",
              "href": "/docs/cost-sharing"
            }
          ]
        },
        {
          "id": "idempotency",
          "title": "Nouvelle tentative après une erreur réseau",
          "paragraphs": [
            "La création initiale renvoie 201 avec replayed=false. La même clé et le même corps canonique renvoient 200, la checkoutUrl d’origine et replayed=true. Une requête différente sous cette clé renvoie 409 IDEMPOTENCY_CONFLICT.",
            "Ne générez pas une autre clé après un délai d’attente. Répétez la requête d’origine avec des champs identiques. Les valeurs omises n’héritent pas à nouveau des paramètres modifiés. orderId aide à corréler une commande mais ne remplace pas Idempotency-Key et n’est pas requis comme unique en stockage."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "read",
          "title": "Lecture et pagination",
          "paragraphs": [
            "GET /api/v1/payments renvoie links et nextCursor ; GET /api/v1/payments/{id} renvoie un lien possédé. invoices:read est requis. La taille de page par défaut est 30 ; limit accepte 1 à 100.",
            "Les réponses GET liste et détail incluent link.payment : un résumé de l’opération associée, ou null quand aucune opération n’existe. Les réponses POST/PATCH peuvent l’omettre ; relisez la facture lorsque vous avez besoin du résumé. Le statut du lien décrit séparément si un nouveau paiement peut commencer. Les champs de carte et les clés privées ne sont jamais inclus.",
            "Passez nextCursor inchangé via URLSearchParams. null marque la fin ; les ID inconnus et ceux d’autres marchands renvoient tous 404."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "HTTP",
            "code": "GET /api/v1/payments?limit=30\nAuthorization: Bearer <server-side key>"
          },
          "note": "",
          "links": []
        },
        {
          "id": "status",
          "title": "Pause, reprise et annulation",
          "paragraphs": [
            "PATCH /api/v1/payments/{id} avec invoices:write accepte uniquement {\"status\":\"active\"}, {\"status\":\"paused\"} ou {\"status\":\"cancelled\"}. L’annulation est définitive. expired est dérivé du moment d’expiration ; une facture expirée ne peut pas être prolongée.",
            "Prix, parts de coûts, description, orderId, métadonnées et expiration sont immuables. Créez une autre facture pour des conditions différentes. Modifier la disponibilité émet invoice.updated, pas un événement de paiement réussi."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "buyer",
          "title": "La réponse client",
          "paragraphs": [
            "GET /api/checkout/{token}?method=card renvoie la facture publique, le devis, la disponibilité des méthodes et l’opération existante. Les métadonnées du propriétaire, les secrets et les soldes ne sont pas exposés.",
            "POST /api/checkout/{token}/pay exige l’Origin du site et une méthode concrète. Les données de carte ne sont acceptées que scellées : {intent,jwe}, après que le navigateur obtient /card-intent. Les codes bancaires sont chiffrés et envoyés via /code. La crypto utilise une facture USDT enregistrée et une paire coin/réseau disponible.",
            "Un nouveau paiement et une intention de carte nécessitent l'approbation de la dernière demande de revue du site du marchand. L'approbation seule ne connecte pas la passerelle de paiement. Si la revue change après l'envoi, l'opération existante reste disponible pour la lecture des statuts, le rapprochement et un code bancaire demandé.",
            "Une connexion live manquante renvoie GATEWAY_NOT_CONNECTED ; une répartition incompatible n’est jamais remplacée par un autre calcul. Status et reconcile lisent l’opération d’origine sans débit en double."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Widget de checkout",
              "href": "/docs/widgets"
            },
            {
              "label": "Confirmer le paiement avec des webhooks",
              "href": "/docs/webhooks"
            }
          ]
        },
        {
          "id": "stores-usd",
          "title": "Plusieurs boutiques et un prix de base USD unique",
          "paragraphs": [
            "Choisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.",
            "Les factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.",
            "Le taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.",
            "Créez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.",
            "Pour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "group": "developers",
      "url": "/docs/payment-links-api",
      "body": "Une requête serveur renvoie un lien prêt à l’emploi\n\nPOST /api/v1/payments et /api/v1/payment-links créent le même type de facture. Le nom de la route payments n’implique pas de débit : le résultat est une facture persistée avec ses conditions et une checkoutUrl pour le client.\n\nEnvoyez Authorization: Bearer <key>, Content-Type: application/json et Idempotency-Key. Les clés d’idempotence contiennent 16 à 100 lettres, chiffres, tirets ou underscores. Persistez une clé pour chaque création logique de commande.\n\ncurl 'https://kevmi.maxeevmax1.chatgpt.site/api/v1/payments' \\\n  -H \"Authorization: Bearer $KEVMI_API_KEY\" \\\n  -H 'Content-Type: application/json' \\\n  -H 'Idempotency-Key: order-1042-create-v1' \\\n  --data '{\"title\":\"Design project · order 1042\",\"description\":\"One-time payment for the agreed design work\",\"amountMinor\":500,\"currency\":\"USD\",\"methods\":[\"card\",\"alipay\"],\"vatCustomerPercent\":100,\"feeCustomerPercent\":0,\"orderId\":\"order-1042\",\"metadata\":{\"campaign\":\"autumn\"}}'\n\nLa réponse contient link, checkoutUrl et replayed. Transmettez checkoutUrl au client ou au widget ; conservez la clé API sur votre serveur.\n\nPérimètres et expiration des clés API\n\nCréez une clé à /account#keys dans votre compte marchand vérifié. Sa valeur complète n’apparaît qu’une fois ; seul un hash est stocké. Les clés durent 90 jours par défaut, avec une durée de vie autorisée de 1 à 365 jours et jusqu’à dix clés actives par compte.\n\nAccordez uniquement les périmètres requis. La révocation ou l’expiration bloque l’accès. Une clé ne remplace pas la session navigateur pour les paramètres du compte, l’administration des endpoints, les applications ou la modération. Ne la placez pas dans les widgets, les URL, les dépôts publics ou les messages d’assistance.\n\nLe site web utilise /api/payment-links avec son cookie de session, l’Origin exact et X-CSRF-Token. Ces routes opèrent sur les mêmes factures possédées.\n\nPérimètre · Objectif\ninvoices:read · Lire les factures possédées et leur liste\ninvoices:write · Créer des factures et modifier la disponibilité des liens\nevents:read · Lire le journal d’événements du serveur\n\nClés API dans votre compte\n\nAny et méthodes API concrètes\n\nAny est un mode de sélection d’interface. Les nouvelles factures acceptent les méthodes : [\"card\", \"alipay\"] ou un sous-ensemble non vide pour USD ; [\"sbp\"] pour RUB ; [\"crypto\"] pour USDT. La valeur any n’est pas une méthode de paiement API.\n\nPour une nouvelle facture dans l'interface, USD propose les cartes et Alipay ; RUB propose SBP ; USDT propose la crypto. L'API peut également enregistrer USD + crypto pour compatibilité, mais son paiement crypto en direct est bloqué avec crypto_requires_usdt. USD et USDT sont distincts, sans conversion automatique ni taux de 1:1 supposé. Un paiement crypto nécessite une facture USDT séparée.\n\nPour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA.\n\nAny dans l’interface du compte\n\nPaiement\n\nChamps et conditions persistées\n\nLa facture enregistre le nom du marchand, le prix, la devise, les méthodes, les deux parts de coûts et les devis calculés. Les métadonnées sont renvoyées au propriétaire et dans les événements serveur, mais pas via le checkout public. N’y stockez pas de secrets de paiement.\n\nSi les parts sont omises, le marchand couvre les frais ; la TVA hérite de vatPayer ou du paramètre du compte. Une répartition partielle peut renvoyer vatPayer=shared. Le titre, orderId et la description sont publics.\n\nChamp · Règle\ntitle / description · 1 à 120 / 0 à 500 caractères\namountMinor · Entier de 1 à 10 000 000 000 ; 500 signifie 5,00 $ en USD\ncurrency / methods · USD : card, alipay ; RUB : sbp ; USDT : crypto. Liste unique non vide.\nvatCustomerPercent / feeCustomerPercent · Parts client entières indépendantes de 0 à 100\nvatPayer · Hérité customer ou merchant ; ne peut pas entrer en conflit avec la part de TVA\norderId · Facultatif, jusqu’à 100 caractères ; visible par le client\nmétadonnées · Jusqu’à dix entrées de chaîne ; clé de 1 à 40 lettres/chiffres/_/- ; valeur jusqu’à 500 caractères ; total jusqu’à 3000 octets UTF-8\nexpiresAt · Unix ms futur dans les 90 jours ; sept jours par défaut\n\nPar compatibilité, l’API enregistre aussi USD + crypto, mais l’exécution crypto en direct est bloquée avec crypto_requires_usdt. Utilisez USDT pour les nouvelles factures crypto ; aucune conversion automatique n’est effectuée.\n\nFormules de répartition des coûts\n\nNouvelle tentative après une erreur réseau\n\nLa création initiale renvoie 201 avec replayed=false. La même clé et le même corps canonique renvoient 200, la checkoutUrl d’origine et replayed=true. Une requête différente sous cette clé renvoie 409 IDEMPOTENCY_CONFLICT.\n\nNe générez pas une autre clé après un délai d’attente. Répétez la requête d’origine avec des champs identiques. Les valeurs omises n’héritent pas à nouveau des paramètres modifiés. orderId aide à corréler une commande mais ne remplace pas Idempotency-Key et n’est pas requis comme unique en stockage.\n\nLecture et pagination\n\nGET /api/v1/payments renvoie links et nextCursor ; GET /api/v1/payments/{id} renvoie un lien possédé. invoices:read est requis. La taille de page par défaut est 30 ; limit accepte 1 à 100.\n\nLes réponses GET liste et détail incluent link.payment : un résumé de l’opération associée, ou null quand aucune opération n’existe. Les réponses POST/PATCH peuvent l’omettre ; relisez la facture lorsque vous avez besoin du résumé. Le statut du lien décrit séparément si un nouveau paiement peut commencer. Les champs de carte et les clés privées ne sont jamais inclus.\n\nPassez nextCursor inchangé via URLSearchParams. null marque la fin ; les ID inconnus et ceux d’autres marchands renvoient tous 404.\n\nGET /api/v1/payments?limit=30\nAuthorization: Bearer <server-side key>\n\nPause, reprise et annulation\n\nPATCH /api/v1/payments/{id} avec invoices:write accepte uniquement {\"status\":\"active\"}, {\"status\":\"paused\"} ou {\"status\":\"cancelled\"}. L’annulation est définitive. expired est dérivé du moment d’expiration ; une facture expirée ne peut pas être prolongée.\n\nPrix, parts de coûts, description, orderId, métadonnées et expiration sont immuables. Créez une autre facture pour des conditions différentes. Modifier la disponibilité émet invoice.updated, pas un événement de paiement réussi.\n\nLa réponse client\n\nGET /api/checkout/{token}?method=card renvoie la facture publique, le devis, la disponibilité des méthodes et l’opération existante. Les métadonnées du propriétaire, les secrets et les soldes ne sont pas exposés.\n\nPOST /api/checkout/{token}/pay exige l’Origin du site et une méthode concrète. Les données de carte ne sont acceptées que scellées : {intent,jwe}, après que le navigateur obtient /card-intent. Les codes bancaires sont chiffrés et envoyés via /code. La crypto utilise une facture USDT enregistrée et une paire coin/réseau disponible.\n\nUn nouveau paiement et une intention de carte nécessitent l'approbation de la dernière demande de revue du site du marchand. L'approbation seule ne connecte pas la passerelle de paiement. Si la revue change après l'envoi, l'opération existante reste disponible pour la lecture des statuts, le rapprochement et un code bancaire demandé.\n\nUne connexion live manquante renvoie GATEWAY_NOT_CONNECTED ; une répartition incompatible n’est jamais remplacée par un autre calcul. Status et reconcile lisent l’opération d’origine sans débit en double.\n\nWidget de checkout\n\nConfirmer le paiement avec des webhooks\n\nPlusieurs boutiques et un prix de base USD unique\n\nChoisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.\n\nLes factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.\n\nLe taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.\n\nCréez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.\n\nPour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé.",
      "readMinutes": 7
    },
    {
      "id": "auth-api",
      "title": "API d'authentification et de session",
      "summary": "La connexion utilise un défi de courte durée, une confirmation Telegram et une preuve de contrôle du navigateur d'origine. Un identifiant Telegram fourni par le client ne constitue pas une preuve d'identité.",
      "group": "developers",
      "url": "/docs/auth-api",
      "tags": [
        "authentification",
        "session",
        "CSRF",
        "défi",
        "API"
      ],
      "sections": [
        {
          "id": "start",
          "title": "Démarrage de la connexion",
          "paragraphs": [
            "POST /api/auth/telegram/start accepte un objet JSON vide {}. Cela nécessite l'Origine exacte de l'application et un bot disponible. Le serveur crée un défi d'une durée de 300 secondes et un cookie protégé de preuve du navigateur.",
            "La réponse 201 contient challengeId, code, expiresAt et telegramUrl. Le cookie de preuve est exclu du lien profond et est inaccessible à JavaScript. La limite est de six démarrages par minute par adresse hachée."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JavaScript",
            "code": "const response = await fetch('/api/auth/telegram/start', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: '{}'\n});\nconst challenge = await response.json();\n// Show code and telegramUrl to the user."
          },
          "note": "",
          "links": []
        },
        {
          "id": "complete",
          "title": "Attente de confirmation",
          "paragraphs": [
            "POST /api/auth/telegram/complete accepte {challengeId}. Cela nécessite l'Origine et le cookie original de preuve du navigateur. Jusqu'à confirmation, la réponse est 202 {status: \"pending\"}.",
            "Après confirmation, 200 retourne status=authenticated, user, csrfToken et expiresAt. Une session est émise une seule fois. Les défis expirés retournent 410 ; les défis utilisés ou annulés retournent 409."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JavaScript",
            "code": "const response = await fetch('/api/auth/telegram/complete', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ challengeId: challenge.challengeId })\n});\nif (response.status === 202) {\n  // Poll again after a delay; do not create a new challenge.\n}"
          },
          "note": "",
          "links": []
        },
        {
          "id": "me",
          "title": "Lecture de la session",
          "paragraphs": [
            "GET /api/auth/me retourne 200 {authenticated:false} lorsqu'aucune session valide n'existe. Une réponse connectée inclut l'utilisateur, le jeton CSRF et l'expiration.",
            "Le cookie __Host-kevmi-session dure jusqu'à 24 heures avec Secure, HttpOnly, SameSite=Lax et Path=/. La base de données stocke un hachage SHA-256 de son jeton. Un formulaire de profil ne peut pas lire ni remplacer le cookie."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "write",
          "title": "Modifications du compte",
          "paragraphs": [
            "Les mutations nécessitent la session, l'Origine exacte et le X-CSRF-Token actuel. Sec-Fetch-Site : cross-site est rejeté. Le serveur n'offre pas d'accès CORS arbitraire.",
            "L'identifiant du compte provient de la session, pas des entrées de la requête. Les enregistrements manquants ou ceux d'un autre utilisateur ne divulguent pas de détails d'appartenance identifiables."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "logout",
          "title": "Déconnexion",
          "paragraphs": [
            "POST /api/auth/logout met fin à la session actuelle et efface le cookie. L'Origine et le CSRF sont requis ; le corps n'est pas lu. Telegram /logout met également fin à toutes les sessions du compte.",
            "Les cookies ne migrent pas automatiquement vers un autre domaine. Lors du changement de domaine de service, mettez à jour APP_ORIGIN et le webhook du bot, puis reconnectez-vous."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "Démarrage de la connexion\n\nPOST /api/auth/telegram/start accepte un objet JSON vide {}. Cela nécessite l'Origine exacte de l'application et un bot disponible. Le serveur crée un défi d'une durée de 300 secondes et un cookie protégé de preuve du navigateur.\n\nLa réponse 201 contient challengeId, code, expiresAt et telegramUrl. Le cookie de preuve est exclu du lien profond et est inaccessible à JavaScript. La limite est de six démarrages par minute par adresse hachée.\n\nconst response = await fetch('/api/auth/telegram/start', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: '{}'\n});\nconst challenge = await response.json();\n// Show code and telegramUrl to the user.\n\nAttente de confirmation\n\nPOST /api/auth/telegram/complete accepte {challengeId}. Cela nécessite l'Origine et le cookie original de preuve du navigateur. Jusqu'à confirmation, la réponse est 202 {status: \"pending\"}.\n\nAprès confirmation, 200 retourne status=authenticated, user, csrfToken et expiresAt. Une session est émise une seule fois. Les défis expirés retournent 410 ; les défis utilisés ou annulés retournent 409.\n\nconst response = await fetch('/api/auth/telegram/complete', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ challengeId: challenge.challengeId })\n});\nif (response.status === 202) {\n  // Poll again after a delay; do not create a new challenge.\n}\n\nLecture de la session\n\nGET /api/auth/me retourne 200 {authenticated:false} lorsqu'aucune session valide n'existe. Une réponse connectée inclut l'utilisateur, le jeton CSRF et l'expiration.\n\nLe cookie __Host-kevmi-session dure jusqu'à 24 heures avec Secure, HttpOnly, SameSite=Lax et Path=/. La base de données stocke un hachage SHA-256 de son jeton. Un formulaire de profil ne peut pas lire ni remplacer le cookie.\n\nModifications du compte\n\nLes mutations nécessitent la session, l'Origine exacte et le X-CSRF-Token actuel. Sec-Fetch-Site : cross-site est rejeté. Le serveur n'offre pas d'accès CORS arbitraire.\n\nL'identifiant du compte provient de la session, pas des entrées de la requête. Les enregistrements manquants ou ceux d'un autre utilisateur ne divulguent pas de détails d'appartenance identifiables.\n\nDéconnexion\n\nPOST /api/auth/logout met fin à la session actuelle et efface le cookie. L'Origine et le CSRF sont requis ; le corps n'est pas lu. Telegram /logout met également fin à toutes les sessions du compte.\n\nLes cookies ne migrent pas automatiquement vers un autre domaine. Lors du changement de domaine de service, mettez à jour APP_ORIGIN et le webhook du bot, puis reconnectez-vous.",
      "readMinutes": 3
    },
    {
      "id": "errors",
      "title": "Erreurs et nouvelles tentatives",
      "summary": "Les erreurs d'API utilisent un format cohérent. Le code concerne la logique applicative ; le message explique le problème. Conservez les entrées utilisateur intactes et proposez une prochaine étape claire.",
      "group": "developers",
      "url": "/docs/errors",
      "tags": [
        "erreur",
        "429",
        "503",
        "nouvelle tentative",
        "statut"
      ],
      "sections": [
        {
          "id": "format",
          "title": "Un format d'erreur",
          "paragraphs": [
            "Les réponses n'incluent pas de traces de pile, SQL, jetons ni de réponse complète d'un fournisseur externe. N'affichez pas de journaux internes bruts à un client."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JSON",
            "code": "{\n  \"error\": {\n    \"code\": \"GATEWAY_NOT_CONNECTED\",\n    \"message\": \"Financial operations are temporarily unavailable. Try later or contact support.\"\n  }\n}"
          },
          "note": "",
          "links": []
        },
        {
          "id": "codes",
          "title": "Groupes d'erreurs courants",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "HTTP",
              "Exemples",
              "Prochaine étape"
            ],
            "rows": [
              [
                "400",
                "INVALID_JSON, UNKNOWN_FIELD, INVALID_INPUT",
                "Vérifiez les entrées et les champs autorisés"
              ],
              [
                "401",
                "AUTH_REQUIRED, SESSION_EXPIRED",
                "Reconnectez-vous"
              ],
              [
                "403",
                "INVALID_ORIGIN, CSRF_REQUIRED",
                "Vérifiez l'origine et la session actuelle"
              ],
              [
                "404",
                "NOT_FOUND, TICKET_NOT_FOUND",
                "Vérifiez l'adresse et l'appartenance"
              ],
              [
                "409",
                "CHALLENGE_UNAVAILABLE",
                "Démarrez une nouvelle connexion"
              ],
              [
                "410",
                "CHALLENGE_EXPIRED",
                "Créez un nouveau lien de connexion"
              ],
              [
                "413",
                "REQUEST_TOO_LARGE",
                "Réduisez le corps de la requête"
              ],
              [
                "415",
                "JSON_REQUIRED",
                "Envoyez application/json"
              ],
              [
                "429",
                "RATE_LIMITED",
                "Réduisez la fréquence et attendez"
              ],
              [
                "503",
                "GATEWAY_NOT_CONNECTED, SERVICE_UNAVAILABLE",
                "Vérifiez la disponibilité ou réessayez plus tard"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "rate",
          "title": "Limites de débit",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Action",
              "Limite"
            ],
            "rows": [
              [
                "Démarrage de la connexion",
                "6 par minute par adresse hachée"
              ],
              [
                "Vérification d'un défi",
                "90 par minute par défi"
              ],
              [
                "Question de connaissance",
                "12 par minute par adresse hachée avec D1"
              ],
              [
                "Création d'un lien serveur",
                "20 par minute par utilisateur"
              ],
              [
                "API marchand",
                "90 requêtes par minute par clé"
              ],
              [
                "Nouvelle application",
                "Cinq par jour par utilisateur"
              ],
              [
                "Reprise d'application / décision du modérateur",
                "30 par minute par utilisateur pour chaque action"
              ],
              [
                "Examen de site web par IA",
                "30 par heure pour l'ensemble du service"
              ],
              [
                "Lire le paiement ou tenter un paiement",
                "90 par minute par adresse hachée"
              ],
              [
                "Créer une demande d'assistance",
                "6 par heure par utilisateur"
              ],
              [
                "Tester une notification",
                "3 par heure par utilisateur"
              ],
              [
                "Génération par IA",
                "60 par heure pour l'ensemble du service par défaut"
              ]
            ]
          },
          "code": null,
          "note": "Retry-After : 60 indique un délai, pas une garantie qu'un quota horaire a été réinitialisé.",
          "links": []
        },
        {
          "id": "retry",
          "title": "Ce qui peut être réessayé",
          "paragraphs": [
            "Une lecture peut être réessayée après un délai lors d'une panne réseau temporaire. Avant de réessayer une mutation, vérifiez si l'opération d'origine a abouti ; une réponse perdue ne prouve pas un échec.",
            "Les opérations financières exigent l'idempotence et une vérification de l'état du serveur. Une redirection du client vers une page de résultat ne remplace pas une confirmation."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "report",
          "title": "Ce qu'il faut inclure dans une demande",
          "paragraphs": [],
          "bullets": [
            "La page et l'action immédiatement avant l'erreur.",
            "L'heure, le fuseau horaire et le code d'erreur visible.",
            "Votre référence de facture ou de demande d'assistance, si disponible.",
            "Une brève description du résultat attendu."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "Ne joignez pas de cookies, jetons, en-têtes d'autorisation, CVV ou codes bancaires.",
          "links": []
        }
      ],
      "body": "Un format d'erreur\n\nLes réponses n'incluent pas de traces de pile, SQL, jetons ni de réponse complète d'un fournisseur externe. N'affichez pas de journaux internes bruts à un client.\n\n{\n  \"error\": {\n    \"code\": \"GATEWAY_NOT_CONNECTED\",\n    \"message\": \"Financial operations are temporarily unavailable. Try later or contact support.\"\n  }\n}\n\nGroupes d'erreurs courants\n\nHTTP · Exemples · Prochaine étape\n400 · INVALID_JSON, UNKNOWN_FIELD, INVALID_INPUT · Vérifiez les entrées et les champs autorisés\n401 · AUTH_REQUIRED, SESSION_EXPIRED · Reconnectez-vous\n403 · INVALID_ORIGIN, CSRF_REQUIRED · Vérifiez l'origine et la session actuelle\n404 · NOT_FOUND, TICKET_NOT_FOUND · Vérifiez l'adresse et l'appartenance\n409 · CHALLENGE_UNAVAILABLE · Démarrez une nouvelle connexion\n410 · CHALLENGE_EXPIRED · Créez un nouveau lien de connexion\n413 · REQUEST_TOO_LARGE · Réduisez le corps de la requête\n415 · JSON_REQUIRED · Envoyez application/json\n429 · RATE_LIMITED · Réduisez la fréquence et attendez\n503 · GATEWAY_NOT_CONNECTED, SERVICE_UNAVAILABLE · Vérifiez la disponibilité ou réessayez plus tard\n\nLimites de débit\n\nAction · Limite\nDémarrage de la connexion · 6 par minute par adresse hachée\nVérification d'un défi · 90 par minute par défi\nQuestion de connaissance · 12 par minute par adresse hachée avec D1\nCréation d'un lien serveur · 20 par minute par utilisateur\nAPI marchand · 90 requêtes par minute par clé\nNouvelle application · Cinq par jour par utilisateur\nReprise d'application / décision du modérateur · 30 par minute par utilisateur pour chaque action\nExamen de site web par IA · 30 par heure pour l'ensemble du service\nLire le paiement ou tenter un paiement · 90 par minute par adresse hachée\nCréer une demande d'assistance · 6 par heure par utilisateur\nTester une notification · 3 par heure par utilisateur\nGénération par IA · 60 par heure pour l'ensemble du service par défaut\n\nRetry-After : 60 indique un délai, pas une garantie qu'un quota horaire a été réinitialisé.\n\nCe qui peut être réessayé\n\nUne lecture peut être réessayée après un délai lors d'une panne réseau temporaire. Avant de réessayer une mutation, vérifiez si l'opération d'origine a abouti ; une réponse perdue ne prouve pas un échec.\n\nLes opérations financières exigent l'idempotence et une vérification de l'état du serveur. Une redirection du client vers une page de résultat ne remplace pas une confirmation.\n\nCe qu'il faut inclure dans une demande\n\nLa page et l'action immédiatement avant l'erreur.\n\nL'heure, le fuseau horaire et le code d'erreur visible.\n\nVotre référence de facture ou de demande d'assistance, si disponible.\n\nUne brève description du résultat attendu.\n\nNe joignez pas de cookies, jetons, en-têtes d'autorisation, CVV ou codes bancaires.",
      "readMinutes": 3
    },
    {
      "id": "security",
      "title": "Sécurité de l'intégration",
      "summary": "Les vérifications fiables s'exécutent sur le serveur. Le navigateur contrôle l'interface, mais ne peut pas établir l'identité, le statut financier ou les montants finaux.",
      "group": "developers",
      "url": "/docs/security",
      "tags": [
        "sécurité",
        "CSRF",
        "cookie",
        "propriété",
        "secret",
        "idempotence"
      ],
      "sections": [
        {
          "id": "identity",
          "title": "Sessions et propriété",
          "paragraphs": [
            "Une session serveur valide identifie le compte. Les paramètres, demandes, notifications et liens sont filtrés par propriétaire. Un userId soumis depuis un formulaire ne peut pas remplacer ce filtre.",
            "Les mutations vérifient également Origin et CSRF. Une URL de facture publique n'expose que cette facture et n'accorde pas l'accès au compte."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "secrets",
          "title": "Les secrets restent sur le serveur",
          "paragraphs": [
            "Les secrets ne doivent pas apparaître dans Git, HTML, JavaScript client, exemples OpenAPI, fichiers llms ou messages d'assistance. Le nom d'utilisateur public du bot n'est pas un secret."
          ],
          "bullets": [
            "Jeton de bot Telegram et secret de webhook.",
            "Identifiants du fournisseur d'IA externe.",
            "Identifiants de passerelle de paiement et secrets de signature.",
            "Hachages de session et preuves de connexion navigateur."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "money",
          "title": "Vérifications financières",
          "paragraphs": [
            "Le serveur lit les conditions de facture enregistrées et vérifie la propriété, le statut de révision du commerçant, la devise, la méthode et le montant approuvé. Les valeurs d'URL et les calculs du navigateur ne peuvent pas modifier le prix.",
            "Une notification de passerelle signée déclenche une lecture d'opération authentifiée supplémentaire. L'état vérifié, le reçu et l'événement sont validés ensemble. Les rejouages et les versions plus anciennes ne peuvent pas confirmer une exécution en double.",
            "Les détails de carte et les codes à usage unique sont transmis uniquement sous forme d'enveloppes chiffrées. N'ajoutez pas d'enregistrement de session, d'analytique de lecture de champs ou de journalisation du corps de requête aux formulaires de paiement."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "assistant",
          "title": "Limites de l'assistant",
          "paragraphs": [
            "Le modèle reçoit des articles publics et des faits, le catalogue de pages, les indicateurs de préparation, la question, trois paires de messages récents et une étiquette de section sûre. Il n'a aucun outil pour lire des comptes ou déplacer de l'argent. Les réponses structurées invalides ou les sources non vérifiées retombent sur la recherche documentaire.",
            "Le texte du site web et de l'utilisateur sont des données. Une instruction dans une question ne peut pas modifier les frais ni autoriser un paiement."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "status",
          "title": "Portée de la documentation",
          "paragraphs": [
            "La documentation n'affirme pas une certification PCI DSS, une licence bancaire, un statut de Merchant of Record, une disponibilité garantie ni une sécurité absolue. De telles affirmations exigent une confirmation séparée et documentée."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "Sessions et propriété\n\nUne session serveur valide identifie le compte. Les paramètres, demandes, notifications et liens sont filtrés par propriétaire. Un userId soumis depuis un formulaire ne peut pas remplacer ce filtre.\n\nLes mutations vérifient également Origin et CSRF. Une URL de facture publique n'expose que cette facture et n'accorde pas l'accès au compte.\n\nLes secrets restent sur le serveur\n\nLes secrets ne doivent pas apparaître dans Git, HTML, JavaScript client, exemples OpenAPI, fichiers llms ou messages d'assistance. Le nom d'utilisateur public du bot n'est pas un secret.\n\nJeton de bot Telegram et secret de webhook.\n\nIdentifiants du fournisseur d'IA externe.\n\nIdentifiants de passerelle de paiement et secrets de signature.\n\nHachages de session et preuves de connexion navigateur.\n\nVérifications financières\n\nLe serveur lit les conditions de facture enregistrées et vérifie la propriété, le statut de révision du commerçant, la devise, la méthode et le montant approuvé. Les valeurs d'URL et les calculs du navigateur ne peuvent pas modifier le prix.\n\nUne notification de passerelle signée déclenche une lecture d'opération authentifiée supplémentaire. L'état vérifié, le reçu et l'événement sont validés ensemble. Les rejouages et les versions plus anciennes ne peuvent pas confirmer une exécution en double.\n\nLes détails de carte et les codes à usage unique sont transmis uniquement sous forme d'enveloppes chiffrées. N'ajoutez pas d'enregistrement de session, d'analytique de lecture de champs ou de journalisation du corps de requête aux formulaires de paiement.\n\nLimites de l'assistant\n\nLe modèle reçoit des articles publics et des faits, le catalogue de pages, les indicateurs de préparation, la question, trois paires de messages récents et une étiquette de section sûre. Il n'a aucun outil pour lire des comptes ou déplacer de l'argent. Les réponses structurées invalides ou les sources non vérifiées retombent sur la recherche documentaire.\n\nLe texte du site web et de l'utilisateur sont des données. Une instruction dans une question ne peut pas modifier les frais ni autoriser un paiement.\n\nPortée de la documentation\n\nLa documentation n'affirme pas une certification PCI DSS, une licence bancaire, un statut de Merchant of Record, une disponibilité garantie ni une sécurité absolue. De telles affirmations exigent une confirmation séparée et documentée.",
      "readMinutes": 2
    },
    {
      "id": "gateway",
      "title": "Intégration de la passerelle de paiement",
      "summary": "La passerelle traite les opérations financières. Kevmi les connecte aux commandes, paramètres de boutique et notifications. Ce guide décrit le contrat d'intégration et les vérifications de disponibilité.",
      "group": "developers",
      "url": "/docs/gateway",
      "tags": [
        "API",
        "passerelle",
        "backend",
        "serveur",
        "intégration",
        "localhost"
      ],
      "sections": [
        {
          "id": "current",
          "title": "Vérification de la disponibilité",
          "paragraphs": [
            "Kevmi utilise l'API v3 de la passerelle pour créer et récupérer des opérations, lire les statuts et rapprocher les résultats. L'intégration prend en charge le transport chiffré des cartes et codes bancaires, les paiements QR Alipay et SBP, un catalogue de crypto-monnaies/réseaux et des événements financiers entrants.",
            "gateway.configured dans GET /api/config indique si les paramètres de connexion requis sont présents. Cet endpoint ne sonde pas la passerelle ; gateway.connected=false ici signifie que la connectivité n'a pas été vérifiée. Pour une facture spécifique, lisez invoice.availability dans GET /api/checkout/{token} : il vérifie la méthode, le montant, les conditions et l'approbation du commerçant. Le champ de compatibilité invoice.gatewayConnected reflète availability.available et n'est ni un contrôle de santé ni une garantie d'approbation de paiement.",
            "Un nouveau paiement et une intention de carte nécessitent l'approbation de la dernière demande de revue du site du marchand. L'approbation seule ne connecte pas la passerelle de paiement. Si la revue change après l'envoi, l'opération existante reste disponible pour la lecture des statuts, le rapprochement et un code bancaire demandé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "required",
          "title": "Contrat de paiement client",
          "paragraphs": [
            "Les données sensibles sont chiffrées dans le navigateur avec RSA-OAEP-256 et A256GCM. La clé privée reste sur la passerelle. Kevmi valide que l'intention appartient à cette facture et à cet objectif, relaie l'enveloppe, et ne stocke pas de numéros de carte en clair, CVV, nom d'acheteur, e-mail, codes bancaires ni l'enveloppe elle-même.",
            "Installez l'extension de transport chiffré sur l'hôte de la passerelle avant d'activer les cartes. Elle vérifie la signature d'intention, l'expiration, le rejouage, la commande et les montants. Il n'y a pas de repli en clair. Ceci décrit le mécanisme de protection, pas la certification PCI."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Route Kevmi",
              "Objectif"
            ],
            "rows": [
              [
                "GET /api/checkout/{token}",
                "Facture, devis, disponibilité de la méthode et paiement existant"
              ],
              [
                "POST /api/checkout/{token}/card-intent",
                "Intention unique et clé publique pour le paiement ou le code"
              ],
              [
                "POST /api/checkout/{token}/pay",
                "Démarrer une opération ; la carte utilise un chiffrement : {intent,jwe}"
              ],
              [
                "POST /api/checkout/{token}/code",
                "Code unique chiffré pour le défi bancaire en cours"
              ],
              [
                "GET /api/checkout/{token}/status",
                "Lire l’opération d’origine sans frais supplémentaires"
              ],
              [
                "POST /api/checkout/{token}/reconcile",
                "Rapprocher explicitement l’opération d’origine"
              ],
              [
                "GET /api/checkout/{token}/crypto-services",
                "Pièces, réseaux et limites actuels pour une facture USDT"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "network",
          "title": "Hébergement et connectivité de la passerelle",
          "paragraphs": [
            "Kevmi prend en charge l’hébergement du site sur Cloudflare Workers avec D1, et l’auto-hébergement sur Node.js avec SQLite. SQLite nécessite un volume persistant et des sauvegardes. La passerelle de paiement s’exécute comme un service distinct avec son propre stockage durable.",
            "Une passerelle externe nécessite une origine HTTPS accessible par le serveur. Dans le pack auto-hébergé, le serveur se connecte à un service de passerelle fixe sur le réseau privé du conteneur ; l’API du service de passerelle n’est pas exposée à Internet. Le site public et les rappels utilisent HTTPS. Le navigateur chiffre également les données de carte et les codes bancaires avant qu’ils n’atteignent Kevmi.",
            "localhost fait référence au serveur ou conteneur actuel ; il n’expose pas l’ordinateur du propriétaire de la passerelle. Les clés de connexion et les secrets n’appartiennent qu’à la configuration du serveur.",
            "Pour un domaine personnalisé, définissez une origine HTTPS publique dans NEXT_PUBLIC_SITE_URL avant la compilation. La documentation, les liens canoniques et les ressources d’indexation utilisent cette valeur. Elle n’accepte qu’un schéma et un hôte avec un port facultatif, sans chemin, requête, fragment ni identifiants. Faites-la correspondre à APP_ORIGIN dans la configuration du serveur."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "adapter",
          "title": "Calcul et conditions prises en charge",
          "paragraphs": [
            "Les factures du nouvel espace de travail utilisent un prix de base en USD et Any propose les quatre méthodes. SBP convertit en RUB au taux de référence gelé de la Banque de Russie ; la crypto utilise la règle de facturation explicite 1:1 USD/USDT. La tarification native héritée reste disponible pour les anciennes factures et les demandes API sans pricingMode=universal. Voir la section multi-boutiques et tarification USD ci-dessous.",
            "Pour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA.",
            "L’envoi d’un total_cents arbitraire ne modifie pas le calcul de taxe du fournisseur. Un montant réel différent du total enregistré entre en révision et ne peut pas confirmer l’exécution. Les champs business_balance de la passerelle sont conservés comme preuve de règlement, et non traités comme un solde marchand Kevmi."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "activation",
          "title": "Connexion d’une passerelle en direct",
          "paragraphs": [
            "La connexion de la passerelle inclut la configuration du serveur, les vérifications des canaux sélectionnés et le traitement des événements financiers vérifiés. L’état de préparation de la configuration est vérifié séparément de la connectivité du fournisseur. Un paiement réussi est accepté après vérification du statut et du montant de l’opération. Les instructions de déploiement se trouvent dans ops/gateway-integration.md."
          ],
          "bullets": [],
          "steps": [
            "Déployez le serveur Kevmi et la passerelle comme services distincts. Configurez un stockage durable, des sauvegardes et les processus en arrière-plan requis.",
            "Pour une connexion externe, définissez une origine HTTPS dans GATEWAY_BASE_URL. Le pack auto-hébergé utilise son service interne configuré. Les deux nécessitent une GATEWAY_API_KEY réservée au serveur et un GATEWAY_WEBHOOK_SECRET distinct ; les secrets n’atteignent jamais le navigateur.",
            "Définissez BACKEND_WEBHOOK_URL sur /api/gateway/webhook chez Kevmi et un BACKEND_WEBHOOK_SECRET correspondant.",
            "Activez le transport chiffré des cartes et conservez sa clé privée exclusivement sur l’hôte de la passerelle. Vérifiez la disponibilité de la clé publique et les paramètres de signature d’intention correspondants.",
            "Vérifiez l’état de préparation des canaux, les restrictions et l’approbation du site marchand avant le lancement."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Webhooks et événements répétés",
              "href": "/docs/webhooks"
            },
            {
              "label": "Sécurité",
              "href": "/docs/security"
            }
          ]
        },
        {
          "id": "stores-usd",
          "title": "Plusieurs boutiques et un prix de base USD unique",
          "paragraphs": [
            "Choisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.",
            "Les factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.",
            "Le taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.",
            "Créez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.",
            "Pour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "Vérification de la disponibilité\n\nKevmi utilise l'API v3 de la passerelle pour créer et récupérer des opérations, lire les statuts et rapprocher les résultats. L'intégration prend en charge le transport chiffré des cartes et codes bancaires, les paiements QR Alipay et SBP, un catalogue de crypto-monnaies/réseaux et des événements financiers entrants.\n\ngateway.configured dans GET /api/config indique si les paramètres de connexion requis sont présents. Cet endpoint ne sonde pas la passerelle ; gateway.connected=false ici signifie que la connectivité n'a pas été vérifiée. Pour une facture spécifique, lisez invoice.availability dans GET /api/checkout/{token} : il vérifie la méthode, le montant, les conditions et l'approbation du commerçant. Le champ de compatibilité invoice.gatewayConnected reflète availability.available et n'est ni un contrôle de santé ni une garantie d'approbation de paiement.\n\nUn nouveau paiement et une intention de carte nécessitent l'approbation de la dernière demande de revue du site du marchand. L'approbation seule ne connecte pas la passerelle de paiement. Si la revue change après l'envoi, l'opération existante reste disponible pour la lecture des statuts, le rapprochement et un code bancaire demandé.\n\nContrat de paiement client\n\nLes données sensibles sont chiffrées dans le navigateur avec RSA-OAEP-256 et A256GCM. La clé privée reste sur la passerelle. Kevmi valide que l'intention appartient à cette facture et à cet objectif, relaie l'enveloppe, et ne stocke pas de numéros de carte en clair, CVV, nom d'acheteur, e-mail, codes bancaires ni l'enveloppe elle-même.\n\nInstallez l'extension de transport chiffré sur l'hôte de la passerelle avant d'activer les cartes. Elle vérifie la signature d'intention, l'expiration, le rejouage, la commande et les montants. Il n'y a pas de repli en clair. Ceci décrit le mécanisme de protection, pas la certification PCI.\n\nRoute Kevmi · Objectif\nGET /api/checkout/{token} · Facture, devis, disponibilité de la méthode et paiement existant\nPOST /api/checkout/{token}/card-intent · Intention unique et clé publique pour le paiement ou le code\nPOST /api/checkout/{token}/pay · Démarrer une opération ; la carte utilise un chiffrement : {intent,jwe}\nPOST /api/checkout/{token}/code · Code unique chiffré pour le défi bancaire en cours\nGET /api/checkout/{token}/status · Lire l’opération d’origine sans frais supplémentaires\nPOST /api/checkout/{token}/reconcile · Rapprocher explicitement l’opération d’origine\nGET /api/checkout/{token}/crypto-services · Pièces, réseaux et limites actuels pour une facture USDT\n\nHébergement et connectivité de la passerelle\n\nKevmi prend en charge l’hébergement du site sur Cloudflare Workers avec D1, et l’auto-hébergement sur Node.js avec SQLite. SQLite nécessite un volume persistant et des sauvegardes. La passerelle de paiement s’exécute comme un service distinct avec son propre stockage durable.\n\nUne passerelle externe nécessite une origine HTTPS accessible par le serveur. Dans le pack auto-hébergé, le serveur se connecte à un service de passerelle fixe sur le réseau privé du conteneur ; l’API du service de passerelle n’est pas exposée à Internet. Le site public et les rappels utilisent HTTPS. Le navigateur chiffre également les données de carte et les codes bancaires avant qu’ils n’atteignent Kevmi.\n\nlocalhost fait référence au serveur ou conteneur actuel ; il n’expose pas l’ordinateur du propriétaire de la passerelle. Les clés de connexion et les secrets n’appartiennent qu’à la configuration du serveur.\n\nPour un domaine personnalisé, définissez une origine HTTPS publique dans NEXT_PUBLIC_SITE_URL avant la compilation. La documentation, les liens canoniques et les ressources d’indexation utilisent cette valeur. Elle n’accepte qu’un schéma et un hôte avec un port facultatif, sans chemin, requête, fragment ni identifiants. Faites-la correspondre à APP_ORIGIN dans la configuration du serveur.\n\nCalcul et conditions prises en charge\n\nLes factures du nouvel espace de travail utilisent un prix de base en USD et Any propose les quatre méthodes. SBP convertit en RUB au taux de référence gelé de la Banque de Russie ; la crypto utilise la règle de facturation explicite 1:1 USD/USDT. La tarification native héritée reste disponible pour les anciennes factures et les demandes API sans pricingMode=universal. Voir la section multi-boutiques et tarification USD ci-dessous.\n\nPour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA.\n\nL’envoi d’un total_cents arbitraire ne modifie pas le calcul de taxe du fournisseur. Un montant réel différent du total enregistré entre en révision et ne peut pas confirmer l’exécution. Les champs business_balance de la passerelle sont conservés comme preuve de règlement, et non traités comme un solde marchand Kevmi.\n\nConnexion d’une passerelle en direct\n\nLa connexion de la passerelle inclut la configuration du serveur, les vérifications des canaux sélectionnés et le traitement des événements financiers vérifiés. L’état de préparation de la configuration est vérifié séparément de la connectivité du fournisseur. Un paiement réussi est accepté après vérification du statut et du montant de l’opération. Les instructions de déploiement se trouvent dans ops/gateway-integration.md.\n\nDéployez le serveur Kevmi et la passerelle comme services distincts. Configurez un stockage durable, des sauvegardes et les processus en arrière-plan requis.\n\nPour une connexion externe, définissez une origine HTTPS dans GATEWAY_BASE_URL. Le pack auto-hébergé utilise son service interne configuré. Les deux nécessitent une GATEWAY_API_KEY réservée au serveur et un GATEWAY_WEBHOOK_SECRET distinct ; les secrets n’atteignent jamais le navigateur.\n\nDéfinissez BACKEND_WEBHOOK_URL sur /api/gateway/webhook chez Kevmi et un BACKEND_WEBHOOK_SECRET correspondant.\n\nActivez le transport chiffré des cartes et conservez sa clé privée exclusivement sur l’hôte de la passerelle. Vérifiez la disponibilité de la clé publique et les paramètres de signature d’intention correspondants.\n\nVérifiez l’état de préparation des canaux, les restrictions et l’approbation du site marchand avant le lancement.\n\nWebhooks et événements répétés\n\nSécurité\n\nPlusieurs boutiques et un prix de base USD unique\n\nChoisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.\n\nLes factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.\n\nLe taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.\n\nCréez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.\n\nPour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé.",
      "readMinutes": 6
    },
    {
      "id": "webhooks",
      "title": "Webhooks : événements, signatures et livraison",
      "summary": "Enregistrez un point de terminaison HTTPS public, prouvez-en le contrôle et recevez des événements de facture et de paiement signés. La livraison est mise en file de manière durable ; traiter le même événement à nouveau doit être sans danger pour votre commande.",
      "tags": [
        "webhook",
        "signature",
        "HMAC",
        "idempotence",
        "événement",
        "nouvelle tentative"
      ],
      "sections": [
        {
          "id": "sources",
          "title": "D’où viennent les événements",
          "paragraphs": [
            "invoice.created ne signifie pas payé. Les événements de paiement proviennent d’une opération serveur vérifiée après une lecture actuelle de la passerelle ; un nom d’événement entrant seul est insuffisant.",
            "L’entrée Passerelle → Kevmi et la livraison Kevmi → marchand sont des tronçons distincts avec des secrets séparés. Le navigateur, la navigation de retour et les messages du widget ne définissent pas l’état financier."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Événement",
              "Source"
            ],
            "rows": [
              [
                "invoice.created",
                "Facture enregistrée"
              ],
              [
                "invoice.updated",
                "Disponibilité du lien modifiée"
              ],
              [
                "payment.succeeded",
                "Paiement exact vérifié par le serveur"
              ],
              [
                "payment.failed",
                "Opération échouée vérifiée"
              ],
              [
                "payment.refunded",
                "Remboursement complet vérifié"
              ],
              [
                "payment.partially_refunded",
                "Remboursement partiel vérifié"
              ],
              [
                "payment.disputed",
                "Litige vérifié"
              ],
              [
                "payment.review_required",
                "L’opération nécessite une révision supplémentaire"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "setup",
          "title": "Enregistrer et vérifier un point de terminaison",
          "paragraphs": [
            "Les URL ne peuvent pas cibler des adresses IP, localhost, des réseaux privés, des ports non standard ni contenir d’identifiants. Le DNS est vérifié avant la livraison ; les requêtes POST sortantes ne suivent pas les redirections. Un compte peut enregistrer jusqu’à cinq points de terminaison.",
            "L’événement de vérification a livemode=false. Un statut HTTP réussi seul est insuffisant : le défi doit correspondre exactement. La rotation du secret nécessite une nouvelle vérification."
          ],
          "bullets": [],
          "steps": [
            "Sur /account#webhooks dans votre compte marchand, saisissez une URL HTTPS publique, une description et les types d’événements dont vous avez besoin.",
            "Enregistrez le secret émis dans le stockage côté serveur. Sa valeur complète n’est affichée qu’une fois.",
            "Vérifiez les signatures sur les octets de la requête d’origine.",
            "Exécutez la vérification du point de terminaison. Pour endpoint.verification, renvoyez un JSON reflétant data.challenge : {\"challenge\":\"la valeur reçue\"}.",
            "Activez le point de terminaison vérifié et inspectez l’historique de livraison."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Webhooks dans votre compte",
              "href": "/account#webhooks"
            }
          ]
        },
        {
          "id": "envelope",
          "title": "Enveloppe d'événement",
          "paragraphs": [
            "id reste identique à chaque tentative de livraison d'un événement. createdAt est un horodatage Unix en millisecondes, et apiVersion identifie la version du contrat. data contient l'objet serveur persisté ; l'exemple est raccourci.",
            "livemode=true distingue un véritable événement serveur de la vérification d'endpoint. Cela ne signifie pas qu'une facture est payée : vérifiez le type et les données de paiement. Gérez les types d'événements connus et validez le schéma."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JSON · shortened example",
            "code": "{\n  \"id\": \"evt_example\",\n  \"type\": \"invoice.created\",\n  \"apiVersion\": \"2026-10-21\",\n  \"createdAt\": 1792540800000,\n  \"livemode\": true,\n  \"data\": {\n    \"invoice\": {\n      \"id\": \"lnk_example\",\n      \"orderId\": \"order-1042\",\n      \"currency\": \"USD\",\n      \"amountMinor\": 500,\n      \"vatCustomerPercent\": 100,\n      \"feeCustomerPercent\": 0\n    }\n  }\n}"
          },
          "note": "",
          "links": []
        },
        {
          "id": "signature",
          "title": "Vérifier HMAC-SHA256",
          "paragraphs": [
            "Kevmi-Signature contient t=secondes,v1=hex. La signature est HMAC-SHA256 sur la chaîne d'horodatage, un point et le corps d'origine : horodatage + \".\" + rawBody. Utilisez le secret d'endpoint spécifique et une comparaison à temps constant.",
            "Rejetez les signatures dont l'horodatage diffère de l'heure du serveur de plus de 300 secondes dans un sens ou dans l'autre. Synchronisez les horloges. N'analysez pas et ne resérialisez pas le JSON avant la vérification : les espaces et l'ordre des propriétés affectent les octets signés."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "Node.js · verification core",
            "code": "import { createHmac, timingSafeEqual } from 'node:crypto';\n\nfunction verifyKevmi(rawBody, header, secret, nowSeconds) {\n  const match = /^t=(\\d{10}),v1=([a-f0-9]{64})$/.exec(header || '');\n  if (!match || Math.abs(nowSeconds - Number(match[1])) > 300) {\n    return false;\n  }\n  const expected = createHmac('sha256', secret)\n    .update(match[1] + '.')\n    .update(rawBody)\n    .digest();\n  const received = Buffer.from(match[2], 'hex');\n  return expected.length === received.length\n    && timingSafeEqual(expected, received);\n}\n\n// Read bytes before JSON parsing; cap the request body.\n// secret comes from your server secret store.\nconst valid = verifyKevmi(rawBody, signature, secret,\n  Math.floor(Date.now() / 1000));\nif (!valid) throw new Error('Invalid webhook signature');\nconst event = JSON.parse(rawBody.toString('utf8'));\n// Validate the event schema and persist its ID together\n// with your order update in one database transaction.\n// Return a 2xx response after durable acceptance."
          },
          "note": "Cet exemple couvre la vérification de signature. Votre serveur HTTP nécessite également une limite de taille de corps, une validation de schéma et une persistance transactionnelle des événements.",
          "links": []
        },
        {
          "id": "delivery",
          "title": "Nouvelles tentatives et accusé de réception",
          "paragraphs": [
            "Toute réponse 2xx accuse réception d'un événement ordinaire. Persistez l'événement de manière durable avant de répondre ; le travail coûteux peut se poursuivre via votre propre file d'attente. Le délai de réponse est de huit secondes. Une erreur réseau ou une réponse non-2xx planifie une nouvelle tentative.",
            "Il y a au plus six tentatives : la livraison initiale plus des délais d'une minute, cinq minutes, 30 minutes, deux heures et 12 heures après des échecs successifs. Ce sont des plannings de file d'attente, pas des garanties d'heure de livraison exacte. Épuiser les tentatives marque la livraison comme échouée.",
            "La livraison est au moins une fois et ne promet pas un ordre strict. Persistez l'ID d'événement unique dans la même transaction que votre mise à jour de commande. Un doublon déjà appliqué doit recevoir 2xx sans exécuter à nouveau la commande.",
            "Une nouvelle tentative manuelle redémarre les tentatives de livraison tout en préservant l'ID d'événement d'origine, l'ID de livraison et le corps exact. Chaque tentative reçoit un horodatage de signature frais. Suspendre un endpoint préserve sa file d'attente ; le supprimer annule les livraisons en attente et échouées."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "reconcile",
          "title": "Historique de livraison et rapprochement",
          "paragraphs": [
            "L'interface affiche l'état de l'endpoint, les livraisons récentes, les nombres de tentatives, la dernière réponse HTTP, l'erreur et l'heure de la prochaine tentative. Ces diagnostics complètent vos propres enregistrements de commandes.",
            "GET /api/v1/events avec events:read renvoie jusqu'à 50 événements et nextCursor. Passez nextCursor opaque inchangé en tant que cursor ; null marque la fin. L'ordre utilise à la fois createdAt et id. L'ancienne limite before Unix-milliseconde reste disponible séparément et ne peut pas être combinée avec cursor. Les endpoints vérifiés reçoivent les événements souscrits au plus tôt à leur enregistrement ; les endpoints suspendus continuent d'accumuler les événements en file d'attente pour livraison après reprise. Cela ne promet pas d'historique antérieur à la création de l'endpoint."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Clés API et création de facture",
              "href": "/docs/payment-links-api"
            }
          ]
        },
        {
          "id": "gateway",
          "title": "Vérifications des reçus de passerelle entrants",
          "paragraphs": [
            "Gateway v3 publie sur /api/gateway/webhook avec X-Gateway-Event-Id, X-Gateway-Timestamp et X-Gateway-Signature : v1=<hex>. HMAC-SHA256 signe horodatage + \".\" + rawBody avec GATEWAY_WEBHOOK_SECRET ; la fenêtre d'horloge est de 300 secondes. L'égalité de l'ID en-tête/corps, la version API, le mode live et le hachage du corps sont vérifiés.",
            "Un ID d'événement réutilisé avec des octets de corps différents est rejeté. Une notification signée déclenche un GET authentifié de l'opération exacte. Ordre, méthode, devise, base, total approuvé et version sont vérifiés. Le succès exige fulfillment_ready=true, verification=provider_confirmed, le montant payé exact et aucun litige ; la crypto exige également une preuve de règlement confirmée.",
            "Le traitement entrant, les reçus et les événements marchands sont protégés contre les doublons. Les anciens formats de notification uniquement navigateur ne peuvent pas établir un paiement réussi. Les webhooks marchands ne contiennent jamais de champs de carte, codes bancaires, données QR, identifiants de fournisseur ou le secret de passerelle."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "telegram",
          "title": "Telegram a un contrat séparé",
          "paragraphs": [
            "POST /api/telegram/webhook vérifie X-Telegram-Bot-Api-Secret-Token, la structure de mise à jour et l'expéditeur. update_id protège contre le traitement en double. Cette route gère la connexion, les commandes, le support et les actions de modération ; elle n'accepte pas les reçus financiers.",
            "Le propriétaire du déploiement configure le jeton du bot, le secret du webhook, l'enregistrement setWebhook et l'adresse HTTPS accessible. Ils sont séparés du secret de signature de l'endpoint marchand."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "stores-usd",
          "title": "Plusieurs boutiques et un prix de base USD unique",
          "paragraphs": [
            "Choisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.",
            "Les factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.",
            "Le taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.",
            "Créez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.",
            "Pour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "group": "developers",
      "url": "/docs/webhooks",
      "body": "D’où viennent les événements\n\ninvoice.created ne signifie pas payé. Les événements de paiement proviennent d’une opération serveur vérifiée après une lecture actuelle de la passerelle ; un nom d’événement entrant seul est insuffisant.\n\nL’entrée Passerelle → Kevmi et la livraison Kevmi → marchand sont des tronçons distincts avec des secrets séparés. Le navigateur, la navigation de retour et les messages du widget ne définissent pas l’état financier.\n\nÉvénement · Source\ninvoice.created · Facture enregistrée\ninvoice.updated · Disponibilité du lien modifiée\npayment.succeeded · Paiement exact vérifié par le serveur\npayment.failed · Opération échouée vérifiée\npayment.refunded · Remboursement complet vérifié\npayment.partially_refunded · Remboursement partiel vérifié\npayment.disputed · Litige vérifié\npayment.review_required · L’opération nécessite une révision supplémentaire\n\nEnregistrer et vérifier un point de terminaison\n\nLes URL ne peuvent pas cibler des adresses IP, localhost, des réseaux privés, des ports non standard ni contenir d’identifiants. Le DNS est vérifié avant la livraison ; les requêtes POST sortantes ne suivent pas les redirections. Un compte peut enregistrer jusqu’à cinq points de terminaison.\n\nL’événement de vérification a livemode=false. Un statut HTTP réussi seul est insuffisant : le défi doit correspondre exactement. La rotation du secret nécessite une nouvelle vérification.\n\nSur /account#webhooks dans votre compte marchand, saisissez une URL HTTPS publique, une description et les types d’événements dont vous avez besoin.\n\nEnregistrez le secret émis dans le stockage côté serveur. Sa valeur complète n’est affichée qu’une fois.\n\nVérifiez les signatures sur les octets de la requête d’origine.\n\nExécutez la vérification du point de terminaison. Pour endpoint.verification, renvoyez un JSON reflétant data.challenge : {\"challenge\":\"la valeur reçue\"}.\n\nActivez le point de terminaison vérifié et inspectez l’historique de livraison.\n\nWebhooks dans votre compte\n\nEnveloppe d'événement\n\nid reste identique à chaque tentative de livraison d'un événement. createdAt est un horodatage Unix en millisecondes, et apiVersion identifie la version du contrat. data contient l'objet serveur persisté ; l'exemple est raccourci.\n\nlivemode=true distingue un véritable événement serveur de la vérification d'endpoint. Cela ne signifie pas qu'une facture est payée : vérifiez le type et les données de paiement. Gérez les types d'événements connus et validez le schéma.\n\n{\n  \"id\": \"evt_example\",\n  \"type\": \"invoice.created\",\n  \"apiVersion\": \"2026-10-21\",\n  \"createdAt\": 1792540800000,\n  \"livemode\": true,\n  \"data\": {\n    \"invoice\": {\n      \"id\": \"lnk_example\",\n      \"orderId\": \"order-1042\",\n      \"currency\": \"USD\",\n      \"amountMinor\": 500,\n      \"vatCustomerPercent\": 100,\n      \"feeCustomerPercent\": 0\n    }\n  }\n}\n\nVérifier HMAC-SHA256\n\nKevmi-Signature contient t=secondes,v1=hex. La signature est HMAC-SHA256 sur la chaîne d'horodatage, un point et le corps d'origine : horodatage + \".\" + rawBody. Utilisez le secret d'endpoint spécifique et une comparaison à temps constant.\n\nRejetez les signatures dont l'horodatage diffère de l'heure du serveur de plus de 300 secondes dans un sens ou dans l'autre. Synchronisez les horloges. N'analysez pas et ne resérialisez pas le JSON avant la vérification : les espaces et l'ordre des propriétés affectent les octets signés.\n\nimport { createHmac, timingSafeEqual } from 'node:crypto';\n\nfunction verifyKevmi(rawBody, header, secret, nowSeconds) {\n  const match = /^t=(\\d{10}),v1=([a-f0-9]{64})$/.exec(header || '');\n  if (!match || Math.abs(nowSeconds - Number(match[1])) > 300) {\n    return false;\n  }\n  const expected = createHmac('sha256', secret)\n    .update(match[1] + '.')\n    .update(rawBody)\n    .digest();\n  const received = Buffer.from(match[2], 'hex');\n  return expected.length === received.length\n    && timingSafeEqual(expected, received);\n}\n\n// Read bytes before JSON parsing; cap the request body.\n// secret comes from your server secret store.\nconst valid = verifyKevmi(rawBody, signature, secret,\n  Math.floor(Date.now() / 1000));\nif (!valid) throw new Error('Invalid webhook signature');\nconst event = JSON.parse(rawBody.toString('utf8'));\n// Validate the event schema and persist its ID together\n// with your order update in one database transaction.\n// Return a 2xx response after durable acceptance.\n\nCet exemple couvre la vérification de signature. Votre serveur HTTP nécessite également une limite de taille de corps, une validation de schéma et une persistance transactionnelle des événements.\n\nNouvelles tentatives et accusé de réception\n\nToute réponse 2xx accuse réception d'un événement ordinaire. Persistez l'événement de manière durable avant de répondre ; le travail coûteux peut se poursuivre via votre propre file d'attente. Le délai de réponse est de huit secondes. Une erreur réseau ou une réponse non-2xx planifie une nouvelle tentative.\n\nIl y a au plus six tentatives : la livraison initiale plus des délais d'une minute, cinq minutes, 30 minutes, deux heures et 12 heures après des échecs successifs. Ce sont des plannings de file d'attente, pas des garanties d'heure de livraison exacte. Épuiser les tentatives marque la livraison comme échouée.\n\nLa livraison est au moins une fois et ne promet pas un ordre strict. Persistez l'ID d'événement unique dans la même transaction que votre mise à jour de commande. Un doublon déjà appliqué doit recevoir 2xx sans exécuter à nouveau la commande.\n\nUne nouvelle tentative manuelle redémarre les tentatives de livraison tout en préservant l'ID d'événement d'origine, l'ID de livraison et le corps exact. Chaque tentative reçoit un horodatage de signature frais. Suspendre un endpoint préserve sa file d'attente ; le supprimer annule les livraisons en attente et échouées.\n\nHistorique de livraison et rapprochement\n\nL'interface affiche l'état de l'endpoint, les livraisons récentes, les nombres de tentatives, la dernière réponse HTTP, l'erreur et l'heure de la prochaine tentative. Ces diagnostics complètent vos propres enregistrements de commandes.\n\nGET /api/v1/events avec events:read renvoie jusqu'à 50 événements et nextCursor. Passez nextCursor opaque inchangé en tant que cursor ; null marque la fin. L'ordre utilise à la fois createdAt et id. L'ancienne limite before Unix-milliseconde reste disponible séparément et ne peut pas être combinée avec cursor. Les endpoints vérifiés reçoivent les événements souscrits au plus tôt à leur enregistrement ; les endpoints suspendus continuent d'accumuler les événements en file d'attente pour livraison après reprise. Cela ne promet pas d'historique antérieur à la création de l'endpoint.\n\nClés API et création de facture\n\nVérifications des reçus de passerelle entrants\n\nGateway v3 publie sur /api/gateway/webhook avec X-Gateway-Event-Id, X-Gateway-Timestamp et X-Gateway-Signature : v1=<hex>. HMAC-SHA256 signe horodatage + \".\" + rawBody avec GATEWAY_WEBHOOK_SECRET ; la fenêtre d'horloge est de 300 secondes. L'égalité de l'ID en-tête/corps, la version API, le mode live et le hachage du corps sont vérifiés.\n\nUn ID d'événement réutilisé avec des octets de corps différents est rejeté. Une notification signée déclenche un GET authentifié de l'opération exacte. Ordre, méthode, devise, base, total approuvé et version sont vérifiés. Le succès exige fulfillment_ready=true, verification=provider_confirmed, le montant payé exact et aucun litige ; la crypto exige également une preuve de règlement confirmée.\n\nLe traitement entrant, les reçus et les événements marchands sont protégés contre les doublons. Les anciens formats de notification uniquement navigateur ne peuvent pas établir un paiement réussi. Les webhooks marchands ne contiennent jamais de champs de carte, codes bancaires, données QR, identifiants de fournisseur ou le secret de passerelle.\n\nTelegram a un contrat séparé\n\nPOST /api/telegram/webhook vérifie X-Telegram-Bot-Api-Secret-Token, la structure de mise à jour et l'expéditeur. update_id protège contre le traitement en double. Cette route gère la connexion, les commandes, le support et les actions de modération ; elle n'accepte pas les reçus financiers.\n\nLe propriétaire du déploiement configure le jeton du bot, le secret du webhook, l'enregistrement setWebhook et l'adresse HTTPS accessible. Ils sont séparés du secret de signature de l'endpoint marchand.\n\nPlusieurs boutiques et un prix de base USD unique\n\nChoisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.\n\nLes factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.\n\nLe taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.\n\nCréez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.\n\nPour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé.",
      "readMinutes": 7
    },
    {
      "id": "limits",
      "title": "Limites et disponibilité",
      "summary": "La disponibilité du paiement dépend de la méthode, du montant, du pays et des conditions d'une facture particulière. Vérifiez le total, les restrictions et le temps de traitement applicable avant confirmation.",
      "group": "payments",
      "url": "/docs/limits",
      "tags": [
        "limite",
        "temps de traitement",
        "retenue",
        "remboursement",
        "contrepassation",
        "restriction"
      ],
      "sections": [
        {
          "id": "pending",
          "title": "Limites d'adaptateur et de canal",
          "paragraphs": [
            "Kevmi vérifie les plages ci-dessous avant de créer une opération. Un canal de paiement peut imposer des restrictions supplémentaires ; un montant dans la plage ne garantit pas l'approbation. Modifier la configuration de la passerelle ne change pas automatiquement les limites Kevmi.",
            "Un nouveau paiement et une intention de carte nécessitent l'approbation de la dernière demande de revue du site du marchand. L'approbation seule ne connecte pas la passerelle de paiement. Si la revue change après l'envoi, l'opération existante reste disponible pour la lecture des statuts, le rapprochement et un code bancaire demandé."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Méthode",
              "Montant vérifié",
              "Plage Kevmi"
            ],
            "rows": [
              [
                "Carte / Alipay",
                "Prix de base USD",
                "$1–$1,000"
              ],
              [
                "SBP",
                "Total client RUB",
                "₽1–₽100,000"
              ],
              [
                "Crypto",
                "Total client USDT",
                "1–1 000 000 USDT + limites de réseau sélectionnées"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "validation",
          "title": "La validation n'est pas une limite commerciale",
          "paragraphs": [
            "Le calculateur et l'API rejettent les montants négatifs, les devises invalides et les calculs où les frais alloués du marchand et la TVA dépassent le montant de base. Ces vérifications protègent l'exactitude des données.",
            "Réussir la validation arithmétique ne garantit pas qu'un fournisseur peut accepter le paiement. Les limites commerciales et de risque sont vérifiées séparément par le canal de paiement."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "refunds",
          "title": "Remboursements et transactions contestées",
          "paragraphs": [
            "Les remboursements vérifiés, les remboursements partiels, les litiges et les états d'examen apparaissent dans l'opération et les événements marchands. Cela n'implique pas que la création d'un remboursement ou d'un versement est implémentée dans le compte.",
            "Ne réexécutez pas pour payment.partially_refunded, payment.refunded, payment.disputed ou payment.review_required. Préservez l'association commande/paiement d'origine et acheminez les cas contestés vers un opérateur autorisé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "subscriptions",
          "title": "Frais récurrents",
          "paragraphs": [
            "Kevmi n'a pas d'abonnements ni de paiements récurrents. Enregistrer un lien de commande n'autorise pas un débit automatique futur. Chaque nouvelle commande est payée séparément."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "ready",
          "title": "Vérifications de préparation",
          "paragraphs": [
            "gateway.configured dans /api/config signale les paramètres de passerelle requis, tandis que /api/health vérifie le stockage du serveur. Ni l'un ni l'autre n'établit la connectivité à un fournisseur de paiement. Utilisez invoice.availability dans GET /api/checkout/{token} pour les conditions d'une facture spécifique ; le succès du paiement est vérifié séparément contre l'opération de passerelle."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Exigences d'intégration",
              "href": "/docs/gateway"
            },
            {
              "label": "Renseignez-vous sur votre cas d'utilisation",
              "href": "/?support=open"
            }
          ]
        }
      ],
      "body": "Limites d'adaptateur et de canal\n\nKevmi vérifie les plages ci-dessous avant de créer une opération. Un canal de paiement peut imposer des restrictions supplémentaires ; un montant dans la plage ne garantit pas l'approbation. Modifier la configuration de la passerelle ne change pas automatiquement les limites Kevmi.\n\nUn nouveau paiement et une intention de carte nécessitent l'approbation de la dernière demande de revue du site du marchand. L'approbation seule ne connecte pas la passerelle de paiement. Si la revue change après l'envoi, l'opération existante reste disponible pour la lecture des statuts, le rapprochement et un code bancaire demandé.\n\nMéthode · Montant vérifié · Plage Kevmi\nCarte / Alipay · Prix de base USD · $1–$1,000\nSBP · Total client RUB · ₽1–₽100,000\nCrypto · Total client USDT · 1–1 000 000 USDT + limites de réseau sélectionnées\n\nLa validation n'est pas une limite commerciale\n\nLe calculateur et l'API rejettent les montants négatifs, les devises invalides et les calculs où les frais alloués du marchand et la TVA dépassent le montant de base. Ces vérifications protègent l'exactitude des données.\n\nRéussir la validation arithmétique ne garantit pas qu'un fournisseur peut accepter le paiement. Les limites commerciales et de risque sont vérifiées séparément par le canal de paiement.\n\nRemboursements et transactions contestées\n\nLes remboursements vérifiés, les remboursements partiels, les litiges et les états d'examen apparaissent dans l'opération et les événements marchands. Cela n'implique pas que la création d'un remboursement ou d'un versement est implémentée dans le compte.\n\nNe réexécutez pas pour payment.partially_refunded, payment.refunded, payment.disputed ou payment.review_required. Préservez l'association commande/paiement d'origine et acheminez les cas contestés vers un opérateur autorisé.\n\nFrais récurrents\n\nKevmi n'a pas d'abonnements ni de paiements récurrents. Enregistrer un lien de commande n'autorise pas un débit automatique futur. Chaque nouvelle commande est payée séparément.\n\nVérifications de préparation\n\ngateway.configured dans /api/config signale les paramètres de passerelle requis, tandis que /api/health vérifie le stockage du serveur. Ni l'un ni l'autre n'établit la connectivité à un fournisseur de paiement. Utilisez invoice.availability dans GET /api/checkout/{token} pour les conditions d'une facture spécifique ; le succès du paiement est vérifié séparément contre l'opération de passerelle.\n\nExigences d'intégration\n\nRenseignez-vous sur votre cas d'utilisation",
      "readMinutes": 3
    },
    {
      "id": "agent-access",
      "title": "Ressources pour les moteurs de recherche et l'IA",
      "summary": "Les informations publiques Kevmi sont disponibles en HTML rendu côté serveur, texte brut et formats structurés. Ces formats partagent une version de connaissance et les mêmes faits commerciaux.",
      "group": "developers",
      "url": "/docs/agent-access",
      "tags": [
        "SEO",
        "indexation",
        "llms",
        "robots",
        "sitemap",
        "agent",
        "JSON"
      ],
      "sections": [
        {
          "id": "files",
          "title": "Ressources publiques",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Adresse",
              "Contenu"
            ],
            "rows": [
              [
                "/docs and /en/docs",
                "Éditions complètes en russe et en anglais"
              ],
              [
                "/llms.txt",
                "Index anglais et faits essentiels"
              ],
              [
                "/llms-full.txt",
                "Texte de connaissances complet en anglais"
              ],
              [
                "/knowledge.json",
                "Faits, frais, articles et version"
              ],
              [
                "/openapi.json",
                "Contrat d'API serveur implémenté"
              ],
              [
                "/sitemap.xml",
                "Pages publiques publiées"
              ],
              [
                "/robots.txt",
                "Directives de crawl"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "facts",
          "title": "Lecture des faits structurés",
          "paragraphs": [
            "knowledge.facts.countries.card décrit la couverture mondiale avec des restrictions explicites. countryCount compte les entrées du répertoire, coverageLabel est 190+, et exactList contient les entrées ISO prises en charge. restrictions préserve la liste d'exclusion des fournisseurs.",
            "source=owner_provided et status=owner_list_received enregistrent l'origine de la liste. independentlyVerified=false et verifiedCountryCount=null signifient que la liste n'a pas été vérifiée indépendamment auprès d'une passerelle en direct ; il s'agit toujours d'une liste reçue et publiée.",
            "partialCoverage contient ** pays avec une couverture de localisation incomplète. unresolvedFootnotes préserve le marqueur * séparé pour la Chine. coverage=listed signifie l'inclusion dans la liste ; partial_locations désigne les restrictions de localisation ; footnote_pending désigne la signification distincte non confirmée d'un marqueur. None ne garantit pas l'approbation de chaque carte.",
            "gatewayConnected=null et gatewayIntegration.liveConfigurationProvided=null signifient que la base de connaissances statique ne contient pas l'état actuel d'un déploiement. gatewayIntegration.availability identifie les points de terminaison pour les vérifications actuelles. gateway.configured dans /api/config signale les paramètres, pas la connectivité du fournisseur. invoice.availability dans la réponse de paiement décrit les conditions de facturation éligibles, tandis que le champ de compatibilité invoice.gatewayConnected reflète availability.available. Ni l'un ni l'autre ne remplace la confirmation d'opération. gatewayIntegration.adapterImplemented=true décrit le support du protocole v3 ; subscriptionsSupported=false exclut les frais récurrents."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JSON · fact excerpt",
            "code": "{\n  \"subscriptionsSupported\": false,\n  \"gatewayConnected\": null,\n  \"countries\": {\n    \"card\": {\n      \"coverageLabel\": \"190+\",\n      \"policy\": \"worldwide_except_restrictions\",\n      \"restrictions\": [\n        {\n          \"code\": \"AF\",\n          \"name\": \"Afghanistan\"\n        },\n        {\n          \"code\": \"AQ\",\n          \"name\": \"Antarctica\"\n        },\n        {\n          \"code\": \"BY\",\n          \"name\": \"Belarus\"\n        },\n        {\n          \"code\": \"MM\",\n          \"name\": \"Burma (Myanmar)\"\n        },\n        {\n          \"code\": \"BI\",\n          \"name\": \"Burundi\"\n        },\n        {\n          \"code\": \"CF\",\n          \"name\": \"Central African Republic\"\n        },\n        {\n          \"code\": \"TD\",\n          \"name\": \"Chad\"\n        },\n        {\n          \"code\": \"CU\",\n          \"name\": \"Cuba\"\n        },\n        {\n          \"code\": \"CD\",\n          \"name\": \"Democratic Republic of Congo\"\n        },\n        {\n          \"code\": \"CG\",\n          \"name\": \"Republic of Congo\"\n        },\n        {\n          \"code\": \"ER\",\n          \"name\": \"Eritrea\"\n        },\n        {\n          \"code\": \"HT\",\n          \"name\": \"Haiti\"\n        },\n        {\n          \"code\": \"IR\",\n          \"name\": \"Iran\"\n        },\n        {\n          \"code\": \"IQ\",\n          \"name\": \"Iraq\"\n        },\n        {\n          \"code\": \"LY\",\n          \"name\": \"Libya\"\n        },\n        {\n          \"code\": \"ML\",\n          \"name\": \"Mali\"\n        },\n        {\n          \"code\": \"NI\",\n          \"name\": \"Nicaragua\"\n        },\n        {\n          \"code\": \"KP\",\n          \"name\": \"North Korea\"\n        },\n        {\n          \"code\": \"RU\",\n          \"name\": \"Russia\"\n        },\n        {\n          \"code\": \"SO\",\n          \"name\": \"Somalia\"\n        },\n        {\n          \"code\": \"SS\",\n          \"name\": \"South Sudan\"\n        },\n        {\n          \"code\": \"SD\",\n          \"name\": \"Sudan\"\n        },\n        {\n          \"code\": \"SY\",\n          \"name\": \"Syria\"\n        },\n        {\n          \"code\": \"VE\",\n          \"name\": \"Venezuela\"\n        },\n        {\n          \"code\": \"YE\",\n          \"name\": \"Yemen\"\n        },\n        {\n          \"code\": \"ZW\",\n          \"name\": \"Zimbabwe\"\n        },\n        {\n          \"code\": \"UA-43\",\n          \"name\": \"Crimea (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-14\",\n          \"name\": \"Donetsk (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-65\",\n          \"name\": \"Kherson (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-09\",\n          \"name\": \"Luhansk (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-23\",\n          \"name\": \"Zaporizhzhia (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"AN\",\n          \"name\": \"Netherlands Antilles\"\n        }\n      ],\n      \"independentlyVerified\": false,\n      \"approvalGuaranteed\": false\n    }\n  },\n  \"gatewayIntegration\": {\n    \"adapterImplemented\": true,\n    \"contract\": \"v3\",\n    \"liveConfigurationProvided\": null,\n    \"availability\": {\n      \"source\": \"runtime\",\n      \"configurationEndpoint\": \"/api/config\",\n      \"configurationIncludesHealthCheck\": false,\n      \"checkoutEndpoint\": \"/api/checkout/{token}\",\n      \"checkoutIncludesProviderApproval\": false\n    }\n  }\n}"
          },
          "note": "",
          "links": []
        },
        {
          "id": "privacy",
          "title": "Limites des informations publiques",
          "paragraphs": [
            "Le texte brut et le JSON ne contiennent pas de sessions, jetons, demandes de support privées, enregistrements de paiement utilisateur ou secrets d'intégration. Les pages de connexion, de compte et de paiement sont exclues de l'indexation de recherche.",
            "La lecture de la documentation publique n'accorde pas de permissions de gestion de boutique. Les enregistrements personnels nécessitent une session valide et les mutations nécessitent des vérifications serveur supplémentaires."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "updates",
          "title": "Mises à jour et citations",
          "paragraphs": [
            "Les articles ont des identifiants stables, des URL, des titres et une date de mise à jour. Liez au guide pertinent lorsque vous citez une réponse et préservez les qualifications concernant les conditions de transaction.",
            "Les sitemaps, les ressources llms et le HTML rendu par serveur facilitent l'extraction du contenu. Ils ne garantissent pas l'indexation, la position de recherche ou l'utilisation par un système d'IA externe.",
            "Seules les traductions publiées ont des URL canoniques, des alternatives hreflang et des entrées de sitemap. Une locale configurée pour une traduction future n'est pas une édition de langue publiée."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "Ressources publiques\n\nAdresse · Contenu\n/docs and /en/docs · Éditions complètes en russe et en anglais\n/llms.txt · Index anglais et faits essentiels\n/llms-full.txt · Texte de connaissances complet en anglais\n/knowledge.json · Faits, frais, articles et version\n/openapi.json · Contrat d'API serveur implémenté\n/sitemap.xml · Pages publiques publiées\n/robots.txt · Directives de crawl\n\nLecture des faits structurés\n\nknowledge.facts.countries.card décrit la couverture mondiale avec des restrictions explicites. countryCount compte les entrées du répertoire, coverageLabel est 190+, et exactList contient les entrées ISO prises en charge. restrictions préserve la liste d'exclusion des fournisseurs.\n\nsource=owner_provided et status=owner_list_received enregistrent l'origine de la liste. independentlyVerified=false et verifiedCountryCount=null signifient que la liste n'a pas été vérifiée indépendamment auprès d'une passerelle en direct ; il s'agit toujours d'une liste reçue et publiée.\n\npartialCoverage contient ** pays avec une couverture de localisation incomplète. unresolvedFootnotes préserve le marqueur * séparé pour la Chine. coverage=listed signifie l'inclusion dans la liste ; partial_locations désigne les restrictions de localisation ; footnote_pending désigne la signification distincte non confirmée d'un marqueur. None ne garantit pas l'approbation de chaque carte.\n\ngatewayConnected=null et gatewayIntegration.liveConfigurationProvided=null signifient que la base de connaissances statique ne contient pas l'état actuel d'un déploiement. gatewayIntegration.availability identifie les points de terminaison pour les vérifications actuelles. gateway.configured dans /api/config signale les paramètres, pas la connectivité du fournisseur. invoice.availability dans la réponse de paiement décrit les conditions de facturation éligibles, tandis que le champ de compatibilité invoice.gatewayConnected reflète availability.available. Ni l'un ni l'autre ne remplace la confirmation d'opération. gatewayIntegration.adapterImplemented=true décrit le support du protocole v3 ; subscriptionsSupported=false exclut les frais récurrents.\n\n{\n  \"subscriptionsSupported\": false,\n  \"gatewayConnected\": null,\n  \"countries\": {\n    \"card\": {\n      \"coverageLabel\": \"190+\",\n      \"policy\": \"worldwide_except_restrictions\",\n      \"restrictions\": [\n        {\n          \"code\": \"AF\",\n          \"name\": \"Afghanistan\"\n        },\n        {\n          \"code\": \"AQ\",\n          \"name\": \"Antarctica\"\n        },\n        {\n          \"code\": \"BY\",\n          \"name\": \"Belarus\"\n        },\n        {\n          \"code\": \"MM\",\n          \"name\": \"Burma (Myanmar)\"\n        },\n        {\n          \"code\": \"BI\",\n          \"name\": \"Burundi\"\n        },\n        {\n          \"code\": \"CF\",\n          \"name\": \"Central African Republic\"\n        },\n        {\n          \"code\": \"TD\",\n          \"name\": \"Chad\"\n        },\n        {\n          \"code\": \"CU\",\n          \"name\": \"Cuba\"\n        },\n        {\n          \"code\": \"CD\",\n          \"name\": \"Democratic Republic of Congo\"\n        },\n        {\n          \"code\": \"CG\",\n          \"name\": \"Republic of Congo\"\n        },\n        {\n          \"code\": \"ER\",\n          \"name\": \"Eritrea\"\n        },\n        {\n          \"code\": \"HT\",\n          \"name\": \"Haiti\"\n        },\n        {\n          \"code\": \"IR\",\n          \"name\": \"Iran\"\n        },\n        {\n          \"code\": \"IQ\",\n          \"name\": \"Iraq\"\n        },\n        {\n          \"code\": \"LY\",\n          \"name\": \"Libya\"\n        },\n        {\n          \"code\": \"ML\",\n          \"name\": \"Mali\"\n        },\n        {\n          \"code\": \"NI\",\n          \"name\": \"Nicaragua\"\n        },\n        {\n          \"code\": \"KP\",\n          \"name\": \"North Korea\"\n        },\n        {\n          \"code\": \"RU\",\n          \"name\": \"Russia\"\n        },\n        {\n          \"code\": \"SO\",\n          \"name\": \"Somalia\"\n        },\n        {\n          \"code\": \"SS\",\n          \"name\": \"South Sudan\"\n        },\n        {\n          \"code\": \"SD\",\n          \"name\": \"Sudan\"\n        },\n        {\n          \"code\": \"SY\",\n          \"name\": \"Syria\"\n        },\n        {\n          \"code\": \"VE\",\n          \"name\": \"Venezuela\"\n        },\n        {\n          \"code\": \"YE\",\n          \"name\": \"Yemen\"\n        },\n        {\n          \"code\": \"ZW\",\n          \"name\": \"Zimbabwe\"\n        },\n        {\n          \"code\": \"UA-43\",\n          \"name\": \"Crimea (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-14\",\n          \"name\": \"Donetsk (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-65\",\n          \"name\": \"Kherson (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-09\",\n          \"name\": \"Luhansk (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-23\",\n          \"name\": \"Zaporizhzhia (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"AN\",\n          \"name\": \"Netherlands Antilles\"\n        }\n      ],\n      \"independentlyVerified\": false,\n      \"approvalGuaranteed\": false\n    }\n  },\n  \"gatewayIntegration\": {\n    \"adapterImplemented\": true,\n    \"contract\": \"v3\",\n    \"liveConfigurationProvided\": null,\n    \"availability\": {\n      \"source\": \"runtime\",\n      \"configurationEndpoint\": \"/api/config\",\n      \"configurationIncludesHealthCheck\": false,\n      \"checkoutEndpoint\": \"/api/checkout/{token}\",\n      \"checkoutIncludesProviderApproval\": false\n    }\n  }\n}\n\nLimites des informations publiques\n\nLe texte brut et le JSON ne contiennent pas de sessions, jetons, demandes de support privées, enregistrements de paiement utilisateur ou secrets d'intégration. Les pages de connexion, de compte et de paiement sont exclues de l'indexation de recherche.\n\nLa lecture de la documentation publique n'accorde pas de permissions de gestion de boutique. Les enregistrements personnels nécessitent une session valide et les mutations nécessitent des vérifications serveur supplémentaires.\n\nMises à jour et citations\n\nLes articles ont des identifiants stables, des URL, des titres et une date de mise à jour. Liez au guide pertinent lorsque vous citez une réponse et préservez les qualifications concernant les conditions de transaction.\n\nLes sitemaps, les ressources llms et le HTML rendu par serveur facilitent l'extraction du contenu. Ils ne garantissent pas l'indexation, la position de recherche ou l'utilisation par un système d'IA externe.\n\nSeules les traductions publiées ont des URL canoniques, des alternatives hreflang et des entrées de sitemap. Une locale configurée pour une traduction future n'est pas une édition de langue publiée.",
      "readMinutes": 5
    },
    {
      "id": "cost-sharing",
      "title": "Répartir les frais de traitement et la TVA",
      "summary": "Choisissez indépendamment quelle partie des frais de traitement et de la TVA votre client paie sur chaque facture. Deux curseurs répartissent chaque coût de 0 à 100 % par pas d'un pour cent, avec le résultat visible avant de créer le lien.",
      "tags": [
        "répartition des coûts",
        "frais de traitement",
        "VAT",
        "pourcentage",
        "curseur",
        "feeCustomerPercent",
        "vatCustomerPercent"
      ],
      "sections": [
        {
          "id": "controls",
          "title": "Deux contrôles pour une commande",
          "paragraphs": [
            "Le contrôle des frais de traitement répartit la totalité des frais d'acceptation, y compris leurs composantes en pourcentage et fixes. Le contrôle de TVA répartit uniquement la taxe. Aucun contrôle ne modifie le tarif, le taux de taxe ou le prix de base du produit.",
            "Entièrement à gauche attribue le coût au client ; entièrement à droite l'attribue au marchand. Les étiquettes affichent les pourcentages exacts et les montants monétaires des deux parties. Les préréglages Client, Répartition égale et Marchand offrent un choix rapide."
          ],
          "bullets": [
            "La part du client est ajoutée au total du paiement.",
            "La part du marchand est déduite du prix de commande de base.",
            "SBP et la cryptomonnaie ont une TVA nulle, donc le contrôle de TVA n'affecte pas leur total.",
            "Les boutons et les curseurs fonctionnent avec le clavier ; l'animation n'est pas nécessaire pour comprendre le résultat."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Ouvrir le calculateur",
              "href": "/pricing"
            }
          ]
        },
        {
          "id": "base",
          "title": "Un prix de base, deux coûts séparés",
          "paragraphs": [
            "Les cartes internationales et Alipay coûtent 10 % du prix de base plus 0,50 $, avec une TVA de 16 % du prix de base. SBP coûte 8 % et la cryptomonnaie 4 % ; aucun n'a de TVA selon le modèle tarifaire publié.",
            "La TVA est ajoutée à partir du prix de base, non extraite en utilisant 16/116. Les frais ne sont pas recalculés sur un total qui inclut la TVA ou la part des frais du client. La commission de Kevmi est déjà incluse dans le tarif publié ; 5 % supplémentaires ne sont pas ajoutés."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "Formula · integer minor units",
            "code": "fee = roundHalfUp(base × rate / 100) + fixed\nvat = vatApplies ? roundHalfUp(base × 16 / 100) : 0\ncustomerFee = roundHalfUp(fee × feeCustomerPercent / 100)\ncustomerVat = roundHalfUp(vat × vatCustomerPercent / 100)\nmerchantFee = fee − customerFee\nmerchantVat = vat − customerVat\ncustomerTotal = base + customerFee + customerVat\nmerchantNet = base − merchantFee − merchantVat"
          },
          "note": "",
          "links": []
        },
        {
          "id": "example",
          "title": "Répartition d'une commande par carte de 5 $",
          "paragraphs": [
            "Chaque exemple ci-dessous utilise un prix de base de 5,00 $, des frais de carte totaux de 1,00 $ et une TVA de 0,80 $. Les pourcentages changent uniquement qui couvre ces coûts."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Parts du client : TVA / frais",
              "Le client paie",
              "Marchand après déductions"
            ],
            "rows": [
              [
                "100 % / 0 % · défaut d'origine",
                "$5.80",
                "$4.00"
              ],
              [
                "0 % / 0 % · le marchand couvre tout",
                "$5.00",
                "$3.20"
              ],
              [
                "100 % / 100 % · le client couvre tout",
                "$6.80",
                "$5.00"
              ],
              [
                "50 % / 23 % · répartition personnalisée",
                "$5.63",
                "$3.83"
              ]
            ]
          },
          "code": null,
          "note": "Le tableau illustre l'arithmétique de répartition. Parmi ces configurations de carte, la passerelle actuelle ne peut exécuter que 100 % de TVA client / 0 % de frais client. Ce calcul n'initie pas de paiement ; il n'y a pas de conversion automatique USD vers USDT.",
          "links": []
        },
        {
          "id": "rounding",
          "title": "Arrondi sans perdre un centime",
          "paragraphs": [
            "Les montants sont en unités monétaires mineures entières. Les frais totaux et la TVA totale sont arrondis séparément d'abord. Chaque part du client utilise ensuite un arrondi au demi supérieur, et le marchand reçoit le reste exact de ce coût. Les deux parts s'additionnent donc toujours au montant d'origine.",
            "Pour un coût d'un centime réparti 50/50, le client se voit attribuer un centime et le marchand zéro. Le pourcentage reste 50 %, tandis que les montants monétaires reflètent la précision disponible de la devise. Le serveur rejette les calculs avec des produits marchands négatifs."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "api",
          "title": "Définir la répartition via l'API",
          "paragraphs": [
            "Envoyez vatCustomerPercent et feeCustomerPercent comme entiers de 0 à 100. Chacun s'applique à la facture en cours de création. Les chaînes vides, les pourcentages fractionnaires et les nombres hors plage sont rejetés.",
            "Omettre feeCustomerPercent attribue la totalité des frais au marchand. Omettre vatCustomerPercent utilise le champ hérité vatPayer ou le défaut du compte. Les valeurs héritées client et marchand correspondent à 100 % et 0 % de TVA client. N'envoyez pas de valeurs conflictuelles vatPayer et vatCustomerPercent.",
            "Les réponses décrivent une part de TVA intermédiaire comme vatPayer=shared. Utilisez le pourcentage numérique pour les nouvelles demandes ; shared n'est pas accepté comme valeur d'entrée héritée vatPayer."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JSON",
            "code": "{\n  \"title\": \"Design project · order 1042\",\n  \"description\": \"One-time payment for the agreed design work\",\n  \"amountMinor\": 500,\n  \"currency\": \"USD\",\n  \"methods\": [\n    \"card\",\n    \"alipay\"\n  ],\n  \"vatCustomerPercent\": 100,\n  \"feeCustomerPercent\": 0,\n  \"orderId\": \"order-1042\",\n  \"metadata\": {\n    \"campaign\": \"autumn\"\n  }\n}"
          },
          "note": "L'exemple utilise la répartition prise en charge du canal carte : toute la TVA au client et la totalité des frais de traitement au marchand. Enregistrer d'autres pourcentages ne les rend pas exécutables.",
          "links": [
            {
              "label": "Créer une facture via l'API",
              "href": "/docs/payment-links-api"
            }
          ]
        },
        {
          "id": "snapshot",
          "title": "Les conditions restent avec la facture",
          "paragraphs": [
            "La facture fige le montant, la devise, les méthodes et les deux parts. Modifier les préférences de la boutique ne modifie pas les liens émis. Les curseurs calculent la répartition ; l'exécution en direct dépend des capacités du canal connecté.",
            "Pour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "group": "payments",
      "url": "/docs/cost-sharing",
      "body": "Deux contrôles pour une commande\n\nLe contrôle des frais de traitement répartit la totalité des frais d'acceptation, y compris leurs composantes en pourcentage et fixes. Le contrôle de TVA répartit uniquement la taxe. Aucun contrôle ne modifie le tarif, le taux de taxe ou le prix de base du produit.\n\nEntièrement à gauche attribue le coût au client ; entièrement à droite l'attribue au marchand. Les étiquettes affichent les pourcentages exacts et les montants monétaires des deux parties. Les préréglages Client, Répartition égale et Marchand offrent un choix rapide.\n\nLa part du client est ajoutée au total du paiement.\n\nLa part du marchand est déduite du prix de commande de base.\n\nSBP et la cryptomonnaie ont une TVA nulle, donc le contrôle de TVA n'affecte pas leur total.\n\nLes boutons et les curseurs fonctionnent avec le clavier ; l'animation n'est pas nécessaire pour comprendre le résultat.\n\nOuvrir le calculateur\n\nUn prix de base, deux coûts séparés\n\nLes cartes internationales et Alipay coûtent 10 % du prix de base plus 0,50 $, avec une TVA de 16 % du prix de base. SBP coûte 8 % et la cryptomonnaie 4 % ; aucun n'a de TVA selon le modèle tarifaire publié.\n\nLa TVA est ajoutée à partir du prix de base, non extraite en utilisant 16/116. Les frais ne sont pas recalculés sur un total qui inclut la TVA ou la part des frais du client. La commission de Kevmi est déjà incluse dans le tarif publié ; 5 % supplémentaires ne sont pas ajoutés.\n\nfee = roundHalfUp(base × rate / 100) + fixed\nvat = vatApplies ? roundHalfUp(base × 16 / 100) : 0\ncustomerFee = roundHalfUp(fee × feeCustomerPercent / 100)\ncustomerVat = roundHalfUp(vat × vatCustomerPercent / 100)\nmerchantFee = fee − customerFee\nmerchantVat = vat − customerVat\ncustomerTotal = base + customerFee + customerVat\nmerchantNet = base − merchantFee − merchantVat\n\nRépartition d'une commande par carte de 5 $\n\nChaque exemple ci-dessous utilise un prix de base de 5,00 $, des frais de carte totaux de 1,00 $ et une TVA de 0,80 $. Les pourcentages changent uniquement qui couvre ces coûts.\n\nParts du client : TVA / frais · Le client paie · Marchand après déductions\n100 % / 0 % · défaut d'origine · $5.80 · $4.00\n0 % / 0 % · le marchand couvre tout · $5.00 · $3.20\n100 % / 100 % · le client couvre tout · $6.80 · $5.00\n50 % / 23 % · répartition personnalisée · $5.63 · $3.83\n\nLe tableau illustre l'arithmétique de répartition. Parmi ces configurations de carte, la passerelle actuelle ne peut exécuter que 100 % de TVA client / 0 % de frais client. Ce calcul n'initie pas de paiement ; il n'y a pas de conversion automatique USD vers USDT.\n\nArrondi sans perdre un centime\n\nLes montants sont en unités monétaires mineures entières. Les frais totaux et la TVA totale sont arrondis séparément d'abord. Chaque part du client utilise ensuite un arrondi au demi supérieur, et le marchand reçoit le reste exact de ce coût. Les deux parts s'additionnent donc toujours au montant d'origine.\n\nPour un coût d'un centime réparti 50/50, le client se voit attribuer un centime et le marchand zéro. Le pourcentage reste 50 %, tandis que les montants monétaires reflètent la précision disponible de la devise. Le serveur rejette les calculs avec des produits marchands négatifs.\n\nDéfinir la répartition via l'API\n\nEnvoyez vatCustomerPercent et feeCustomerPercent comme entiers de 0 à 100. Chacun s'applique à la facture en cours de création. Les chaînes vides, les pourcentages fractionnaires et les nombres hors plage sont rejetés.\n\nOmettre feeCustomerPercent attribue la totalité des frais au marchand. Omettre vatCustomerPercent utilise le champ hérité vatPayer ou le défaut du compte. Les valeurs héritées client et marchand correspondent à 100 % et 0 % de TVA client. N'envoyez pas de valeurs conflictuelles vatPayer et vatCustomerPercent.\n\nLes réponses décrivent une part de TVA intermédiaire comme vatPayer=shared. Utilisez le pourcentage numérique pour les nouvelles demandes ; shared n'est pas accepté comme valeur d'entrée héritée vatPayer.\n\n{\n  \"title\": \"Design project · order 1042\",\n  \"description\": \"One-time payment for the agreed design work\",\n  \"amountMinor\": 500,\n  \"currency\": \"USD\",\n  \"methods\": [\n    \"card\",\n    \"alipay\"\n  ],\n  \"vatCustomerPercent\": 100,\n  \"feeCustomerPercent\": 0,\n  \"orderId\": \"order-1042\",\n  \"metadata\": {\n    \"campaign\": \"autumn\"\n  }\n}\n\nL'exemple utilise la répartition prise en charge du canal carte : toute la TVA au client et la totalité des frais de traitement au marchand. Enregistrer d'autres pourcentages ne les rend pas exécutables.\n\nCréer une facture via l'API\n\nLes conditions restent avec la facture\n\nLa facture fige le montant, la devise, les méthodes et les deux parts. Modifier les préférences de la boutique ne modifie pas les liens émis. Les curseurs calculent la répartition ; l'exécution en direct dépend des capacités du canal connecté.\n\nPour un nouveau paiement en direct par carte ou Alipay, la passerelle actuelle ne prend en charge que feeCustomerPercent=0 et vatCustomerPercent=100 : le marchand couvre la totalité des frais de traitement et la TVA est ajoutée intégralement pour le client. D'autres parts peuvent être enregistrées et calculées sur une facture, mais l'exécution est bloquée avec unsupported_allocation. Le serveur ne modifie jamais silencieusement les conditions enregistrées. Les paiements crypto SBP et USDT prennent en charge toutes les parts de frais de traitement et n'ont pas de TVA.",
      "readMinutes": 6
    },
    {
      "id": "widgets",
      "title": "Intégrer le paiement sur votre site web",
      "summary": "Ouvrir le paiement dans une fenêtre modale, l'intégrer dans une page ou envoyer le client vers une page de paiement dédiée. Le widget utilise une URL de paiement publique et n'a jamais besoin de clé API marchande dans le navigateur.",
      "tags": [
        "widget",
        "iframe",
        "intégration",
        "HTML",
        "intégration",
        "modale",
        "paiement"
      ],
      "sections": [
        {
          "id": "flow",
          "title": "De la facture au paiement",
          "paragraphs": [
            "Créez une facture dans /account#links et recevez immédiatement le checkoutUrl. Ouvrez /account#widget, collez le lien et choisissez une modale, un bloc en ligne ou une redirection. Les clés et les webhooks sont disponibles dans les sections de compte voisines.",
            "L'aperçu du constructeur utilise toujours une commande de démonstration sans facturation. Le code du widget généré conserve votre lien en direct, dont les conditions proviennent de la facture serveur enregistrée.",
            "Pour une nouvelle facture dans l'interface, USD propose les cartes et Alipay ; RUB propose SBP ; USDT propose la crypto. L'API peut également enregistrer USD + crypto pour compatibilité, mais son paiement crypto en direct est bloqué avec crypto_requires_usdt. USD et USDT sont distincts, sans conversion automatique ni taux de 1:1 supposé. Un paiement crypto nécessite une facture USDT séparée."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Constructeur d'intégration",
              "href": "/account#widget"
            },
            {
              "label": "API des liens de paiement",
              "href": "/docs/payment-links-api"
            }
          ]
        },
        {
          "id": "markup",
          "title": "Un bouton avec un repli sur lien normal",
          "paragraphs": [
            "Cet exemple ouvre une démonstration sans facturer d'argent. Remplacez les deux valeurs d'URL par checkoutUrl provenant de votre réponse de facture. Chargez le script depuis la même origine Kevmi que l'URL de paiement.",
            "Le href ouvre le paiement lorsque JavaScript est indisponible. data-kevmi-label donne à l'iframe un nom accessible. Incluez le script une fois par page."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "HTML",
            "code": "<script src=\"https://kevmi.maxeevmax1.chatgpt.site/widgets/kevmi.js\" defer></script>\n<a href=\"https://kevmi.maxeevmax1.chatgpt.site/en/pay/demo\"\n   data-kevmi-checkout=\"https://kevmi.maxeevmax1.chatgpt.site/en/pay/demo\"\n   data-kevmi-mode=\"modal\"\n   data-kevmi-label=\"Order checkout\">Pay securely</a>"
          },
          "note": "",
          "links": []
        },
        {
          "id": "modes",
          "title": "Trois façons d'ouvrir le paiement",
          "paragraphs": [
            "Utilisez un conteneur tel que div pour le mode en ligne et remplacez CHECKOUT_URL_FROM_API par une URL réelle. Le cadre s'adapte à la largeur de son conteneur ; les messages de paiement peuvent redimensionner sa hauteur dans une plage limitée.",
            "La modale se ferme avec son bouton, la touche Échap ou un clic sur l'arrière-plan. Le focus revient au déclencheur d'origine après la fermeture. Les paramètres de mouvement réduit raccourcissent la transition."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "data-kevmi-mode",
              "Comportement",
              "Utile pour"
            ],
            "rows": [
              [
                "modale",
                "Une boîte de dialogue superposée ; le mode par défaut",
                "Un bouton de paiement au niveau de la commande"
              ],
              [
                "en ligne",
                "Une iframe à l'intérieur du conteneur sélectionné",
                "Une étape de paiement sur votre site"
              ],
              [
                "redirection",
                "Navigation vers Kevmi dans l'onglet actuel",
                "Une page de paiement complète"
              ]
            ]
          },
          "code": {
            "language": "HTML",
            "code": "<div data-kevmi-checkout=\"CHECKOUT_URL_FROM_API\"\n     data-kevmi-mode=\"inline\"\n     data-kevmi-label=\"Order checkout\"></div>"
          },
          "note": "",
          "links": []
        },
        {
          "id": "javascript",
          "title": "Ouvrir le paiement depuis votre interface",
          "paragraphs": [
            "Les événements de document kevmi:opened et kevmi:closed permettent à votre interface de réagir à l'ouverture et à la fermeture. Un événement kevmi:error sur le déclencheur signale une URL de paiement invalide. Aucun d'eux ne prouve un paiement. Appelez l'API JavaScript après le chargement du script du widget."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JavaScript",
            "code": "window.Kevmi.open(checkoutUrl, {\n  mode: 'modal',\n  label: 'Order checkout',\n  closeLabel: 'Close checkout'\n});\n\n// Inline blocks added after page load are detected automatically.\n// You may also request mounting explicitly:\nwindow.Kevmi.mount(document);"
          },
          "note": "",
          "links": []
        },
        {
          "id": "security",
          "title": "Ce qui prouve un paiement réussi",
          "paragraphs": [
            "Ne mettez pas de clés API ni de secrets de signature dans le HTML. Le widget ne reçoit qu'un lien public vers une facture. Le paiement chiffre les détails de carte et les codes bancaires avec la clé de passerelle ; le serveur Kevmi ne les accepte pas en texte clair.",
            "postMessage met à jour l'état de l'interface, pas l'exécution de la commande. Vérifiez l'origine du message et la fenêtre source avant le traitement. Utilisez un événement vérifié payment.succeeded ou un statut succeeded dans le résumé GET link.payment du serveur pour le résultat final."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "Ouvrir le paiement, fermer un widget ou revenir au site marchand ne prouve pas que l'argent a été reçu.",
          "links": [
            {
              "label": "Signatures et livraison des webhooks",
              "href": "/docs/webhooks"
            }
          ]
        },
        {
          "id": "deployment",
          "title": "Avant d'ajouter le widget en production",
          "paragraphs": [],
          "bullets": [
            "Autorisez l'origine Kevmi dans vos directives Content Security Policy script-src et frame-src sans élargir des politiques non liées.",
            "Vérifiez les écrans étroits, l'accès au clavier et les thèmes clair et sombre.",
            "Confirmez que la facture est active, non expirée et a le bon prix et les bonnes parts de coût.",
            "Conservez un lien de paiement ordinaire comme repli.",
            "Testez les livraisons échouées et les événements de webhook en double sans émettre une commande deux fois."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "group": "developers",
      "url": "/docs/widgets",
      "body": "De la facture au paiement\n\nCréez une facture dans /account#links et recevez immédiatement le checkoutUrl. Ouvrez /account#widget, collez le lien et choisissez une modale, un bloc en ligne ou une redirection. Les clés et les webhooks sont disponibles dans les sections de compte voisines.\n\nL'aperçu du constructeur utilise toujours une commande de démonstration sans facturation. Le code du widget généré conserve votre lien en direct, dont les conditions proviennent de la facture serveur enregistrée.\n\nPour une nouvelle facture dans l'interface, USD propose les cartes et Alipay ; RUB propose SBP ; USDT propose la crypto. L'API peut également enregistrer USD + crypto pour compatibilité, mais son paiement crypto en direct est bloqué avec crypto_requires_usdt. USD et USDT sont distincts, sans conversion automatique ni taux de 1:1 supposé. Un paiement crypto nécessite une facture USDT séparée.\n\nConstructeur d'intégration\n\nAPI des liens de paiement\n\nUn bouton avec un repli sur lien normal\n\nCet exemple ouvre une démonstration sans facturer d'argent. Remplacez les deux valeurs d'URL par checkoutUrl provenant de votre réponse de facture. Chargez le script depuis la même origine Kevmi que l'URL de paiement.\n\nLe href ouvre le paiement lorsque JavaScript est indisponible. data-kevmi-label donne à l'iframe un nom accessible. Incluez le script une fois par page.\n\n<script src=\"https://kevmi.maxeevmax1.chatgpt.site/widgets/kevmi.js\" defer></script>\n<a href=\"https://kevmi.maxeevmax1.chatgpt.site/en/pay/demo\"\n   data-kevmi-checkout=\"https://kevmi.maxeevmax1.chatgpt.site/en/pay/demo\"\n   data-kevmi-mode=\"modal\"\n   data-kevmi-label=\"Order checkout\">Pay securely</a>\n\nTrois façons d'ouvrir le paiement\n\nUtilisez un conteneur tel que div pour le mode en ligne et remplacez CHECKOUT_URL_FROM_API par une URL réelle. Le cadre s'adapte à la largeur de son conteneur ; les messages de paiement peuvent redimensionner sa hauteur dans une plage limitée.\n\nLa modale se ferme avec son bouton, la touche Échap ou un clic sur l'arrière-plan. Le focus revient au déclencheur d'origine après la fermeture. Les paramètres de mouvement réduit raccourcissent la transition.\n\ndata-kevmi-mode · Comportement · Utile pour\nmodale · Une boîte de dialogue superposée ; le mode par défaut · Un bouton de paiement au niveau de la commande\nen ligne · Une iframe à l'intérieur du conteneur sélectionné · Une étape de paiement sur votre site\nredirection · Navigation vers Kevmi dans l'onglet actuel · Une page de paiement complète\n\n<div data-kevmi-checkout=\"CHECKOUT_URL_FROM_API\"\n     data-kevmi-mode=\"inline\"\n     data-kevmi-label=\"Order checkout\"></div>\n\nOuvrir le paiement depuis votre interface\n\nLes événements de document kevmi:opened et kevmi:closed permettent à votre interface de réagir à l'ouverture et à la fermeture. Un événement kevmi:error sur le déclencheur signale une URL de paiement invalide. Aucun d'eux ne prouve un paiement. Appelez l'API JavaScript après le chargement du script du widget.\n\nwindow.Kevmi.open(checkoutUrl, {\n  mode: 'modal',\n  label: 'Order checkout',\n  closeLabel: 'Close checkout'\n});\n\n// Inline blocks added after page load are detected automatically.\n// You may also request mounting explicitly:\nwindow.Kevmi.mount(document);\n\nCe qui prouve un paiement réussi\n\nNe mettez pas de clés API ni de secrets de signature dans le HTML. Le widget ne reçoit qu'un lien public vers une facture. Le paiement chiffre les détails de carte et les codes bancaires avec la clé de passerelle ; le serveur Kevmi ne les accepte pas en texte clair.\n\npostMessage met à jour l'état de l'interface, pas l'exécution de la commande. Vérifiez l'origine du message et la fenêtre source avant le traitement. Utilisez un événement vérifié payment.succeeded ou un statut succeeded dans le résumé GET link.payment du serveur pour le résultat final.\n\nOuvrir le paiement, fermer un widget ou revenir au site marchand ne prouve pas que l'argent a été reçu.\n\nSignatures et livraison des webhooks\n\nAvant d'ajouter le widget en production\n\nAutorisez l'origine Kevmi dans vos directives Content Security Policy script-src et frame-src sans élargir des politiques non liées.\n\nVérifiez les écrans étroits, l'accès au clavier et les thèmes clair et sombre.\n\nConfirmez que la facture est active, non expirée et a le bon prix et les bonnes parts de coût.\n\nConservez un lien de paiement ordinaire comme repli.\n\nTestez les livraisons échouées et les événements de webhook en double sans émettre une commande deux fois.",
      "readMinutes": 4
    },
    {
      "id": "applications",
      "title": "Faire une demande pour connecter votre boutique",
      "summary": "Soumettez votre site web après vous être connecté avec Telegram et suivez chaque étape de révision à une URL privée. Les vérifications automatisées aident le réviseur ; un modérateur prend toujours la décision finale.",
      "tags": [
        "demande",
        "intégration",
        "modération",
        "révision du site web",
        "statut",
        "Telegram",
        "AI"
      ],
      "sections": [
        {
          "id": "submit",
          "title": "Soumettre une demande",
          "paragraphs": [
            "Les descriptions exigent 40 à 3000 caractères ; les noms de projet admettent jusqu'à 100. Le site web doit être accessible sans connexion. Les URL contenant des identifiants, des hôtes privés, des ports non standard ou des paramètres de requête ne sont pas acceptées.",
            "Le compte vérifié possède la demande. Le contact Telegram saisi sert à la communication et ne change pas la propriété. Transférer l'URL de suivi n'accorde pas l'accès à un autre compte."
          ],
          "bullets": [],
          "steps": [
            "Connectez-vous ou inscrivez-vous avec Telegram, puis ouvrez /account#applications.",
            "Saisissez une adresse de site web HTTPS publique, un nom de projet, une catégorie et une description de vos produits ou services.",
            "Ajoutez un contact Telegram. Expliquez ce que les clients reçoivent et comment les commandes sont exécutées.",
            "Confirmez votre autorité à soumettre le site et envoyez le formulaire.",
            "Conservez l'adresse /account#applications/{id} qui s'ouvre immédiatement après la soumission."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Soumettre votre site web",
              "href": "/account#applications"
            }
          ]
        },
        {
          "id": "stages",
          "title": "Quatre étapes de révision",
          "paragraphs": [
            "La ligne de connexion et les marqueurs d'étape reflètent les états serveur persistés. Rouvrir la page poursuit le même processus. Fermer l'onglet n'annule pas votre demande ; les tâches en arrière-plan continuent de travailler et récupèrent les étapes interrompues."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Étape",
              "Ce qui se passe",
              "Statut affiché"
            ],
            "rows": [
              [
                "Demande reçue",
                "Les détails de la soumission et l'URL privée sont enregistrés",
                "La première étape est terminée"
              ],
              [
                "Examen du contenu",
                "L'IA compare la description avec le contenu du site public",
                "En cours, terminée ou en attente d'un spécialiste"
              ],
              [
                "Vérifications techniques",
                "La disponibilité et un ensemble limité de liens sont examinés",
                "Un résultat distinct et l'horodatage de l'étape"
              ],
              [
                "Examen du spécialiste",
                "Un modérateur examine la soumission et les constatations",
                "En attente de décision, approuvée ou un motif de refus"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "attention",
          "title": "Une étape jaune nécessite un spécialiste",
          "paragraphs": [
            "Un marqueur jaune signifie qu'une étape nécessite une attention, par exemple parce que les informations sont insuffisantes, qu'un lien est indisponible ou qu'un résultat automatisé ne peut pas être accepté avec confiance. Ce n'est pas un rejet définitif. La page de statut explique l'étape suivante.",
            "Un modérateur peut effacer l'étape en cours pour que la vérification suivante se poursuive. Une étape refusée affiche une croix et un motif visible par l'utilisateur que le modérateur peut modifier avant l'envoi. Effacer une étape intermédiaire ne supprime jamais l'examen manuel final."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "scope",
          "title": "Ce que couvrent les vérifications automatisées",
          "paragraphs": [
            "Les vérifications examinent la page d'accueil publique : HTTPS, réponse HTTP, titre, texte et schémas de liens suspects. Elles demandent également des en-têtes pour au plus trois liens sur le même site. Le nombre de redirections, la taille de la réponse et le temps de requête sont limités.",
            "Les vérifications n'accèdent pas aux zones connectées, n'exécutent pas de fichiers téléchargés et ne remplacent pas un audit de sécurité ou un scanner de logiciels malveillants. Terminer une étape ne garantit pas que chaque page est exempte de contenu malveillant.",
            "Le contenu du site est une donnée non fiable. Les instructions présentes sur un site ne peuvent pas attribuer un administrateur, modifier les conditions Kevmi ni approuver une demande. Une IA indisponible et une sortie de modèle malformée nécessitent un examen par un spécialiste au lieu de passer silencieusement l'étape."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "updates",
          "title": "Mises à jour Telegram",
          "paragraphs": [
            "La réception d'une demande, la fin d'une étape, la demande d'attention d'un spécialiste et la prise d'une décision finale créent des notifications avec un lien de suivi privé. Celles-ci utilisent la catégorie Assistance dans les paramètres de notification du compte. Désactiver cette catégorie arrête les messages.",
            "L'événement de demande et l'entrée de la boîte d'envoi de notification sont validés ensemble. La livraison Telegram utilise une file d'attente de réessai et nécessite un bot connecté. La page de suivi reste la source du statut actuel si Telegram est indisponible ou si le bot est bloqué.",
            "La modération reçoit des alertes séparées. Seuls les utilisateurs figurant sur la liste blanche de modération du serveur peuvent effacer une étape depuis Telegram ; un ancien bouton ne peut pas appliquer une décision répétée. Les motifs de refus sont modifiés dans l'espace de travail de modération."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Paramètres de notification",
              "href": "/docs/notifications"
            }
          ]
        },
        {
          "id": "api",
          "title": "Contrat de demande et de décision",
          "paragraphs": [
            "La propriété provient de la session. Les candidats ne peuvent pas soumettre userId, le statut, les rôles ni les résultats d'examen. Répéter la création avec la même clé d'idempotence et le même corps renvoie la demande existante ; modifier le corps avec cette clé produit un conflit.",
            "Une décision de modérateur s'applique uniquement à la version attendue de la demande. Les décisions simultanées sont enregistrées une fois ; l'autre requête reçoit un 409. Un motif de refus est un texte brut de 10 à 1500 caractères. Les preuves internes d'examen sont réservées aux modérateurs."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Route",
              "Accès et comportement"
            ],
            "rows": [
              [
                "POST /api/applications",
                "Session + CSRF + clé d'idempotence ; 202 avec une URL privée"
              ],
              [
                "GET /api/applications",
                "Demandes du compte actuel"
              ],
              [
                "GET /api/applications/{id}",
                "Soumission détenue, étapes et historique public"
              ],
              [
                "POST /api/applications/{id}/resume",
                "Session + CSRF ; poursuit uniquement le traitement des demandes"
              ],
              [
                "GET /api/moderation/applications",
                "Modérateurs vérifiés uniquement"
              ],
              [
                "POST /api/moderation/applications/{id}/decision",
                "approve_step ou reject, expectedVersion et un motif de refus"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "outcome",
          "title": "Après la décision",
          "paragraphs": [
            "Un nouveau paiement et une intention de carte nécessitent l'approbation de la dernière demande de revue du site du marchand. L'approbation seule ne connecte pas la passerelle de paiement. Si la revue change après l'envoi, l'opération existante reste disponible pour la lecture des statuts, le rapprochement et un code bancaire demandé.",
            "En cas de refus, le marchand voit le motif et peut corriger les documents avant de présenter une nouvelle demande. Une étape jaune signifie qu'un spécialiste doit encore décider ; ce n'est pas une approbation automatique."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Assistance",
              "href": "/?support=open"
            },
            {
              "label": "Disponibilité de la passerelle",
              "href": "/docs/gateway"
            }
          ]
        },
        {
          "id": "stores-usd",
          "title": "Plusieurs boutiques et un prix de base USD unique",
          "paragraphs": [
            "Choisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.",
            "Les factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.",
            "Le taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.",
            "Créez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.",
            "Pour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "group": "start",
      "url": "/docs/applications",
      "body": "Soumettre une demande\n\nLes descriptions exigent 40 à 3000 caractères ; les noms de projet admettent jusqu'à 100. Le site web doit être accessible sans connexion. Les URL contenant des identifiants, des hôtes privés, des ports non standard ou des paramètres de requête ne sont pas acceptées.\n\nLe compte vérifié possède la demande. Le contact Telegram saisi sert à la communication et ne change pas la propriété. Transférer l'URL de suivi n'accorde pas l'accès à un autre compte.\n\nConnectez-vous ou inscrivez-vous avec Telegram, puis ouvrez /account#applications.\n\nSaisissez une adresse de site web HTTPS publique, un nom de projet, une catégorie et une description de vos produits ou services.\n\nAjoutez un contact Telegram. Expliquez ce que les clients reçoivent et comment les commandes sont exécutées.\n\nConfirmez votre autorité à soumettre le site et envoyez le formulaire.\n\nConservez l'adresse /account#applications/{id} qui s'ouvre immédiatement après la soumission.\n\nSoumettre votre site web\n\nQuatre étapes de révision\n\nLa ligne de connexion et les marqueurs d'étape reflètent les états serveur persistés. Rouvrir la page poursuit le même processus. Fermer l'onglet n'annule pas votre demande ; les tâches en arrière-plan continuent de travailler et récupèrent les étapes interrompues.\n\nÉtape · Ce qui se passe · Statut affiché\nDemande reçue · Les détails de la soumission et l'URL privée sont enregistrés · La première étape est terminée\nExamen du contenu · L'IA compare la description avec le contenu du site public · En cours, terminée ou en attente d'un spécialiste\nVérifications techniques · La disponibilité et un ensemble limité de liens sont examinés · Un résultat distinct et l'horodatage de l'étape\nExamen du spécialiste · Un modérateur examine la soumission et les constatations · En attente de décision, approuvée ou un motif de refus\n\nUne étape jaune nécessite un spécialiste\n\nUn marqueur jaune signifie qu'une étape nécessite une attention, par exemple parce que les informations sont insuffisantes, qu'un lien est indisponible ou qu'un résultat automatisé ne peut pas être accepté avec confiance. Ce n'est pas un rejet définitif. La page de statut explique l'étape suivante.\n\nUn modérateur peut effacer l'étape en cours pour que la vérification suivante se poursuive. Une étape refusée affiche une croix et un motif visible par l'utilisateur que le modérateur peut modifier avant l'envoi. Effacer une étape intermédiaire ne supprime jamais l'examen manuel final.\n\nCe que couvrent les vérifications automatisées\n\nLes vérifications examinent la page d'accueil publique : HTTPS, réponse HTTP, titre, texte et schémas de liens suspects. Elles demandent également des en-têtes pour au plus trois liens sur le même site. Le nombre de redirections, la taille de la réponse et le temps de requête sont limités.\n\nLes vérifications n'accèdent pas aux zones connectées, n'exécutent pas de fichiers téléchargés et ne remplacent pas un audit de sécurité ou un scanner de logiciels malveillants. Terminer une étape ne garantit pas que chaque page est exempte de contenu malveillant.\n\nLe contenu du site est une donnée non fiable. Les instructions présentes sur un site ne peuvent pas attribuer un administrateur, modifier les conditions Kevmi ni approuver une demande. Une IA indisponible et une sortie de modèle malformée nécessitent un examen par un spécialiste au lieu de passer silencieusement l'étape.\n\nMises à jour Telegram\n\nLa réception d'une demande, la fin d'une étape, la demande d'attention d'un spécialiste et la prise d'une décision finale créent des notifications avec un lien de suivi privé. Celles-ci utilisent la catégorie Assistance dans les paramètres de notification du compte. Désactiver cette catégorie arrête les messages.\n\nL'événement de demande et l'entrée de la boîte d'envoi de notification sont validés ensemble. La livraison Telegram utilise une file d'attente de réessai et nécessite un bot connecté. La page de suivi reste la source du statut actuel si Telegram est indisponible ou si le bot est bloqué.\n\nLa modération reçoit des alertes séparées. Seuls les utilisateurs figurant sur la liste blanche de modération du serveur peuvent effacer une étape depuis Telegram ; un ancien bouton ne peut pas appliquer une décision répétée. Les motifs de refus sont modifiés dans l'espace de travail de modération.\n\nParamètres de notification\n\nContrat de demande et de décision\n\nLa propriété provient de la session. Les candidats ne peuvent pas soumettre userId, le statut, les rôles ni les résultats d'examen. Répéter la création avec la même clé d'idempotence et le même corps renvoie la demande existante ; modifier le corps avec cette clé produit un conflit.\n\nUne décision de modérateur s'applique uniquement à la version attendue de la demande. Les décisions simultanées sont enregistrées une fois ; l'autre requête reçoit un 409. Un motif de refus est un texte brut de 10 à 1500 caractères. Les preuves internes d'examen sont réservées aux modérateurs.\n\nRoute · Accès et comportement\nPOST /api/applications · Session + CSRF + clé d'idempotence ; 202 avec une URL privée\nGET /api/applications · Demandes du compte actuel\nGET /api/applications/{id} · Soumission détenue, étapes et historique public\nPOST /api/applications/{id}/resume · Session + CSRF ; poursuit uniquement le traitement des demandes\nGET /api/moderation/applications · Modérateurs vérifiés uniquement\nPOST /api/moderation/applications/{id}/decision · approve_step ou reject, expectedVersion et un motif de refus\n\nAprès la décision\n\nUn nouveau paiement et une intention de carte nécessitent l'approbation de la dernière demande de revue du site du marchand. L'approbation seule ne connecte pas la passerelle de paiement. Si la revue change après l'envoi, l'opération existante reste disponible pour la lecture des statuts, le rapprochement et un code bancaire demandé.\n\nEn cas de refus, le marchand voit le motif et peut corriger les documents avant de présenter une nouvelle demande. Une étape jaune signifie qu'un spécialiste doit encore décider ; ce n'est pas une approbation automatique.\n\nAssistance\n\nDisponibilité de la passerelle\n\nPlusieurs boutiques et un prix de base USD unique\n\nChoisissez Toutes les boutiques pour les analyses et opérations agrégées, ou sélectionnez une boutique pour ses propres enregistrements. Chaque boutique possède un storeId, un nom, une TVA par défaut, des factures, des clés API, des points de terminaison webhook, un historique d'événements et une application de site Web distincts. Les notifications et les tickets de support appartiennent au compte. Un compte peut créer jusqu'à 100 boutiques. Les enregistrements existants restent dans sa première boutique.\n\nLes factures du nouvel espace de travail utilisent pricingMode=\"universal\" et un prix de base en USD. Any inclut carte, alipay, sbp et crypto ; un commerçant peut sélectionner un sous-ensemble. Les cartes et Alipay facturent en USD. SBP facture en RUB en utilisant le taux de référence USD/RUB de la Banque de Russie. La crypto facture en USDT selon la règle de facturation explicite 1 USD = 1 USDT. Il s'agit d'une règle de conversion de facturation, pas d'une cotation USDT de marché. La passerelle fournit le taux de la pièce sélectionnée, le montant exact du transfert et les instructions avant le transfert.\n\nLe taux de référence et les deux montants sont gelés à la création. Les factures impliquant une conversion RUB expirent dans les 24 heures. Si le taux de référence ne peut pas être obtenu, la création échoue avec FX_UNAVAILABLE ; aucun taux de secours inventé ou obsolète n'est utilisé. Le montant en monnaie mineure du propriétaire et les cotations utilisent la monnaie comptable USD. quotes[method].settlement contient la cotation de frais native. Le paiement public expose la monnaie de frais sélectionnée dans currency, le prix d'origine dans baseAmountMinor/baseCurrency, et le taux de référence dans fx. Une fois qu'un paiement a été envoyé, sa méthode ne peut pas être modifiée ; une facture a une seule opération de passerelle.\n\nCréez une clé API dans la boutique prévue et envoyez Authorization: Bearer <key> depuis votre serveur. Sa liaison de boutique est immuable ; X-Kevmi-Store ne peut pas lui accorder l'accès à une autre boutique. Les sessions de navigateur sélectionnent X-Kevmi-Store: <storeId> ; si omis, la première boutique est sélectionnée. La valeur all n'est acceptée que par GET /api/account/dashboard et GET /api/payment-links. Les mutations nécessitent une boutique sélectionnée, Origin et X-CSRF-Token. Les identifiants de compte et les identifiants de boutique sont des identifiants différents.\n\nPour la compatibilité, les demandes API sans pricingMode=\"universal\" conservent la tarification native et les restrictions de monnaie d'origine. Les factures existantes ne sont jamais recalculées. Les reçus confirmés dans les analyses reflètent les paiements vérifiés moins les dépenses de facture enregistrées ; ils ne constituent pas un solde retirable. Les monnaies de facture héritées restent séparées et les paiements sont organisés avec le support. Exécutez une commande uniquement après avoir vérifié payment.fulfillmentReady=true et payment.status=\"succeeded\" via l'API serveur, l'historique d'événements ou un webhook signé.",
      "readMinutes": 6
    }
  ],
  "facts": {
    "paymentType": "one_time",
    "subscriptionsSupported": false,
    "incomingFees": {
      "card": {
        "percent": 10,
        "fixedUsdMinor": 50,
        "vatApplies": true
      },
      "alipay": {
        "percent": 10,
        "fixedUsdMinor": 50,
        "vatApplies": true
      },
      "sbp": {
        "percent": 8,
        "fixedUsdMinor": 0,
        "vatApplies": false
      },
      "crypto": {
        "percent": 4,
        "fixedUsdMinor": 0,
        "vatApplies": false
      }
    },
    "vat": {
      "ratePercent": 16,
      "base": "order_base_amount",
      "defaultPayer": "customer",
      "payerOptions": [
        "customer",
        "merchant",
        "shared"
      ],
      "customerPercentRange": [
        0,
        100
      ],
      "customerPercentStep": 1,
      "feeBase": "order_base_amount",
      "source": "owner_confirmed",
      "example": {
        "baseUsdMinor": 500,
        "feeUsdMinor": 100,
        "vatUsdMinor": 80,
        "customerPayer": {
          "chargedUsdMinor": 580,
          "merchantNetUsdMinor": 400
        },
        "merchantPayer": {
          "chargedUsdMinor": 500,
          "merchantNetUsdMinor": 320
        }
      }
    },
    "payout": {
      "asset": "USDT",
      "network": "TRC20",
      "sourceFees": {
        "card": "4%",
        "alipay": "4%",
        "sbp": "5% + RUB 400",
        "crypto": "0% + $3"
      },
      "creationImplemented": false,
      "gatewayBalanceIsMerchantLedger": false,
      "fixedCryptoFeeCurrency": "USD"
    },
    "costSharing": {
      "pricingVersion": 2,
      "independent": [
        "vatCustomerPercent",
        "feeCustomerPercent"
      ],
      "range": [
        0,
        100
      ],
      "step": 1,
      "defaultVatCustomerPercent": 100,
      "defaultFeeCustomerPercent": 0,
      "customerSharesAddedToCharge": true,
      "merchantSharesDeductedFromBase": true,
      "rounding": "half_up_customer_share_then_exact_merchant_remainder",
      "invoiceTermsImmutable": true,
      "liveGatewayAllocation": {
        "card": {
          "vatCustomerPercent": 100,
          "feeCustomerPercent": 0
        },
        "alipay": {
          "vatCustomerPercent": 100,
          "feeCustomerPercent": 0
        },
        "sbp": {
          "feeCustomerPercent": [
            0,
            100
          ],
          "vatApplies": false
        },
        "crypto": {
          "feeCustomerPercent": [
            0,
            100
          ],
          "vatApplies": false
        },
        "otherSavedCardSplitsExecutable": false
      },
      "example": {
        "baseUsdMinor": 500,
        "vatCustomerPercent": 50,
        "feeCustomerPercent": 23,
        "customerVatMinor": 40,
        "customerFeeMinor": 23,
        "customerTotalMinor": 563,
        "merchantNetMinor": 383
      }
    },
    "paymentLinks": {
      "methodSelection": "customer_from_invoice_methods",
      "interfaceAnyMode": "all_methods_for_invoice_currency",
      "allowedMethodsByCurrency": {
        "USD": [
          "card",
          "alipay"
        ],
        "RUB": [
          "sbp"
        ],
        "USDT": [
          "crypto"
        ]
      },
      "apiCreateField": "methods",
      "legacyUsdCryptoApiSaveAccepted": true,
      "legacyUsdCryptoExecutable": false,
      "cryptoRequiresExplicitUsdt": true,
      "ownerGetPaymentField": "payment",
      "ownerGetPaymentNullable": true,
      "createAndPatchPaymentSummaryOptional": true,
      "apiAnyValueSupported": false,
      "quotesPerMethod": true,
      "automaticCurrencyConversion": false
    },
    "merchantAPI": {
      "basePath": "/api/v1",
      "createInvoicePath": "/api/v1/payments",
      "createsCharge": false,
      "returnsCheckoutUrl": true,
      "scopes": [
        "invoices:read",
        "invoices:write",
        "events:read"
      ],
      "defaultKeyLifetimeDays": 90,
      "maximumActiveKeys": 10,
      "keysStoredAsHashes": true
    },
    "widgets": {
      "script": "/widgets/kevmi.js",
      "modes": [
        "modal",
        "inline",
        "redirect"
      ],
      "publicCheckoutUrlOnly": true,
      "browserMessagesConfirmPayment": false
    },
    "webhooks": {
      "events": [
        "invoice.created",
        "invoice.updated",
        "payment.succeeded",
        "payment.failed",
        "payment.refunded",
        "payment.partially_refunded",
        "payment.disputed",
        "payment.review_required"
      ],
      "signatureHeader": "Kevmi-Signature",
      "signatureAlgorithm": "HMAC-SHA256",
      "signatureInput": "timestamp.rawBody",
      "timestampToleranceSeconds": 300,
      "delivery": "at_least_once",
      "maximumAttempts": 6,
      "retryDelaySeconds": [
        60,
        300,
        1800,
        7200,
        43200
      ],
      "endpointVerificationRequired": true,
      "paymentSource": "validated_gateway_receipt",
      "financialStatusFromBrowser": false
    },
    "applications": {
      "path": "/account#applications",
      "trackingPath": "/account#applications/{id}",
      "authentication": "telegram_session",
      "visibility": "owner_and_moderators",
      "stages": [
        "received",
        "ai_review",
        "technical_review",
        "manual_review"
      ],
      "manualFinalDecisionRequired": true,
      "businessTypes": [
        "digital_goods",
        "software",
        "services",
        "physical_goods",
        "education",
        "other"
      ],
      "submissionLimitPerDay": 5,
      "resumeLimitPerMinute": 30,
      "moderationLimitPerMinute": 30,
      "aiReviewsPerHour": 30,
      "unknownAutomatedResults": "needs_review",
      "checks": "bounded_public_content_and_same_origin_links",
      "safetyGuarantee": false,
      "notificationCategory": "support",
      "approvalActivatesGateway": false,
      "latestApprovalRequiredForNewPayment": true,
      "invoiceCreationBeforeApproval": true,
      "existingOperationReadableAfterApprovalChange": true
    },
    "countries": {
      "card": {
        "countryCount": 223,
        "ownerReportedCountryCount": null,
        "coverageLabel": "190+",
        "restrictions": [
          {
            "code": "AF",
            "name": "Afghanistan",
            "nameEn": "Afghanistan"
          },
          {
            "code": "AQ",
            "name": "Antarctica",
            "nameEn": "Antarctica"
          },
          {
            "code": "BY",
            "name": "Belarus",
            "nameEn": "Belarus"
          },
          {
            "code": "MM",
            "name": "Burma (Myanmar)",
            "nameEn": "Burma (Myanmar)"
          },
          {
            "code": "BI",
            "name": "Burundi",
            "nameEn": "Burundi"
          },
          {
            "code": "CF",
            "name": "Central African Republic",
            "nameEn": "Central African Republic"
          },
          {
            "code": "TD",
            "name": "Chad",
            "nameEn": "Chad"
          },
          {
            "code": "CU",
            "name": "Cuba",
            "nameEn": "Cuba"
          },
          {
            "code": "CD",
            "name": "Democratic Republic of Congo",
            "nameEn": "Democratic Republic of Congo"
          },
          {
            "code": "CG",
            "name": "Republic of Congo",
            "nameEn": "Republic of Congo"
          },
          {
            "code": "ER",
            "name": "Eritrea",
            "nameEn": "Eritrea"
          },
          {
            "code": "HT",
            "name": "Haiti",
            "nameEn": "Haiti"
          },
          {
            "code": "IR",
            "name": "Iran",
            "nameEn": "Iran"
          },
          {
            "code": "IQ",
            "name": "Iraq",
            "nameEn": "Iraq"
          },
          {
            "code": "LY",
            "name": "Libya",
            "nameEn": "Libya"
          },
          {
            "code": "ML",
            "name": "Mali",
            "nameEn": "Mali"
          },
          {
            "code": "NI",
            "name": "Nicaragua",
            "nameEn": "Nicaragua"
          },
          {
            "code": "KP",
            "name": "North Korea",
            "nameEn": "North Korea"
          },
          {
            "code": "RU",
            "name": "Russia",
            "nameEn": "Russia"
          },
          {
            "code": "SO",
            "name": "Somalia",
            "nameEn": "Somalia"
          },
          {
            "code": "SS",
            "name": "South Sudan",
            "nameEn": "South Sudan"
          },
          {
            "code": "SD",
            "name": "Sudan",
            "nameEn": "Sudan"
          },
          {
            "code": "SY",
            "name": "Syria",
            "nameEn": "Syria"
          },
          {
            "code": "VE",
            "name": "Venezuela",
            "nameEn": "Venezuela"
          },
          {
            "code": "YE",
            "name": "Yemen",
            "nameEn": "Yemen"
          },
          {
            "code": "ZW",
            "name": "Zimbabwe",
            "nameEn": "Zimbabwe"
          },
          {
            "code": "UA-43",
            "countryCode": "UA",
            "name": "Crimea (Region of Ukraine)",
            "nameEn": "Crimea (Region of Ukraine)"
          },
          {
            "code": "UA-14",
            "countryCode": "UA",
            "name": "Donetsk (Region of Ukraine)",
            "nameEn": "Donetsk (Region of Ukraine)"
          },
          {
            "code": "UA-65",
            "countryCode": "UA",
            "name": "Kherson (Region of Ukraine)",
            "nameEn": "Kherson (Region of Ukraine)"
          },
          {
            "code": "UA-09",
            "countryCode": "UA",
            "name": "Luhansk (Region of Ukraine)",
            "nameEn": "Luhansk (Region of Ukraine)"
          },
          {
            "code": "UA-23",
            "countryCode": "UA",
            "name": "Zaporizhzhia (Region of Ukraine)",
            "nameEn": "Zaporizhzhia (Region of Ukraine)"
          },
          {
            "code": "AN",
            "name": "Netherlands Antilles",
            "nameEn": "Netherlands Antilles"
          }
        ],
        "verifiedCountryCount": null,
        "exactList": [
          "AX",
          "AL",
          "DZ",
          "AS",
          "AD",
          "AO",
          "AI",
          "AG",
          "AR",
          "AM",
          "AW",
          "AU",
          "AT",
          "AZ",
          "BS",
          "BH",
          "BD",
          "BB",
          "BE",
          "BZ",
          "BJ",
          "BM",
          "BT",
          "BO",
          "BQ",
          "BA",
          "BW",
          "BV",
          "BR",
          "IO",
          "BN",
          "BG",
          "BF",
          "CV",
          "KH",
          "CM",
          "CA",
          "KY",
          "CL",
          "CN",
          "CX",
          "CC",
          "CO",
          "KM",
          "CK",
          "CR",
          "HR",
          "CW",
          "CY",
          "CZ",
          "CI",
          "DK",
          "DJ",
          "DM",
          "DO",
          "EC",
          "EG",
          "SV",
          "GQ",
          "EE",
          "SZ",
          "ET",
          "FK",
          "FO",
          "FM",
          "FJ",
          "FI",
          "FR",
          "GF",
          "PF",
          "TF",
          "GA",
          "GM",
          "GE",
          "DE",
          "GH",
          "GI",
          "GR",
          "GL",
          "GD",
          "GP",
          "GU",
          "GT",
          "GG",
          "GN",
          "GW",
          "GY",
          "HM",
          "VA",
          "HN",
          "HK",
          "HU",
          "IS",
          "IN",
          "ID",
          "IE",
          "IM",
          "IL",
          "IT",
          "JM",
          "JP",
          "JE",
          "JO",
          "KZ",
          "KE",
          "KI",
          "KW",
          "KG",
          "LA",
          "LV",
          "LB",
          "LS",
          "LR",
          "LI",
          "LT",
          "LU",
          "MO",
          "MG",
          "MW",
          "MY",
          "MV",
          "MT",
          "MH",
          "MQ",
          "MR",
          "MU",
          "YT",
          "MX",
          "MD",
          "MC",
          "MN",
          "ME",
          "MS",
          "MA",
          "MZ",
          "NA",
          "NR",
          "NP",
          "NL",
          "NC",
          "NZ",
          "NE",
          "NG",
          "NU",
          "NF",
          "MK",
          "MP",
          "NO",
          "OM",
          "PK",
          "PW",
          "PA",
          "PG",
          "PY",
          "PE",
          "PH",
          "PN",
          "PL",
          "PT",
          "PR",
          "QA",
          "RO",
          "RW",
          "RE",
          "BL",
          "SH",
          "KN",
          "LC",
          "MF",
          "PM",
          "VC",
          "WS",
          "SM",
          "ST",
          "SA",
          "SN",
          "RS",
          "SC",
          "SL",
          "SG",
          "SX",
          "SK",
          "SI",
          "SB",
          "ZA",
          "GS",
          "KR",
          "ES",
          "LK",
          "PS",
          "SR",
          "SJ",
          "SE",
          "CH",
          "TW",
          "TJ",
          "TZ",
          "TH",
          "TL",
          "TG",
          "TK",
          "TO",
          "TT",
          "TN",
          "TM",
          "TC",
          "TV",
          "TR",
          "UG",
          "UA",
          "AE",
          "GB",
          "UM",
          "US",
          "UY",
          "UZ",
          "VU",
          "VN",
          "VG",
          "VI",
          "WF",
          "EH",
          "ZM"
        ],
        "records": [
          {
            "code": "AX",
            "name": "Îles Åland",
            "nameEn": "Åland Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AL",
            "name": "Albanie",
            "nameEn": "Albania",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "DZ",
            "name": "Algérie",
            "nameEn": "Algeria",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AS",
            "name": "Samoa américaines",
            "nameEn": "American Samoa",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AD",
            "name": "Andorre",
            "nameEn": "Andorra",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AO",
            "name": "Angola",
            "nameEn": "Angola",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AI",
            "name": "Anguilla",
            "nameEn": "Anguilla",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AG",
            "name": "Antigua-et-Barbuda",
            "nameEn": "Antigua & Barbuda",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AR",
            "name": "Argentine",
            "nameEn": "Argentina",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AM",
            "name": "Arménie",
            "nameEn": "Armenia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AW",
            "name": "Aruba",
            "nameEn": "Aruba",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AU",
            "name": "Australie",
            "nameEn": "Australia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AT",
            "name": "Autriche",
            "nameEn": "Austria",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AZ",
            "name": "Azerbaïdjan",
            "nameEn": "Azerbaijan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BS",
            "name": "Bahamas",
            "nameEn": "Bahamas",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BH",
            "name": "Bahreïn",
            "nameEn": "Bahrain",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BD",
            "name": "Bangladesh",
            "nameEn": "Bangladesh",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BB",
            "name": "Barbade",
            "nameEn": "Barbados",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BE",
            "name": "Belgique",
            "nameEn": "Belgium",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BZ",
            "name": "Belize",
            "nameEn": "Belize",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BJ",
            "name": "Bénin",
            "nameEn": "Benin",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BM",
            "name": "Bermudes",
            "nameEn": "Bermuda",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BT",
            "name": "Bhoutan",
            "nameEn": "Bhutan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BO",
            "name": "Bolivie",
            "nameEn": "Bolivia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BQ",
            "name": "Pays-Bas caribéens",
            "nameEn": "Caribbean Netherlands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BA",
            "name": "Bosnie-Herzégovine",
            "nameEn": "Bosnia & Herzegovina",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BW",
            "name": "Botswana",
            "nameEn": "Botswana",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BV",
            "name": "Île Bouvet",
            "nameEn": "Bouvet Island",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BR",
            "name": "Brésil",
            "nameEn": "Brazil",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IO",
            "name": "Territoire britannique de l’océan Indien",
            "nameEn": "British Indian Ocean Territory",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BN",
            "name": "Brunei",
            "nameEn": "Brunei",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BG",
            "name": "Bulgarie",
            "nameEn": "Bulgaria",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BF",
            "name": "Burkina Faso",
            "nameEn": "Burkina Faso",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CV",
            "name": "Cap-Vert",
            "nameEn": "Cape Verde",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KH",
            "name": "Cambodge",
            "nameEn": "Cambodia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CM",
            "name": "Cameroun",
            "nameEn": "Cameroon",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CA",
            "name": "Canada",
            "nameEn": "Canada",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KY",
            "name": "Îles Caïmans",
            "nameEn": "Cayman Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CL",
            "name": "Chili",
            "nameEn": "Chile",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CN",
            "name": "Chine",
            "nameEn": "China",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CX",
            "name": "Île Christmas",
            "nameEn": "Christmas Island",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CC",
            "name": "Îles Cocos",
            "nameEn": "Cocos (Keeling) Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CO",
            "name": "Colombie",
            "nameEn": "Colombia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KM",
            "name": "Comores",
            "nameEn": "Comoros",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CK",
            "name": "Îles Cook",
            "nameEn": "Cook Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CR",
            "name": "Costa Rica",
            "nameEn": "Costa Rica",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "HR",
            "name": "Croatie",
            "nameEn": "Croatia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CW",
            "name": "Curaçao",
            "nameEn": "Curaçao",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CY",
            "name": "Chypre",
            "nameEn": "Cyprus",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CZ",
            "name": "Tchéquie",
            "nameEn": "Czechia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CI",
            "name": "Côte d’Ivoire",
            "nameEn": "Côte d’Ivoire",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "DK",
            "name": "Danemark",
            "nameEn": "Denmark",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "DJ",
            "name": "Djibouti",
            "nameEn": "Djibouti",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "DM",
            "name": "Dominique",
            "nameEn": "Dominica",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "DO",
            "name": "République dominicaine",
            "nameEn": "Dominican Republic",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "EC",
            "name": "Équateur",
            "nameEn": "Ecuador",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "EG",
            "name": "Égypte",
            "nameEn": "Egypt",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SV",
            "name": "Salvador",
            "nameEn": "El Salvador",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GQ",
            "name": "Guinée équatoriale",
            "nameEn": "Equatorial Guinea",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "EE",
            "name": "Estonie",
            "nameEn": "Estonia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SZ",
            "name": "Eswatini",
            "nameEn": "Eswatini",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ET",
            "name": "Éthiopie",
            "nameEn": "Ethiopia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "FK",
            "name": "Îles Malouines",
            "nameEn": "Falkland Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "FO",
            "name": "Îles Féroé",
            "nameEn": "Faroe Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "FM",
            "name": "Micronésie",
            "nameEn": "Micronesia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "FJ",
            "name": "Fidji",
            "nameEn": "Fiji",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "FI",
            "name": "Finlande",
            "nameEn": "Finland",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "FR",
            "name": "France",
            "nameEn": "France",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GF",
            "name": "Guyane française",
            "nameEn": "French Guiana",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PF",
            "name": "Polynésie française",
            "nameEn": "French Polynesia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TF",
            "name": "Terres australes françaises",
            "nameEn": "French Southern Territories",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GA",
            "name": "Gabon",
            "nameEn": "Gabon",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GM",
            "name": "Gambie",
            "nameEn": "Gambia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GE",
            "name": "Géorgie",
            "nameEn": "Georgia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "DE",
            "name": "Allemagne",
            "nameEn": "Germany",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GH",
            "name": "Ghana",
            "nameEn": "Ghana",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GI",
            "name": "Gibraltar",
            "nameEn": "Gibraltar",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GR",
            "name": "Grèce",
            "nameEn": "Greece",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GL",
            "name": "Groenland",
            "nameEn": "Greenland",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GD",
            "name": "Grenade",
            "nameEn": "Grenada",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GP",
            "name": "Guadeloupe",
            "nameEn": "Guadeloupe",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GU",
            "name": "Guam",
            "nameEn": "Guam",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GT",
            "name": "Guatemala",
            "nameEn": "Guatemala",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GG",
            "name": "Guernesey",
            "nameEn": "Guernsey",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GN",
            "name": "Guinée",
            "nameEn": "Guinea",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GW",
            "name": "Guinée-Bissau",
            "nameEn": "Guinea-Bissau",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GY",
            "name": "Guyana",
            "nameEn": "Guyana",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "HM",
            "name": "Îles Heard-et-MacDonald",
            "nameEn": "Heard & McDonald Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "VA",
            "name": "État de la Cité du Vatican",
            "nameEn": "Vatican City",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "HN",
            "name": "Honduras",
            "nameEn": "Honduras",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "HK",
            "name": "R.A.S. chinoise de Hong Kong",
            "nameEn": "Hong Kong SAR China",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "HU",
            "name": "Hongrie",
            "nameEn": "Hungary",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IS",
            "name": "Islande",
            "nameEn": "Iceland",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IN",
            "name": "Inde",
            "nameEn": "India",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ID",
            "name": "Indonésie",
            "nameEn": "Indonesia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IE",
            "name": "Irlande",
            "nameEn": "Ireland",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IM",
            "name": "Île de Man",
            "nameEn": "Isle of Man",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IL",
            "name": "Israël",
            "nameEn": "Israel",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IT",
            "name": "Italie",
            "nameEn": "Italy",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "JM",
            "name": "Jamaïque",
            "nameEn": "Jamaica",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "JP",
            "name": "Japon",
            "nameEn": "Japan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "JE",
            "name": "Jersey",
            "nameEn": "Jersey",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "JO",
            "name": "Jordanie",
            "nameEn": "Jordan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KZ",
            "name": "Kazakhstan",
            "nameEn": "Kazakhstan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KE",
            "name": "Kenya",
            "nameEn": "Kenya",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KI",
            "name": "Kiribati",
            "nameEn": "Kiribati",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KW",
            "name": "Koweït",
            "nameEn": "Kuwait",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KG",
            "name": "Kirghizstan",
            "nameEn": "Kyrgyzstan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LA",
            "name": "Laos",
            "nameEn": "Laos",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LV",
            "name": "Lettonie",
            "nameEn": "Latvia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LB",
            "name": "Liban",
            "nameEn": "Lebanon",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LS",
            "name": "Lesotho",
            "nameEn": "Lesotho",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LR",
            "name": "Liberia",
            "nameEn": "Liberia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LI",
            "name": "Liechtenstein",
            "nameEn": "Liechtenstein",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LT",
            "name": "Lituanie",
            "nameEn": "Lithuania",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LU",
            "name": "Luxembourg",
            "nameEn": "Luxembourg",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MO",
            "name": "R.A.S. chinoise de Macao",
            "nameEn": "Macao SAR China",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MG",
            "name": "Madagascar",
            "nameEn": "Madagascar",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MW",
            "name": "Malawi",
            "nameEn": "Malawi",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MY",
            "name": "Malaisie",
            "nameEn": "Malaysia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MV",
            "name": "Maldives",
            "nameEn": "Maldives",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MT",
            "name": "Malte",
            "nameEn": "Malta",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MH",
            "name": "Îles Marshall",
            "nameEn": "Marshall Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MQ",
            "name": "Martinique",
            "nameEn": "Martinique",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MR",
            "name": "Mauritanie",
            "nameEn": "Mauritania",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MU",
            "name": "Maurice",
            "nameEn": "Mauritius",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "YT",
            "name": "Mayotte",
            "nameEn": "Mayotte",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MX",
            "name": "Mexique",
            "nameEn": "Mexico",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MD",
            "name": "Moldavie",
            "nameEn": "Moldova",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MC",
            "name": "Monaco",
            "nameEn": "Monaco",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MN",
            "name": "Mongolie",
            "nameEn": "Mongolia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ME",
            "name": "Monténégro",
            "nameEn": "Montenegro",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MS",
            "name": "Montserrat",
            "nameEn": "Montserrat",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MA",
            "name": "Maroc",
            "nameEn": "Morocco",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MZ",
            "name": "Mozambique",
            "nameEn": "Mozambique",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NA",
            "name": "Namibie",
            "nameEn": "Namibia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NR",
            "name": "Nauru",
            "nameEn": "Nauru",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NP",
            "name": "Népal",
            "nameEn": "Nepal",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NL",
            "name": "Pays-Bas",
            "nameEn": "Netherlands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NC",
            "name": "Nouvelle-Calédonie",
            "nameEn": "New Caledonia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NZ",
            "name": "Nouvelle-Zélande",
            "nameEn": "New Zealand",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NE",
            "name": "Niger",
            "nameEn": "Niger",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NG",
            "name": "Nigeria",
            "nameEn": "Nigeria",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NU",
            "name": "Niue",
            "nameEn": "Niue",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NF",
            "name": "Île Norfolk",
            "nameEn": "Norfolk Island",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MK",
            "name": "Macédoine du Nord",
            "nameEn": "North Macedonia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MP",
            "name": "Îles Mariannes du Nord",
            "nameEn": "Northern Mariana Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NO",
            "name": "Norvège",
            "nameEn": "Norway",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "OM",
            "name": "Oman",
            "nameEn": "Oman",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PK",
            "name": "Pakistan",
            "nameEn": "Pakistan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PW",
            "name": "Palaos",
            "nameEn": "Palau",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PA",
            "name": "Panama",
            "nameEn": "Panama",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PG",
            "name": "Papouasie-Nouvelle-Guinée",
            "nameEn": "Papua New Guinea",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PY",
            "name": "Paraguay",
            "nameEn": "Paraguay",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PE",
            "name": "Pérou",
            "nameEn": "Peru",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PH",
            "name": "Philippines",
            "nameEn": "Philippines",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PN",
            "name": "Îles Pitcairn",
            "nameEn": "Pitcairn Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PL",
            "name": "Pologne",
            "nameEn": "Poland",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PT",
            "name": "Portugal",
            "nameEn": "Portugal",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PR",
            "name": "Porto Rico",
            "nameEn": "Puerto Rico",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "QA",
            "name": "Qatar",
            "nameEn": "Qatar",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "RO",
            "name": "Roumanie",
            "nameEn": "Romania",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "RW",
            "name": "Rwanda",
            "nameEn": "Rwanda",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "RE",
            "name": "La Réunion",
            "nameEn": "Réunion",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BL",
            "name": "Saint-Barthélemy",
            "nameEn": "St. Barthélemy",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SH",
            "name": "Sainte-Hélène",
            "nameEn": "St. Helena",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KN",
            "name": "Saint-Christophe-et-Niévès",
            "nameEn": "St. Kitts & Nevis",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LC",
            "name": "Sainte-Lucie",
            "nameEn": "St. Lucia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MF",
            "name": "Saint-Martin",
            "nameEn": "St. Martin",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PM",
            "name": "Saint-Pierre-et-Miquelon",
            "nameEn": "St. Pierre & Miquelon",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "VC",
            "name": "Saint-Vincent-et-les Grenadines",
            "nameEn": "St. Vincent & Grenadines",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "WS",
            "name": "Samoa",
            "nameEn": "Samoa",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SM",
            "name": "Saint-Marin",
            "nameEn": "San Marino",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ST",
            "name": "Sao Tomé-et-Principe",
            "nameEn": "São Tomé & Príncipe",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SA",
            "name": "Arabie saoudite",
            "nameEn": "Saudi Arabia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SN",
            "name": "Sénégal",
            "nameEn": "Senegal",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "RS",
            "name": "Serbie",
            "nameEn": "Serbia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SC",
            "name": "Seychelles",
            "nameEn": "Seychelles",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SL",
            "name": "Sierra Leone",
            "nameEn": "Sierra Leone",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SG",
            "name": "Singapour",
            "nameEn": "Singapore",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SX",
            "name": "Saint-Martin (partie néerlandaise)",
            "nameEn": "Sint Maarten",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SK",
            "name": "Slovaquie",
            "nameEn": "Slovakia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SI",
            "name": "Slovénie",
            "nameEn": "Slovenia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SB",
            "name": "Îles Salomon",
            "nameEn": "Solomon Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ZA",
            "name": "Afrique du Sud",
            "nameEn": "South Africa",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GS",
            "name": "Géorgie du Sud-et-les Îles Sandwich du Sud",
            "nameEn": "South Georgia & South Sandwich Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KR",
            "name": "Corée du Sud",
            "nameEn": "South Korea",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ES",
            "name": "Espagne",
            "nameEn": "Spain",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LK",
            "name": "Sri Lanka",
            "nameEn": "Sri Lanka",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PS",
            "name": "Territoires palestiniens",
            "nameEn": "Palestinian Territories",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SR",
            "name": "Suriname",
            "nameEn": "Suriname",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SJ",
            "name": "Svalbard et Jan Mayen",
            "nameEn": "Svalbard & Jan Mayen",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SE",
            "name": "Suède",
            "nameEn": "Sweden",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CH",
            "name": "Suisse",
            "nameEn": "Switzerland",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TW",
            "name": "Taïwan",
            "nameEn": "Taiwan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TJ",
            "name": "Tadjikistan",
            "nameEn": "Tajikistan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TZ",
            "name": "Tanzanie",
            "nameEn": "Tanzania",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TH",
            "name": "Thaïlande",
            "nameEn": "Thailand",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TL",
            "name": "Timor oriental",
            "nameEn": "Timor-Leste",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TG",
            "name": "Togo",
            "nameEn": "Togo",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TK",
            "name": "Tokelau",
            "nameEn": "Tokelau",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TO",
            "name": "Tonga",
            "nameEn": "Tonga",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TT",
            "name": "Trinité-et-Tobago",
            "nameEn": "Trinidad & Tobago",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TN",
            "name": "Tunisie",
            "nameEn": "Tunisia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TM",
            "name": "Turkménistan",
            "nameEn": "Turkmenistan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TC",
            "name": "Îles Turques-et-Caïques",
            "nameEn": "Turks & Caicos Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TV",
            "name": "Tuvalu",
            "nameEn": "Tuvalu",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TR",
            "name": "Turquie",
            "nameEn": "Türkiye",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "UG",
            "name": "Ouganda",
            "nameEn": "Uganda",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "UA",
            "name": "Ukraine",
            "nameEn": "Ukraine",
            "marker": "**",
            "coverage": "partial_locations",
            "note": "Les cartes sont indisponibles en Crimée, à Donetsk, à Louhansk, à Kherson et à Zaporijjia. Le reste de l'Ukraine est disponible."
          },
          {
            "code": "AE",
            "name": "Émirats arabes unis",
            "nameEn": "United Arab Emirates",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GB",
            "name": "Royaume-Uni",
            "nameEn": "United Kingdom",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "UM",
            "name": "Îles mineures éloignées des États-Unis",
            "nameEn": "U.S. Outlying Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "US",
            "name": "États-Unis",
            "nameEn": "United States",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "UY",
            "name": "Uruguay",
            "nameEn": "Uruguay",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "UZ",
            "name": "Ouzbékistan",
            "nameEn": "Uzbekistan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "VU",
            "name": "Vanuatu",
            "nameEn": "Vanuatu",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "VN",
            "name": "Viêt Nam",
            "nameEn": "Vietnam",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "VG",
            "name": "Îles Vierges britanniques",
            "nameEn": "British Virgin Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "VI",
            "name": "Îles Vierges des États-Unis",
            "nameEn": "U.S. Virgin Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "WF",
            "name": "Wallis-et-Futuna",
            "nameEn": "Wallis & Futuna",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "EH",
            "name": "Sahara occidental",
            "nameEn": "Western Sahara",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ZM",
            "name": "Zambie",
            "nameEn": "Zambia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          }
        ],
        "source": "owner_provided",
        "status": "owner_list_received",
        "policy": "worldwide_except_restrictions",
        "independentlyVerified": false,
        "partialCoverage": {
          "marker": "**",
          "countryCodes": [
            "UA"
          ],
          "note": "Les cartes sont indisponibles en Crimée, à Donetsk, à Louhansk, à Kherson et à Zaporijjia. Le reste de l'Ukraine est disponible."
        },
        "unresolvedFootnotes": [],
        "approvalGuaranteed": false
      },
      "sbp": [
        "RU"
      ],
      "alipay": [
        "CN"
      ],
      "crypto": {
        "exactList": null,
        "status": "live_catalog_required",
        "invoiceCurrency": "USDT",
        "cataloguePath": "/api/checkout/{token}/crypto-services"
      }
    },
    "cryptoAcceptance": {
      "invoiceCurrency": "USDT",
      "coinCount": 16,
      "pairCount": 31,
      "pairs": [
        {
          "currency": "AVAX",
          "network": "avalanche",
          "networkLabel": "Avalanche C-Chain"
        },
        {
          "currency": "BCH",
          "network": "bch",
          "networkLabel": "Bitcoin Cash"
        },
        {
          "currency": "BNB",
          "network": "bsc",
          "networkLabel": "BNB Smart Chain"
        },
        {
          "currency": "BTC",
          "network": "btc",
          "networkLabel": "Bitcoin"
        },
        {
          "currency": "DAI",
          "network": "bsc",
          "networkLabel": "BNB Smart Chain"
        },
        {
          "currency": "DAI",
          "network": "eth",
          "networkLabel": "Ethereum"
        },
        {
          "currency": "DAI",
          "network": "polygon",
          "networkLabel": "Polygon PoS"
        },
        {
          "currency": "DASH",
          "network": "dash",
          "networkLabel": "Dash"
        },
        {
          "currency": "DOGE",
          "network": "doge",
          "networkLabel": "Dogecoin"
        },
        {
          "currency": "ETH",
          "network": "eth",
          "networkLabel": "Ethereum"
        },
        {
          "currency": "ETH",
          "network": "arbitrum",
          "networkLabel": "Arbitrum One"
        },
        {
          "currency": "ETH",
          "network": "bsc",
          "networkLabel": "BNB Smart Chain"
        },
        {
          "currency": "GRAM",
          "network": "ton",
          "networkLabel": "TON"
        },
        {
          "currency": "LTC",
          "network": "ltc",
          "networkLabel": "Litecoin"
        },
        {
          "currency": "POL",
          "network": "eth",
          "networkLabel": "Ethereum"
        },
        {
          "currency": "POL",
          "network": "polygon",
          "networkLabel": "Polygon PoS"
        },
        {
          "currency": "SHIB",
          "network": "eth",
          "networkLabel": "Ethereum"
        },
        {
          "currency": "TRX",
          "network": "tron",
          "networkLabel": "TRON"
        },
        {
          "currency": "USDC",
          "network": "arbitrum",
          "networkLabel": "Arbitrum One"
        },
        {
          "currency": "USDC",
          "network": "bsc",
          "networkLabel": "BNB Smart Chain"
        },
        {
          "currency": "USDC",
          "network": "polygon",
          "networkLabel": "Polygon PoS"
        },
        {
          "currency": "USDC",
          "network": "eth",
          "networkLabel": "Ethereum"
        },
        {
          "currency": "USDC",
          "network": "avalanche",
          "networkLabel": "Avalanche C-Chain"
        },
        {
          "currency": "USDT",
          "network": "tron",
          "networkLabel": "TRON"
        },
        {
          "currency": "USDT",
          "network": "avalanche",
          "networkLabel": "Avalanche C-Chain"
        },
        {
          "currency": "USDT",
          "network": "bsc",
          "networkLabel": "BNB Smart Chain"
        },
        {
          "currency": "USDT",
          "network": "ton",
          "networkLabel": "TON"
        },
        {
          "currency": "USDT",
          "network": "polygon",
          "networkLabel": "Polygon PoS"
        },
        {
          "currency": "USDT",
          "network": "arbitrum",
          "networkLabel": "Arbitrum One"
        },
        {
          "currency": "USDT",
          "network": "eth",
          "networkLabel": "Ethereum"
        },
        {
          "currency": "XMR",
          "network": "xmr",
          "networkLabel": "Monero"
        }
      ],
      "catalogueSource": "owner_provided",
      "liveAvailabilitySource": "/api/checkout/{token}/crypto-services",
      "referenceCatalogueConfirmsAvailability": false,
      "transferInstructionsSource": "created_gateway_operation",
      "invoiceFixesOtherCoinExchangeRate": false,
      "exactTransferAmountRequired": true,
      "merchantPayout": {
        "asset": "USDT",
        "network": "TRC20",
        "distinctFromAcceptanceNetworks": true,
        "creationImplemented": false
      }
    },
    "support": {
      "knowledgeScope": "all_published_articles_and_facts",
      "articleCount": 25,
      "historyMessagesPerRequest": 6,
      "historyStorage": "browser_local_storage",
      "historySync": "device_only",
      "separateConversations": true,
      "perConversationDrafts": true,
      "pageContext": "safe_section_label_only",
      "privateAccountAccess": false,
      "financialActions": false,
      "fallback": "documentation_search",
      "readinessEndpoint": "/api/config"
    },
    "notifications": {
      "pageSize": 30,
      "readStateStorage": "server",
      "readStateAffectsTelegramDelivery": false,
      "readEndpoint": "/api/notifications/read"
    },
    "gatewayIntegration": {
      "adapterImplemented": true,
      "contract": "v3",
      "liveConfigurationProvided": null,
      "requiredEnvironment": [
        "GATEWAY_API_KEY",
        "GATEWAY_WEBHOOK_SECRET"
      ],
      "connectionModes": {
        "externalHttps": {
          "originEnvironment": "GATEWAY_BASE_URL"
        },
        "selfHostedService": {
          "capability": "GATEWAY_SERVICE",
          "fixedDestination": true,
          "publicGatewayApi": false
        }
      },
      "availability": {
        "source": "runtime",
        "configurationEndpoint": "/api/config",
        "configurationField": "gateway.configured",
        "configurationIncludesHealthCheck": false,
        "checkoutEndpoint": "/api/checkout/{token}",
        "checkoutField": "invoice.availability",
        "checkoutCompatibilityAlias": "invoice.gatewayConnected",
        "checkoutIncludesProviderApproval": false
      },
      "cardTransport": "browser_JWE_to_gateway",
      "cardPlaintextAcceptedByKevmi": false,
      "hostedCardApi": false,
      "sealedAlgorithms": [
        "RSA-OAEP-256",
        "A256GCM"
      ],
      "ingress": {
        "path": "/api/gateway/webhook",
        "signatureHeader": "X-Gateway-Signature",
        "timestampHeader": "X-Gateway-Timestamp",
        "eventIdHeader": "X-Gateway-Event-Id",
        "signatureAlgorithm": "HMAC-SHA256",
        "signatureInput": "timestamp.rawBody",
        "timestampToleranceSeconds": 300,
        "authenticatedOperationReadRequired": true
      },
      "successRequires": [
        "fulfillment_ready",
        "provider_confirmed",
        "exact_paid_amount",
        "no_dispute",
        "crypto_settlement_evidence_if_crypto"
      ],
      "statusDoesNotCharge": true,
      "reconciliationDoesNotCharge": true,
      "oneDispatchedOperationPerInvoice": true,
      "ledgerNotImplemented": true
    },
    "merchantWorkspace": {
      "multipleStores": true,
      "storeLimit": 100,
      "storeEndpoint": "/api/stores",
      "storeHeader": "X-Kevmi-Store",
      "aggregateReadOnly": true,
      "pricingMode": "universal",
      "baseCurrency": "USD",
      "sbpChargeCurrency": "RUB",
      "cryptoChargeCurrency": "USDT",
      "usdUsdtInvoiceRatio": "1:1",
      "referenceRateSource": "https://www.cbr.ru/scripts/XML_daily.asp",
      "fxInvoiceMaxHours": 24,
      "path": "/account",
      "sections": [
        "overview",
        "payments",
        "payouts",
        "pricing",
        "stores",
        "links",
        "applications",
        "keys",
        "webhooks",
        "widget",
        "events",
        "knowledge",
        "store",
        "notifications",
        "support"
      ]
    },
    "gatewayConnected": null,
    "limitsConfirmed": false,
    "scope": "Public product documentation only. No user records or secrets."
  },
  "locale": "fr",
  "docGroups": [
    {
      "id": "start",
      "title": "Premiers pas",
      "description": "De votre première visite à une boutique configurée.",
      "icon": "bolt"
    },
    {
      "id": "payments",
      "title": "Paiements et conditions",
      "description": "Liens, montants, TVA, moyens de paiement et versements.",
      "icon": "card"
    },
    {
      "id": "account",
      "title": "Compte et assistance",
      "description": "Telegram, notifications et aide pour vos questions.",
      "icon": "settings"
    },
    {
      "id": "developers",
      "title": "Développeurs",
      "description": "API, sécurité, webhooks et intégration de la passerelle.",
      "icon": "book"
    }
  ],
  "navPages": [
    {
      "href": "/",
      "title": "Vue d’ensemble",
      "icon": "grid"
    },
    {
      "href": "/payment-methods",
      "title": "Moyens de paiement",
      "icon": "card"
    },
    {
      "href": "/pricing",
      "title": "Tarifs",
      "icon": "percent"
    },
    {
      "href": "/payment-links",
      "title": "Liens de paiement",
      "icon": "link"
    },
    {
      "href": "/countries",
      "title": "Couverture",
      "icon": "globe"
    },
    {
      "href": "/docs",
      "title": "Documentation",
      "icon": "book"
    },
    {
      "href": "/?support=open",
      "title": "Assistance",
      "icon": "chat"
    },
    {
      "href": "/integrations",
      "title": "Intégrations",
      "icon": "code"
    }
  ],
  "paymentMethods": [
    {
      "id": "card",
      "name": "Cartes internationales",
      "shortName": "Cartes",
      "description": "Paiements par carte pour les clients internationaux.",
      "incomingPercent": 10,
      "incomingFixedMinor": 50,
      "incomingFixedCurrency": "USD",
      "payoutPercent": 4,
      "payoutFixedMinor": 0,
      "payoutFixedCurrency": "USD",
      "vatApplies": true,
      "region": "Paiements internationaux",
      "symbol": "card",
      "geography": "Visa et Mastercard depuis plus de 190 pays, excepté la liste des restrictions et cinq régions d'Ukraine.",
      "countryCount": 223,
      "ownerReportedCountryCount": null,
      "coverageLabel": "190+"
    },
    {
      "id": "sbp",
      "name": "SBP",
      "shortName": "SBP",
      "description": "Payez via une banque avec le système russe de paiements rapides.",
      "incomingPercent": 8,
      "incomingFixedMinor": 0,
      "incomingFixedCurrency": "RUB",
      "payoutPercent": 5,
      "payoutFixedMinor": 40000,
      "payoutFixedCurrency": "RUB",
      "vatApplies": false,
      "region": "Russie",
      "symbol": "sbp",
      "geography": "Russie. La disponibilité dépend de la banque et de la transaction.",
      "countryCount": 1
    },
    {
      "id": "alipay",
      "name": "Alipay",
      "shortName": "Alipay",
      "description": "Paiements Alipay pour les clients en Chine.",
      "incomingPercent": 10,
      "incomingFixedMinor": 50,
      "incomingFixedCurrency": "USD",
      "payoutPercent": 4,
      "payoutFixedMinor": 0,
      "payoutFixedCurrency": "USD",
      "vatApplies": true,
      "region": "Chine",
      "symbol": "alipay",
      "geography": "Chine. La disponibilité dépend du compte et de la transaction.",
      "countryCount": 1
    },
    {
      "id": "crypto",
      "name": "Cryptomonnaie",
      "shortName": "Crypto",
      "description": "Paiements ponctuels en cryptomonnaie avec 4 % de frais et sans TVA.",
      "incomingPercent": 4,
      "incomingFixedMinor": 0,
      "incomingFixedCurrency": "USD",
      "payoutPercent": 0,
      "payoutFixedMinor": 300,
      "payoutFixedCurrency": "USD",
      "vatApplies": false,
      "region": "Actifs numériques",
      "symbol": "crypto",
      "geography": "Tous les pays du monde. Choisissez une pièce prise en charge et un réseau. Les versements utilisent USDT TRC20.",
      "countryCount": null
    }
  ],
  "payoutFees": {
    "card": "4%",
    "alipay": "4%",
    "sbp": "5% + RUB 400",
    "crypto": "0% + $3"
  },
  "documentationLocale": "fr"
}
