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.
https://hub.gamesphere.mx/api/v1Authorization: Bearer <api_key>. Crea tus llaves en el panel → Integración.gs_test_… (pruebas: los pedidos nunca llegan a Exel ni generan cobro) y gs_live_… (producción). Cada llave solo ve los pedidos de su modo.429 con Retry-After.POST /envios/cotizar (opcional): precio vigente y opciones de paquetería para el CP del cliente.POST /pedidos: el pedido queda Pendiente de pago. Precio y envío se respetan hasta apartado_hasta (24 h por omisión).total a Gamesphere con el folio como referencia y lo registras con POST /pedidos/{folio}/pago → En revisión de pago.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.
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"] } } }
401 | Llave faltante, inválida o revocada. |
404 | Recurso no encontrado (o de otro modo prueba/producción). |
409 | Conflicto de estado o existencias: sin_almacen_unico, sin_existencias, estado_invalido, transportista_no_disponible. |
422 | Datos inválidos. |
429 | Límite de peticiones. |
502 | Exel no respondió; reintenta en unos minutos. |
/productosPará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.
/productos/{referencia}Detalle con existencias y precio en tiempo real, existencias por almacén e imágenes.
/categorias · /marcas/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.
/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.
/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": "…" } ] }
/pedidosFiltros: estado (uno o varios separados por coma), num_orden, desde (actualizados desde una fecha), pagina, por_pagina (máx. 200).
/pedidos/{folio}/pagoDespué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.
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": "…" } }
/pedidos/{folio}/aceptar-cambioAceptas el nuevo total: queda pendiente_pago por la diferencia (saldo).
/pedidos/{folio}/rechazar-cambioNo 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.
/pedidos/{folio}/cancelarSolo antes de que el pago sea confirmado. Cuerpo opcional { "motivo": "…" }.
/pedidos/{folio}/reactivarUn pedido vencido (no se pagó a tiempo) se recotiza y abre un nuevo plazo.
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.
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);
/webhooks/pruebaEnvía un prueba.ping a tu URL y regresa el resultado.
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:
/pruebas/pedidos/{folio}/simular-pagoConfirma el pago y lo pasa a pedido_exel (folio Exel SIM-…).
/pruebas/pedidos/{folio}/simular-envio/pruebas/pedidos/{folio}/simular-entregaCada paso dispara sus webhooks, así pruebas tu integración de punta a punta.
| Estado | Significado |
|---|---|
pendiente_pago | Creado; esperando tu pago hasta apartado_hasta. |
revision_pago | Registraste un pago; Gamesphere lo está verificando. |
pagado | Pago confirmado; se está colocando en Exel. |
requiere_atencion | Cambió precio, existencias o hubo un error con Exel. Ver atencion. |
pedido_exel | Exel lo recibió; se está preparando. |
enviado | Salió con guía (guia). |
entregado | Recibido por el cliente final. |
vencido | No se pagó a tiempo. Puedes reactivarlo. |
cancelado | Cancelado. |
reembolso | Cancelado después del pago; Gamesphere te devuelve el dinero. |
Dudas de integración: escribe al equipo de Gamesphere.