Quiero conectar mi tienda con la API de Gudink para que los pedidos se creen solos.
Antes de escribir código, leé la documentación completa, en este orden:
- Guía canónica: https://staging.gudink.com/api/v1/llms.txt (texto plano, sin clave).
Si otra página dice algo distinto, vale esta guía.
- Contrato exacto (OpenAPI): https://staging.gudink.com/api/v1/openapi.json (sin clave).
Ante una diferencia entre un ejemplo y la especificación, vale la especificación.
- Entorno de pruebas: https://ayuda.gudink.com/api/entorno-de-pruebas.md
- Errores, reintentos y límites: https://ayuda.gudink.com/api/errores-y-limites.md
- Si mi tienda es una plataforma (WooCommerce, Shopify, un ERP): lo que todo conector
resuelve, en la sección "Conectar una plataforma de e-commerce" de la guía y en
https://ayuda.gudink.com/api/conectar-una-plataforma.md
Entorno: trabajá SOLO contra el entorno de pruebas hasta que yo te diga lo contrario.
- GUDINK_API_BASE=https://staging.gudink.com/api/v1
- GUDINK_API_KEY=clave que empieza con gk_stg_ (ya está en mis variables de entorno)
- Nunca escribas https://app.gudink.com en el código: la URL base sale siempre de
GUDINK_API_BASE. Producción es cambiar esas dos variables, nada más.
- La cuenta, los productos, la clave y el destino de avisos de pruebas son otros que
los de producción. No guardes en el código ningún product_id ni variant_id.
Reglas que no se negocian:
1. La clave de Gudink se usa SOLO en el servidor, leída de la variable de entorno
GUDINK_API_KEY. Nunca en el navegador, nunca en el repositorio, nunca en una URL,
nunca en la descarga de una imagen.
2. Todo pedido se crea con un external_id único para siempre en mi cuenta de Gudink:
un prefijo propio de esta instalación (un código que generás una vez y guardás en
la configuración) más el número de pedido de mi tienda, por ejemplo woo-k7p2-10432.
Nunca el número de pedido solo. Ante un error de red, un timeout o un 5xx, reintentá con el MISMO external_id y el MISMO
cuerpo (guardá el cuerpo exacto que mandaste). Nunca generes un external_id nuevo
para reintentar. Si se acaban los intentos, consultá GET /orders?external_id=...
antes de volver a mandar. Después de cada 200 o 201 mirá status: si es
"cancelled", ese pedido no va (para volver a pedirlo, external_id nuevo).
3. Decidí por error.code y por el status HTTP, nunca por el texto del mensaje.
4. Los importes son enteros en pesos argentinos con IVA incluido. No dividas ni
multipliques por impuestos.
5. Las imágenes de los productos se descargan SIN la cabecera Authorization y se
alojan en mi sitio. No se enlazan directo.
6. Validá el formato del destinatario y la dirección en mi checkout ANTES de cobrar
(tabla "Qué va en cada campo").
7. En un pedido a domicilio, mandá en shipping_address.province la province que
devolvió la cotización. Si la cotización responde province_required, pedile la provincia a mi
comprador con un selector de las 24 provincias exactas de la documentación.
8. Ignorá los campos que no conozcas, tratá un status desconocido como "en curso" y
respondé 2xx a un tipo de aviso que no conozcas.
9. Gudink no le escribe a mi comprador: el seguimiento se lo paso yo.
10. Una línea es siempre el par product_id + variant_id: el mismo variant_id aparece
en varios productos, con precios distintos. Guardá las variantes con esa clave.
11. Un 409 out_of_stock no se reintenta en bucle. En pruebas, cancelá cada pedido
que no vayas a simular hasta el final: los pedidos sin pagar reservan stock.
12. Cada llamada a la API lleva una cabecera User-Agent propia (por ejemplo
MiTienda/1.0 (+https://mitienda.com)). Un 403 que no es JSON es un bloqueo de la
red, no un problema de la clave: los error.code sólo cuentan si la respuesta trae
el sobre { "error": { ... } }.
13. Las tareas programadas (sincronizar, alarmas) van con el cron del servidor, no con
uno que dependa de las visitas al sitio.
Lo que tenés que construir:
A. Sincronizar el catálogo: GET /products paginando hasta next_cursor null. Guardar
cada variante por el par (product_id, variant_id), con price y available, y el
updated_at del producto. Cada 60 minutos, y además
GET /products/:id de cada producto del carrito justo antes de cobrar.
B. En el checkout: POST /shipping/quotes con el carrito y el código postal, y mostrar
las opciones con su price. Cada opción tiene un type: home (a domicilio) o pickup
(retiro en sucursal). Si mi comprador elige pickup, mostrarle las sucursales de
pickup_points (nombre, dirección, horario, operador) y que elija una antes de pagar.
Una opción con un type que no conozcas, no la muestres.
C. Cuando la plata de mi comprador está acreditada (no cuando el pedido se registra):
POST /orders con el quote_id y el service_code elegidos. En un retiro, también el
pickup_point_id de la sucursal elegida y SIN shipping_address (sección "Retiro en
sucursal" de la guía). Si el carrito tiene
productos que no son de Gudink, cotizá y pedí sólo las líneas de Gudink.
D. Un endpoint HTTPS que reciba los avisos de Gudink, verifique la firma con
GUDINK_WEBHOOK_SECRET, deduplique por webhook-id, responda 2xx enseguida y
actualice el pedido en mi sistema. Tiene que aceptar el aviso de prueba
(type "webhook.test", sin order). Con order.shipped u order.tracking_updated,
pasarle el seguimiento a mi comprador.
E. Manejo de errores según la tabla de la documentación: hasta 4 intentos, nunca
antes de Retry-After (si no viene, esperas de 1, 2 y 4 segundos). Adentro del
checkout, nunca más de 30 segundos por espera: si Retry-After pide más, guardar
el pedido como pendiente y seguir en segundo plano. En segundo plano, esperar lo
que pida Retry-After. Un 5xx que no es JSON se trata como un error de red.
F. Una forma de ponerse al día después de una caída: GET /orders?created_after=...
para los pedidos nuevos y GET /orders?updated_after=... para los que ya tenía.
G. Una alarma para mí, por ejemplo cada hora: GET /orders?status=pending_payment y
avisarme de los que tienen expires_at en las próximas 24 horas, con su pay_url.
Si un pedido llega cancelado, mirá cancel_reason y avisame para que decida.
Para verificar, corré el "Recorrido de prueba de punta a punta" de la página del
entorno de pruebas: creá un pedido de prueba y hacelo avanzar con
POST /sandbox/orders/{id}/simulate (pay, start_production, ship, deliver), comprobando
que mi sistema recibe cada aviso y guarda el número de seguimiento. NO pagues el pedido
desde pay_url. Mostrame el resultado de cada uno de los diez pasos.
Si algo de la documentación no alcanza para decidir, no adivines: decime qué falta.
Mi web está hecha con: [completar: WooCommerce, Next.js, Shopify, etc.]
Dónde querés que quede el endpoint de avisos: [completar: por ejemplo /api/gudink/webhook]