← Acceso al panel

API del Hub Gamesphere · v1

Con esta API tu tienda consulta el catálogo de Gamesphere con tus precios, cotiza envíos, crea pedidos, registra pagos y recibe el seguimiento hasta la entrega. Los productos los surte Exel del Norte y se envían directo a tu cliente final.

Para empezarFlujo de un pedidoErroresCatálogoCotizar envío Crear pedidoConsultar pedidosRegistrar pagoCambios de precioCancelar / reactivar WebhooksAmbiente de pruebasEstados

Para empezar

Flujo de un pedido

  1. POST /envios/cotizar (opcional): precio vigente y opciones de paquetería para el CP del cliente.
  2. POST /pedidos: el pedido queda Pendiente de pago. Precio y envío se respetan hasta apartado_hasta (24 h por omisión).
  3. Transfieres el total a Gamesphere con el folio como referencia y lo registras con POST /pedidos/{folio}/pago → En revisión de pago.
  4. Gamesphere confirma el depósito → Pagado → el Hub reconfirma existencias y lo coloca en Exel → Pedido en Exel.
  5. Exel envía al cliente final → Enviado (con número de guía) → Entregado.

Cada cambio de estado te llega por webhook. Si algo cambia después del pago (sube el costo, se agota en el almacén), el pedido pasa a Requiere atención; ver Cambios de precio.

Errores

Los errores usan códigos HTTP estándar y este cuerpo:

{ "error": { "codigo": "datos_incompletos", "mensaje": "Faltan o son inválidos: direccion.colonia", "detalle": { "campos": ["direccion.colonia"] } } }
401Llave faltante, inválida o revocada.
404Recurso no encontrado (o de otro modo prueba/producción).
409Conflicto de estado o existencias: sin_almacen_unico, sin_existencias, estado_invalido, transportista_no_disponible.
422Datos inválidos.
429Límite de peticiones.
502Exel no respondió; reintenta en unos minutos.

Catálogo

GET/productos

Parámetros: q (texto), categoria, subcategoria, marca, con_existencias=true, actualizado_desde (ISO; para sincronizar solo cambios), referencias (lista separada por comas), orden (nombre|precio|existencias), pagina, por_pagina (máx. 500).

curl -H "Authorization: Bearer gs_live_xxx" "https://hub.gamesphere.mx/api/v1/productos?con_existencias=true&por_pagina=100&pagina=1"

{ "datos": [ {
    "referencia": "3MPBADAB001", "sku": "680-5", "codigo_barras": "021200666971",
    "nombre": "Banderitas 3M 680 Post It Amarillo 12 Piezas",
    "marca": { "id": "3M", "nombre": "3M" }, "categoria": { "id": "17", "nombre": "Oficina y Escolar" },
    "subcategoria": { "id": "11", "nombre": "Hojas Notas y Formatos" }, "familia": { "id": "BADAB", "nombre": "BANDERITAS" },
    "existencias": 84, "precio": 488.11, "moneda": "MXN", "precio_incluye_iva": true,
    "imagenes": null, "activo": true, "actualizado": "2026-10-28T18:00:03.120Z" } ],
  "pagina": 1, "por_pagina": 100, "total": 8712, "paginas": 88 }

precio es tu precio Gamesphere (lo que pagas), con IVA. Tu precio al público lo defines tú. El catálogo se actualiza cada 30 minutos; un producto que Exel deja de surtir queda con activo: false y existencias: 0.

GET/productos/{referencia}

Detalle con existencias y precio en tiempo real, existencias por almacén e imágenes.

GET/categorias · /marcas

Cotizar envío

POST/envios/cotizar
{ "codigo_postal": "80000", "productos": [ { "referencia": "3MPBADAB001", "cantidad": 2 } ] }

{ "productos": [ { "referencia": "3MPBADAB001", "nombre": "…", "cantidad": 2, "precio_unitario": 488.11, "importe": 976.22 } ],
  "subtotal": 976.22,
  "opciones": [
    { "almacen": "CN", "almacen_nombre": "CULIACAN", "transportista": "ESTA", "transportista_nombre": "ESTAFETA 5kg", "costo": 168.20 },
    { "almacen": "CN", "almacen_nombre": "CULIACAN", "transportista": "FEDX", "transportista_nombre": "FEDERAL EXPRESS", "costo": 266.80 } ] }

Cada pedido sale de un solo almacén. Si ningún almacén tiene todo, recibes 409 sin_almacen_unico con la disponibilidad por producto para que dividas el pedido.

Crear pedido

POST/pedidos
{
  "num_orden": "W-10045",                       // tu número de pedido; único por empresa
  "productos": [ { "referencia": "3MPBADAB001", "cantidad": 2 } ],
  "cliente": { "nombre": "Juan Pérez", "correo": "juan@correo.com", "telefono": "6671234567" },
  "direccion": { "calle": "Av. Obregón", "numero_exterior": "100", "numero_interior": "",
                 "colonia": "Centro", "codigo_postal": "80000", "ciudad": "Culiacán", "estado": "Sinaloa",
                 "referencias": "Portón negro" },
  "envio": { "almacen": "CN", "transportista": "ESTA" },   // opcional; si lo omites se elige el más barato
  "comentario": "Opcional"
}

Respuesta 201 con el pedido completo (ver estructura), incluido pago:

"pago": { "monto": 1144.42, "referencia": "GS-001001", "instrucciones": "BanBajío · CLABE …", "fecha_limite": "2026-10-30T03:28:36Z" }

Idempotencia: si envías el mismo num_orden otra vez recibes 200 con el pedido existente, sin duplicarlo. Úsalo para reintentar sin miedo ante un corte de red.

Consultar pedidos

GET/pedidos/{folio}
{ "folio": "GS-001001", "num_orden": "W-10045", "estado": "pedido_exel", "estado_texto": "Pedido en Exel", "prueba": false,
  "creado": "…", "apartado_hasta": "…", "pagado_en": "…",
  "cliente": { "nombre": "Juan Pérez", "correo": "juan@correo.com", "telefono": "6671234567" }, "direccion": { … },
  "envio": { "almacen": "CN", "almacen_nombre": "CULIACAN", "transportista": "ESTA", "transportista_nombre": "ESTAFETA 5kg", "costo": 168.2 },
  "productos": [ … ], "subtotal": 976.22, "total": 1144.42, "pagado": 1144.42, "saldo": 0,
  "pagos": [ { "id": 7, "monto": 1144.42, "referencia": "SPEI 123", "estatus": "confirmado" } ],
  "exel": { "folio": "903372777", "estatus": "confirmada" },
  "guia": { "numero": "1234567890", "paqueteria": "ESTAFETA", "url": "https://…" },
  "atencion": null,
  "bitacora": [ { "evento": "creado", "de": null, "a": "pendiente_pago", "actor": "empresa", "detalle": "…", "fecha": "…" } ] }
GET/pedidos

Filtros: estado (uno o varios separados por coma), num_orden, desde (actualizados desde una fecha), pagina, por_pagina (máx. 200).

Registrar pago

POST/pedidos/{folio}/pago

Después de transferir. Envía multipart/form-data con comprobante (PDF/JPG/PNG/WEBP/HEIC, máx. 10 MB), o JSON con el archivo en base64:

{ "monto": 1144.42, "referencia": "SPEI 0987654", "comprobante_base64": "JVBERi0xLjQK…", "comprobante_tipo": "application/pdf" }

Si omites monto se toma el saldo. El pedido pasa a revision_pago. Si Gamesphere rechaza el pago (no identificado), vuelve a pendiente_pago con el motivo en pagos[].motivo_rechazo.

Cambios de precio o existencias

Al enviar a Exel, el Hub reconfirma precio, flete y existencias. Si el costo subió más de la tolerancia, el pedido pasa a requiere_atencion con:

"atencion": { "motivo": "El costo en Exel subió $320.00 desde que se creó el pedido.",
  "ajuste": { "tipo": "precio", "nuevo_subtotal": 1290.10, "nuevo_envio": 168.2, "nuevo_total": 1458.30, "diferencia": 313.88, "mensaje": "…" } }
POST/pedidos/{folio}/aceptar-cambio

Aceptas el nuevo total: queda pendiente_pago por la diferencia (saldo).

POST/pedidos/{folio}/rechazar-cambio

No aceptas: el pedido se cancela y Gamesphere te reembolsa (reembolso). Otros motivos de atención (existencias, error de Exel) los resuelve Gamesphere y te avisa por webhook.

Cancelar y reactivar

POST/pedidos/{folio}/cancelar

Solo antes de que el pago sea confirmado. Cuerpo opcional { "motivo": "…" }.

POST/pedidos/{folio}/reactivar

Un pedido vencido (no se pagó a tiempo) se recotiza y abre un nuevo plazo.

Webhooks

Configura la URL en el panel → Integración. Enviamos POST con JSON en cada cambio de estado:

POST https://tutienda.com/webhooks/gamesphere
X-Hub-Evento: pedido.enviado
X-Hub-Entrega: evt_123
X-Hub-Firma: t=1761700000,v1=5f2b…

{ "id": "evt_123", "evento": "pedido.enviado", "creado": "2026-10-28T20:00:00Z", "data": { "pedido": { …igual que GET /pedidos/{folio}… } } }

Eventos: pedido.creado, pedido.en_revision_pago, pedido.pendiente_pago, pedido.pagado, pedido.en_exel, pedido.requiere_atencion, pedido.enviado, pedido.entregado, pedido.vencido, pedido.cancelado, pedido.actualizado, prueba.ping.

Responde 2xx en menos de 10 s. Si no, reintentamos a 1, 5, 15, 60 min, 3, 6, 12 y 24 h. Puede llegar el mismo evento más de una vez: usa id para no procesarlo doble y toma siempre el estado del pedido como la verdad.

Verificar la firma

Calcula HMAC-SHA256 de {t}.{cuerpo crudo} con tu secreto de webhook y compáralo con v1. Rechaza si t tiene más de 5 minutos.

// Node.js (Express): usa el cuerpo crudo
const crypto = require('crypto');
app.post('/webhooks/gamesphere', express.raw({ type: 'application/json' }), (req, res) => {
  const [t, v1] = req.get('X-Hub-Firma').split(',').map(p => p.split('=')[1]);
  const esperada = crypto.createHmac('sha256', process.env.GS_WEBHOOK_SECRETO).update(`${t}.${req.body}`).digest('hex');
  const ok = esperada.length === v1.length && crypto.timingSafeEqual(Buffer.from(esperada), Buffer.from(v1));
  if (!ok || Math.abs(Date.now() / 1000 - Number(t)) > 300) return res.sendStatus(401);
  const evento = JSON.parse(req.body);
  // … actualiza tu pedido con evento.data.pedido
  res.sendStatus(200);
});
// PHP
$cuerpo = file_get_contents('php://input');
parse_str(str_replace(',', '&', $_SERVER['HTTP_X_HUB_FIRMA']), $f);
$esperada = hash_hmac('sha256', $f['t'] . '.' . $cuerpo, getenv('GS_WEBHOOK_SECRETO'));
if (!hash_equals($esperada, $f['v1']) || abs(time() - (int)$f['t']) > 300) { http_response_code(401); exit; }
$evento = json_decode($cuerpo, true);
POST/webhooks/prueba

Envía un prueba.ping a tu URL y regresa el resultado.

Ambiente de pruebas

Con una llave gs_test_ todo funciona igual (catálogo real, cotización real), pero los pedidos tienen folio PR-, nunca llegan a Exel y no se cobran. Para avanzar un pedido de prueba por los estados:

POST/pruebas/pedidos/{folio}/simular-pago

Confirma el pago y lo pasa a pedido_exel (folio Exel SIM-…).

POST/pruebas/pedidos/{folio}/simular-envio
POST/pruebas/pedidos/{folio}/simular-entrega

Cada paso dispara sus webhooks, así pruebas tu integración de punta a punta.

Estados del pedido

EstadoSignificado
pendiente_pagoCreado; esperando tu pago hasta apartado_hasta.
revision_pagoRegistraste un pago; Gamesphere lo está verificando.
pagadoPago confirmado; se está colocando en Exel.
requiere_atencionCambió precio, existencias o hubo un error con Exel. Ver atencion.
pedido_exelExel lo recibió; se está preparando.
enviadoSalió con guía (guia).
entregadoRecibido por el cliente final.
vencidoNo se pagó a tiempo. Puedes reactivarlo.
canceladoCancelado.
reembolsoCancelado después del pago; Gamesphere te devuelve el dinero.

Dudas de integración: escribe al equipo de Gamesphere.