DEV Community

Vigilmon
Vigilmon

Posted on

How to Monitor Your Stripe Payment Integration with Vigilmon

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
  });
});
Enter fullscreen mode Exit fullscreen mode

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)}
        )
Enter fullscreen mode Exit fullscreen mode

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 });
});
Enter fullscreen mode Exit fullscreen mode

Setting Up Vigilmon Monitors

  1. Go to vigilmon.online and sign up free
  2. Add MonitorHTTP(S)
  3. URL: https://yourapp.com/health/payments
  4. Interval: 2 minutes (respects Stripe API rate limits)
  5. Response validation:
    • Status: 200
    • Body contains: "status":"ok"
    • Body contains: "charges_enabled":true

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:

  1. Check Stripe Dashboard → Events tab for recent activity
  2. Check API key → Stripe Dashboard → Developers → API keys
  3. Check webhook logs → Stripe Dashboard → Developers → Webhooks
  4. Check your server logs for Stripe error codes
  5. 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)