Volver a docs

API e Integraciones

Documentación técnica para conectar Conexiones con tu sitio, Zapier, Slack o tu sistema interno.

1. Webhooks salientes

Conexiones envía un POST a tu URL cada vez que ocurre un evento relevante (venta, reembolso, etc). Configura suscripciones en /admin/webhooks.

Formato de la request

POST https://tu-app.com/webhook
Content-Type: application/json
User-Agent: Conexiones-Webhook/1.0
x-conexiones-event: sale.confirmed
x-conexiones-timestamp: 1716732000000
x-conexiones-signature: 6f3b1...
x-conexiones-delivery: wd_abc...

{
  "event": "sale.confirmed",
  "timestamp": "2026-05-26T12:00:00.000Z",
  "data": {
    "orderId": "CNX-MPMQ-XXXX",
    "eventId": "evt_xxxxx",
    "eventName": "Mi Evento",
    "eventDate": "2026-06-30T22:30:00.000Z",
    "customerEmail": "comprador@gmail.com",
    "customerName": "Pedro Pérez",
    "ticketCount": 2,
    "total": 42400,
    "subtotal": 40000,
    "serviceFee": 2400,
    "discountCode": null,
    "discountAmount": 0,
    "paymentMethod": "mercado-pago",
    "paidAt": "2026-05-26T12:00:00.000Z"
  }
}

Eventos disponibles

EventoCuándo se dispara
sale.confirmedUna orden pasa a estado paid (incluye cortesías y FREE)
refund.createdUna orden pagada es reembolsada
*Todos los eventos (suscripción por defecto)

Verificar firma HMAC

Cada request lleva una firma en el header x-conexiones-signature. La firma se calcula como HMAC-SHA256(secret, timestamp + "." + body) en hexadecimal. El secret se genera al crear el webhook y se muestra UNA SOLA VEZ.

Ejemplo Node.js

import { createHmac, timingSafeEqual } from 'node:crypto'

function verifyConexiones(req, secret) {
  const ts = req.headers['x-conexiones-timestamp']
  const sig = req.headers['x-conexiones-signature']
  const body = req.rawBody  // necesitas el body crudo, no parseado

  // Rechazar requests > 5 min para evitar replay
  if (Math.abs(Date.now() - Number(ts)) > 5 * 60_000) {
    throw new Error('Webhook expirado')
  }

  const expected = createHmac('sha256', secret)
    .update(`${ts}.${body}`)
    .digest('hex')

  const a = Buffer.from(sig, 'hex')
  const b = Buffer.from(expected, 'hex')
  if (a.length !== b.length || !timingSafeEqual(a, b)) {
    throw new Error('Firma inválida')
  }
}

Ejemplo Python

import hmac, hashlib, time

def verify_conexiones(headers, body, secret):
    ts = headers['x-conexiones-timestamp']
    sig = headers['x-conexiones-signature']

    if abs(time.time() * 1000 - int(ts)) > 5 * 60_000:
        raise ValueError('Webhook expirado')

    expected = hmac.new(
        secret.encode(),
        f"{ts}.{body}".encode(),
        hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(sig, expected):
        raise ValueError('Firma inválida')

Reintentos y entrega

  • Timeout: 5 segundos. Si tu endpoint no responde en ese tiempo, lo registramos como fallo.
  • Body máximo: 16 KB. Si el payload se acerca, segmentamos.
  • El servidor espera 2xx. Cualquier otro código se loguea pero no se reintenta automáticamente todavía (en roadmap).
  • Cada delivery queda en la tabla webhook_deliveries con status + response (visible en futura UI).

2. Widget embebido

Permite vender entradas DESDE el sitio del productor sin que el comprador salga de la página.

Snippet mínimo

<button data-conexiones-evento="slug-del-evento">
  Comprar entrada
</button>
<script src="https://www.conexiones.cloud/embed.js" defer></script>

API JS pública

// Abrir programáticamente
ConexionesEmbed.open('slug-del-evento', {
  referrer: 'newsletter-marzo',  // tracking opcional
})

// Cerrar
ConexionesEmbed.close()

// Versión y URL base
ConexionesEmbed.version  // "1.0.0"
ConexionesEmbed.baseUrl  // "https://www.conexiones.cloud"

Mercado Pago en iframe

MP bloquea ser cargado dentro de iframes cross-origin (su política, no la nuestra). El widget detecta el caso y abre el form de pago de MP en una ventana nueva via window.open. Tras el pago, el comprador vuelve al sitio del productor — puede refrescar el modal o navegar al email para descargar las entradas.

Para más detalle: docs principales o ver el snippet completo en /embed-demo.html dentro del repo.

3. Estabilidad y versionado

  • Campos nuevos son aditivos: podemos agregar propiedades al payload de un evento sin previo aviso. Tu integración debería ignorar propiedades desconocidas en lugar de fallar.
  • Campos no se renombran: si quitamos o renombramos un campo, será con un evento nuevo (p.ej. sale.confirmed.v2) y mantendremos el anterior por al menos 90 días.
  • Endpoints internos: las rutas bajo /api/admin/* NO son API pública. No las uses desde fuera; usa el widget o los webhooks.
  • Sandbox: aún no exponemos un entorno de sandbox separado. Para probar webhooks puedes usar el evento Propositalk Charlas Deportivas con código FREE — la venta se confirma sin cobro real y dispara el webhook normalmente.

¿Necesitas ayuda?

Escribe a contacto@conexiones.cloud y dime tu use case. Si lo que necesitas es razonable lo agregamos.