Guía de Solución de Problemas
Esta guía cubre problemas comunes de integración y soluciones concretas.
Errores de Autenticación
Síntoma
CryptoBotError: code=401, name=UNAUTHORIZED
Verificaciones
import os
from cryptobot import CryptoBotClient
client = CryptoBotClient(api_token=os.environ["CRYPTOBOT_API_TOKEN"])
print(client.get_me().name)
Si eso falla:
Confirme que el token está presente y no está vacío.
Confirme que el token pertenece al entorno previsto.
Si usa un token de testnet, establezca
is_mainnet=False.
Discrepancia entre Mainnet y Testnet
import os
from cryptobot import CryptoBotClient
mainnet = CryptoBotClient(api_token=os.environ["CRYPTOBOT_API_TOKEN"], is_mainnet=True)
testnet = CryptoBotClient(api_token=os.environ["CRYPTOBOT_TESTNET_TOKEN"], is_mainnet=False)
Use un token por entorno y no los mezcle.
Fallos de Validación de Monto
Síntoma
CryptoBotError: code=400, name=AMOUNT_TOO_SMALL
Solución
Valide el monto antes de las llamadas a la API:
from decimal import Decimal
from cryptobot.models import Asset
MIN_AMOUNTS = {
Asset.USDT: Decimal("0.01"),
Asset.USDC: Decimal("0.01"),
Asset.TON: Decimal("0.01"),
Asset.BTC: Decimal("0.000001"),
}
def validate_amount(asset: Asset, amount: float):
value = Decimal(str(amount))
minimum = MIN_AMOUNTS.get(asset)
if minimum is not None and value < minimum:
raise ValueError(f"Amount too small for {asset.name}. Minimum is {minimum}")
El Estado de la Factura No se Actualiza
Si una factura parece estar estancada:
Consulte por ID de factura.
Verifique
Status.paidoStatus.expired.Cree una factura de reemplazo si expiró.
from cryptobot.models import Asset, Status
def refresh_invoice(client, invoice_id: int):
invoices = client.get_invoices(invoice_ids=str(invoice_id))
return invoices[0] if invoices else None
def renew_if_expired(client, invoice):
if invoice.status != Status.expired:
return invoice
return client.create_invoice(
asset=invoice.asset,
amount=float(invoice.amount),
description=invoice.description,
payload=invoice.payload,
expires_in=3600,
)
Problemas de Transferencia
Saldo insuficiente
CryptoBotError: code=400, name=INSUFFICIENT_FUNDS
from decimal import Decimal
def has_balance(client, asset, amount: float) -> bool:
required = Decimal(str(amount))
for bal in client.get_balances():
if bal.currency_code == asset.name:
return Decimal(bal.available) >= required
return False
spend_id duplicado
CryptoBotError: code=400, name=SPEND_ID_ALREADY_USED
from datetime import datetime
import uuid
def unique_spend_id(prefix: str, user_id: int) -> str:
return f"{prefix}_{user_id}_{datetime.utcnow().strftime('%Y%m%d%H%M%S')}_{uuid.uuid4().hex[:8]}"
Problemas de Timeout y Conexión
Aumente el timeout y habilite los reintentos/backoff integrados para errores de transporte transitorios:
import os
from cryptobot import CryptoBotClient
from cryptobot.models import Asset
client = CryptoBotClient(
api_token=os.environ["CRYPTOBOT_API_TOKEN"],
timeout=30.0,
max_retries=3,
retry_backoff=0.5,
)
invoice = client.create_invoice(asset=Asset.USDT, amount=5, description="network-safe")
Fallos de Firma de Webhook
La mayoría de los errores de firma provienen de verificar JSON analizado en lugar del cuerpo crudo.
import json
import os
from fastapi import FastAPI, HTTPException, Request
from cryptobot.webhook import check_signature
app = FastAPI()
api_token = os.environ["CRYPTOBOT_API_TOKEN"]
@app.post("/webhook")
async def webhook(request: Request):
raw = await request.body()
raw_str = raw.decode("utf-8")
if not check_signature(api_token, raw_str, request.headers):
raise HTTPException(status_code=400, detail="Invalid signature")
data = json.loads(raw_str)
return {"ok": True, "update_type": data.get("update_type")}
Webhooks No Recibidos
Lista de verificación:
El endpoint es accesible públicamente a través de HTTPS.
La URL del webhook en Crypto Bot es correcta.
Su servicio está escuchando en la ruta/puerto esperados.
El proxy reverso reenvía el cuerpo de la solicitud y los encabezados sin cambios.
Para pruebas locales, ejecute su script de listener y expóngalo con ngrok:
ngrok http 2203
Errores de Análisis de Enum
Al convertir la entrada del usuario a enums, normalice y valide:
from cryptobot.models import Asset, Status
def parse_asset(text: str) -> Asset:
try:
return Asset[text.upper()]
except KeyError as exc:
raise ValueError(f"Unsupported asset: {text}") from exc
def parse_status(text: str) -> Status:
try:
return Status[text.lower()]
except KeyError as exc:
raise ValueError(f"Unsupported status: {text}") from exc
Errores de Límite de Tasa
Síntoma
CryptoBotError: code=429, name=TOO_MANY_REQUESTS
Solución
import os
from cryptobot import CryptoBotClient
client = CryptoBotClient(
api_token=os.environ["CRYPTOBOT_API_TOKEN"],
max_retries=4,
retry_backoff=0.5,
retryable_status_codes={429},
)
app = client.get_me()
print(app.name)
Prueba Rápida de Testnet
import os
from cryptobot import CryptoBotClient
from cryptobot.models import Asset
def smoke_test() -> bool:
client = CryptoBotClient(
api_token=os.environ["CRYPTOBOT_TESTNET_TOKEN"],
is_mainnet=False,
)
try:
client.get_me()
client.get_balances()
client.get_exchange_rates()
client.create_invoice(asset=Asset.USDT, amount=1, description="smoke")
return True
except Exception:
return False