Skip to main content
POST
/
api
/
webhooks
/
stripe
Stripe Webhook
curl --request POST \
  --url https://api.example.com/api/webhooks/stripe \
  --header 'stripe-signature: <stripe-signature>'
{
  "status": true,
  "message": "Webhook recibido correctamente",
  "data": {
    "received": true,
    "type": "payment_intent.succeeded"
  }
}
This endpoint receives webhook events from Stripe, enabling your application to respond to payment events in real-time. The endpoint implements secure signature verification to ensure events are legitimately sent by Stripe.
Critical Security Requirement: This endpoint MUST verify webhook signatures using the stripe-signature header and STRIPE_WEBHOOK_SECRET. Never process webhooks without signature verification, as this could allow attackers to send fraudulent events to your application.

Signature Verification

The endpoint uses Stripe’s constructEvent method to verify that incoming webhooks are authentic. This process:
  1. Reads the raw request body (webhook payload must be raw, not parsed JSON)
  2. Extracts the stripe-signature header containing the signature and timestamp
  3. Uses the STRIPE_WEBHOOK_SECRET to verify the signature matches the payload
  4. Rejects any requests with invalid or missing signatures
The webhook route must be registered before body-parser middleware to ensure the raw body is available for signature verification (see stripeWebhook.js:24).

Configuration

Required Environment Variable: STRIPE_WEBHOOK_SECRETYou must configure this secret in your environment. The webhook secret is provided in your Stripe Dashboard when you create a webhook endpoint. It typically starts with whsec_.

Setup Instructions

  1. Create Webhook Endpoint in Stripe Dashboard:
    • Navigate to Developers > Webhooks in your Stripe Dashboard
    • Click “Add endpoint”
    • Enter your webhook URL: https://yourdomain.com/api/webhooks/stripe
    • Select the events you want to receive (see Event Types below)
  2. Copy Webhook Secret:
    • After creating the endpoint, Stripe displays your webhook signing secret
    • Add this to your environment variables as STRIPE_WEBHOOK_SECRET
  3. Deploy and Test:
    • Deploy your application with the webhook secret configured
    • Use the Stripe Dashboard to send test events
    • See Testing Webhooks for comprehensive testing instructions

Headers

stripe-signature
string
required
The signature header generated by Stripe, containing timestamp and signature values. This header is automatically added by Stripe when sending webhook events.
Content-Type
string
Must be application/json

Request Body

The request body is a raw Stripe Event object. The exact structure varies by event type, but all events follow this general format:
{
  "id": "evt_1234567890",
  "object": "event",
  "api_version": "2023-10-16",
  "created": 1234567890,
  "type": "payment_intent.succeeded",
  "data": {
    "object": {
      // Event-specific data (e.g., PaymentIntent, Refund, Charge)
    }
  },
  "livemode": false,
  "pending_webhooks": 1,
  "request": {
    "id": "req_1234567890",
    "idempotency_key": null
  }
}

Event Types

The webhook currently handles the following Stripe event types (see stripeWebhook.js:32-47):
Triggered when a payment is successfully completed. The event.data.object contains the complete PaymentIntent object.Use cases:
  • Update order status to “paid”
  • Send confirmation email to customer
  • Trigger fulfillment process
  • Update user account balance
Triggered when a payment attempt fails. The event.data.object contains the PaymentIntent with error details.Use cases:
  • Notify customer of failed payment
  • Log failure reason for analysis
  • Trigger retry logic or alternative payment flows
  • Update order status to “payment_failed”
Triggered when a refund is created. The event.data.object contains the Refund object.Use cases:
  • Update order status to “refunded”
  • Send refund confirmation to customer
  • Update inventory if applicable
  • Log refund for accounting
Triggered when a charge is refunded. The event.data.object contains the Charge object with refund details.Use cases:
  • Process partial or full refunds
  • Update transaction records
  • Notify relevant parties
  • Trigger reversal of fulfillment
Other event types are also received and logged, but do not have specific handling logic. The webhook returns a 200 status for all valid events, regardless of type.

Response

status
boolean
required
Indicates whether the webhook was received successfully. Always true for valid webhooks.
message
string
required
Confirmation message. Returns “Webhook recibido correctamente” for successful receipt.
data
object
required
Contains webhook receipt confirmation details.

Example Requests

{
  "id": "evt_1QR7tPABC123def456",
  "object": "event",
  "type": "payment_intent.succeeded",
  "data": {
    "object": {
      "id": "pi_3QR7tPABC123def456",
      "object": "payment_intent",
      "amount": 2000,
      "currency": "usd",
      "status": "succeeded",
      "customer": "cus_ABC123def456",
      "payment_method": "pm_1QR7tPABC123def456",
      "charges": {
        "data": [
          {
            "id": "ch_3QR7tPABC123def456",
            "amount": 2000,
            "currency": "usd",
            "status": "succeeded"
          }
        ]
      }
    }
  },
  "livemode": false,
  "created": 1234567890
}

Example Responses

{
  "status": true,
  "message": "Webhook recibido correctamente",
  "data": {
    "received": true,
    "type": "payment_intent.succeeded"
  }
}

Security Best Practices

  1. Always Verify Signatures: Never disable signature verification in production. This is your primary defense against fraudulent webhook events.
  2. Use HTTPS: Webhook endpoints must use HTTPS in production to prevent man-in-the-middle attacks.
  3. Implement Idempotency: Stripe may send the same event multiple times. Use the event.id to ensure you only process each event once.
  4. Return 200 Quickly: Stripe expects a 200 response within a few seconds. Process events asynchronously if they require long-running operations.
  5. Monitor Webhook Failures: Check your Stripe Dashboard regularly for webhook delivery failures and adjust your endpoint accordingly.

Testing

For local development and testing of webhooks, see the comprehensive guide at Testing Webhooks, which covers:
  • Using Stripe CLI to forward webhooks to localhost
  • Sending test events from the Stripe Dashboard
  • Validating signature verification
  • Debugging common webhook issues

Error Handling

The endpoint implements several error checks:
Error ConditionHTTP StatusResponse Message
Missing STRIPE_WEBHOOK_SECRET500”Missing STRIPE_WEBHOOK_SECRET in environment variables”
Missing stripe-signature header400”Missing stripe-signature header”
Invalid signature400”Webhook signature verification failed: [error details]“
Valid webhook received200”Webhook recibido correctamente”

Additional Resources

Build docs developers (and LLMs) love