How to Monitor Your Stripe Payment Integration with Vigilmon
Stripe processes hundreds of billions of dollars per year and maintains 99.99%+ uptime. But your integration with Stripe can still break — expired API keys, webhook failures, outdated SDK versions, or misconfigurations that cause silent payment failures.
This guide shows you how to monitor your Stripe integration end-to-end with Vigilmon.
What Can Break in a Stripe Integration
Stripe itself rarely goes down, but your integration can fail in these ways:
- Expired or revoked API keys: Payments silently fail with 401 errors
- Webhook delivery failures: Payment events not processed, orders stuck in pending
- Insufficient permissions: Restricted key missing required capabilities
- Network connectivity: Your server cannot reach api.stripe.com
- Price ID changes: Product/price IDs deleted or changed in Stripe dashboard
- Subscription sync failures: Subscription status not updating in your database
Building a Stripe Health Check Endpoint
Node.js / Express
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
app.get('/health/payments', async (req, res) => {
const checks = {};
const start = Date.now();
try {
// Verify API key and account status
const account = await stripe.accounts.retrieve();
checks.api_key = 'ok';
checks.charges_enabled = account.charges_enabled;
if (!account.charges_enabled) {
checks.api_key = 'charges_disabled';
}
} catch (err) {
checks.api_key = err.statusCode === 401 ? 'invalid_key' : 'error';
return res.status(503).json({ status: 'error', checks, error: err.message });
}
// Check webhook endpoint is configured
try {
const webhooks = await stripe.webhookEndpoints.list({ limit: 10 });
const activeWebhook = webhooks.data.find(wh =>
wh.status === 'enabled' &&
wh.url.includes(process.env.DOMAIN)
);
checks.webhook = activeWebhook ? 'ok' : 'not_configured';
} catch (err) {
checks.webhook = 'error';
}
const allOk = checks.api_key === 'ok' && checks.charges_enabled === true;
return res.status(allOk ? 200 : 503).json({
status: allOk ? 'ok' : 'degraded',
latency_ms: Date.now() - start,
checks
});
});
Python / FastAPI
import stripe
import time
import os
from fastapi import FastAPI
from fastapi.responses import JSONResponse
app = FastAPI()
stripe.api_key = os.getenv('STRIPE_SECRET_KEY')
@app.get('/health/payments')
async def payment_health():
start = time.time()
checks = {}
try:
account = stripe.Account.retrieve()
checks['api_key'] = 'ok'
checks['charges_enabled'] = account.charges_enabled
all_ok = checks['api_key'] == 'ok' and checks['charges_enabled']
status_code = 200 if all_ok else 503
return JSONResponse(
status_code=status_code,
content={
'status': 'ok' if all_ok else 'degraded',
'latency_ms': round((time.time() - start) * 1000),
'checks': checks
}
)
except stripe.error.AuthenticationError:
return JSONResponse(
status_code=503,
content={'status': 'error', 'message': 'Stripe API key invalid or expired'}
)
except Exception as e:
return JSONResponse(
status_code=503,
content={'status': 'error', 'message': str(e)}
)
Monitoring Stripe Webhooks
Webhooks are critical for payment confirmation. A broken webhook means events pile up silently.
let lastWebhookAt = null;
app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), async (req, res) => {
try {
const event = stripe.webhooks.constructEvent(
req.body,
req.headers['stripe-signature'],
process.env.STRIPE_WEBHOOK_SECRET
);
lastWebhookAt = new Date();
await processStripeEvent(event);
res.json({ received: true });
} catch (err) {
res.status(400).json({ error: err.message });
}
});
app.get('/health/payments/webhooks', (req, res) => {
if (!lastWebhookAt) {
return res.json({ status: 'ok', last_webhook: null });
}
const minutesSinceWebhook = (Date.now() - lastWebhookAt) / 60000;
if (minutesSinceWebhook > 120) {
return res.status(503).json({
status: 'warning',
minutes_since: Math.round(minutesSinceWebhook),
message: 'No webhook events received in 2+ hours'
});
}
res.json({ status: 'ok', last_webhook: lastWebhookAt });
});
Setting Up Vigilmon Monitors
- Go to vigilmon.online and sign up free
- Add Monitor → HTTP(S)
- URL:
https://yourapp.com/health/payments - Interval: 2 minutes (respects Stripe API rate limits)
- Response validation:
- Status:
200 - Body contains:
"status":"ok" - Body contains:
"charges_enabled":true
- Status:
Recommended Monitor Setup
| Monitor | Interval | Alert If |
|---|---|---|
/health/payments |
2 min | Status != ok or charges disabled |
/health/payments/webhooks |
5 min | No webhook in 2 hours |
| Checkout page | 1 min | Status != 200 |
| Stripe status page | 5 min | Not 200 |
Incident Response
When Vigilmon alerts on payment health:
- Check Stripe Dashboard → Events tab for recent activity
- Check API key → Stripe Dashboard → Developers → API keys
- Check webhook logs → Stripe Dashboard → Developers → Webhooks
- Check your server logs for Stripe error codes
- Check Stripe Status → status.stripe.com
Summary
Your Stripe integration is only as reliable as your monitoring. With Vigilmon:
- API key alerts before payments start failing
- Webhook monitoring to catch silent delivery failures
- Checkout page uptime to confirm the full payment flow is accessible
- Stripe status awareness to distinguish your bugs from their outages
Protect your payment revenue with monitoring at vigilmon.online — free to start.
Top comments (0)