Resolved

Stripe webhook integration fails with hardcoded values and mixed architecture

Stripe
Python
Backend
API
Payment Processing
DevOps
Configuration
Security

Payment system suffered from hardcoded rate limits, improper Stripe key placement, and lack of webhook signature verification | Architecture cleanup required for production-ready Stripe integration with proper separation of concerns

Issue

The Stripe webhook integration in the payment system had several critical flaws that prevented its use in production:

  • Hardcoded values were scattered throughout the codebase, including rate limits and Redis TTLs.
  • Architecture violations occurred where Stripe API keys were initialized in the webhook handler instead of the payment processor.
  • Missing security measures: No signature verification or deduplication for webhook events.
  • Scattered configuration: The .env file contained illogically grouped variables, complicating maintenance.
  • Technical debt in tests: Test scripts used hardcoded values instead of environment variables.

Culprit

Configuration Issues

  • Hardcoded values were present in multiple locations, such as rate limits (e.g., "100/minute") in decorators and hardcoded Redis TTLs (300 seconds).
  • The .env file had a mixed organization, with Stripe rate limits separated from Stripe keys, making configuration management difficult.

Architecture Flaws

  • Improper Initialization: Stripe API keys were incorrectly initialized in the webhook handler (main.py) instead of the payment processor (payment_mcp_server.py).
  • Missing Security: The webhook handler lacked signature verification using STRIPE_WEBHOOK_SECRET, exposing the system to spoofed events.
  • No Deduplication: Redis-based idempotency checks for webhook events were missing, leading to potential duplicate processing.

Test Infrastructure Gaps

  • Test scripts, such as test-image.sh, used hardcoded AWS values instead of sourcing them from environment variables, violating the principle of configuration management.

Solution

To address these issues, the following changes were implemented:

Webhook Security Implementation

A robust webhook infrastructure was added to main.py to ensure:

  • Signature Verification: Validates the authenticity of incoming webhook events using STRIPE_WEBHOOK_SECRET.
  • Redis Deduplication: Prevents duplicate processing of webhook events by checking Redis for previously processed events.
  • Rate Limiting: Uses environment variables to dynamically set rate limits for webhook processing.

Configuration Centralization

All hardcoded values were moved to a logically grouped .env file, ensuring:

  • Consistent Naming: Variables were organized in a structured manner, making configuration management easier.
  • Environment Variables: Dynamic loading of configuration values to enable environment-specific tuning.

Architecture Separation

The architecture was refactored to:

  • Initialize Stripe API keys in the payment processor (payment_mcp_server.py) instead of the webhook handler.
  • Separate Concerns: Ensure the webhook handler only focuses on verification and deduplication, while payment operations are handled by the payment processor.

Environment Management

The common.sh script was updated to:

  • Export all Stripe-related variables (STRIPE_PUBLISHABLE_KEY, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET).
  • Set default values for environment variables to ensure backward compatibility.

Test Script Fix

Test scripts were updated to:

  • Source environment variables from .env instead of using hardcoded values.
  • Enable consistent testing across different environments.

Key Results

  • Security: Webhook signature verification prevents spoofed events, ensuring data integrity.
  • Reliability: Redis deduplication prevents duplicate processing, improving system reliability.
  • Maintainability: Centralized configuration in .env with logical grouping simplifies maintenance.
  • Scalability: Configurable rate limits protect against abuse and allow environment-specific tuning.
  • Correct Architecture: Proper separation of concerns ensures clean and maintainable code.
  • Production Ready: Elimination of technical debt ensures a robust and reliable payment processing system.