
API Export
只读 REST API,用于将您 elpizzero 账户中的数据——订单、菜单、配送区域、餐厅信息和指标——导出到您自己的系统(CRM、BI、财务、屏幕等)。包含实时流 (SSE) 和出站 webhooks,以便实时响应变化。
- Base URL:
https://elpizzero.com/api/export - Auth: 每个请求携带
Authorization: Bearer <token>。 - 格式:JSON UTF-8。金额为整数分,日期为 ISO-8601 UTC。
- 方法:所有资源均支持
GET;POST/DELETE仅用于管理您的 webhooks。
身份验证
通过请求头传递 Bearer token。token 的格式为 elp_live_<32hex> 或 elp_test_<32hex>。
Authorization: Bearer elp_live_3b8f0c2a1d4e5f6079a8b7c6d5e4f3a2
在 控制面板 → 集成 → API 密钥 中生成和撤销 token,并选择其权限。token 仅完整显示一次。
权限
| Scope | 启用 |
|---|---|
pedidos.leer | /pedidos, /pedidos/{id}, /pedidos/{id}/historial, /resumen |
carta.leer | /carta |
restaurante.leer | /restaurante, /zonas |
stream.escuchar | /stream (SSE) |
webhook.recibir | /webhooks(新增/删除/列表) |
token 缺少所需 scope → 403 alcance_insuficiente。
环境
elp_live_ 和 elp_test_ 读取的是相同的真实数据;不存在带模拟数据的沙盒。前缀仅是便于区分 token 的标签。
Rate limit
每个 token 每分钟 60 次请求。每个响应中包含请求头:X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset。超出限制 → 429 + Retry-After。
约定
- 金额:整数分(
total_cents: 820= 8,20 €)。币种在单独字段中(moneda: "EUR")。 - 日期:带
Z的 ISO-8601 UTC(2026-05-31T20:42:15Z)。 - ID:不透明,带类型前缀 —
ped_、prod_、cat_、tam_、grp_、opt_、zon_、rest_、itm_、wh_。请将其视为字符串。 - 隔离:每个 token 绑定一家餐厅,仅返回该餐厅的数据。
- 分页:基于 cursor(
cursor→paginacion.siguiente),默认降序。
错误
统一的响应体 + 一致的 HTTP 状态码:
{
"ok": false,
"error": "Esta llave no tiene el alcance necesario: pedidos.leer",
"codigo": "alcance_insuficiente",
"doc": "https://elpizzero.com/docs/api/export#auth"
}
| HTTP | codigo |
|---|---|
| 401 | llave_ausente · llave_invalida · llave_revocada · llave_expirada |
| 403 | alcance_insuficiente · restaurante_inactivo |
| 400 | parametro_invalido(包含 valores_validos) |
| 404 | no_encontrado |
| 405 / 429 | metodo_invalido · limite_alcanzado |
订单列表
餐厅的订单,按 id 降序,cursor 分页。
| Query | Tipo | 说明 |
|---|---|---|
estado | csv | pendienteconfirmadoen_preparacionlistoen_repartoentregadocancelado |
tipo | enum | repartorecogidamesa |
desde / hasta | ISO | creado_en 的范围(desde ≤ x < hasta)。 |
limite | int | 1–100,默认 25。 |
cursor | string | 上一页返回的 paginacion.siguiente 的值。 |
curl "https://elpizzero.com/api/export/pedidos?estado=entregado&desde=2026-05-01&limite=50" \
-H "Authorization: Bearer elp_live_..."
{
"datos": [ /* Objeto Pedido */ ],
"paginacion": { "limite":50, "siguiente":"ni", "anterior":null, "total_aprox":494 }
}
cursor = paginacion.siguiente 迭代,直到其为 null,即可导出全部历史记录。获取单个订单
返回订单对象。{id} 需带前缀,例如 ped_ni。如果不属于您,则返回 404 no_encontrado。
订单历史
{
"pedido_id": "ped_ni",
"eventos": [
{ "momento":"2026-05-31T20:42:15Z", "accion":"order_created",
"origen":"sistema", // sistema|panel|tpv|apk_recepcion|api
"usuario":null, "detalle":{} }
]
}
菜单
完整的树结构:分类 → 商品 → 规格 → 选项组 → 选项。?solo_disponibles=true 会排除隐藏/售罄的项目。
{
"restaurante_id":"rest_1", "restaurante_slug":"tu-restaurante",
"moneda":"EUR", "idioma_origen":"es", "generado_en":"2026-06-01T18:41:27Z",
"categorias": [{
"id":"cat_v", "nombre":"Pizzas", "activa":true,
"visible_dias":["lun","mar","mie","jue","vie","sab","dom"], "visible_horario":null,
"productos": [{
"id":"prod_3J", "nombre":"Margarita", "precio_cents":680,
"disponible":true, "destacado":false, "alergenos":["gluten","lacteos"],
"tamaños":[{ "id":"tam_11", "nombre":"mediana", "precio_cents":680, "predeterminado":true }],
"grupos_opcion":[{ "id":"grp_73", "nombre":"Extras", "requerido":false,
"min_seleccion":0, "max_seleccion":5,
"opciones":[{ "id":"opt_8", "nombre":"Extra queso", "precio_cents":120 }] }]
}]
}]
}
配送区域
以 GeoJSON 表示的多边形配送区域(坐标为 [lng, lat],闭合环)。
{ "datos": [{
"id":"zon_8", "nombre":"Albatera", "slug":"albatera",
"color":"#44c3e5", "tarifa_cents":250, "pedido_minimo_cents":2000,
"minutos_estimados":40, "activa":true,
"poligono":{ "tipo":"Polygon", "coordenadas":[[[-0.872,38.186], /* … */]] }
}] }
餐厅
餐厅资料:联系方式、位置、每日营业时间、品牌、各渠道语言、口碑评价。不含敏感税务数据。
{
"id":"rest_1", "slug":"tu-restaurante", "nombre":"Tu Restaurante",
"moneda":"EUR", "zona_horaria":"Europe/Madrid",
"acepta_pedidos":true, "pedido_minimo_cents":500,
"horario":{ "viernes":[{"desde":"18:45","hasta":"23:30"}] /* … */ },
"contacto":{ "email":"…", "telefono":"…", "web":"…" },
"ubicacion":{ "direccion":"…", "ciudad":"…", "lat":38.14, "lng":-0.88 },
"branding":{ "logo_url":"…", "color_primario":"…", "galeria":[] },
"reputacion":{ "puntuacion":4.7, "votos":128 }
}
汇总 / 指标
periodo ∈ hoyayer7d30dmes_actual。按餐厅所在时区计算;不包含已取消/已拒绝的订单。
{
"periodo":"30d", "desde":"2026-05-03T00:00:00+02:00", "hasta":"2026-06-02T00:00:00+02:00",
"zona_horaria":"Europe/Madrid",
"kpis":{ "pedidos_total":442, "pedidos_cancelados":52, "clientes_distintos":413,
"ventas_cents":893435, "ticket_medio_cents":2021, "moneda":"EUR" },
"mix_tipo":{ "reparto":268, "recogida":171, "mesa":3 },
"top_productos":[{ "producto_id":"prod_3K", "nombre":"Margarita", "unidades":150, "ventas_cents":113845 }]
}
实时流 (SSE)
Server-Sent Events。即时推送事件。通过 query 进行身份验证(EventSource 不支持请求头)。通过 Last-Event-ID 每 5 分钟原生重连;约每 25 秒发送一次 conexion.ping。
const es = new EventSource("https://elpizzero.com/api/export/stream?llave=elp_live_...");
es.addEventListener("pedido.nuevo", e => {
const ev = JSON.parse(e.data); // ev.datos.pedido = Objeto Pedido
console.log(ev.datos.pedido.numero);
});
可选过滤参数 ?eventos=pedido.nuevo,pedido.aceptado。推送的事件类型:
pedido.nuevopedido.aceptadopedido.rechazadopedido.estado_cambiadopedido.item_modificadopedido.entregadopedido.cancelado
出站 webhooks
pull → push 的替代方案:订单发生变化时,我们会向您的 URL 发送 POST。仅出站。
curl -X POST "https://elpizzero.com/api/export/webhooks" \
-H "Authorization: Bearer elp_live_..." -H "Content-Type: application/json" \
-d '{"url":"https://tu-sistema.com/hook","nombre":"Mi CRM","eventos":["pedido.aceptado","pedido.entregado"]}'
{ "id":"wh_3", "url":"https://tu-sistema.com/hook",
"eventos":["pedido.aceptado","pedido.entregado"],
"secreto_firma":"a1b2…(64 hex, se muestra UNA vez)", "activo":true }
事件:实时流中的事件 + 通配符 pedido.* 和 *。 GET /webhooks 列表 · DEL /webhooks/{id} 删除。
投递与签名
每次推送都包含以下请求头;请求体与实时流中的对象相同:
X-Elp-Evento: pedido.aceptado
X-Elp-Id: 84213 # úsalo como clave de idempotencia
X-Elp-Firma: <hmac_sha256_hex(secreto, cuerpo_crudo)>
X-Elp-Intento: 1
// Verificación (Node)
const firma = crypto.createHmac("sha256", SECRETO).update(rawBody).digest("hex");
if (firma !== req.headers["x-elp-firma"]) return res.sendStatus(401);
X-Elp-Intento 递增)。请根据 X-Elp-Id 去重。订单对象
由 /pedidos、/pedidos/{id}、实时流和 webhooks 返回的结构。示例中的客户数据已匿名化。direccion/mesa/entrega/fiscal 在不适用时为 null。
{
"id":"ped_ni", "numero":"20260531-095",
"tipo":"reparto", // reparto|recogida|mesa
"estado":"en_preparacion",
"fuente":"web_publica", // web_publica|tpv|manual|admin
"creado_en":"2026-05-31T20:42:15Z", "aceptado_en":"…Z",
"entregado_en":null, "programado_para":null,
"restaurante":{ "id":"rest_1", "slug":"tu-restaurante", "nombre":"Tu Restaurante" },
"cliente":{ "nombre":"Juan Pérez", "telefono":"+34 600 000 000",
"email":"cliente@ejemplo.com", "consintio_marketing":false },
"direccion":{ "linea":"Calle Mayor 22", "codigo_postal":null, "pais":"ES", "lat":38.154, "lng":-0.880 },
"mesa":null,
"items":[{ "id":"itm_A3", "producto_id":"prod_3K", "nombre":"Margarita",
"tamaño":"mediana", "cantidad":1,
"precio_unitario_cents":720, "opciones_total_cents":120, "total_cents":840,
"estado_cocina":"pendiente",
"opciones":[{ "id":"opc_5", "grupo":"Extras", "nombre":"Extra queso", "cantidad":1, "precio_cents":120 }] }],
"totales":{ "moneda":"EUR", "subtotal_cents":840, "descuento_cents":0, "propina_cents":0,
"tarifa_reparto_cents":100, "impuestos_cents":85, "total_cents":1025,
"iva_desglose":[{ "tipo_porcentaje":10, "base_cents":940, "iva_cents":85 }] },
"pago":{ "metodo":"online", "estado":"pagado", "proveedor":"stripe",
"referencia_externa":"pi_3Td…", "pagos":[] },
"entrega":{ "repartidor_nombre":null, "zona_id":"zon_a", "zona_nombre":"Granja de Rocamora", "tarifa_cents":100 },
"fiscal":{ "factura_numero":"FA-1132/2026", "factura_fecha":"…Z", "factura_pdf":"https://…/factura.pdf" },
"instrucciones":null
}
示例:厨房电视屏幕
自包含的 HTML+JS(只读):粘贴您的 token,在电视上打开,订单即通过实时流实时进入。