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

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-signatureheader - 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
- Uses
Step 3: Route by Event Type
- Node: Route Event
- Type: Switch/Router
- Routes:
checkout.session.completed→ Provision Pathinvoice.payment_failed→ Suspension Pathcustomer.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,tierfrom session metadata - Retrieves customer email
- Prepares data for provisioning
- Gets
Step A2: Update Subscription Status
- Node: Update Org Subscription
- Type: PostgreSQL Update
- Table:
public.organizations - Actions:
- Sets
subscription_tierto selected tier - Sets
subscription_status: 'active' - Updates
stripe_subscription_id - Records
subscription_started_attimestamp
- Sets
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_atto NOW + 14 days - Suspends workstation after grace period
- Sets
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_attimestamp - Begins 30-day data retention period
- Sets
Step C2: Trigger Offboarding
- Node: Publish Offboard Event
- Type: Google Cloud Pub/Sub
- Topic:
billing-events - Actions:
- Publishes
subscription.canceledevent - Includes org ID and cancellation reason
- WF-008 processes offboarding after retention period
- Publishes
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 Type | Action | Next Workflow |
|---|---|---|
checkout.session.completed | Activate subscription, provision | WF-004 |
invoice.payment_succeeded | Update payment status | None |
invoice.payment_failed | Start grace period, notify | None |
customer.subscription.updated | Sync tier changes | Depends |
customer.subscription.deleted | Begin offboarding | WF-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
Related Documents
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:
- Explore: Additional related features
- Practice: Apply concepts in your project
- Reference: Related documentation