Skip to main content

WF-003: Stripe Webhook Handler Workflow

Overview

This workflow processes Stripe webhook events, handling successful payments, failed payments, and subscription cancellations. It serves as the central event router for all payment-related automation.

Trigger: HTTP POST from Stripe to /stripe/webhook Duration: ~1-3 seconds Related Workflows: WF-004 (Provisioning), WF-008 (Offboarding)


Prerequisites

Before starting, ensure you have:

  • Required tools installed
  • Access to necessary resources
  • Basic understanding of concepts

Verify setup:

# Verification command

Workflow Diagram

Payment State Machine


Step-by-Step Narrative

Step 1: Webhook Received

  • Node: Stripe Webhook
  • Type: HTTP POST Endpoint
  • Path: /stripe/webhook
  • Actions:
    • Receives raw webhook payload from Stripe
    • Extracts stripe-signature header
    • Passes to verification node

Step 2: Verify Webhook Signature

  • Node: Verify Signature
  • Type: Code (JavaScript)
  • Actions:
    • Uses stripe.webhooks.constructEvent()
    • Verifies signature using webhook signing secret
    • Rejects invalid signatures with 401
    • Extracts event type and data object
    • Logs verification attempt for audit

Step 3: Route by Event Type

  • Node: Route Event
  • Type: Switch/Router
  • Routes:
    • checkout.session.completed → Provision Path
    • invoice.payment_failed → Suspension Path
    • customer.subscription.deleted → Offboarding Path
    • Other events → Log and acknowledge

Route A: Checkout Session Completed

Step A1: Extract Session Metadata

  • Node: Extract Metadata
  • Type: Code
  • Actions:
    • Gets org_id, user_id, tier from session metadata
    • Retrieves customer email
    • Prepares data for provisioning

Step A2: Update Subscription Status

  • Node: Update Org Subscription
  • Type: PostgreSQL Update
  • Table: public.organizations
  • Actions:
    • Sets subscription_tier to selected tier
    • Sets subscription_status: 'active'
    • Updates stripe_subscription_id
    • Records subscription_started_at timestamp

Step A3: Trigger Workstation Provisioning

  • Node: Publish Provision Event
  • Type: Google Cloud Pub/Sub
  • Topic: workstation-provisioning-requests
  • Actions:
    • Publishes provisioning request
    • Includes user ID, org ID, tier
    • WF-004 picks up and provisions workstation

Step A4: Send Confirmation Email

  • Node: Send Receipt
  • Type: Email Send
  • Actions:
    • Sends payment confirmation email
    • Includes subscription details and tier
    • Provides receipt link from Stripe
    • Notifies that workstation is being created

Route B: Payment Failed

Step B1: Record Payment Failure

  • Node: Log Payment Failure
  • Type: PostgreSQL Insert
  • Table: public.payment_events
  • Actions:
    • Records failure reason from Stripe
    • Stores invoice ID and amount
    • Increments failed_payment_count

Step B2: Start Grace Period

  • Node: Start Grace Period
  • Type: PostgreSQL Update
  • Table: public.organizations
  • Actions:
    • Sets subscription_status: 'past_due'
    • Sets grace_period_ends_at to NOW + 14 days
    • Suspends workstation after grace period

Step B3: Send Payment Failed Email

  • Node: Send Dunning Email
  • Type: Email Send
  • Actions:
    • Notifies user of payment failure
    • Includes update payment method link
    • Warns of suspension in 14 days
    • Provides support contact

Route C: Subscription Deleted

Step C1: Mark Subscription Canceled

  • Node: Cancel Subscription
  • Type: PostgreSQL Update
  • Table: public.organizations
  • Actions:
    • Sets subscription_status: 'canceled'
    • Records subscription_ended_at timestamp
    • Begins 30-day data retention period

Step C2: Trigger Offboarding

  • Node: Publish Offboard Event
  • Type: Google Cloud Pub/Sub
  • Topic: billing-events
  • Actions:
    • Publishes subscription.canceled event
    • Includes org ID and cancellation reason
    • WF-008 processes offboarding after retention period

Step C3: Send Cancellation Confirmation

  • Node: Send Cancellation Email
  • Type: Email Send
  • Actions:
    • Confirms subscription cancellation
    • Explains 30-day data retention
    • Provides data export instructions
    • Includes re-subscription link

Data Flow

Input (from Stripe):
{
"id": "evt_xxx",
"type": "checkout.session.completed",
"data": {
"object": {
"customer": "cus_xxx",
"subscription": "sub_xxx",
"metadata": {
"org_id": "org-uuid",
"user_id": "user-uuid",
"tier": "professional"
}
}
}
}

Output:
{
"received": true
}

Event Types Handled

Event TypeActionNext Workflow
checkout.session.completedActivate subscription, provisionWF-004
invoice.payment_succeededUpdate payment statusNone
invoice.payment_failedStart grace period, notifyNone
customer.subscription.updatedSync tier changesDepends
customer.subscription.deletedBegin offboardingWF-008

Security Considerations

  • Webhook signature verified on every request
  • Signing secret stored in Secret Manager
  • Endpoint only accepts POST from Stripe IPs (optional)
  • All events logged for audit trail
  • Idempotency key prevents duplicate processing

Troubleshooting

Common Issue 1

Problem: Description of issue Solution: Steps to resolve

Common Issue 2

Problem: Description of issue Solution: Steps to resolve

Next Steps

After completing this guide:

  1. Explore: Additional related features
  2. Practice: Apply concepts in your project
  3. Reference: Related documentation