Guide de l'opérateur
Sommaire
- 1. Ce que vous installez
- 2. Avant de commencer
- 3. Le compte de gros
- 4. Le serveur et le domaine
- 5. Récupérez le kit et configurez-le
- 6. Placez les clés
- 7. Démarrez en mode démo
- 8. Paiements
- 9. Agents et fédération
- 10. La commande test, puis la mise en vente
- 11. Au quotidien
- 12. Commandes des agents
- 13. Droit, taxes et conditions
- 14. Dépannage
Ce guide vous mène d'un serveur vide à votre première vente, puis couvre le travail quotidien : commandes, remboursements, solde, sauvegardes, mises à jour. Prévoyez une heure pour l'installation. L'essentiel de cette heure, c'est attendre le compte de gros et l'enregistrement DNS.
Autres documents : présentation · guide pour les agents · prise en main · intégrations · SDK
1. Ce que vous installez
https://esim.example.com
│
Caddy (80, 443, Let's Encrypt)
┌───────────────┼──────────────────────────────┐
│ │ │
store rails (/agents/*) node (/.well-known/ai-market.json, /ai-market/*)
achats des gens achats des agents via x402 les hubs trouvent vos offres
│ │
└──── votre solde eSIM Access ────┘ les paiements vont sur vos portefeuilles
- store est le site : pages par pays, paiement, page de commande avec le QR code.
- rails est le nœud vendeur pour les agents IA : offres gratuites, commandes payantes via x402.
- node est
aimarket node. Il indique aux hubs AIMarket ce que vous vendez, pour que les agents vous trouvent. Démarrez-le en dernier, quand tout le reste fonctionne. - Caddy obtient et renouvelle le certificat HTTPS et répartit les requêtes entre les trois services.
store et rails achètent sur le même compte de gros. Aucun des deux ne détient d'argent : les acheteurs paient à vos adresses, et le kit ne fait que lire les réseaux pour voir arriver les paiements.
2. Avant de commencer
| Il vous faut | Remarques |
|---|---|
| Un compte eSIM Access | Inscription sur esimaccess.com. Étape 3. |
| 50 $ ou plus sur le solde | La première recharge est d'au moins 50 $ (carte, PayPal ou Alipay ; virement bancaire à partir de 3 000 $). |
| Un serveur Linux | Docker Engine avec le plugin compose, une IPv4 publique, ports 80 et 443 ouverts. 1 vCPU et 1 Go de mémoire suffisent. |
| Un domaine ou sous-domaine | Par exemple esim.example.com, avec un enregistrement A vers le serveur. |
| Des adresses de portefeuille | EVM (une adresse pour les sept réseaux EVM), Tron, Solana, TON. N'importe quelle combinaison convient. |
| Des CGV et une politique de confidentialité | Deux pages publiques. eSIM Access attend que le site de chaque revendeur y renvoie. |
| Facultatif : une clé Coinbase Developer Platform | Active l'USDC sans gas sur Base pour les personnes et les commandes x402 des agents. Étape 8. |
| Facultatif : Stripe | Active les cartes. Étape 8. |
3. Le compte de gros
- Inscrivez-vous sur esimaccess.com et confirmez votre e-mail.
- Rechargez le solde (dans la console : solde, puis recharge). Le minimum est de 50 $. Chaque eSIM vendue est payée sur ce solde au prix de gros : c'est votre stock, pas une commission.
- Ouvrez la section développeur (API) de la console. Elle affiche deux valeurs : l'AccessCode et la SecretKey. Traitez la SecretKey comme un mot de passe.
Il n'y a pas de bac à sable : chaque commande API est réelle. Deux façons de tester à peu de frais :
- Commandez le forfait le moins cher (quelques dizaines de centimes), puis annulez le profil non utilisé. Les profils non utilisés sont remboursés sur le solde.
- Avant votre première recharge, demandez au support un petit crédit de test : Customer Support, puis Submit ticket, type « Top Up ». Expliquez que vous intégrez l'API et qu'il vous faut quelques dollars pour des commandes de test.
4. Le serveur et le domaine
- Créez un enregistrement A de votre domaine vers l'IPv4 du serveur. Vérifiez depuis votre ordinateur :
dig +short esim.example.com
- Installez Docker sur le serveur (docs.docker.com/engine/install) et vérifiez que compose fonctionne :
docker compose version
- Ouvrez les ports 80 et 443 dans le pare-feu du serveur et dans le panneau de votre hébergeur. Let's Encrypt vérifie le port 80 avant d'émettre le certificat.
5. Récupérez le kit et configurez-le
git clone https://github.com/alexar76/esim-operator-kit.git
cd esim-operator-kit
cp .env.example .env
nano .env
| Réglage | Quoi mettre |
|---|---|
DOMAIN | Votre domaine, sans https://. |
STORE_NAME | Le nom que voient les acheteurs dans l'en-tête, le titre et la fenêtre du portefeuille. |
PRODUCT_ID | Un identifiant court de vos offres dans la fédération, par exemple esim-mytravel. Lettres, chiffres, tirets. |
STORE_CONTACT | L'e-mail auquel écrivent les acheteurs. Affiché en pied de page. |
STORE_TERMS_URL, STORE_PRIVACY_URL | Vos CGV et votre politique de confidentialité. Liées en pied de page. |
MARGIN_PCT | Votre marge sur le prix de gros, en pourcentage. 100 le double. |
MIN_MARGIN_USD | La marge minimale par eSIM, en dollars. Les forfaits bon marché prennent au moins cela en plus. |
DEMO_MODE | 1 affiche un bandeau et n'encaisse rien. 0 vend. Gardez 1 jusqu'à l'étape 10. |
PAY_TO_EVM, PAY_TO_TON, PAY_TO_TRON, PAY_TO_SOLANA | Vos adresses de réception. Une ligne vide désactive ce réseau. |
EVM_CHAINS | Les réseaux EVM proposés, par chain id : 8453 Base, 1 Ethereum, 42161 Arbitrum, 10 OP, 137 Polygon, 56 BNB Chain, 43114 Avalanche. |
EVM_RPC_<chain id>, SOLANA_RPC | Facultatif : vos propres points d'accès RPC. Les publics sont limités en débit. |
SUPPLIER | D'où viennent les eSIM : esimaccess (par défaut), airalo, esimgo ou http pour votre propre système. Voir intégrations. |
WEBHOOK_URL, WEBHOOK_SECRET_FILE | Facultatif : le statut de chaque commande, signé, vers votre CRM, votre facturation, Telegram ou un tableur. Voir intégrations. |
Comment le prix est calculé. Prix = gros × (1 + MARGIN_PCT/100), mais jamais moins que gros + MIN_MARGIN_USD. Arrondi au centime supérieur. Avec les valeurs par défaut (100 % et 1,00 $), la France 1 Go pour 7 jours coûte 0,70 $ en gros et se vend 1,70 $. Un forfait de 20 Go à 9,00 $ en gros se vend 18,00 $. Les boutiques eSIM de détail demandent souvent de 4 à 8 $ pour les petits forfaits : vous avez de la marge.
Des adresses seulement. Chaque PAY_TO_* est une adresse de réception. Le kit n'a jamais besoin d'une clé privée ni d'une phrase de récupération. Si un guide ou une personne vous demande d'en mettre une dans .env, c'est une erreur.
6. Placez les clés
Les clés vivent dans secrets/, une valeur par fichier. Le dossier est hors git et monté en lecture seule dans les conteneurs. Saisissez les valeurs sans qu'elles atterrissent dans l'historique du shell :
cd ~/esim-operator-kit
umask 077
printf 'AccessCode: '; read -rs v; printf %s "$v" > secrets/esimaccess_access_code; echo
printf 'SecretKey: '; read -rs v; printf %s "$v" > secrets/esimaccess_secret_key; echo
unset v
Les conteneurs tournent sous l'utilisateur 1000 : donnez-lui les fichiers de clés et les dossiers de données :
mkdir -p data/store data/rails data/node data/caddy
sudo chown 1000:1000 secrets/*
sudo chown -R 1000:1000 data/store data/rails data/node
ls -l secrets
Le dossier lui-même reste à vous : vous pourrez ajouter des fichiers plus tard. Chaque nouveau fichier de clé demande le même sudo chown 1000:1000 et chmod 600.
secrets/README.md liste tous les fichiers facultatifs : la clé CDP, les clés tonapi et TronGrid, les clés Stripe.
7. Démarrez en mode démo
docker compose up -d --build
docker compose ps
docker compose logs --tail 30 store rails
La première construction prend quelques minutes. Vérifiez ensuite trois choses :
curl -s https://esim.example.com/agents/healthz
curl -s -X POST https://esim.example.com/agents/quote -H 'content-type: application/json' \
-d '{"country":"FR","min_gb":3,"min_days":7,"limit":3}'
- La réponse de santé indique
"ok":trueet le nombre d'offres, environ 1 700 avec eSIM Access."demo":trueest normal pour l'instant. - La demande d'offres liste de vrais forfaits à vos prix.
https://esim.example.com/affiche votre boutique avec le bandeau démo. Ouvrez un pays et parcourez le paiement : chaque étape répond « Mode démo : les paiements sont désactivés ».
Si la réponse de santé indique "ok":false, les clés de gros sont fausses ou illisibles. Voir la section 14.
Vérifiez vos prix. Cette commande affiche votre solde et les meilleures offres des pays de votre choix, à votre marge, avec le prix de gros à côté :
docker compose exec -T rails node scripts/catalog.mjs FR ES IT US JP TH
Modifiez MARGIN_PCT ou MIN_MARGIN_USD dans .env et appliquez avec docker compose up -d.
8. Paiements
Chaque moyen s'active dès que son adresse (et sa clé, si besoin) est renseignée. Activez ceux qu'utilisent vos acheteurs. L'USDT sur Tron est la façon la plus courante de payer en crypto ; viennent ensuite l'USDT et l'USDC sur les réseaux EVM et l'USDT sur TON.
| Moyen | À renseigner | Comment paie l'acheteur | Comment la vitrine confirme |
|---|---|---|---|
| USDC sur Base, sans gas | PAY_TO_EVM + secrets/cdp_api_key.json | Signe un message dans un portefeuille du navigateur et ne paie pas de gas. | Le facilitateur CDP règle la signature. L'eSIM est livrée d'abord, puis le paiement est réglé ; si le règlement échoue, l'eSIM est annulée. |
| USDC / USDT sur 7 réseaux EVM | PAY_TO_EVM (+ EVM_CHAINS) | Envoie le virement depuis un portefeuille du navigateur, ou depuis n'importe quel portefeuille ou plateforme d'échange, et colle le hash de la transaction. | Lit le reçu : un transfert de ce jeton vers vous, d'au moins le prix, plus récent que la commande. Attend les confirmations : 3 sur Ethereum et BNB Chain, 10 sur Polygon, 1 ailleurs. Une transaction paie une commande. |
| USDT sur Tron | PAY_TO_TRON (+ secrets/trongrid_key) | Envoie exactement le montant affiché, depuis TronLink sur la page ou depuis n'importe quel portefeuille. | Chaque commande demande le prix plus quelques millionièmes de dollar (0,0099 $ de plus au maximum). Ce montant exact identifie la commande parmi vos transferts USDT confirmés. |
| USDC sur Solana | PAY_TO_SOLANA (+ SOLANA_RPC) | Ouvre le lien Solana Pay ou scanne son QR code (Phantom, Solflare, Backpack). | Chaque commande a sa propre clé de référence, que le portefeuille ajoute au transfert. La vitrine retrouve la transaction grâce à elle. |
| USDT ou TON sur TON | PAY_TO_TON (+ secrets/tonapi_key) | Connecte Tonkeeper ou un autre portefeuille via TON Connect, ou paie à la main avec le commentaire indiqué. | Retrouve le transfert par le commentaire de la commande via tonapi.io. |
| Cartes | secrets/stripe_secret_key + secrets/stripe_webhook_secret | Stripe Checkout. | Le webhook Stripe. |
Un paiement envoyé (tous les moyens sauf Base sans gas et les cartes) est recherché pendant 24 heures après la création de la commande.
Clé Coinbase Developer Platform. Elle active l'USDC sans gas sur Base pour les personnes et les commandes x402 des agents. Sans elle, la vitrine accepte encore l'USDC sur Base en simple virement, mais le nœud pour agents ne prend aucune commande.
- Connectez-vous sur portal.cdp.coinbase.com et créez un projet.
- API Keys : créez une clé API secrète et téléchargez son fichier JSON.
- Copiez le fichier dans
secrets/cdp_api_key.json(il contientidetprivateKey), puis lancezsudo chown 1000:1000 secrets/cdp_api_key.json && sudo chmod 600 secrets/cdp_api_key.jsonetdocker compose up -d.
Stripe. Dans le tableau de bord Stripe, ajoutez un point de terminaison webhook https://<votre domaine>/api/stripe/webhook avec les événements checkout.session.completed et checkout.session.async_payment_succeeded. Mettez la clé secrète (sk_live_…) dans secrets/stripe_secret_key et le secret de signature du point de terminaison (whsec_…) dans secrets/stripe_webhook_secret.
Limites de débit. Les points d'accès publics TronGrid, tonapi et RPC suffisent pour une petite boutique. Quand les ventes deviennent régulières, ajoutez une clé TronGrid gratuite et une clé tonapi, et pointez EVM_RPC_<id> et SOLANA_RPC vers votre propre fournisseur.
9. Agents et fédération
Le nœud rails répond déjà aux agents sur https://<votre domaine>/agents/. Pour que les agents vous trouvent en cherchant sur un hub, décrivez votre nœud à la fédération et annoncez-le.
- Générez
node.tomlà partir de votre catalogue réel. Mettez votre nom, votre domaine et votrePRODUCT_ID:
docker compose exec -T rails node scripts/node-toml.mjs \
--name "My Travel eSIM" --url https://esim.example.com \
--product esim-mytravel --upstream http://rails:9490 > node.toml
head -20 node.toml
- Démarrez le nœud :
docker compose --profile federation up -d --build node
curl -s https://esim.example.com/.well-known/ai-market.json | head -c 400; echo
- Vérifiez-le comme le fera un hub, puis annoncez-le :
docker compose exec node aimarket doctor --url https://esim.example.com
docker compose exec node aimarket node knock --config /node/node.toml --hub https://modelmarket.dev
Avant de vous référencer, le hub appelle esim.quote avec un vrai pays. Une fois référencé, un agent qui cherche « eSIM France » sur le hub obtient vos offres. Le paiement ne passe jamais par le hub : l'agent paie votre nœud via x402, directement sur votre portefeuille.
data/node/ contient la clé de signature du nœud, son identité dans la fédération. Sauvegardez-la. Refaites le point 1 quand le catalogue gagne des pays.
10. La commande test, puis la mise en vente
- Dans
.env, mettezDEMO_MODE=0et revérifiez les adressesPAY_TO_*, caractère par caractère. - Appliquez :
docker compose up -d
curl -s https://esim.example.com/agents/healthz
"demo":false doit apparaître. "paid_orders":true apparaît quand la clé CDP et PAY_TO_EVM sont renseignées.
- Achetez le forfait le moins cher d'un pays dans votre propre boutique, avec votre propre portefeuille, sur le réseau que vos acheteurs utiliseront le plus selon vous. La page de commande doit afficher le QR code en moins d'une minute.
- Vérifiez le paiement dans votre portefeuille et la commande dans la console eSIM Access.
- Si vous ne voulez pas garder l'eSIM, annulez le profil non utilisé dans la console eSIM Access. Le prix de gros revient sur votre solde. Votre paiement est de toute façon allé sur votre propre portefeuille.
Faites de même pour chaque réseau activé. Vous êtes alors en vente.
11. Au quotidien
Commandes. La vitrine les garde dans data/store/orders.json. Listez celles qui demandent votre attention :
sudo jq -r '.[] | select(.status=="refund_due" or .status=="underpaid")
| [.created_at, .id, .status, .method, (.price_cents/100), .payment.ref, (.payment.payer // "-"), (.error // "")] | @tsv' \
data/store/orders.json
| Statut | Signification | Que faire |
|---|---|---|
awaiting_payment | La commande existe, rien n'est encore arrivé. | Rien. |
delivered | Payée, l'eSIM est chez l'acheteur. | Rien. |
refund_due | Payée, mais le grossiste n'a pas livré : solde épuisé, ou forfait retiré. | Remboursez l'acheteur à payment.payer sur le même réseau, ou rechargez et vendez-lui le forfait à la main. |
underpaid | Un paiement inférieur au prix est arrivé. | Remboursez-le, ou demandez la différence à l'acheteur et livrez à la main. |
expired | Rien n'est arrivé en 24 heures. | Rien. Un paiement arrivé plus tard n'est pas rapproché ; vous le verrez sur votre portefeuille sans commande. |
Les acheteurs écrivent à STORE_CONTACT. Demandez-leur le numéro de commande dans l'adresse de leur page (/o/<numéro>). Ne demandez pas le lien complet : il contient leur jeton.
Solde. Gardez le solde de gros au-dessus de quelques jours de ventes. Quand il ne couvre pas une commande, le paiement indique « Ce forfait est temporairement indisponible » au lieu d'encaisser. Vérifiez-le avec :
docker compose exec -T rails node scripts/catalog.mjs | head -1
Journaux.
docker compose logs -f --tail 100 store rails
Les journaux ne contiennent jamais de code d'activation ni de clé.
Sauvegardes. Sauvegardez data/ et secrets/ chaque jour, ailleurs que sur le serveur :
data/store/: les commandes. Si vous les perdez, les pages de commande des acheteurs cessent de fonctionner.data/rails/: les commandes des agents, la clé de leurs jetons de statut et la clé de signature du nœud.data/node/: l'identité dans la fédération.data/caddy/: les certificats. Ils peuvent être réémis, mais la sauvegarde évite les limites de Let's Encrypt.
Mises à jour.
git pull
docker compose up -d --build
docker compose --profile federation up -d --build node # si vous utilisez le nœud de fédération
Lisez les notes de version avant de mettre à jour une boutique qui vend.
12. Commandes des agents
Les agents achètent via POST /agents/order (voir le guide pour les agents). Le nœud vérifie le paiement x402, achète le profil et ne règle qu'une fois le profil créé. Si le règlement échoue, il annule le profil et le prix de gros revient sur votre solde. Les commandes des agents sont enregistrées dans data/rails/orders.json, sans codes d'activation. Les USDC arrivent sur PAY_TO_EVM sur Base.
13. Droit, taxes et conditions
Ceci n'est pas un conseil juridique ou fiscal. Consultez un comptable dans votre pays avant de vendre.
- Le vendeur, c'est vous. Vos acheteurs achètent chez vous, à vos conditions. eSIM Access est votre fournisseur. Remboursements, support et taxes sont à votre charge.
- CGV et confidentialité. eSIM Access attend que votre site publie des conditions de vente et une politique de confidentialité. Renseignez
STORE_TERMS_URLetSTORE_PRIVACY_URL. Les conditions doivent couvrir les remboursements (une eSIM installée n'est en général pas remboursable), la compatibilité (un téléphone désimlocké qui gère l'eSIM) et le début de validité. - TVA dans l'UE. Les services de télécommunication vendus aux consommateurs sont taxés dans le pays de l'acheteur. Le guichet unique (OSS) permet de déclarer tous les pays de l'UE en une seule déclaration. Hors UE, les règles diffèrent.
- Crypto. Le droit d'accepter des cryptoactifs, et la façon de les comptabiliser, dépendent de votre pays. Conservez les enregistrements des commandes : la vitrine a le réseau, la transaction et le montant de chaque paiement.
- Données personnelles. La vitrine ne demande rien aux acheteurs : ni nom, ni e-mail. Elle garde la commande (forfait, prix, moyen) et le paiement (transaction et adresse du payeur). Une adresse blockchain peut néanmoins être une donnée personnelle au sens du RGPD : mentionnez-la dans votre politique de confidentialité.
14. Dépannage
| Ce que vous voyez | Cause | Solution |
|---|---|---|
| Le navigateur dit que le certificat n'est pas valide | Le DNS ne pointe pas encore ici, ou le port 80 est fermé | dig +short <domaine>, ouvrez le port 80, puis docker compose restart caddy et lisez docker compose logs caddy. |
healthz affiche "ok":false ou la boutique n'affiche aucun pays | Les clés de gros sont fausses ou l'utilisateur 1000 ne peut pas les lire. Les journaux disent catalogue not loaded yet: <code>. | sudo rm secrets/esimaccess_*, réécrivez-les comme à l'étape 6, puis docker compose restart store rails. |
EACCES ou permission denied dans les journaux | Les dossiers de données n'appartiennent pas à l'utilisateur 1000 | sudo chown -R 1000:1000 data/store data/rails data/node |
| Le paiement indique « Ce forfait est temporairement indisponible » | Le solde de gros ne couvre pas le forfait | Rechargez eSIM Access. |
| Chaque paiement répond « Mode démo : les paiements sont désactivés » | DEMO_MODE=1 | Étape 10. |
| Un réseau manque au paiement | Son PAY_TO_* est vide | Vérifiez .env, puis docker compose up -d. |
| La vitrine redémarre en boucle | Un PAY_TO_* n'est pas une adresse valide : la vitrine refuse de démarrer avec | docker compose logs store la nomme. Corrigez .env. |
| Un paiement Tron est introuvable | Le montant n'était pas exact, souvent parce qu'une plateforme d'échange en a déduit ses frais | Retrouvez le transfert sur votre portefeuille et remboursez-le, ou livrez à la main. Demandez aux acheteurs d'envoyer le montant exact depuis un portefeuille. |
| Un paiement TON est introuvable | Le commentaire manquait ou a été modifié | Comme ci-dessus. Avec TON Connect, le portefeuille remplit le commentaire tout seul. |
aimarket doctor signale une adresse privée | L'url de node.toml n'est pas votre domaine public | Régénérez node.toml (étape 9) avec --url https://<domaine>. |
node ne démarre pas : node.toml est un dossier | Compose l'a créé parce que le fichier n'existait pas | rmdir node.toml, générez le fichier (étape 9), redémarrez. |