04.b - Stripe-Webhook-Handling
Relevant source files
Purpose and ScopeLink copied!
This document details the Stripe webhook endpoint that receives and processes payment events from Stripe's payment processing system. The endpoint is responsible for signature verification, event processing, logging payment details, and dispatching notifications to the ntfy.sh message broker for downstream automation.
For information about creating Stripe checkout sessions, see Stripe Checkout Creation. For details on how payments are linked to GitHub installations, see Payment-to-Installation Linking. For information about the ntfy.sh notification system that receives these webhook notifications, see ntfy Integration & Message Broker.
Endpoint ArchitectureLink copied!
The Stripe webhook handler is implemented as a Next.js 14 App Router route handler located at app/api/webhooks/stripe/route.ts
It supports three HTTP methods to accommodate different operational requirements.
Supported HTTP MethodsLink copied!
| Method | Purpose | Response |
|---|---|---|
OPTIONS | CORS preflight requests | 200 with CORS headers |
GET | Verification endpoint | "Stripe webhook endpoint is active" |
POST | Webhook event processing | {received: true} or error |
The OPTIONS handler app/api/webhooks/stripe/route.ts L6-L15
enables cross-origin requests from Stripe's webhook delivery system by returning appropriate CORS headers (Access-Control-Allow-Origin: *, Access-Control-Allow-Methods, Access-Control-Allow-Headers).
The GET handler app/api/webhooks/stripe/route.ts L18-L20
provides a simple health check endpoint for verifying that the webhook URL is accessible.
Sources: app/api/webhooks/stripe/route.ts L1-L93
Webhook Signature VerificationLink copied!
Stripe webhook signature verification is the critical security mechanism that ensures webhook requests originate from Stripe and have not been tampered with during transit.
Verification FlowLink copied!
Diagram: Webhook Signature Verification Flow
The verification process uses the stripe.webhooks.constructEvent() method from the Stripe SDK app/api/webhooks/stripe/route.ts L40
which performs cryptographic validation of the webhook signature against the request body and the STRIPE_WEBHOOK_SECRET environment variable.
Key Implementation DetailsLink copied!
- Request Body: Must be accessed as raw text using
request.text()app/api/webhooks/stripe/route.ts L23 before signature verification - Signature Header: Retrieved from
stripe-signatureheader app/api/webhooks/stripe/route.ts L24 - Webhook Secret: Loaded from
STRIPE_WEBHOOK_SECRETenvironment variable app/api/webhooks/stripe/route.ts L30 - Error Handling: Invalid signatures return 400 status with error message app/api/webhooks/stripe/route.ts L41-L44
// Signature verification code structure (app/api/webhooks/stripe/route.ts:39-44)event = stripe.webhooks.constructEvent(body, signature, webhookSecret)
Sources: app/api/webhooks/stripe/route.ts L22-L44
Event ProcessingLink copied!
The webhook handler processes the checkout.session.completed event type, which Stripe fires when a customer successfully completes payment through Stripe Checkout.
checkout.session.completed Event HandlingLink copied!
Diagram: checkout.session.completed Event Processing Flow
Extracted Session DataLink copied!
The handler extracts the following data from the Stripe Checkout Session object app/api/webhooks/stripe/route.ts L49-L59
:
| Field | Source | Purpose |
|---|---|---|
session.id | Session ID | Full session identifier for correlation |
session.amount_total | Total amount in cents | Payment amount ($10.00 = 1000) |
session.customer_email | Customer email | Primary contact information |
session.customer_details?.email | Fallback email | Alternative email source |
session.payment_status | Payment status | Confirmation of successful payment |
Console Logging FormatLink copied!
The handler logs payment details to the server console in a formatted structure app/api/webhooks/stripe/route.ts L51-L59
:
================================================================================
💰 NEW PAYMENT RECEIVED
================================================================================
Session ID: cs_test_abc123...
Amount: $10
Customer Email: user@example.com
Payment Status: paid
Timestamp: 2024-01-15T10:30:45.123Z
================================================================================
This console output appears in Vercel function logs and provides an audit trail for manual payment verification.
Sources: app/api/webhooks/stripe/route.ts L46-L82
ntfy.sh Notification DispatchLink copied!
After logging the payment, the webhook handler sends a notification to ntfy.sh, which serves as the message broker triggering the automation pipeline that clones customer repositories.
Notification Message ConstructionLink copied!
Diagram: ntfy.sh Notification Message Construction
Message FormatLink copied!
The notification message app/api/webhooks/stripe/route.ts L68
follows this structure:
New GoDeep.wiki Sale!
💰 Amount: $10.00
📧 Customer: user@example.com
🔑 Match ID: abc123def456
⏰ Time: 1/15/2024, 10:30:45 AM
⚠️ Waiting for customer to connect GitHub...
Match this ID with Step 2 notification.
Match ID ConceptLink copied!
The Match ID is the last 12 characters of the full Stripe session ID app/api/webhooks/stripe/route.ts L67
This shortened identifier serves two purposes:
- Manual Correlation: Enables the system owner to match payment notifications with GitHub connection notifications
- Size Reduction: Full session IDs (e.g.,
cs_test_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6) are truncated tom3n4o5p6for readability
The full session ID is still logged to the console app/api/webhooks/stripe/route.ts L54
and stored in Stripe's dashboard for complete correlation if needed.
ntfy.sh Request ConfigurationLink copied!
The notification is sent via HTTP POST app/api/webhooks/stripe/route.ts L70-L79
:
| Header | Value | Purpose |
|---|---|---|
Content-Type | text/plain | Plain text message body |
Title | Step 1: Payment Received - GoDeep.wiki | Notification title |
Priority | high | Priority level for client apps |
Tags | moneybag,tada | Visual emoji tags |
The ntfy.sh topic is configured via the NTFY_TOPIC environment variable app/api/webhooks/stripe/route.ts L62
with a default value of godeep-wiki-payments if not specified.
Sources: app/api/webhooks/stripe/route.ts L61-L81
Error Handling and Response CodesLink copied!
The webhook handler implements a layered error handling strategy to provide clear diagnostics while maintaining security.
Error Response MatrixLink copied!
| Condition | HTTP Status | Response Body | Logged |
|---|---|---|---|
Missing stripe-signature header | 400 | "Missing stripe-signature header" | No |
STRIPE_WEBHOOK_SECRET not configured | 500 | "Webhook secret not configured" | Yes |
| Invalid webhook signature | 400 | "Webhook Error: {message}" | Yes |
| Event processing error | 500 | "Error processing webhook" | Yes |
| Successful processing | 200 | {"received": true} | Yes |
Error Handling Code FlowLink copied!
Diagram: Error Handling Sequence
Try-Catch Block StructureLink copied!
The handler uses two nested try-catch blocks app/api/webhooks/stripe/route.ts L39-L91
:
- Outer Try-Catch: Captures signature verification failures app/api/webhooks/stripe/route.ts L39-L44
- Inner Try-Catch: Captures event processing and ntfy.sh dispatch failures app/api/webhooks/stripe/route.ts L46-L91
All errors are logged to the console using console.error() for debugging and audit purposes.
Sources: app/api/webhooks/stripe/route.ts L39-L92
Configuration RequirementsLink copied!
The webhook handler depends on the following environment variables:
Required Environment VariablesLink copied!
| Variable | Purpose | Example | Configured In |
|---|---|---|---|
STRIPE_WEBHOOK_SECRET | Webhook signature verification | whsec_abc123... | Stripe Dashboard → Webhooks |
NTFY_TOPIC | ntfy.sh notification topic | godeep-wiki-payments | Manual configuration |
The STRIPE_WEBHOOK_SECRET is obtained from the Stripe Dashboard when configuring the webhook endpoint. In production, the webhook URL should be set to https://godeep.wiki/api/webhooks/stripe.
Webhook Configuration in StripeLink copied!
To configure this webhook in the Stripe Dashboard:
- Navigate to Developers → Webhooks
- Click Add endpoint
- Enter webhook URL:
https://godeep.wiki/api/webhooks/stripe - Select event:
checkout.session.completed - Copy the signing secret and set as
STRIPE_WEBHOOK_SECRET
Sources: app/api/webhooks/stripe/route.ts L30-L34
Integration with Automation PipelineLink copied!
The Stripe webhook serves as the first event source in the two-phase notification system that triggers repository cloning automation.
Two-Phase Notification SystemLink copied!
Diagram: Webhook Integration in Two-Phase Notification System
The webhook notification is labeled "Step 1" because it represents the first of two required events:
- Step 1: Payment received (this webhook)
- Step 2: GitHub repository connected (see OAuth Callback Handler)
Both notifications include the same Match ID (last 12 characters of session_id) to enable manual correlation by the system owner. The automation scripts do not automatically trigger from this webhook alone—they require the Step 2 notification that includes the installation_id.
Sources: app/api/webhooks/stripe/route.ts L68-L78
Refresh this wiki
Last indexed: 23 November 2025 (922b35)
On this page
- Stripe Webhook Handling
- Purpose and Scope
- Endpoint Architecture
- Supported HTTP Methods
- Webhook Signature Verification
- Verification Flow
- Key Implementation Details
- Event Processing
- checkout.session.completed Event Handling
- Extracted Session Data
- Console Logging Format
- ntfy.sh Notification Dispatch
- Notification Message Construction
- Message Format
- Match ID Concept
- ntfy.sh Request Configuration
- Error Handling and Response Codes
- Error Response Matrix
- Error Handling Code Flow
- Try-Catch Block Structure
- Configuration Requirements
- Required Environment Variables
- Webhook Configuration in Stripe
- Integration with Automation Pipeline
- Two-Phase Notification System
Ask Devin about godeep.wiki-jb