Troubleshooting: Stripe Webhook проблеми
Симптоми
- Потребител плаща, но планът не се променя на Pro
- Stripe Dashboard показва webhook failures
- Subscription cancellation не се отразява
Диагностика
1. Stripe Dashboard
Stripe Dashboard → Developers → Webhooks → Recent events
Проверете:
- Status: Дали event-ите получават 200 отговор
- Endpoint URL:
https://api.dictaro.ai/billing/webhook - Events: checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.payment_failed
2. API логове
az vm run-command invoke \
--resource-group dictaro-rg --name dictaro-vm \
--command-id RunShellScript \
--scripts "cd /home/rosen/whisper-keyboard/licensing-go && docker compose logs licensing --tail 100 | grep -i stripe"
3. Grafana метрики
В Grafana → Licensing Overview дашборд → "Billing Webhooks" панел:
licensing_billing_webhooks_total{event, status}
Чести проблеми
Webhook signature verification failed
Причина: STRIPE_WEBHOOK_SECRET не съвпада.
Решение:
- Stripe Dashboard → Webhooks → вашия endpoint → Signing secret → Reveal
- Сравнете с
STRIPE_WEBHOOK_SECRETв GitHub Secrets - Ако не съвпадат: обновете secret-а и redeploy
Webhook endpoint unreachable
Причина: API-то не е достъпно или Cloudflare блокира.
Решение:
- Проверете
curl https://api.dictaro.ai/health - Проверете дали Cloudflare Tunnel е активен
- В Stripe: retry failed webhook events
Checkout completed but plan not updated
Причина: Webhook-ът е получен, но database update е fail-нал.
Решение:
- Проверете логовете за грешки
- Ръчно обновете плана:
UPDATE users SET plan = 'pro',
stripe_subscription_id = '<sub_id>'
WHERE email = '<email>';
Duplicate webhook events
Причина: Stripe retry при timeout.
Решение: Idempotency е вградена — checkout.session.completed проверява дали потребителят вече е Pro.
Ръчна промяна на план
Ако webhook обработката е невъзможна:
# Свързване с PostgreSQL
psql "postgresql://dictaro:<password>@dictaro-db-server.postgres.database.azure.com:5432/dictaro?sslmode=require"
-- Преглед на потребител
SELECT id, email, plan, stripe_customer_id, stripe_subscription_id FROM users WHERE email = 'user@example.com';
-- Ръчен upgrade
UPDATE users SET plan = 'pro' WHERE email = 'user@example.com';
-- Ръчен downgrade
UPDATE users SET plan = 'free', stripe_subscription_id = NULL WHERE email = 'user@example.com';