Saltar al contenido
Desarrolladores

Webhooks de comunidad

Mateflow envía un HTTP POST a tu URL cuando ocurre algo en una comunidad. Esta página explica qué recibe tu receptor, cómo verificarlo, qué pasa cuando falla y todos los campos de cada evento.

Inicio rápido

Cada entrega es un POST con un cuerpo JSON. Si varios webhooks están suscritos a un evento, cada uno recibe su propia copia.

  1. En el panel de administración de tu comunidad, abre Configuración → Integraciones → Webhooks y crea un webhook: introduce la URL, elige los eventos, genera un secreto y actívalo.
  2. Procesa cada solicitud en este orden:
    1. Lee el cuerpo sin procesar de la solicitud y verifica la firma.
    2. Si test es true, devuelve 200 y termina.
    3. Deduplica por event_id.
    4. Pasa el trabajo a tu propia cola y devuelve un 2xx en menos de 10 segundos.
  3. Haz clic en Probar Webhook para enviar una solicitud de prueba y abre Registros de entrega para ver la solicitud y la respuesta.

Planes y configuración

Los webhooks son una función de plan y solo los administradores de la comunidad pueden gestionarlos.

PlanWebhooks por comunidad
FreeNo disponible
StarterNo disponible
Growth5
Business20
EnterpriseIlimitados
  • Si bajas a un plan sin webhooks, tu configuración de webhooks se conserva, pero no se entrega ni se registra nada. Al volver a subir de plan se restablece la entrega.
  • Los webhooks se crean y se gestionan en la consola de administración. La Community Open API no tiene endpoints para ellos.

Configuración

AjusteRequisito
URLEl formulario de administración solo acepta URL https://, de hasta 1.024 caracteres.
Direcciones inaccesiblesLas solicitudes a direcciones que se resuelven a rangos de loopback, privados o de enlace local se bloquean al conectar y se tratan como un error de red. Para el desarrollo local, usa un túnel público.
NombreHasta 100 caracteres.
EventosAl menos uno, del catálogo de más abajo. Un webhook guardado antes con una lista de eventos vacía recibe todos los eventos.
SecretoOpcional, hasta 128 caracteres. Una vez guardado se puede reemplazar, pero no volver a leer. Sin secreto, las solicitudes no se firman, por lo que recomendamos encarecidamente definir uno. El secreto nunca aparece en una solicitud.

Formato de entrega

Cada entrega es un POST con un tiempo de espera de 10 segundos por solicitud.

Cabeceras

CabeceraValorNotas
Content-Typeapplication/jsonSiempre JSON.
User-AgentMateflow-Webhook/1.0Identifica a Mateflow como remitente.
X-Mateflow-TimestampSegundos UnixCuándo se envió esta solicitud. Forma parte de la firma.
X-Mateflow-Signaturesha256= seguido de un resumen hexadecimalSolo está presente cuando el webhook tiene un secreto.

Los webhooks personalizados no tienen la cabecera X-Mateflow-Delivery-Id. Lee delivery_id del cuerpo.

Cuerpo

CampoTipoDescripción
eventstringEl código del evento.
event_idstringEl identificador único del evento. Deduplica por este campo. Se mantiene igual entre reintentos automáticos y reenvíos manuales, y en todos los webhooks suscritos al evento. Trátalo como una cadena opaca.
occurred_atRFC 3339Cuándo ocurrió el evento, con precisión de segundos. Se mantiene igual entre reintentos.
delivery_idstring (decimal)Identifica esta entrega. Cambia en cada reintento automático; un reenvío manual conserva el valor original.
timestampRFC 3339Cuándo se generó el cuerpo. Un reenvío manual conserva el valor original, así que usa la cabecera para juzgar la antigüedad.
webhook_idhashidEl webhook que recibe esta entrega.
site_idhashidLa comunidad.
dataobjectLos datos del evento, descritos en el catálogo de eventos.

En casos raros, cuando falla la generación de ID, event_id y occurred_at pueden faltar. Acéptalo y recurre a event más el ID de negocio de data para detectar duplicados.

JSON
{
  "event": "payment.received",
  "event_id": "86116692152877061",
  "occurred_at": "2026-11-03T00:00:00Z",
  "delivery_id": "86116692152877060",
  "timestamp": "2026-11-03T00:00:01Z",
  "webhook_id": "qP3aXm71Bd",
  "site_id": "Z5Kf08mFv8r",
  "data": {
    "member_id": "b7Lq2WxR9e",
    "username": "sample_member",
    "email": "sample.member@example.com",
    "invoice_id": "in_1Abc",
    "subscription_id": "sub_1Abc",
    "amount_cents": 2900,
    "currency": "usd",
    "period_start": "2026-11-03T00:00:00Z",
    "period_end": "2026-12-03T00:00:00Z"
  }
}

Verificar firmas

Cuando un webhook tiene un secreto, cada solicitud se firma con HMAC-SHA256 sobre la cabecera de marca de tiempo y el cuerpo sin procesar.

Firma
X-Mateflow-Signature = "sha256=" + hex(
  HMAC-SHA256(secret, X-Mateflow-Timestamp + "." + raw_request_body)
)
  • Usa los bytes sin procesar. Los caracteres especiales en HTML pueden aparecer escapados en el cuerpo, así que si analizas el JSON y lo vuelves a serializar obtienes bytes distintos y la firma no coincidirá.
  • Toma la marca de tiempo de la cabecera, no del cuerpo. Un reenvío manual actualiza solo la marca de tiempo de la cabecera y la firma.
  • Comprobar la marca de tiempo no interfiere con los reintentos. Cada reintento automático y cada reenvío manual se firman de nuevo, así que una ventana de 5 minutos es suficiente.
Node.js
const crypto = require('crypto');

// rawBody must be the untouched bytes, e.g. from express.raw({ type: 'application/json' }).
function verifyMateflowSignature(rawBody, headers, secret, toleranceSeconds = 300) {
  const timestamp = headers['x-mateflow-timestamp'];
  const received = headers['x-mateflow-signature'] || '';
  if (!timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > toleranceSeconds) {
    return false;
  }
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.`)
    .update(rawBody)
    .digest('hex');
  const a = Buffer.from(received);
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Python
import hashlib
import hmac
import time


def verify_mateflow_signature(raw_body: bytes, headers, secret: str, tolerance_seconds: int = 300) -> bool:
    timestamp = headers.get("X-Mateflow-Timestamp", "")
    received = headers.get("X-Mateflow-Signature", "")
    if not timestamp.isdigit() or abs(time.time() - int(timestamp)) > tolerance_seconds:
        return False
    signed = timestamp.encode() + b"." + raw_body
    expected = "sha256=" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(received.encode(), expected.encode())

Vector de prueba

Usa estos valores para comprobar tu cálculo de la firma. La marca de tiempo ha caducado, así que amplía tu ventana de tiempo mientras pruebas.

Vector de prueba
secret                 my_signing_secret
X-Mateflow-Timestamp   1793664000
raw body (UTF-8)       {"event":"member.joined","data":{"username":"张三"}}
X-Mateflow-Signature   sha256=3f4c83828ce0086150c9bd48c1654899357b7c05265c1d1b6c172225ee04b4b4

Rotar un secreto

Un secreto nuevo entra en vigor en cuanto se guarda, y los reintentos en cola también se firman con él. No hay un periodo en el que Mateflow firme con ambos, así que haz que tu receptor acepte tanto el secreto antiguo como el nuevo durante el cambio.

Respuestas y reintentos

Cómo se juzga una entrega depende únicamente de tu código de estado. El cuerpo de la respuesta no se analiza.

Tu receptorResultadoSe reintenta
2xxCorrectaNo
5xx, 408, 429FallidaSí
Tiempo de espera agotado, fallo de conexión, dirección bloqueadaFallida, registrada con estado 0Sí
Cualquier otro 4xxFallidaNo
  • Calendario de reintentos: tras un fallo, Mateflow espera 1 minuto, 10 minutos, 1 hora y después 6 horas. Con el primer intento, son como máximo 5 intentos en unas 7 horas.
  • Cuándo se rinde la entrega: cuando se agotan los reintentos, o ante un estado que no se reintenta, el propietario de la comunidad y los administradores reciben un correo, como máximo uno por webhook cada 24 horas.
  • Interrumpida a medias: si el webhook se elimina o se desactiva, o el plan deja de incluir webhooks, los intentos posteriores ni se envían ni se registran.
  • Redirecciones: las entregas siguen las redirecciones, pero un 301, 302 o 303 convierte el POST en un GET sin cuerpo. Introduce la URL final y no cuentes con una redirección de http a https.

Reenvío manual

Reenviar en Registros de entrega envía de nuevo una entrega a la URL actual del webhook.

  • El cuerpo es idéntico, incluidos event_id, delivery_id y timestamp. La cabecera de marca de tiempo y la firma son nuevas.
  • Lo intenta una sola vez y no se reintenta si falla. El resultado aparece como una fila nueva en el registro.
  • Solo se pueden reenviar entregas de webhooks personalizados, y el webhook debe seguir existiendo y estar activado.

Registros de entrega

Los registros se conservan 30 días. Solo se guardan los primeros 4 KB del cuerpo de cada respuesta.

Fiabilidad

Lo que tu receptor puede y no puede dar por sentado.

  • Al menos una vez. El mismo evento puede llegar más de una vez. Deduplica por event_id.
  • Añade una segunda comprobación para todo lo que implique dinero. Mateflow ya deduplica el mismo pago y el mismo inicio o fin de suscripción, pero si esa comprobación no está disponible envía en lugar de descartar, y entonces los dos eventos tienen valores de event_id distintos. Comprueba también invoice_id, subscription_id o order_id.
  • Sin garantía de orden. Las entregas se ejecutan en paralelo y se reintentan, así que access_group_removed y access_group_added de un miembro pueden llegar invertidos. Para saber cuál fue primero, usa occurred_at, que tiene precisión de segundos.
  • Es posible una pérdida rara. Los eventos se ponen en cola después de confirmar los datos, así que un proceso que termina entre esos dos pasos pierde el evento.
  • Concilia si sincronizas el estado. Trata un evento como una señal de que algo cambió, lee el estado actual desde la Open API (por ejemplo /member/get con el ámbito members.read) y ejecuta periódicamente una comparación completa. La Open API no devuelve direcciones de correo, así que toma esas de los eventos.

Catálogo de eventos

Puedes suscribirte a 17 eventos.

Reglas para todos los campos

  • Los ID de Mateflow son cadenas hashid, los mismos valores que usa la API. Un valor de 0 no se codifica y aparece como el número 0.
  • member_id y user_id se refieren a la misma persona. member.joined, los eventos de publicaciones y los de comentarios usan user_id; todo lo demás usa member_id.
  • Los ID de Stripe se pasan sin cambios: invoice_id, subscription_id, charge_id y payment_intent_id.
  • Las fechas y horas son RFC 3339 en UTC.
  • Los importes son enteros en la unidad más pequeña de la moneda (céntimos para USD), y currency es un código de moneda en minúsculas.
  • Un campo opcional que no aplica se omite. No es null ni una cadena vacía.
  • Los campos y los valores de enumeración solo se añaden, nunca se cambian. Tu receptor debe tolerar los nuevos.

Todos los eventos

EventoSignificadoNombre de usuario y correo
member.joinedSe unió un miembro nuevoSí
member.leftUn miembro salió de la comunidadSí
member.role_changedCambió el rol de un miembroNo
member.suspendedUn miembro fue suspendido o expulsadoNo
member.reinstatedSe levantó una suspensión o una expulsiónNo
member.access_group_addedUn miembro pasó a tener un grupo de accesoSí
member.access_group_removedUn miembro dejó de tener un grupo de accesoSí
post.createdSe publicó una publicaciónNo
post.deletedSe eliminó una publicaciónNo
comment.createdSe publicó un comentarioNo
comment.deletedSe eliminó un comentarioNo
payment.receivedLlegó un pago, por una factura de suscripción o por una compra únicaSí
subscription.renewedUna suscripción se renovó correctamenteSí
payment.failedFalló el pago de una facturaSí
subscription.createdSe creó una suscripción en StripeSí
subscription.canceledUna suscripción terminóSí
refund.issuedSe emitió un reembolsoSí

Miembros

member.joined

Se unió un miembro nuevo.

CampoTipoSiempre presenteDescripción
user_idhashidSíID del miembro.
usernamestringSíNombre de usuario.
emailstringSíDirección de correo.

Se envía cuando

  • Un registro se completa, incluido el inicio de sesión social, un primer inicio de sesión con SSO y el registro mediante una invitación.
  • Se completa un registro de pago.
  • Se aprueba una solicitud de ingreso.
  • Alguien se registra de nuevo con el mismo correo y se restaura su cuenta. El evento se envía otra vez.

No se envía cuando

  • Se importan miembros desde un archivo CSV.
  • Un miembro sigue esperando aprobación en una comunidad que revisa las solicitudes de ingreso.

member.left

Un miembro salió de la comunidad.

CampoTipoSiempre presenteDescripción
member_idhashidSíEl mismo valor que el user_id del miembro en member.joined.
usernamestringSíNombre de usuario antes de salir, aunque la salida borre sus datos personales.
emailstringSíDirección de correo antes de salir, en las mismas condiciones.
sourcestringSíCómo salió. Consulta la tabla de abajo.
removed_byhashidNoEl administrador que actuó. Solo para removed y anonymized.
reasonstringNoSolo para removed, cuando el administrador indicó un motivo.
sourceSignificadoRegistrarse de nuevo con el mismo correo
removedUn administrador eliminó al miembroRestaura el mismo ID y vuelve a enviar member.joined
account_deletedEl miembro eliminó su propia cuenta, de inmediato o al terminar el periodo de reflexión de 30 díasEliminación inmediata: igual que arriba. Tras el periodo de reflexión: un ID nuevo
anonymizedUn administrador anonimizó al miembro conforme al GDPR (RGPD)Un ID nuevo
inactivityLimpieza de cuentas inactivas, que se ejecuta en lotes nocturnosUn ID nuevo

No se envía cuando

  • Se desactiva una cuenta.
  • Un miembro está dentro del periodo de reflexión tras pedir que se elimine su cuenta. Se envía cuando el periodo termina, y no se envía en absoluto si lo cancela.
  • Un miembro es expulsado o suspendido, lo que envía member.suspended.
  • Alguien nunca llegó a unirse, como una solicitud de ingreso rechazada o pendiente.
  • Termina una suscripción.
  • Se elimina la comunidad.
  • Un miembro sale de un solo espacio.
  • Los grupos de acceso que se borran al salir no se envían uno por uno como member.access_group_removed. Interpreta member.left como que el miembro ya no tiene ningún grupo de acceso.

member.role_changed

Cambió el rol de un miembro.

CampoTipoSiempre presenteDescripción
member_idhashidSíID del miembro.
previous_rolestringSímember, moderator o admin, siempre en minúsculas.
rolestringSíLos mismos valores.
changed_byhashidSíQuién hizo el cambio.

No se envía cuando

  • El rol no cambió realmente.
  • Solo cambió Billing Admin o un rol personalizado.

member.suspended

Un miembro fue suspendido o expulsado. Ambos casos usan este evento y se distinguen por ban_type.

CampoTipoSiempre presenteDescripción
member_idhashidSíID del miembro.
suspended_byhashidSíEl administrador que actuó.
reasonstringSíLa nota interna del administrador. Puede ser una cadena vacía. No se la muestres al miembro.
ban_typestringSísuspend o ban.
duration_daysnumberNoSolo para suspend.
suspended_untilRFC 3339NoSolo para suspend.
viastringNomoderation cuando se hizo al tramitar una denuncia. Se omite cuando se hizo desde la gestión de miembros.

Se envía cuando

  • Se suspende o se expulsa a un miembro desde la gestión de miembros o al tramitar una denuncia, de uno en uno o en bloque.

No se envía cuando

  • Un miembro solo recibe una advertencia.

member.reinstated

Se levantó una suspensión o una expulsión.

CampoTipoSiempre presenteDescripción
member_idhashidSíID del miembro.
reinstated_byhashidNoEl administrador que actuó. Se omite cuando via es expired.
fromstringSíQué se levantó: suspend o ban.
viastringNomoderation (levantada en moderación), appeal (apelación aprobada) o expired (la suspensión terminó). Se omite cuando se levantó desde la gestión de miembros.

No se envía cuando

  • Una suspensión terminó, pero el miembro tiene otra expulsión activa, por lo que sigue restringido.
  • Cuando termina una suspensión, el evento suele salir en unos minutos, porque los vencimientos se comprueban cada 5 minutos. occurred_at es el momento en que se detectó el vencimiento.

member.access_group_added, member.access_group_removed

Un miembro pasó a tener o dejó de tener un grupo de acceso. Cada evento abarca a un miembro y un grupo de acceso, así que pasar una suscripción de Silver a Gold envía un removed y un added.

CampoTipoSiempre presenteDescripción
member_idhashidSíID del miembro.
usernamestringSíNombre de usuario.
emailstringSíDirección de correo.
access_group_idhashidSíEl mismo valor que access_groups[].id en la Open API.
access_group_namestringSíEl nombre del grupo en ese momento. Si el grupo se eliminó, el nombre anterior a la eliminación.
sourcestringSíConsulta la tabla de abajo.
changed_byhashidNoSolo para manual y invitation.
sourceEventosSignificadochanged_by
manualadded, removedUn administrador lo concedió o lo quitó en la consolaEl administrador
subscriptionadded, removedUna suscripción empezó, terminó o cambió de nivelNinguno
invitationaddedEl miembro aceptó una invitaciónQuien invitó
defaultaddedEl miembro entró en el grupo predeterminadoNinguno
group_deletedremovedSe eliminó el grupo de accesoNinguno

No se envía cuando

  • El conjunto de grupos del miembro no cambió realmente.
  • Un miembro entra automáticamente en el grupo predeterminado al registrarse.
  • El cambio afecta a un miembro que sigue esperando aprobación.
  • Los grupos se borran porque se eliminó la cuenta.
  • Eliminar un grupo de acceso o definir un grupo predeterminado es un cambio en bloque. Los eventos se envían miembro por miembro y llegan entre segundos y minutos después de la acción, mientras que occurred_at sigue siendo el momento de la acción. Su event_id tiene un formato distinto, por eso hay que tratarlo como opaco.

Contenido

En los cuatro eventos, post_id es el ID del contenido en sí y user_id es el autor, no quien realizó la acción. space_id se omite cuando el contenido no está en un espacio. También se envía el contenido de los espacios privados, así que filtra por space_id si tu receptor lo necesita.

post.created

Se publicó una publicación o una entrada de blog.

CampoTipoSiempre presenteDescripción
post_idhashidSíID de la publicación.
user_idhashidSíEl autor.
space_idhashidNoEl espacio que la contiene.
titlestringSíTítulo. Puede ser una cadena vacía.
bodystringSíFuente en Markdown, hasta 500 caracteres. Puede cortarse antes, en una palabra o un signo de puntuación, sin puntos suspensivos. En una entrada de blog es el extracto.

Se envía cuando

  • Una publicación o una entrada de blog pasa a ser pública: se publica directamente, se aprueba desde la cola de revisión o llega la hora programada.

No se envía cuando

  • Se publica un comentario, lo que envía comment.created.
  • Una entrada de blog envía este evento solo en su primera publicación, pero una que se despublicó y luego se programó de nuevo puede enviarlo otra vez. Haz que tu procesamiento sea idempotente por post_id.

post.deleted

Se eliminó una publicación o una entrada de blog.

CampoTipoSiempre presenteDescripción
post_idhashidSíID de la publicación.
user_idhashidSíEl autor.
space_idhashidNoEl espacio que la contiene.

Se envía cuando

  • El autor la elimina, un administrador la elimina (una a una o en bloque), se retira al tramitar una denuncia, o una expulsión borra el contenido del miembro. Borrar el contenido de un miembro puede producir un lote de eventos.

No se envía cuando

  • Una entrada de blog se despublica y vuelve a borrador, lo cual no es una eliminación.
  • Eliminar una publicación programada que nunca se publicó también envía este evento, así que recibirlo no significa que hayas recibido antes post.created.
  • No existe un evento aparte para restaurar contenido.

comment.created

Se publicó un comentario.

CampoTipoSiempre presenteDescripción
post_idhashidSíEl ID propio del comentario.
parent_idhashidSíLa publicación o el comentario al que se responde.
user_idhashidSíEl autor.
space_idhashidNoEl espacio que la contiene.
bodystringSíLas mismas reglas que body en post.created.

comment.deleted

Se eliminó un comentario. Se envía en las mismas condiciones que post.deleted.

CampoTipoSiempre presenteDescripción
post_idhashidSíEl ID propio del comentario.
parent_idhashidSíLa publicación o el comentario al que se responde.
user_idhashidSíEl autor.
space_idhashidNoEl espacio que la contiene.

Pagos y suscripciones

Estos eventos cubren las suscripciones de Stripe, las compras únicas de espacios y los reembolsos. Llevan username y email, salvo que el miembro ya no exista.

Las compras dentro de la app y las suscripciones concedidas como regalo o mediante un código de canje no envían payment.* ni subscription.*. Si el plan está vinculado a un grupo de acceso, envían member.access_group_added con source igual a subscription, y member.access_group_removed cuando termina el acceso, que puedes usar para seguir los cambios de derechos de acceso.

En un registro de pago el pago se produce antes que la cuenta, así que los eventos del primer pago se envían cuando la cuenta ya existe: member.joined, subscription.created y payment.received si se paga la primera factura. Pueden llegar en cualquier orden.

payment.received

Llegó un pago. Hay dos formas de carga útil, y se distinguen por si invoice_id está presente.

CampoTipoFactura de suscripciónCompra únicaDescripción
member_idhashidSíSíID del miembro.
usernamestringNormalmenteNormalmenteSe omite si el miembro ya no existe.
emailstringNormalmenteNormalmenteSe omite si el miembro ya no existe.
amount_centsnumberSíSíEl importe pagado. 0 para la factura de importe cero cuando empieza una prueba.
currencystringSíSíMoneda.
invoice_idstringSíNoID de la factura de Stripe.
subscription_idstringSíNoID de la suscripción de Stripe.
period_startRFC 3339SíNoInicio del periodo que compró este pago.
period_endRFC 3339SíNoFin del periodo que compró este pago. Puedes usarlo como fecha de caducidad del acceso.
order_idhashidNoSíID del pedido.
space_idhashidNoSíEl espacio comprado.
payment_intent_idstringNoSíID del PaymentIntent de Stripe.
  • El evento no tiene plan_id.
  • Una compra única envía este evento después de conceder el acceso, una vez por pedido.

subscription.renewed

Una suscripción se renovó correctamente. Los campos son los mismos que en la forma de factura de suscripción de payment.received.

  • Una renovación envía ambos eventos, con valores de event_id distintos. Si te suscribes a los dos, no registres los ingresos dos veces.

payment.failed

Falló el pago de una factura. Se envía en cada fallo, incluida cada vez que Stripe reintenta el cobro.

CampoTipoSiempre presenteDescripción
member_idhashidSíID del miembro.
usernamestringNoSe omite si el miembro ya no existe.
emailstringNoSe omite si el miembro ya no existe.
invoice_idstringSíID de la factura de Stripe.
subscription_idstringSíID de la suscripción de Stripe.
amount_due_centsnumberSíEl importe adeudado.
currencystringSíMoneda.
attempt_countnumberSíQué intento es para la factura.

subscription.created

Se creó una suscripción en Stripe. Esto no significa que se haya pagado; para eso usa payment.received.

CampoTipoSiempre presenteDescripción
member_idhashidSíID del miembro.
usernamestringNoSe omite si el miembro ya no existe.
emailstringNoSe omite si el miembro ya no existe.
subscription_idstringSíID de la suscripción de Stripe.
plan_idhashidSíEl ID del plan de suscripción de miembros.
statusstringSíValores habituales: active, trialing e incomplete (primera factura sin liquidar).
price_centsnumberSíEl precio unitario del plan, antes de descuentos.
currencystringSíMoneda.
billing_periodstringSímonthly o annual.
period_startRFC 3339SíInicio del periodo actual.
period_endRFC 3339SíFin del periodo actual.

subscription.canceled

Una suscripción terminó realmente. Que un miembro programe la cancelación al final del periodo no lo envía; sí lo envía el final del periodo.

CampoTipoSiempre presenteDescripción
member_idhashidSíID del miembro.
usernamestringNoSe omite si el miembro ya no existe.
emailstringNoSe omite si el miembro ya no existe.
subscription_idstringSíID de la suscripción de Stripe.
plan_idhashidSíEl ID del plan de suscripción de miembros.
previous_statusstringSíEl estado antes de terminar, como active, trialing o past_due.
cancelled_atRFC 3339SíCuándo terminó.
  • Una suscripción que caduca sin haberse pagado nunca también envía este evento, con previous_status igual a incomplete. Ese miembro nunca tuvo acceso, así que no lo cuentes como baja.
  • La ortografía es inconsistente: el evento es canceled, el campo es cancelled_at y el valor del estado de la suscripción es cancelled.

refund.issued

Se emitió un reembolso. Los reembolsos de facturas de suscripción y de compras únicas comparten este evento con campos distintos. Se distinguen por si invoice_id está presente.

CampoTipoFactura de suscripciónCompra únicaDescripción
member_idhashidSíSíID del miembro.
usernamestringNormalmenteNormalmenteSe omite si el miembro ya no existe.
emailstringNormalmenteNormalmenteSe omite si el miembro ya no existe.
amount_refunded_centsnumberSíSíEl total reembolsado hasta ahora, no el importe de este reembolso.
currencystringSíSíMoneda.
refund_statusstringrefunded o partially_refundedrefundedEl estado después del reembolso.
is_partialbooleanSíSiempre falseSi es un reembolso parcial.
previous_statusstringPor ejemplo paid o partially_refundedcompletedEl estado antes del reembolso.
invoice_idstringSíNoID de la factura de Stripe.
charge_idstringSí, puede ser una cadena vacíaSolo en reembolsos iniciados en StripeID del cargo de Stripe.
order_idhashidNoSíID del pedido.
space_idhashidNoSíEl espacio comprado.
payment_intent_idstringNoSíID del PaymentIntent de Stripe.
  • Un reembolso parcial de una compra única hecho en Stripe no envía ningún evento, y el pedido y el acceso se quedan como estaban.

Entregas de prueba

Probar Webhook, en la consola de administración, envía una solicitud de inmediato y escribe el resultado en el registro de entregas. También se puede probar un webhook desactivado, y la prueba no se reintenta. El formato es el mismo que el de una entrega real, firma incluida, salvo por lo siguiente.

ElementoEntrega de pruebaEntrega real
testtrueNo está presente
eventSiempre member.joined, sean cuales sean los eventos a los que esté suscrito el webhookEl evento suscrito
dataDatos de ejemploDatos reales
event_id, occurred_atNo están presentesPresentes

Comprueba primero test y devuelve 200 cuando sea true. De lo contrario, una prueba de member.joined podría crear de verdad un miembro en tu sistema.

Otros canales

Registros de entrega también muestra estas fuentes. Usan los mismos eventos que los webhooks personalizados, en formatos distintos.

CanalCuerpoFirmaOtras diferencias
ZapierEl mismo data. El sobre añade un booleano test y no tiene webhook_id.Solo si se definió un secreto de firma al conectar. Mismo algoritmo.Añade una cabecera X-Mateflow-Delivery-Id.
Slack, DiscordSolo texto legible, como text en Slack y content en Discord.Igual que Zapier.Añade una cabecera X-Mateflow-Delivery-Id. Sin campos estructurados.
Regla de automatización: Enviar webhookLa plantilla escrita en la regla.Solo si la regla tiene un secreto. Mismo algoritmo.No usa este sobre. La regla decide cuándo se envía.
Llama de vuelta a tu comunidad con la Open API

Empieza a construir

Crea un webhook en la consola de administración de tu comunidad, envía una entrega de prueba y compruébala en los registros.

Prueba gratis de 14 días · Después, Free hasta 100 miembros · Sin tarjeta