Empieza aquí

MODO PRUEBA

Winal es un orquestador de pagos para negocios mexicanos: una sola API para cobrar con tarjeta, SPEI, CoDi, DiMo y OXXO, sin atarte a un solo proveedor de por vida. Tú conservas tus propias cuentas (Mercado Pago, Conekta, STP…) — Winal nunca custodia tu dinero, solo orquesta el cobro y ruteo entre proveedores. Cada cobro, devolución y liquidación queda en un ledger de doble partida que siempre cuadra, listo para auditoría.

🧪 Prueba TODO sin cuenta de ningún proveedor
El conector Sim viene activo por defecto: tarjeta, SPEI, CoDi y OXXO funcionan de extremo a extremo con tokens tok_sim_*, sin dar de alta Mercado Pago, Conekta ni ningún banco. Es el proveedor que usa esta guía. Detalle completo en Modo de pruebas.

Cómo funciona un cobro

Todo cobro en Winal pasa por tres momentos. El estado processing nunca se resuelve por un timeout local: solo evidencia real del proveedor (un webhook verificado, o una consulta de estado) puede cerrarlo.

1

Tu servidor crea el intent

POST /v1/payment_intents con el monto. Devuelve un client_secret seguro de exponer al navegador.

requires_payment_method
2

Tu página confirma

winal.js confirma con el método y token del pagador, y pinta el QR/CLABE/referencia si hace falta acción.

processing / requires_action
3

Tu servidor se entera por webhook

Winal firma y entrega payment_intent.succeeded (o failed). Esa es la verdad, no la respuesta HTTP de confirmar.

succeeded

Tu primer cobro en 5 minutos

Necesitas una clave sk_test_… del portal (portal → API Keys) y nada más — winal.js no tiene build ni dependencias.

1. Tu servidor crea el intent

Con tu clave de prueba, desde tu backend (nunca desde el navegador):

bash
curl -s https://api.winal.com.mx/v1/payment_intents \
  -H "Authorization: Bearer $SK" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "amount_minor": 84900, "currency": "MXN" }'
201 · respuesta real
{
  "id": "5b6b8b3e-1e4b-4c8a-9b2e-6f6a2c9d41a2",
  "object": "payment_intent",
  "amount_minor": 84900,
  "tip_minor": 0,
  "total_minor": 84900,
  "currency": "MXN",
  "status": "requires_payment_method",
  "client_secret": "pi_secret_9fZ3kQ7bV1x...",
  "livemode": false,
  "created_at": "2026-07-05T18:30:00Z",
  "updated_at": "2026-07-05T18:30:00Z"
}

Los campos next_action, metadata y attempts no aparecen: Winal omite cualquier campo en null de la respuesta (no lo devuelve como null, directamente no está). tip_minor/total_minor sí son siempre visibles (total_minor = amount_minor + tip_minor; ver Reportes → Propinas). Envía id y client_secret a tu página.

2. Tu página confirma con winal.js

html
<script src="https://api.winal.com.mx/js/winal.js"></script>
<div id="winal-mount"></div>
<script>
  const winal = Winal({ baseUrl: "https://api.winal.com.mx" });

  winal.confirmPayment({
    clientSecret: "pi_secret_9fZ3kQ7bV1x...",  // el del paso 1
    intentId: "5b6b8b3e-1e4b-4c8a-9b2e-6f6a2c9d41a2",
    paymentMethod: "card",         // "card" | "spei" | "codi" | "dimo" | "oxxo"
    paymentToken: "tok_sim_ok",    // prueba; producción: token del proveedor
    mountEl: document.getElementById("winal-mount"),
    onStatus: (status, intent) => console.log("estado:", status),
  }).then((intent) => {
    if (intent.status === "succeeded") alert("¡Pago exitoso!");
  }).catch((err) => alert(err.message));
</script>

confirmPayment llama al endpoint público (sin Authorization: el client_secret autentica), pinta automáticamente en mountEl el QR, la CLABE o la referencia según el método, y hace polling cada 2 s hasta un estado terminal. Ver el detalle de cada método en Métodos de pago.

3. Tu servidor confirma con el webhook — la fuente de verdad

Registra tu URL una vez (también puedes hacerlo desde el portal → Webhooks):

bash
curl -s https://api.winal.com.mx/v1/webhook_endpoints \
  -H "Authorization: Bearer $SK" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://tu-servidor.mx/webhooks/winal" }'
201 · respuesta real
{
  "id": "c1a9f2e0-77b1-4a3d-9e0a-1f2b3c4d5e6f",
  "object": "webhook_endpoint",
  "url": "https://tu-servidor.mx/webhooks/winal",
  "secret": "whsec_8Kx9...  (solo se muestra aquí, una vez)"
}

Nunca asumas éxito por el 200 de confirm: el estado final llega por payment_intent.succeeded (ver Webhooks para la verificación de firma) o consultando el intent desde tu servidor:

bash
curl -s "https://api.winal.com.mx/v1/payment_intents/5b6b8b3e-1e4b-4c8a-9b2e-6f6a2c9d41a2?expand=attempts" \
  -H "Authorization: Bearer $SK"
200 · respuesta real (ya conciliado)
{
  "id": "5b6b8b3e-1e4b-4c8a-9b2e-6f6a2c9d41a2",
  "object": "payment_intent",
  "amount_minor": 84900,
  "tip_minor": 0,
  "total_minor": 84900,
  "currency": "MXN",
  "status": "succeeded",
  "client_secret": "pi_secret_9fZ3kQ7bV1x...",
  "livemode": false,
  "created_at": "2026-07-05T18:30:00Z",
  "updated_at": "2026-07-05T18:30:04Z",
  "attempts": [
    {
      "id": "a13fce02-...",
      "object": "attempt",
      "status": "captured",
      "connector_key": "sim",
      "method": "card",
      "provider_ref": "sim_charge_9c1f...",
      "created_at": "2026-07-05T18:30:01Z"
    }
  ]
}

Siguientes pasos

  • Entornos y Base URL — sandbox vs. producción, sk_test_ vs. sk_live_ y tu Base URL.
  • Autenticación y seguridad — Bearer sk_, rotación y expiración de llaves, 2FA/SSO del portal y postura de red.
  • Métodos de pago — el shape real de next_action para SPEI, CoDi, DiMo, OXXO, BNPL y card-present.
  • Winal Connect — si tu negocio ES una plataforma: cobra, parte y dispersa a tus sub-comercios, sin custodia.
  • Onboarding de sub-comercios — el flujo KYC/KYB draft → submit → aprobado, requisito de Connect.
  • Payouts — dispersión a cualquier CLABE por SPEI, con o sin Connect.
  • Pago de servicios — catálogo, consulta de adeudo y pago de CFE, agua, telefonía y recargas.
  • Webhooks — verificación de firma, catálogo de eventos y reintentos.
  • Eventos y polling — alternativa a webhooks para desarrollo local (GET /v1/events).
  • Modo de pruebas — todos los tokens tok_sim_* y cómo simular pagos entrantes.
  • CLI winallogin/charge/listen/status desde tu terminal.
  • Errores — el envelope y los códigos de dominio reales.
  • Facturación CFDI — CFDI de ingreso (PUE) y facturas PPD con complemento de pagos (REP).
  • Reportes — propinas y corte de caja, informe de ahorro, y exports contables CONTPAQi/Aspel.
  • Integraciones — plugin oficial de WooCommerce.
  • Versionado y cambios — política de /v1, api_version por fecha y changelog.
  • Genera tu cliente — el contrato OpenAPI, los 4 SDKs oficiales y cómo generar un cliente en cualquier lenguaje.
  • Referencia de API — cada endpoint, sus headers y sus cuerpos exactos.