Modo demo: una tienda de referencia para operadores de eSIM. Precios reales, pagos desactivados. Lanza tu propio operador →
Travel eSIM · demo
Español

Guía del operador

Contenido

Esta guía te lleva de un servidor vacío a tu primera venta y después cubre el trabajo diario: pedidos, reembolsos, saldo, copias de seguridad, actualizaciones. Reserva una hora para la configuración. Casi toda esa hora es esperar a la cuenta mayorista y al registro DNS.

Otros documentos: resumen · guía para agentes · incorporación · integraciones · SDK

1. Qué vas a montar

            https://esim.example.com
                      │
                   Caddy (80, 443, Let's Encrypt)
      ┌───────────────┼──────────────────────────────┐
      │               │                              │
   store          rails (/agents/*)              node (/.well-known/ai-market.json, /ai-market/*)
 compran personas  compran agentes por x402      los hubs encuentran tus ofertas
      │               │
      └──── tu saldo en eSIM Access ────┘      los pagos van a tus monederos

store y rails compran de la misma cuenta mayorista. Ninguno guarda dinero: los compradores pagan a tus direcciones, y el kit solo lee las redes para ver llegar los pagos.

2. Antes de empezar

NecesitasNotas
Una cuenta en eSIM AccessRegístrate en esimaccess.com. Paso 3.
$50 o más de saldoLa primera recarga es de al menos $50 (tarjeta, PayPal o Alipay; transferencia bancaria desde $3.000).
Un servidor LinuxDocker Engine con el plugin compose, una IPv4 pública, puertos 80 y 443 abiertos. Bastan 1 vCPU y 1 GB de memoria.
Un dominio o subdominioPor ejemplo esim.example.com, con un registro A hacia el servidor.
Direcciones de monederoEVM (una dirección para las siete redes EVM), Tron, Solana, TON. Cualquier combinación sirve.
Condiciones y política de privacidadDos páginas públicas. eSIM Access espera que el sitio de cada revendedor las enlace.
Opcional: una clave de Coinbase Developer PlatformActiva USDC sin gas en Base para personas y los pedidos x402 de los agentes. Paso 8.
Opcional: StripeActiva las tarjetas. Paso 8.

3. La cuenta mayorista

  1. Regístrate en esimaccess.com y confirma tu correo.
  2. Recarga el saldo (en la consola: saldo, luego recarga). El mínimo es $50. Cada eSIM que vendes se paga con este saldo al precio mayorista: es tu existencia, no una comisión.
  3. Abre la sección de desarrollador (API) de la consola. Muestra dos valores: el AccessCode y la SecretKey. Trata la SecretKey como una contraseña.

No hay sandbox: cada pedido por la API es real. Dos maneras baratas de probar:

4. El servidor y el dominio

  1. Crea un registro A de tu dominio hacia la IPv4 del servidor. Compruébalo desde tu ordenador:
dig +short esim.example.com
  1. Instala Docker en el servidor (docs.docker.com/engine/install) y comprueba que compose funciona:
docker compose version
  1. Abre los puertos 80 y 443 en el cortafuegos del servidor y en el panel de tu proveedor. Let's Encrypt comprueba el puerto 80 antes de emitir el certificado.

5. Descarga el kit y configúralo

git clone https://github.com/alexar76/esim-operator-kit.git
cd esim-operator-kit
cp .env.example .env
nano .env
AjusteQué poner
DOMAINTu dominio, sin https://.
STORE_NAMEEl nombre que ven los compradores en la cabecera, el título y la ventana del monedero.
PRODUCT_IDUn identificador corto de tus ofertas en la federación, por ejemplo esim-mytravel. Letras, cifras, guiones.
STORE_CONTACTEl correo al que escriben los compradores. Se muestra en el pie.
STORE_TERMS_URL, STORE_PRIVACY_URLTus condiciones y tu política de privacidad. Se enlazan en el pie.
MARGIN_PCTTu margen sobre el precio mayorista, en porcentaje. 100 lo duplica.
MIN_MARGIN_USDEl margen mínimo por eSIM, en dólares. Los planes baratos llevan al menos esto encima.
DEMO_MODE1 muestra un aviso y no cobra. 0 vende. Mantén 1 hasta el paso 10.
PAY_TO_EVM, PAY_TO_TON, PAY_TO_TRON, PAY_TO_SOLANATus direcciones de cobro. Una línea vacía desactiva esa red.
EVM_CHAINSQué redes EVM ofrecer, por su chain id: 8453 Base, 1 Ethereum, 42161 Arbitrum, 10 OP, 137 Polygon, 56 BNB Chain, 43114 Avalanche.
EVM_RPC_<chain id>, SOLANA_RPCOpcional: tus propios endpoints RPC. Los públicos tienen límites.
SUPPLIERDe dónde salen las eSIM: esimaccess (por defecto), airalo, esimgo o http para tu propio sistema. Mira integraciones.
WEBHOOK_URL, WEBHOOK_SECRET_FILEOpcional: el estado de cada pedido, firmado, hacia tu CRM, facturación, Telegram o una hoja. Mira integraciones.

Cómo se calcula el precio. Precio = mayorista × (1 + MARGIN_PCT/100), pero nunca menos que mayorista + MIN_MARGIN_USD. Se redondea al céntimo hacia arriba. Con los valores por defecto (100 % y $1.00), Francia 1 GB por 7 días cuesta $0.70 al por mayor y se vende a $1.70. Un plan de 20 GB a $9.00 al por mayor se vende a $18.00. Las tiendas minoristas de eSIM suelen pedir de $4 a $8 por los planes pequeños, así que tienes margen.

Solo direcciones. Cada PAY_TO_* es una dirección donde recibes. El kit nunca necesita una clave privada ni una frase semilla. Si una guía o una persona te pide ponerla en .env, está mal.

6. Coloca las claves

Las claves viven en secrets/, un valor por archivo. La carpeta está fuera de git y se monta en solo lectura en los contenedores. Escribe los valores sin que queden en el historial de la 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

Los contenedores se ejecutan como el usuario 1000, así que dale los archivos de claves y las carpetas de datos:

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

La carpeta sigue siendo tuya, así que puedes añadir archivos más tarde. Cada archivo de clave nuevo necesita el mismo sudo chown 1000:1000 y chmod 600.

secrets/README.md lista todos los archivos opcionales: la clave CDP, las claves de tonapi y TronGrid y las claves de Stripe.

7. Arranca en modo demo

docker compose up -d --build
docker compose ps
docker compose logs --tail 30 store rails

La primera compilación tarda unos minutos. Después comprueba tres cosas:

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}'

Si la respuesta de salud dice "ok":false, las claves mayoristas son incorrectas o no se pueden leer. Mira la sección 14.

Revisa tus precios. Esto imprime tu saldo y las mejores ofertas de los países que quieras, con tu margen y el precio mayorista al lado:

docker compose exec -T rails node scripts/catalog.mjs FR ES IT US JP TH

Cambia MARGIN_PCT o MIN_MARGIN_USD en .env y aplícalo con docker compose up -d.

8. Pagos

Cada método se activa cuando su dirección (y su clave, si la necesita) está puesta. Activa los que usan tus compradores. USDT en Tron es la forma más común de pagar en cripto; le siguen USDT y USDC en redes EVM y USDT en TON.

MétodoQué ponerCómo paga el compradorCómo lo confirma la tienda
USDC en Base, sin gasPAY_TO_EVM + secrets/cdp_api_key.jsonFirma un mensaje en un monedero del navegador y no paga gas.El facilitador de CDP liquida la firma. Primero se entrega la eSIM, después se liquida el pago; si la liquidación falla, la eSIM se cancela.
USDC / USDT en 7 redes EVMPAY_TO_EVM (+ EVM_CHAINS)Envía la transferencia desde un monedero del navegador, o desde cualquier monedero o exchange y pega el hash de la transacción.Lee el recibo: una transferencia de ese token hacia ti, de al menos el precio, posterior al pedido. Espera confirmaciones: 3 en Ethereum y BNB Chain, 10 en Polygon, 1 en las demás. Una transacción paga un pedido.
USDT en TronPAY_TO_TRON (+ secrets/trongrid_key)Envía exactamente el importe mostrado, desde TronLink en la página o desde cualquier monedero.Cada pedido pide el precio más unas millonésimas de dólar (como mucho $0.0099 más). Ese importe exacto identifica el pedido entre tus transferencias USDT confirmadas.
USDC en SolanaPAY_TO_SOLANA (+ SOLANA_RPC)Abre el enlace de Solana Pay o escanea su QR (Phantom, Solflare, Backpack).Cada pedido tiene su propia clave de referencia, que el monedero añade a la transferencia. La tienda encuentra la transacción por ella.
USDT o TON en TONPAY_TO_TON (+ secrets/tonapi_key)Conecta Tonkeeper u otro monedero con TON Connect, o paga a mano con el comentario indicado.Encuentra la transferencia por el comentario del pedido a través de tonapi.io.
Tarjetassecrets/stripe_secret_key + secrets/stripe_webhook_secretStripe Checkout.El webhook de Stripe.

Un pago enviado (todos los métodos salvo Base sin gas y tarjetas) se busca durante 24 horas después de crear el pedido.

Clave de Coinbase Developer Platform. Activa USDC sin gas en Base para personas y los pedidos x402 de los agentes. Sin ella, la tienda sigue aceptando USDC en Base como transferencia normal, pero el nodo para agentes no acepta pedidos.

  1. Entra en portal.cdp.coinbase.com y crea un proyecto.
  2. API Keys: crea una clave API secreta y descarga su archivo JSON.
  3. Copia el archivo a secrets/cdp_api_key.json (contiene id y privateKey), luego ejecuta sudo chown 1000:1000 secrets/cdp_api_key.json && sudo chmod 600 secrets/cdp_api_key.json y docker compose up -d.

Stripe. En el panel de Stripe, añade un endpoint de webhook https://<tu dominio>/api/stripe/webhook con los eventos checkout.session.completed y checkout.session.async_payment_succeeded. Pon la clave secreta (sk_live_…) en secrets/stripe_secret_key y el secreto de firma del endpoint (whsec_…) en secrets/stripe_webhook_secret.

Límites. Los endpoints públicos de TronGrid, tonapi y RPC bastan para una tienda pequeña. Cuando tengas ventas regulares, añade una clave gratuita de TronGrid y una de tonapi, y apunta EVM_RPC_<id> y SOLANA_RPC a tu propio proveedor.

9. Agentes y federación

El nodo rails ya responde a los agentes en https://<tu dominio>/agents/. Para que los agentes te encuentren buscando en un hub, describe tu nodo a la federación y anúncialo.

  1. Genera node.toml a partir de tu catálogo real. Usa tu nombre, tu dominio y tu PRODUCT_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
  1. Arranca el nodo:
docker compose --profile federation up -d --build node
curl -s https://esim.example.com/.well-known/ai-market.json | head -c 400; echo
  1. Compruébalo como lo hará un hub y anúncialo:
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

Antes de listarte, el hub llama a esim.quote con un país real. Una vez listado, un agente que busque «eSIM France» en el hub obtiene tus ofertas. El pago nunca pasa por el hub: el agente paga a tu nodo por x402, directamente a tu monedero.

data/node/ guarda la clave de firma del nodo, que es su identidad en la federación. Haz copia de seguridad. Repite el punto 1 cuando el catálogo gane países.

10. El pedido de prueba y la puesta en marcha

  1. En .env, pon DEMO_MODE=0 y revisa otra vez las direcciones PAY_TO_*, carácter a carácter.
  2. Aplícalo:
docker compose up -d
curl -s https://esim.example.com/agents/healthz

Debe aparecer "demo":false. "paid_orders":true aparece cuando la clave CDP y PAY_TO_EVM están puestas.

  1. Compra el plan más barato de un país en tu propia tienda, con tu propio monedero, en la red que esperas que más usen los compradores. La página del pedido debe mostrar el código QR en menos de un minuto.
  2. Comprueba el pago en tu monedero y el pedido en la consola de eSIM Access.
  3. Si no quieres quedarte la eSIM, cancela el perfil sin usar en la consola de eSIM Access. El precio mayorista vuelve a tu saldo. Tu pago fue a tu propio monedero de todos modos.

Haz lo mismo con cada red que hayas activado. Y ya estás vendiendo.

11. El día a día

Pedidos. La tienda los guarda en data/store/orders.json. Lista los que te necesitan:

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
EstadoSignificadoQué hacer
awaiting_paymentEl pedido existe y aún no ha llegado nada.Nada.
deliveredPagado, y la eSIM está con el comprador.Nada.
refund_duePagado, pero el mayorista no entregó: se acabó el saldo o retiraron el plan.Reembolsa al comprador a payment.payer en la misma red, o recarga y véndele el plan a mano.
underpaidLlegó un pago por debajo del precio.Reembólsalo, o pide al comprador la diferencia y entrega a mano.
expiredNo llegó nada en 24 horas.Nada. Un pago que llegue después no se empareja; lo verás en tu monedero sin pedido.

Los compradores escriben a STORE_CONTACT. Pídeles el número de pedido de la dirección de su página (/o/<número>). No pidas el enlace completo: contiene su token.

Saldo. Mantén el saldo mayorista por encima de unos días de ventas. Cuando no cubre un pedido, el pago dice «Este plan no está disponible temporalmente» en lugar de cobrar. Compruébalo con:

docker compose exec -T rails node scripts/catalog.mjs | head -1

Registros.

docker compose logs -f --tail 100 store rails

Los registros nunca contienen un código de activación ni una clave.

Copias de seguridad. Copia data/ y secrets/ cada día, fuera del servidor:

Actualizaciones.

git pull
docker compose up -d --build
docker compose --profile federation up -d --build node    # si usas el nodo de federación

Lee las notas de la versión antes de actualizar una tienda que vende.

12. Pedidos de agentes

Los agentes compran con POST /agents/order (mira la guía para agentes). El nodo verifica el pago x402, compra el perfil y liquida solo cuando el perfil existe. Si la liquidación falla, cancela el perfil y el precio mayorista vuelve a tu saldo. Los pedidos de agentes se registran en data/rails/orders.json, sin códigos de activación. Los USDC llegan a PAY_TO_EVM en Base.

13. Leyes, impuestos y condiciones

Esto no es asesoramiento legal ni fiscal. Consulta a un asesor en tu país antes de vender.

14. Resolución de problemas

Qué vesCausaSolución
El navegador dice que el certificado no es válidoEl DNS aún no apunta aquí, o el puerto 80 está cerradodig +short <dominio>, abre el puerto 80, luego docker compose restart caddy y lee docker compose logs caddy.
healthz muestra "ok":false o la tienda no muestra paísesLas claves mayoristas son incorrectas o el usuario 1000 no puede leerlas. Los registros dicen catalogue not loaded yet: <code>.sudo rm secrets/esimaccess_*, escríbelas de nuevo como en el paso 6, luego docker compose restart store rails.
EACCES o permission denied en los registrosLas carpetas de datos no son del usuario 1000sudo chown -R 1000:1000 data/store data/rails data/node
El pago dice «Este plan no está disponible temporalmente»El saldo mayorista no cubre el planRecarga eSIM Access.
Cada pago responde «Modo demo: los pagos están desactivados»DEMO_MODE=1Paso 10.
Falta una red en el pagoSu PAY_TO_* está vacíoRevisa .env, luego docker compose up -d.
La tienda se reinicia una y otra vezUn PAY_TO_* no es una dirección válida: la tienda se niega a arrancar con elladocker compose logs store la nombra. Corrige .env.
No se encuentra un pago en TronEl importe no era exacto, a menudo porque un exchange descontó su comisiónBusca la transferencia en tu monedero y reembólsala, o entrega a mano. Pide a los compradores enviar el importe exacto desde un monedero.
No se encuentra un pago en TONFaltaba el comentario o se cambióIgual que arriba. Con TON Connect el monedero pone el comentario solo.
aimarket doctor informa de una dirección privadaEl url de node.toml no es tu dominio públicoGenera node.toml de nuevo (paso 9) con --url https://<dominio>.
node no arranca: node.toml es una carpetaCompose la creó porque el archivo no existíarmdir node.toml, genera el archivo (paso 9), arranca de nuevo.

El kit en GitHub →