# Testing webhook endpoints

## Verifying webhook authenticity

[Verify](https://docs.stripe.com/webhooks.md#verify-events) that incoming webhooks were sent by Stripe. To make sure your integration handles both genuine and fraudulent webhooks correctly, write tests for each case:

#### Ruby

```ruby
require "net/http"
require "stripe"

RSpec.describe "webhook endpoint" do
  WEBHOOK_SECRET = "whsec_test_secret"
  PAYLOAD = '{
    "id": "evt_test_123",
    "object": "v2.core.event",
    "type": "v1.billing.meter.error_report_triggered",
    "created": "2025-04-01T12:00:00.000Z",
    "livemode": false,
    "related_object": {
      "id": "mtr_123",
      "type": "billing.meter",
      "url": "/v1/billing/meters/mtr_123"
    }
  }'

  it "accepts a validly signed payload" do
    expect(post_payload(signature_header(PAYLOAD))).to eq(200)
  end

  it "rejects an invalid signature" do
    expect(post_payload("t=123456789,v1=badsignature")).to eq(400)
  end

  it "rejects a missing signature" do
    expect(post_payload(nil)).to eq(400)
  end

  def signature_header(payload)
    timestamp = Time.now
    signature = Stripe::Webhook::Signature.compute_signature(timestamp, payload, WEBHOOK_SECRET)
    Stripe::Webhook::Signature.generate_header(timestamp, signature)
  end

  def post_payload(signature)
    headers = { "Content-Type" => "application/json" }
    headers["Stripe-Signature"] = signature if signature

    Net::HTTP.post(URI("http://localhost:4242/webhooks"), PAYLOAD, headers).code.to_i
  end
end
```
