Crear un pedido de la integración
POST /api/integration/create-order
Descripción
Crea en una sola llamada un pedido completo con sus productos, el cliente y el domicilio.
Detalles
Guarda todo el pedido o nada: si una línea, el domicilio o el envío no son válidos, no queda nada guardado. Los precios, nombres y tiempos de servicio de los productos los pone el restaurante. Las reglas del canal deciden si el pedido va directo a cocina o espera. Una referencia externa ya usada devuelve el mismo pedido sin crear otro. En modo simulación valida y calcula los totales sin guardar nada.
Permisos requeridos
orders.integration
Request
| Nombre | Tipo | Requerido | Reglas |
|---|---|---|---|
| externalReference | string | Sí |
min:1
max:60
|
| channelCode | string | No |
max:60
|
| fulfillmentUuid | string | Sí |
min:36
max:36
|
| dryRun | bool | No |
default:0
|
| notes | string | No |
max:500
|
| customerName | string | No |
max:150
|
| customerPhone | string | No |
max:30
|
| addressLine | string | No |
max:300
|
| addressDetail | string | No |
max:200
|
| municipalityCode | string | No |
max:10
|
| reference | string | No |
max:300
|
| deliveryZoneId | int | No |
min_value:1
|
| deliveryFeeCents | int | No |
min_value:0
|
| items | array | Sí | — |
| items[].productId | int | No |
min_value:1
|
| items[].sku | string | No |
max:50
|
| items[].menuId | int | Sí |
min_value:1
|
| items[].qty | int | Sí |
min_value:1
max_value:999
|
| items[].note | string | No |
max:500
|
| items[].productPriceId | int | No |
min_value:1
|
| items[].productPriceOptionId | int | No |
min_value:1
|
| items[].modifiers | array | No | — |
| items[].modifiers[].modifierGroupId | int | Sí |
min_value:1
|
| items[].modifiers[].modifierId | int | Sí |
min_value:1
|
| items[].modifiers[].quantity | int | Sí |
min_value:1
|
Respuesta
Campos que devuelve dentro de data. Nada fuera de esta lista sale en la respuesta.
| Campo | Tipo | Descripción |
|---|---|---|
| order | object | Encabezado del pedido |
| order.orderUuid | string Admite vacío | Identificador del pedido; vacío en una simulación |
| order.orderCode | string Admite vacío | Código corto del pedido; vacío en una simulación |
| order.externalReference | string | Número del pedido en el sistema de la integración |
| order.lifecycleStatus | string | Estado del pedido |
| order.paymentStatus | string | Estado del pago |
| order.channelCode | string | Canal de venta del pedido |
| order.fulfillmentUuid | string | Canal de entrega del pedido |
| order.fulfillmentTypeCode | string | Tipo de canal de entrega |
| order.notes | string Admite vacío | Nota general del pedido |
| order.subtotalCents | int | Total de los productos en centavos |
| order.discountCents | int | Descuento en centavos |
| order.taxCents | int | Impuestos en centavos |
| order.tipCents | int | Propina en centavos |
| order.deliveryFeeCents | int | Costo del envío en centavos |
| order.grandTotalCents | int | Total a pagar en centavos |
| order.paidCents | int | Pagado en centavos |
| order.balanceCents | int | Saldo pendiente en centavos |
| order.deliveryStatus | string Admite vacío | Estado del domicilio; vacío si no es a domicilio |
| order.createdAt | datetime | Cuándo se creó el pedido |
| items | array | Líneas del pedido con su precio cobrado |
| items[].itemUuid | string | Identificador de la línea |
| items[].productId | int | Producto de la línea |
| items[].name | string | Nombre del producto |
| items[].qty | decimal | Cantidad |
| items[].unitPriceCents | int | Precio unitario en centavos |
| items[].modifiersTotalCents | int | Opciones por unidad en centavos |
| items[].priceCents | int | Total de la línea en centavos |
| items[].lifecycleStatus | string | Estado de la línea |
| items[].note | string Admite vacío | Nota de la línea |
| itemModifiers | array | Opciones elegidas en las líneas |
| itemModifiers[].itemUuid | string | Línea a la que pertenece la opción |
| itemModifiers[].modifierId | int | Identificador de la opción |
| itemModifiers[].name | string | Nombre de la opción |
| itemModifiers[].quantity | decimal | Cantidad de la opción |
| itemModifiers[].unitPriceCents | int | Precio de la opción en centavos |
| itemModifiers[].totalCents | int | Total de la opción en centavos |
| isExistingOrder | bool | Si la referencia ya estaba usada y se devolvió el pedido existente |
| isDryRun | bool | Si fue una simulación que no guardó nada |
Ejemplo de request
curl -X POST https://restofy.pro/api/integration/create-order \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <accessToken>" \
-d '{
"externalReference": "string",
"fulfillmentUuid": "string",
"items": [
{
"menuId": 1,
"qty": 1
}
]
}'
Los valores son demo: reemplázalos por datos reales del negocio.
Ejemplo de respuesta
Actualizado: 2026-11-02T19:00:57Z
HTTP 200
Request
{
"externalReference": "WEB-79D4B0AD",
"fulfillmentUuid": "038465df-d113-11f1-8bb6-de64ef616b7c",
"customerName": "Laura Gómez",
"customerPhone": "+573001234567",
"addressLine": "Calle 85 # 12-40",
"addressDetail": "Apto 302",
"reference": "Portería azul",
"items": [
{
"productId": 9,
"menuId": 1,
"qty": 3
}
],
"deliveryZoneId": 1
}
Response
{
"success": true,
"message": "Operación realizada correctamente",
"data": {
"order": {
"orderUuid": "9fc370cb-db1a-48fa-9d24-b064076e0d94",
"orderCode": "36A-B74",
"externalReference": "WEB-79D4B0AD",
"lifecycleStatus": "open",
"paymentStatus": "unpaid",
"channelCode": "channel.staff.pos",
"fulfillmentUuid": "038465df-d113-11f1-8bb6-de64ef616b7c",
"fulfillmentTypeCode": "fulfillment.delivery",
"notes": null,
"subtotalCents": 6900000,
"discountCents": 0,
"taxCents": 0,
"tipCents": 0,
"deliveryFeeCents": 100,
"grandTotalCents": 6900100,
"paidCents": 0,
"balanceCents": 6900100,
"deliveryStatus": "pending",
"createdAt": "2026-11-02T18:34:05.000Z"
},
"items": [
{
"itemUuid": "be2009a7-2a2e-45c7-bda9-769d927303a1",
"productId": 9,
"name": "Cazuela de Mariscos",
"qty": "3.0000",
"unitPriceCents": 2300000,
"modifiersTotalCents": 0,
"priceCents": 6900000,
"lifecycleStatus": "confirmed",
"note": null
}
],
"itemModifiers": [],
"isExistingOrder": false,
"isDryRun": false
}
}