Qué vas a tener
Un mensaje en Telegram (chat privado o grupo) cuando falle un cobro de factura: cliente, email, importe y enlace de la factura.
Necesitas un bot (BotFather), token y chat_id. Primero pruebas el destino con curl; enganchar Stripe firmado es el paso siguiente.
- Evento payment_failed
- Tu código lo traduce
- Telegram muestra el aviso
JSON del evento: Webhooks de Stripe. Bot y chat_id: Avisos con un bot de Telegram.
Requisitos
- Un bot de Telegram con su token y el chat_id, y haberle dado Start
- Para la primera mitad, nada más
- Para la segunda: cuenta de Stripe en modo test y un sitio donde alojar el receptor — ver el aviso de más abajo
Bot y chat
- Si aún no tienes bot: @BotFather (se abre en una pestaña nueva) →
/newbot→ nombre y username que acabe enbot→ copia el token. - Abre el enlace
t.me/…que te da BotFather, pulsa Start (o añade el bot a un grupo con permiso de enviar; eliddel grupo suele ser negativo). - Saca el
chat_id(sustituyepega-aqui-tu-tokenpor el de BotFather):
TOKEN="pega-aqui-tu-token"
curl -sS "https://api.telegram.org/bot${TOKEN}/getUpdates"Busca:
"chat": {
"id": 123456789,
"type": "private"
}Ese "id" es el chat_id. Si result viene vacío, manda otro mensaje al bot y reintenta. Detalle y grupos: Avisos con un bot de Telegram.
Prueba el destino
Sustituye también 123456789 por tu chat_id.
TOKEN="pega-aqui-tu-token"
CHAT_ID="123456789"
curl -sS -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
-H "Content-Type: application/json" \
-d "{\"chat_id\":${CHAT_ID},\"text\":\"Pago fallido (prueba)\
Cliente: cus_demo\
Email: demo@example.com\
Importe: 19.00 EUR\
Evento: invoice.payment_failed\"}"Resultado esperado: "ok": true y el mensaje en Telegram.
Eso demuestra el formato del aviso y que el bot entrega al chat. No demuestra una entrega firmada desde Stripe.
Qué mapearás desde Stripe
| Campo Stripe | En el mensaje |
|---|---|
customer | Cliente |
customer_email | |
amount_due / currency | Importe (céntimos → unidades; 1900 + eur = 19,00 EUR) |
id de factura | Factura |
type del evento | Evento |
hosted_invoice_url | Enlace (si existe) |
Usa texto plano al principio (sin parse_mode) para no pelearte con escapes.
Engancha Stripe
Ya tienes el mensaje pintado en Telegram. Pero Stripe no puede hablar directamente con Telegram: alguien tiene que recibir el evento, comprobar que viene de Stripe y traducirlo al texto del mensaje.
Eso no se resuelve con un solo curl. Opciones:
- No-code (Zapier, Make, etc.)
- Más rápido si no quieres escribir ni hospedar código.
- Endpoint HTTPS propio
- Stripe Dashboard → Developers → Webhooks → URL que verifique `Stripe-Signature` y luego llame a sendMessage.
- Stripe CLI en local
- Solo desarrollo: reenvía a un proceso **tuyo** en un puerto; sin ese proceso no hay aviso a Telegram.
Si tiras por el camino propio, el receptor hace esto — en el orden en que se enumera. No es código para copiar, es el guion:
- Recibir
POSTdel body raw. - Verificar firma con el signing secret (docs Stripe (se abre en una pestaña nueva)).
- Si
type === "invoice.payment_failed", mapear factura → texto (céntimos → unidades). POSTahttps://api.telegram.org/bot<TOKEN>/sendMessageconchat_id+text.- Responder
2xxa Stripe pronto. - Deduplicar por
evt_…o porinvoice.id.
Ejemplo de CLI cuando ya tengas algo escuchando en un puerto local (p. ej. 4242):
stripe listen --forward-to localhost:4242/webhook
# en otra terminal:
stripe trigger invoice.payment_failedPuedes parar tras la prueba del destino Telegram y dejar el pegamento Stripe para cuando tengas dónde hospedar el receptor. Ver el evento en bruto: Webhooks de Stripe.
Docs: Stripe webhooks (se abre en una pestaña nueva) · Bot API sendMessage (se abre en una pestaña nueva).
Seguridad
- Si el token se filtra: BotFather →
/revoke, actualiza env/secrets. - Separa endpoints test y live en Stripe.
- Un bot solo para avisos operativos reduce el radio de daño.
- Piensa en reintentos: Stripe puede emitir varios
payment_failedpor la misma factura.
Errores habituales
| Qué ves | Causa habitual | Qué hacer |
|---|---|---|
Sin chat_id | No diste Start / no hay updates | Abre el bot, Start, reintenta getUpdates |
Unauthorized | Token revocado o mal pegado | Nuevo token en BotFather |
chat not found | chat_id de otro chat o bot | Vuelve a sacar el id |
| Silencio con curl OK | Miras otro chat o grupo | Confirma el chat del bot |
| Stripe “entrega fallida” | Endpoint sin 2xx o firma mala | Logs del receptor; secret del endpoint concreto |
| Muchos mensajes por un cliente | Reintentos sin dedupe | Filtra por factura o espacia avisos |
| 400 de Telegram | JSON mal formado o parse_mode sin escapar | Empieza en texto plano |
Alternativas
- Email de Stripe
- Cero código; menos visible en el móvil.
- Incoming Webhook de otro chat
- Mismo evento, otro destino (p. ej. Discord o Slack).
- Otro origen al mismo bot
- Puedes reutilizar token y chat_id para avisos que no sean de Stripe.