Add Telegram notification on every new paid order

Sends to the monitoring bot immediately when payment is confirmed:
- Customer name and email
- Service/slug ordered
- Total amount (includes all fees: service + formation + state + addons)
- Payment method
- Order number and type

Fire-and-forget — never blocks the payment flow.
Requires TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID env vars on API container.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
justin 2026-05-04 07:32:42 -05:00
parent 7d783bdb39
commit c9881868dd
2 changed files with 38 additions and 0 deletions

View file

@ -1183,6 +1183,42 @@ export async function handlePaymentComplete(
const paymentMethod = (order.payment_method as string) || "card";
console.log(`[checkout] Payment confirmed: ${order_type} ${order_id} via ${paymentMethod}`);
// ── Telegram order notification ──────────────────────────────────────
try {
const botToken = process.env.TELEGRAM_BOT_TOKEN;
const chatId = process.env.TELEGRAM_CHAT_ID;
if (botToken && chatId) {
const customerName = (order.customer_name as string) || "Unknown";
const customerEmail = (order.customer_email as string) || "";
const serviceName = (order.service_slug as string)
|| (order.service_name as string)
|| order_type;
// Calculate total in dollars
const feeCents = Number(order.service_fee_cents || order.total_cents || 0);
const formationCents = Number(order.formation_fee_cents || 0);
const stateCents = Number(order.state_fee_cents || 0);
const addonCents = Number(order.addon_fee_cents || 0);
const pucCents = Number(order.puc_fee_cents || 0);
const totalCents = feeCents + formationCents + stateCents + addonCents + pucCents;
const totalDollars = (totalCents / 100).toFixed(2);
const msg = `💰 NEW ORDER\n\n`
+ `Customer: ${customerName}\n`
+ `Email: ${customerEmail}\n`
+ `Service: ${serviceName}\n`
+ `Total: $${totalDollars}\n`
+ `Payment: ${paymentMethod}\n`
+ `Order: ${order_id}\n`
+ `Type: ${order_type}`;
fetch(`https://api.telegram.org/bot${botToken}/sendMessage`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ chat_id: chatId, text: msg }),
}).catch(() => {}); // fire and forget
}
} catch {}
// ── CDR traffic study paywall: issue grants on qualifying orders ──────
//
// When a customer pays for a 499-A filing service OR the standalone

View file

@ -48,6 +48,8 @@ services:
- LISTMONK_URL=http://listmonk:9000
- LISTMONK_USER=${LISTMONK_USER:-admin}
- LISTMONK_PASSWORD=${LISTMONK_PASSWORD}
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID}
depends_on:
- api-postgres
restart: unless-stopped