Winal tiene un solo API con dos modos que conviven en la misma URL: el
modo prueba (llaves sk_test_…) y el modo producción
(llaves sk_live_…). No hay dos hosts distintos ni dos cuentas: la
llave que presentas decide en qué modo trabajas y qué dinero se mueve.
Base URL, misma superficie de endpoints. Cambias
sk_test_ por sk_live_ y el mismo código pasa de simular a
cobrar de verdad. Todo lo que devuelve la API trae livemode: false en
prueba y livemode: true en producción.
Base URL
Una sola: https://api.winal.com.mx. Los ejemplos de esta documentación ya la
traen escrita, así que un curl se copia y se pega tal cual. La raíz
https://winal.com.mx apunta a la misma aplicación y es la que ve una
persona en el navegador (documentación, liga de pago /pay/…, autofactura
/factura/…); para lo que llama tu código, usa siempre el host
api..
| Entorno | Base URL | Llave | livemode |
|---|---|---|---|
| Prueba (sandbox) | https://api.winal.com.mx | sk_test_… | false |
| Producción | https://api.winal.com.mx (la misma) | sk_live_… | true |
No la dejes escrita en tu código. Guárdala en una variable de entorno
(WINAL_BASE_URL) para que apuntar a otro host —una instancia dedicada el día
que crezcas, un ambiente propio de pruebas— sea cambiar una línea de configuración y no un
find-and-replace por todo el repo.
Modo prueba vs. producción
Los dos modos están aislados: un intent, un cliente o un webhook creado con
sk_test_ jamás aparece bajo sk_live_ ni al revés. En prueba,
el conector Sim viene activo por defecto — cobras de extremo a extremo con
tokens tok_sim_* sin dar de alta ningún proveedor real (ver
Modo de pruebas). En producción, el ruteo usa los
conectores reales que configuraste en el portal (Mercado Pago, Conekta, STP…).
| Modo prueba | Producción | |
|---|---|---|
| Prefijo de llave | sk_test_ | sk_live_ |
| Conector por defecto | Sim (caos determinista) | tus conectores reales |
| Tokens de pago | tok_sim_* | token real del proveedor |
| Movimiento de dinero | ninguno (simulado) | real |
livemode en respuestas y webhooks | false | true |
?live=true ni un header de entorno. El prefijo de la
llave es lo único que decide el modo. Trata tu sk_live_ como una
credencial de producción: nunca en el navegador, nunca en un repo, nunca en logs.
Tu Idempotency-Key también es de su modo
El aislamiento incluye el espacio de llaves de idempotencia: una
Idempotency-Key se identifica por (tu cuenta, el modo, la llave). O sea
que puedes reusar en producción las mismas llaves con las que integraste en prueba
sin recibir un conflicto y sin recibir por error la operación de prueba. Importa si tu punto
de venta deriva la llave de su propio folio de ticket —lo recomendable— y ensayó con los
mismos folios con los que después vende: en producción esa petición es nueva, y crea
su propia operación.
Dentro de un mismo modo nada cambia: repetir la misma llave con el mismo cuerpo devuelve la misma operación sin volver a ejecutarla, y repetirla con otro cuerpo sigue siendo un conflicto. Es lo que impide un doble cargo —y, en recargas, una segunda recarga al mismo teléfono, que no tiene reverso—, así que reintentar con la misma llave sigue siendo siempre lo correcto.
Cómo obtienes tu sk_test_
Crea tu cuenta en winal.com.mx/registro: verificas tu correo y la
pantalla te muestra una sola vez tu llave de prueba sk_test_… con un
botón de copiar. Guárdala en tu gestor de secretos en ese momento — por seguridad no se
vuelve a mostrar completa.
sk_live_), el mismo tablero trae una
sección con un checklist en vivo que te pide una capacidad completa, no todas:
cobrar de verdad (un conector real —el simulador no cuenta— con sus credenciales de
producción y tu ruteo de producción definido) o facturar de verdad (perfil fiscal
completo y tu CSD; la cuenta con el PAC la pone Winal), más 2FA activo en todo tu equipo, que sí se
le pide a toda cuenta. Si cobras en efectivo y solo quieres timbrar, con facturar te basta. En cuanto lo cumples,
solicitas la activación con un clic — nosotros la revisamos y resolvemos. Es la única
aprobación que no es autoservicio, a propósito: mover dinero real exige que quien pide no sea
quien concede. Detalle completo en Tu tablero.
# Guarda la Base URL y la llave como variables de entorno
export WINAL_BASE_URL="https://api.winal.com.mx"
export SK="sk_test_..." # la que copiaste del registro
curl -s "$WINAL_BASE_URL/v1/payment_intents" \
-H "Authorization: Bearer $SK" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "amount_minor": 84900, "currency": "MXN" }'
Verifica que estás vivo
El endpoint GET /health no requiere autenticación y no consume cupo de
rate limit — úsalo para confirmar tu Base URL antes de integrar. El
estado público (/status) reporta salud de
componentes sin exponer nada sensible.
curl -s "$WINAL_BASE_URL/health"
# → { "status": "ok" }
Siguiente paso
- Autenticación y seguridad — cómo se presenta la llave, rotación, expiración y postura de red.
- Tu tablero — qué hay en cada sección y el camino real a producción.
- Empieza aquí — tu primer cobro de prueba de extremo a extremo.
- Modo de pruebas — todos los tokens
tok_sim_*y cómo simular pagos entrantes. - Versionado y cambios — cómo evoluciona el API sin romperte.