Skip to main content
Executor receives webhooks from external services for payment processing and authentication events.

Stripe Webhook

Receives Stripe payment and subscription events.
POST /stripe/webhook

Authentication

Requires valid Stripe webhook signature in the Stripe-Signature header. Signature is verified using the webhook secret configured in STRIPE_WEBHOOK_SECRET.

Headers

Stripe-Signature
string
required
Stripe webhook signature. Generated by Stripe for each webhook delivery. Format: t=<timestamp>,v1=<signature>
Content-Type
string
required
Must be application/json

Request Body

Stripe event object:
{
  "id": "evt_1234567890",
  "object": "event",
  "type": "customer.subscription.created",
  "data": {
    "object": {
      // Event-specific payload
    }
  },
  "created": 1234567890
}

Supported Events

Executor handles these Stripe event types:
customer.subscription.created
New subscription created
customer.subscription.updated
Subscription modified (plan change, status change, etc.)
customer.subscription.deleted
Subscription canceled or expired
invoice.payment_succeeded
Successful payment for an invoice
invoice.payment_failed
Failed payment attempt
checkout.session.completed
Checkout session completed successfully

Response

{
  "received": true
}
HTTP 200 indicates successful receipt and processing.

Example Request

curl -X POST https://executor.example.com/stripe/webhook \
  -H "Stripe-Signature: t=1234567890,v1=abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "id": "evt_1234567890",
    "type": "customer.subscription.created",
    "data": {
      "object": {
        "id": "sub_1234567890",
        "customer": "cus_1234567890",
        "status": "active"
      }
    }
  }'

Error Responses

400 Bad Request
Invalid webhook signature or malformed payload
401 Unauthorized
Missing or invalid Stripe-Signature header

Configuration

Stripe webhook handling requires:
STRIPE_WEBHOOK_SECRET
string
required
Webhook signing secret from Stripe dashboard. Used to verify webhook authenticity.
STRIPE_API_KEY
string
required
Stripe secret API key for making API calls

Testing

Use Stripe CLI to test webhooks locally:
stripe listen --forward-to localhost:3000/stripe/webhook
stripe trigger customer.subscription.created

WorkOS Webhooks

WorkOS AuthKit automatically registers webhook endpoints for authentication events.

Registration

Webhook routes are registered via @convex-dev/workos-authkit:
authKit.registerRoutes(http);
The AuthKit package handles:
  • Webhook URL registration
  • Signature verification
  • Event parsing and routing

Supported Events

organization.created
New organization created in WorkOS
organization.updated
Organization details modified
organization.deleted
Organization removed from WorkOS
organization_membership.created
User added to organization
organization_membership.updated
Organization membership modified (role change, etc.)
organization_membership.deleted
User removed from organization
user.created
New user account created
user.updated
User profile updated
user.deleted
User account deleted
session.created
New user session started

Event Processing

WorkOS events are processed by handlers in executor/packages/database/src/auth/event_handlers.ts. Event processing:
  1. Signature Verification - AuthKit verifies the webhook signature using WORKOS_WEBHOOK_SECRET
  2. Event Routing - Events are routed to type-specific handlers
  3. Database Updates - Handlers update Convex database tables:
    • Organizations → organizations table
    • Memberships → organizationMembers table
    • Users → accounts table
  4. Workspace Sync - Organization changes trigger workspace provisioning/updates

Configuration

WorkOS webhook handling requires:
WORKOS_CLIENT_ID
string
required
WorkOS application client ID
WORKOS_API_KEY
string
required
WorkOS API key for making API calls
WORKOS_WEBHOOK_SECRET
string
required
Webhook signing secret from WorkOS dashboard

Webhook URLs

AuthKit registers webhook endpoints dynamically. Typical URL pattern:
https://executor.example.com/auth/workos/webhook
Exact path is managed by the @convex-dev/workos-authkit package.

Testing

Test WorkOS webhooks using the WorkOS dashboard:
  1. Navigate to Webhooks in WorkOS dashboard
  2. Add endpoint URL: https://your-deployment.convex.site/auth/workos/webhook
  3. Select event types to subscribe to
  4. Use Send test webhook to trigger events

Event Handler Implementation

Event handlers are configured in executor/packages/database/convex/auth.ts:7-41:
const authKitInstance = new AuthKit<DataModel>(workosComponent, {
  authFunctions,
  additionalEventTypes: [
    "organization.created",
    "organization.updated",
    "organization.deleted",
    "organization_membership.created",
    "organization_membership.updated",
    "organization_membership.deleted",
  ],
});

const authKitEvents = authKitInstance.events(workosEventHandlers);
Handlers are implemented in executor/packages/database/src/auth/event_handlers.ts.

Webhook Security

Signature Verification

All webhooks verify signatures before processing:
1

Extract Signature

Parse signature from request headers:
  • Stripe: Stripe-Signature header
  • WorkOS: Verified by AuthKit middleware
2

Compute Expected Signature

Calculate HMAC using webhook secret and request body
3

Compare Signatures

Use timing-safe comparison to prevent timing attacks
4

Reject Invalid Signatures

Return 401 Unauthorized if signatures don’t match

Replay Protection

Webhooks include timestamp verification:
  • Stripe: Timestamp in signature (t= component) must be within tolerance window
  • WorkOS: AuthKit handles replay protection automatically

IP Allowlisting

Consider restricting webhook endpoints to known service IPs:

Monitoring

Webhook Logs

Webhook processing logs are available in Convex dashboard under LogsFunctions. Filter by:
  • Stripe: Search for stripe/webhook
  • WorkOS: Search for authKit or workos

Failed Deliveries

Check service dashboards for delivery failures:
  • Stripe: Dashboard → Developers → Webhooks → View logs
  • WorkOS: Dashboard → Webhooks → Event log

Retry Behavior

  • Stripe: Automatic retries with exponential backoff (up to 3 days)
  • WorkOS: Automatic retries with exponential backoff
Both services mark endpoints as unhealthy after repeated failures.

Source Files

  • Route registration: executor/packages/database/convex/http.ts:14-17
  • Stripe integration: Via @convex-dev/stripe package
  • WorkOS integration: executor/packages/database/convex/auth.ts:1-54
  • WorkOS event handlers: executor/packages/database/src/auth/event_handlers.ts

Build docs developers (and LLMs) love