Seller-Hub-API
Índice
- Inicio
- Requisitos previos de integración
- Flujo de integración
- Flujo de operación
- Configuración de la integración
- Operación
- Validación final
Inicio
Bienvenido a la documentación de la API de SellerHub para Proveedores. Esta API le permite integrar su sistema con la plataforma de GoodMeal para gestionar de forma automatizada:
- Productos: consulta, carga, edición y actualización de stock en sus tiendas.
- Órdenes de compra: recepción, aceptación, actualización y cancelación de órdenes.
- Delivery: cotización y seguimiento del estado de cada envío.
En este documento encontrará los requisitos de integración, el flujo de operación y ejemplos prácticos para cada funcionalidad.
Requisitos previos de integración
Para integrar con SellerHub API, es importante cumplir con los siguientes requisitos:
| Requisito | Descripción |
|---|---|
| Credenciales | Las credenciales son claves únicas que te proporcionamos para que puedas configurar tu información y acceder a consumir los servicios. Estas son proporcionadas por el equipo de GoodMeal y las debes resguardar de manera segura. |
| Tiendas | Las tiendas, son donde cargaras tus productos, para ello estas serán configuradas por GoodMeal, quien luego te hará entrega de los accesos a cada una, para que puedas utilizar con la integración. |
| Parámetros de cuenta | Son algunos parámetros necesarios para funcionar, uno es para poder cotizar delivery con tu servicio (Si es que es necesario) y otro para que podamos hacer ingreso de las órdenes de compra en tus sistemas. De esto se hace cargo GoodMeal. |
Flujo de integración

Para usar el sistema de GoodMeal, debes conectar tu sistema a la API Seller, que te permitira:
- Consultar productos de tus tiendas
- Crear / Editar productos
- Agregar / Quitar stock de tus productos
- Obtener / Editar ordenes generadas por usuarios (desde la APP de GoodMeal)
- Permitir cotizar delivery
Flujo de operación

Configuración de la integración
La integración con SellerHub API es simple de utilizar y solo requiere contar con el token de uso, y toda la configuración previa que hace GoodMeal, con eso listo, podemos ir a configurar parámetros esenciales para funcionar.
Configuración de token de uso
Todas las llamadas a la API deben hacer uso del header:
X-API-TOKEN : <token-de-uso>
Y además, el {clientId}, que es un valor que te entregamos, como identificador de usuario.
Configuración de firma HMAC
Con la intención de verificar autenticidad e integridad de los mensajes, se utiliza esta firma HMAC.
La firma se envía en la cabecera X-Signature, con formato sha256=<hex> o solo el <hex>.
Cómo se calcula la firma
- Algoritmo: HMAC-SHA256.
- Payload: bytes exactos del body HTTP (el JSON tal como se envía en
Content-Type: application/json). - No uses
JSON.stringify()de un objeto ya parseado en el cliente: espacios, orden de claves y saltos de línea cambian la firma. - Requests sin body (p. ej.
GET): firmar cadena vacía ("").
Ejemplo en Node.js:
const crypto = require("crypto");
const secret = process.env.X_API_KEY; // el toke-de-uso asignado
const body = JSON.stringify(payload); // mismo texto que enviarás en el request
const hex = crypto.createHmac("sha256", secret).update(body).digest("hex");
// Cabecera
// X-Signature: sha256=<hex>
Ejemplo en terminal (OpenSSL):
echo -n '{"products":[]}' | openssl dgst -sha256 -hmac "$X_API_KEY" | awk '{print "sha256="$2}'
Ejemplo en Postman:
- Crea un Environment con
x_api_key= valor deX-API-KEY(el toke-de-uso asignado). - Body: raw → JSON.
- En Pre-request Script de la colección o de la request:
const secret = pm.environment.get("x_api_key");
const body = pm.request.body?.raw ?? "";
const hex = CryptoJS.HmacSHA256(body, secret).toString(CryptoJS.enc.Hex);
pm.request.headers.upsert({
key: "X-Signature",
value: `sha256=${hex}`,
});
Rutas cliente (/api/:clientId/...)
| Cabecera | Valor |
|---|---|
X-API-KEY |
<token-de-uso> asignado al cliente |
X-Signature |
HMAC-SHA256 del body con secreto X-API-KEY |
Configurar parámetros de tu cuenta
Hay dos parámetros que son esenciales para operar, a continuación como configurar cada uno.
Configuración de cotización de delivery
Para poder cotizar delivery con tus servicios, debemos ser capaces de llamarlos, para ello deberás configurar el parámetro: base_url_notification_trip , para ello debes llamar al método:
POST /{clientId}/accounts/params
{
'type': 'base_url_notification_trip',
'value': '<url-de-acceso-para-cotizar-delivery>',
'access': {
'method': 'TOKEN',
'token': {
'api-token': '<api-token>'
}
}
}
Esto es solo para configurarlo, luego en la sección de Gestión de orden, se comenta su utilización.
Configuración de envío de órdenes de compra
Ahora necesitamos saber a donde te enviaremos las órdenes de compra, para ello debemos configurar el siguiente parámetro: base_url_notification_purchase, para ello debes llamar al método:
POST /{clientId}/accounts/params
{
'type': 'base_url_notification_purchase',
'value': '<url-de-acceso-para-ordenes-de-compra>',
'access': {
'method': 'TOKEN',
'token': {
'api-token': '<api-token>'
}
}
}
Esto es solo para configurarlo, luego en la sección de Gestión de orden, se comenta su uso.
Tipos de respuesta
Basamos todas las respuestas en el estándar HTML, por ende todas las respuestas de la API van por los códigos:
- 200: Cuando todo está OK, se responde este valor, en conjunto con la respuesta.
- 4XX: Cuando hay un recurso que falla por temas de request, se retorna un 4XX, ya sea porque no se encontró el recurso (404), porque está prohibido acceder a él (401), etc.
- 5XX: Cuando el servicio encuentra un problema interno, responderá un 5XX y nuestro equipo técnico debe revisarlo.
Idempotencia (event_id)
Varias operaciones de escritura aceptan el campo event_id como clave de idempotencia. Si reenvías la misma operación con el mismo valor, la API evita aplicarla dos veces.
| Aspecto | Detalle |
|---|---|
| Obligatorio | No. Puedes omitir event_id; la petición se procesará, pero sin garantía de idempotencia ante reintentos. |
| Formato | UUID (por ejemplo, 8faceb77-576a-42fc-92db-c15eb728f424). Debe ser generado y enviado por tu sistema (el cliente de la API). |
| Cuándo usarlo | En cada operación que quieras poder reintentar de forma segura (timeouts de red, errores transitorios, etc.). |
| Reintentos | Si una petición falló o no obtuviste respuesta y deseas reenviarla sin duplicar el efecto, reutiliza el mismo event_id. Para una operación nueva, genera un nuevo UUID. |
Dónde enviarlo:
| Operación | Ubicación de event_id |
|---|---|
Crear o editar productos (POST /{clientId}/products) |
Raíz del body: "event_id" |
Actualizar stock (PUT /{clientId}/products/stock) |
Raíz del body: "event_id" |
Actualizar órdenes (PUT /{clientId}/orders) |
Dentro de cada ítem: order.event_id |
Recomendamos enviar event_id en integraciones automatizadas. El comportamiento con estados y respuestas HTTP descrito abajo aplica hoy a PUT /{clientId}/orders.
Estados de idempotencia (actualización de órdenes)
Al enviar order.event_id en PUT /{clientId}/orders, la API registra la operación y responde según uno de estos escenarios:
| Estado | HTTP | Significado | Qué hacer |
|---|---|---|---|
Éxito (success) |
200 OK |
La orden se procesó correctamente, o ya se había procesado antes con el mismo event_id y se devuelve la misma respuesta almacenada (sin volver a ejecutar la operación). |
Usar el body de la respuesta. Si fue un reintento, la orden no se duplicó. |
En proceso (in_progress) |
409 Conflict |
Otra petición con el mismo event_id se está procesando en este momento. |
Esperar unos segundos y reintentar con el mismo event_id y el mismo payload. |
Inválido (invalid) |
400 Bad Request |
El request no cumple las reglas de idempotencia (por ejemplo, el mismo order.event_id repetido dos veces dentro del arreglo orders de una sola petición). |
Corregir el payload. Mensaje típico: Duplicate order.event_id in request: <uuid>. |
Fallido (failed) |
400 Bad Request |
La operación no pudo completarse por un error de negocio o rechazo del servicio downstream. | Revisar el mensaje de error. Si quieres intentar de nuevo como operación distinta, usa un nuevo event_id. |
| Reintentos agotados | 429 Too Many Requests |
La API agotó los reintentos internos para procesar la operación (Max retry attempts exceeded). |
Esperar antes de reintentar (backoff). Puedes volver a enviar con el mismo event_id si no estás seguro de si la operación llegó a aplicarse. |
Reglas adicionales:
- Las órdenes del arreglo
orderssinorder.event_idse procesan de forma normal, sin registro de idempotencia (pueden convivir en la misma petición con órdenes que sí llevanevent_id). - En una misma petición, cada
order.event_iddebe ser único; no repitas el mismo UUID en dos ítems del arreglo. - Si varias órdenes llevan
event_idy algunas ya fueron procesadas, la respuesta200puede incluir un arregloresultscon el resultado por cadaevent_id. - Ante
409 Conflicto429 Too Many Requests(reintentos agotados), implementa backoff (espera incremental) antes de reintentar; no envíes ráfagas de peticiones con el mismoevent_id.
Limites de consumo
Tamaño máximo por solicitud
Algunos endpoints procesan registros en lote dentro de un mismo request. El arreglo correspondiente no puede superar los siguientes límites; si necesitas enviar más elementos, divide la operación en varias peticiones.
| Operación | Método y ruta | Campo | Límite |
|---|---|---|---|
| Crear o editar productos | POST /{clientId}/products |
products |
50 productos por solicitud |
| Publicar o actualizar stock | PUT /{clientId}/products/stock |
products |
50 productos por solicitud |
| Actualizar órdenes | PUT /{clientId}/orders |
orders |
10 órdenes por solicitud |
Si envías más registros de los permitidos, la API responderá con un error de validación (400).
Operación
Publicar productos
Ahora que ya has configurado tu tienda, vamos a cargar información en tu tienda, para que puedas vender.
Cargar y editar productos
Para poder vender a través de GoodMeal, debes cargar productos dentro de la tienda, para ello vamos a utilizar este método. Puedes enviar hasta 50 productos por solicitud en el arreglo products (ver Límites de consumo).
{
"method": "POST",
"url": "/{clientId}/products",
"headers": {
"Content-Type": "application/json",
"X-API-TOKEN": "",
},
"body": {
"store_code": "<string>",
"event_id" : "<string>",
"products": [
{
"category": "<string>",
"description": "<string>",
"discount_percent": "<number>",
"external_id": "<string>",
"name": "<string>",
"price_regular": "<number>",
"quantity": "<number>",
"size": "<string>",
"sku": "<string>",
"unit": "<string>",
"upc_ean": "<string>"
},
{
"category": "<integer>",
"description": "<string>",
"discount_percent": "<number>",
"external_id": "<string>",
"name": "<string>",
"price_regular": "<number>",
"quantity": "<number>",
"size": "<string>",
"sku": "<string>",
"unit": "<string>",
"upc_ean": "<string>"
}
]
}
}
Este es un ejemplo, puedes ir a la definición de la API, para ver cada parte en detalle. El campo event_id es opcional; sirve como clave de idempotencia (ver Idempotencia (event_id)).
El campo size es opcional y se envía como string con la abreviatura del tamaño del producto (ver Tamaños).
Obtener productos
Para consultar los productos cargados en una tienda, utiliza este método. Debes indicar el store_code de la tienda y el número de page como parámetros de consulta. La respuesta viene paginada.
{
"method": "GET",
"url": "/{clientId}/products?store_code=<string>&page=<integer>",
"headers": {
"X-API-TOKEN": ""
}
}
Parámetros
| Parámetro | Ubicación | Descripción |
|---|---|---|
store_code |
Query | Código de la tienda a consultar. |
page |
Query | Número de página a consultar (comienza en 1). |
Paginación
| Campo | Descripción |
|---|---|
data |
Lista de productos de la página solicitada. |
links.first |
URL de la primera página. |
links.last |
URL de la última página. Puede ser null si aún no se conoce. |
links.prev |
URL de la página anterior. null en la primera página. |
links.next |
URL de la página siguiente. null en la última página. |
meta.current_page |
Página actual. |
meta.current_page_url |
URL de la página actual. |
meta.from |
Índice del primer producto en la página. |
meta.to |
Índice del último producto en la página. |
meta.per_page |
Cantidad de productos por página. |
meta.path |
URL base del endpoint sin parámetros de consulta. |
Ejemplo de respuesta:
{
"status": 200,
"statusMsg": "Success",
"data": [
{
"name": "<string>",
"sku": "<string>",
"categories": [
{
"id": "<integer>",
"name": "<string>",
"description": "<string|null>"
}
],
"description": "<string>",
"discount_percentage": "<integer>",
"unit": "<string|null>",
"quantity": "<integer>",
"weight": "<number|null>",
"size": {
"name": "<string>",
"abbreviation": "<string>"
},
"image_url": "<string>",
"price": "<integer>",
"price_discount": "<integer>",
"volume": "<number|null>"
}
],
"links": {
"first": "<string|null>",
"last": "<string|null>",
"prev": "<string|null>",
"next": "<string|null>"
},
"meta": {
"current_page": "<integer>",
"current_page_url": "<string>",
"from": "<integer>",
"path": "<string>",
"per_page": "<integer>",
"to": "<integer>"
}
}
Puedes ir a la definición de la API para ver cada campo en detalle.
Categorías
Estas son las categorías de las que disponemos:
Nombres de categorías
- Picoteo
- Congelados
- Desayuno
- Cocina
- Bebidas
- Limpieza
- Cuidado personal
- Frutas y/o verduras
- Supermercado
Tamaños
El campo size corresponde al tamaño físico del producto. Se envía como string con la abreviatura del catálogo de tamaños disponibles. Este valor es importante porque se utiliza al cotizar y solicitar delivery: el sistema calcula la capacidad del envío según el tamaño acumulado de los productos de la orden.
| Abreviatura | Tamaño | Referencia |
|---|---|---|
xs |
Extra small | Tamaño mínimo del catálogo |
sm |
Small | Se puede llevar con una mano (ej. una botella de agua) |
md |
Medium | Requiere una bolsa para transportarlo (ej. una bolsa de supermercado) |
lg |
Large | Requiere ambas manos (ej. un monitor) |
xl |
Extra large | Requiere varios viajes para transportar el contenido |
Cómo elegir el tamaño correcto
- Asigna el
sizeque mejor represente el empaque real del producto, no su peso ni su unidad de venta. - Si un producto es más grande que Small pero cabe en una bolsa de compras, usa
md. - Si el comprador necesitaría llevarlo con las dos manos, considera
lgo superior. - Un valor incorrecto puede afectar la cotización de delivery y el tipo de vehículo asignado al envío.
Relación con el delivery
Los tamaños se utilizan para estimar si el pedido puede despacharse en vehículo de 2 ruedas (bicicleta, moto) o requiere vehículo de 4 ruedas (auto).
Cantidad y unidades
El campo unit y quantity_unit, corresponde a la unidad de medida y la cantidad de esa unidad, no son obligatorios, pero puede ayudar a mejorar la busqueda de un cliente.
Lista de unidades:
- gr: Gramos
- kg: Kilogramos
- lb: libras
- lt: litros
- ml: mililitros
- oz: Onza
- un: Unidad
Actualizar stock
Ya agregaste los productos, ahora debemos agregar el stock necesario para poder vender, para ello debemos hacer uso de esta llamada. El arreglo products admite hasta 50 ítems por solicitud (ver Límites de consumo).
{
"method": "PUT",
"url": "/{clientId}/products/stock",
"headers": {
"X-API-TOKEN": "",
"Content-Type": "application/json"
},
"body": {
"store_code": "<number>",
"event_id" : "<string>",
"products": [
{
"sku": "<string>",
"stock": "<number>"
},
{
"sku": "<string>",
"stock": "<number>"
}
]
}
}
Cuidado!
Una vez cargues stock, estos comenzaran aparecer en la tienda, para su venta, asi que ten cuidado con cargar stock, si no quieres vender.
Mi stock publicado
Consulta el stock que tienes publicado en una tienda, junto con el estado de la publicación, la fecha y hora de publicación, el horario de atención configurado y el detalle de cada producto con su stock.
{
"method": "GET",
"url": "/{clientId}/products/stock?store_code=<string>",
"headers": {
"X-API-TOKEN": ""
}
}
Parámetros
| Parámetro | Ubicación | Descripción |
|---|---|---|
store_code |
Query | Código de la tienda a consultar. |
Respuesta (data)
| Campo | Descripción |
|---|---|
status |
Estado de la publicación. Valores: ACTIVE, INACTIVE. |
post_date |
Fecha y hora de publicación en formato ISO 8601 (UTC), por ejemplo 2026-05-25T04:00:00.000000Z. |
initial_pick_up_time |
Hora de apertura de la tienda (formato HH:mm). |
end_pick_up_time |
Hora de cierre de la tienda (formato HH:mm). |
products |
Lista de productos publicados en la tienda. |
Productos (data.products[])
| Campo | Descripción |
|---|---|
name |
Nombre del producto. |
status |
Estado del producto. Valores: ACTIVE, INACTIVE. |
current_stock |
Stock actual disponible para la venta. |
initial_stock |
Stock con el que inició la publicación. |
total_stock |
Stock total del producto en la publicación. |
Ejemplo de respuesta
{
"status": 200,
"statusMsg": "Success",
"data": {
"id": 726,
"restaurant_id": 225,
"status": "ACTIVE",
"post_date": "2026-05-25T04:00:00.000000Z",
"initial_pick_up_time": "04:30",
"end_pick_up_time": "23:30",
"today_active": true,
"store_routine_schedule_id": null,
"products": [
{
"id": 2090,
"name": "PAN 2025",
"status": "ACTIVE",
"current_stock": 8,
"initial_stock": 1,
"total_stock": 23,
"shop_product_id": 622,
"price": 1625,
"real_price": 2500
}
]
}
}
Detalle de producto publicado
Obtiene el detalle de un producto publicado por su identificador. El product_id corresponde al campo id de cada ítem en la lista de GET /{clientId}/products/stock.
{
"method": "GET",
"url": "/{clientId}/products/stock/{product_id}?store_code=<string>",
"headers": {
"X-API-TOKEN": ""
}
}
Parámetros
| Parámetro | Ubicación | Descripción |
|---|---|---|
product_id |
Path | Identificador del producto publicado. |
store_code |
Query | Código de la tienda a consultar. |
Respuesta (data)
| Campo | Descripción |
|---|---|
id |
Identificador del producto publicado. |
name |
Nombre del producto. |
status |
Estado del producto. Valores: ACTIVE, INACTIVE. |
current_stock |
Stock actual disponible para la venta. |
initial_stock |
Stock con el que inició la publicación. |
total_stock |
Stock total del producto en la publicación. |
sell_stock |
Stock vendido. |
shop_product_id |
Identificador del producto en la tienda. |
type |
Tipo de producto (por ejemplo, MULTI_PRODUCT). |
net_content |
Contenido neto del producto. |
price |
Precio de venta. |
real_price |
Precio de referencia. |
store_id |
Identificador interno de la tienda. |
is_cross_selling |
Indica si el producto es de venta cruzada. |
Ejemplo de respuesta
{
"status": 200,
"statusMsg": "Success",
"data": {
"id": 2090,
"product_id": null,
"name": "PAN 2025",
"shop_product_id": 622,
"brand": null,
"type": "MULTI_PRODUCT",
"net_content": "10 lt",
"price": 1625,
"real_price": 2500,
"store_id": 226,
"current_stock": 8,
"initial_stock": 1,
"total_stock": 23,
"status": "ACTIVE",
"sell_stock": 11,
"is_cross_selling": false,
"tags": null,
"expiration_date": null,
"label": null,
"max_stock": null
}
}
Gestión de orden de compra
Ahora que publicaste productos, debemos procesar las órdenes de compra que te lleguen, de tus usuarios.
Cotizar delivery
Lo primero, si estás ofreciendo delivery, el usuario cotizará tu servicio, de todas las opciones que configuraste, tu deber es responderle un precio a cobrar y el usuario decidirá si lo acepta o no, esto lo veremos en el siguiente apartado.
Para ello te llegará una llamada a tu servicio de delivery configurado con lo siguiente:
{
"code_id": "<string>",
"delivery": {
"address": "<string>",
"delivery_code": "<string>",
"detailed_address": {
"aditional_address_information": "<string>",
"city": "<string>",
"commune": "<string>",
"country": "<string>",
"state": "<string>",
"street_address_1": "<string>",
"zip_code": "<string>"
},
"location": {
"lat": "<string>",
"log": "<string>"
}
},
"products": [
{
"category": "<integer>",
"description": "<string>",
"discount_percent": "<number>",
"external_id": "<string>",
"name": "<string>",
"price_regular": "<number>",
"quantity": "<number>",
"size": "sm",
"sku": "<string>",
"unit": "<string>",
"upc_ean": "<string>"
},
{
"category": "<integer>",
"description": "<string>",
"discount_percent": "<number>",
"external_id": "<string>",
"name": "<string>",
"price_regular": "<number>",
"quantity": "<number>",
"size": "sm",
"sku": "<string>",
"unit": "<string>",
"upc_ean": "<string>"
}
],
"store_code": "<string>"
}
Para el objeto delivery:
{
"type": "object",
"properties": {
"address": {
"type": "string",
"description": "direccion del usuario, calle y numero"
},
"delivery_code": {
"type": "string",
"description": "el codigo del tipo de delivery que ingresaste al configurar tu cuenta"
},
"aditional_address_information": {
"type": "string",
"description": "informacion extra de la direccion, ej. Depto 101"
},
"city": {
"type": "string",
"description": "Ciudad del delivery"
},
"commune": {
"type": "string",
"description": "Comuna del delivery (CL)"
},
"country": {
"type": "string",
"description": "Pais del delivery (CL)"
},
"street_address_1": {
"type": "string",
"description": "Direccion completa"
},
"zip_code": {
"type": "string",
"description": "codigo ZIP de la direccion"
},
"lat": {
"type": "string",
"description": "Latitud de la direccion"
},
"log": {
"type": "string",
"description": "Longitud de la direccion"
}
}
}
Luego se incluye un arreglo de productos, para que se pueda calcular la capacidad del delivery, lo más importante de aquí:
- external_id: que corresponde al ID que utilizan en sus sistemas para identificar el producto.
- quantity: que es la cantidad del producto que se quiere comprar
- sku: que es el SKU del producto tuyo.
Como respuesta se espera un 200 OK con el siguiente body:
{
"total_price_trip": 1500,
"extra_info": "Se va a enviar en caja de 8 unidades.",
"expires": "2024-07-15T14:24:18.377Z",
"duration": 38,
"pickup_duration": 23
}
Donde:
- total_price_trip: precio a cobrar por el delivery (obligatorio). Debe ser un número. Moneda CLP
- extra_info: comentario adicional sobre el envío (opcional). Por ejemplo, restricciones de empaque o plazos estimados.
- expires: fecha y hora de expiración de la cotización en formato DATETIME TZ(obligatorio). Indica hasta cuándo el precio cotizado sigue siendo válido.
- duration: duración total estimada del envío en minutos . Incluye el tiempo de retiro y traslado hasta el destino(opcional).
- pickup_duration: tiempo estimado en minutos hasta que el repartidor llegue al punto de retiro (opcional).
Si no puedes realizar el delivery para la dirección o productos solicitados, responde con un código 4XX según lo indicado en Tipos de respuesta.
Recepcionar una orden de compra
Ahora que ya se pudo concretar la venta, debemos enviarte la orden de compra a la url que configuraste previamente.
el objeto delivery, solo aparece cuando la tienda tiene custom delivery activado.
-
purchase_type: Retiro Delivery Custom Delivery -
order_status: APPROVED CANCELED
Para ello, te enviaremos esto:
{
"order_id": "<string>",
"purchase_type": "<string>",
"buyer_name": "<string>",
"buyer_email": "<string|null>",
"order_product_price": <number>,
"created_at": "<string>",
"store_code": "<string>",
"order_status": "<string>",
"delivery": {
"address": "<string>",
"delivery_code": "<string>",
"detailed_address": {
"aditional_address_information": "<string>",
"city": "<string>",
"commune": "<string>",
"country": "<string>",
"state": "<string>",
"street_address_1": "<string>",
"zip_code": "<string>"
},
"location": {
"lat": "<string>",
"log": "<string>"
}
},
"products": [
{
"name": "<string>",
"quantity": <number>,
"sku": "<string>",
"price": <number>,
"type": "<string>"
},
{
"name": "<string>",
"quantity": <number>,
"sku": "<string>",
"price": <number>,
"type": "<string>"
}
]
}
Donde se incluye el {order_id}, que corresponde al ID de la orden, para poder identificarla más adelante, para hacer cambios.
Dentro hay dos objetos importantes:
- delivery: El objeto previamente utilizado para definir el delivery, que corresponde a la cotización previa.
- products: un arreglo con todos los productos comprados en la orden
Como respuesta se espera lo siguiente (o simplemente un 200 OK, sin body):
{
"order_status": "string",
"detail_order_status": "string",
"delivery_status": "string",
"detail_delivery_status": "string",
"quote_id": "string",
"tracking_url": "string"
}
Donde:
- order_status: puede ser uno de los siguientes estados:
- PENDING: orden está siendo procesada, te permite dar una revisión más exhaustiva de la orden, antes de aceptarla, puedes cambiar algunas cosas de la orden, estando aquí.
- APPROVED: orden aceptada, ya solo puedes actualizar información de delivery y la url de la boleta, entre otros.
- CANCELED: orden cancelada, le avisamos al cliente, que no puedes procesar la orden.
- detail_order_status: Un comentario interno, no será visto por el cliente.
- delivery_status (opcional): para el caso que quieras actualizar el estado del delivery,
- PENDING: preparando el pedido
- ON_GOING: en camino a entregar el pedido
- NEAR: llegando a destino
- DELIVERED: entregado
- CANCELED: cancelado
- quote_id: ID de cotizacion de delivery
- tracking_url: url para tracking, si es que hay delivery asociado.
Actualizar una orden de compra
Mientras una orden de compra, este en estado PENDING, puedes editar cierta información. En cada petición puedes incluir hasta 10 órdenes en el arreglo orders (ver Límites de consumo).
Incluye order.event_id (UUID opcional) para idempotencia: si reenvías la misma actualización, la API devuelve la respuesta previa o indica si aún está en proceso (409). Ver Estados de idempotencia.
PUT /{clientId}/orders
{
"orders": [
{
"delivery": {
"quote_id": "QWEDW-IJEDA-JWED",
"status": "PENDING",
"tracking_url": "https://..."
},
"order": {
"invoice_url": "https://...",
"event_id" : "asdasd-asdasda-asdad-abscd",
"order_id": "asdasd-asdasda-asdad-",
"status": "PENDING"
},
"products": [
{
"available_quantity": 50,
"quantity": 100,
"sku": "23423423"
}
],
"store_code": "QQW@#D@D@#D"
}
]
}
Los campos que puedes editar, estando en estado PENDING son:
- delivery.status: puedes actualizar el estado del delivery
- delivery.tracking_url: Puedes agregar la URL de tracking para delivery
- order.invoice_url: Puedes agregar la URL de la boleta de la orden
- order.status: Puedes dejarlo siempre en PENDING, para seguir editando, luego pasarlo a APPROVED o CANCELED.
- products.available_quantity: IMPORTANTE aquí debes agregar la cantidad de stock que tienes disponible para esta orden, si tienes el stock, no hay necesidad de modificarlo, pero si tienes menos, debes actualizar ese producto, para que podamos hacer la devolución al comprador.
Actualizar información de delivery
Una vez una orden este en estado APPROVED, puedes editar el objeto delivery con información relacionada con el estado del delivery:
- PENDING: preparando el pedido
- ON_GOING: en camino a entregar el pedido
- NEAR: llegando a destino
- DELIVERED: entregado
- CANCELED: cancelado
Con el mismo método anterior (PUT /{storeId}/orders), pero además, cuando cambies el estado, se enviarán notificaciones PUSH al usuario, para que este sepa en qué estado está su pedido.
Cancelar una orden de compra
Puedes cancelar una orden por cualquier motivo, de diversas formas:
- Cuando recibes una orden, puedes enviarnos el estado CANCELED
{ "order_status": "CANCELED", ... } - Cuando quieras actualizar la orden, nos envías el estado CANCELED:
PUT /{clientId}/orders { "value": { "orders": [ { "delivery": { ... }, "order": { "event_id" : "asdasd-asdasda-asdad-asdfd", "order_id": "asdasd-asdasda-asdad-", "status": "CANCELED" }, "products": [ ... ], "store_code": "QQW@#D@D@#D" } ] } } - Llamando al método de API, donde puedes enviar varias:
PUT /{clientId}/orders/canceled { "orders": [ { "order_id" : "8faceb77-576a-42fc-92db-c15eb728f424", "store_code": "e11a5997-404a-448c-bebe-31bdca2698b1" } ] }
Validación final
Una vez integrado con un ambiente previo, se hace un flujo de compra normal para validar que todos los puntos de integración están funcionando correctamente.
Cuando se autorice la integración por ambas partes, se procederá a mover configuraciones hacia un ambiente productivo para comenzar a operar.