webhooks

ruby
timestamp = request.headers.fetch('X-Signature-Timestamp')
signature = request.headers.fetch('X-Signature')
payload = request.raw_post

data = "#{timestamp}.#{payload}"
expected = OpenSSL::HMAC.hexdigest('SHA256', ENV.fetch('WEBHOOK_SECRET'), data)

HMAC signed API requests for webhook and partner integrity

hmac api-signing webhooks
by Kai Nakamura 2 tabs
ruby
event_id = request.headers.fetch('X-Event-Id')
timestamp = request.headers.fetch('X-Signature-Timestamp').to_i

raise ActionController::BadRequest, 'stale request' if Time.now.to_i - timestamp > 300
raise ActionController::BadRequest, 'replay detected' if WebhookEvent.exists?(external_id: event_id)

Secure webhook endpoint design with replay protection

webhooks replay-protection hmac
by Kai Nakamura 1 tab
ruby
class CreateProcessedEvents < ActiveRecord::Migration[7.1]
  def change
    create_table :processed_events do |t|
      t.string :event_key, null: false
      t.string :job_class, null: false
      t.jsonb :metadata, null: false, default: {}

Idempotent Job with Advisory Lock

rails postgres reliability
by codesnips 3 tabs
typescript
import crypto from 'crypto';

interface VerifyOptions {
  rawBody: Buffer;
  signatureHeader: string | undefined;
  secret: string;

Webhook signature verification (timing-safe compare)

security webhooks hmac
by codesnips 3 tabs
ruby
class AddUniqueIndexToInventorySnapshots < ActiveRecord::Migration[7.1]
  disable_ddl_transaction!

  def change
    add_index :inventory_snapshots,
              [:warehouse_id, :sku],

Bulk Upsert with insert_all + Unique Index

rails activerecord postgres
by codesnips 3 tabs
typescript
import { Injectable } from '@nestjs/common';

export interface RateLimitResult {
  allowed: boolean;
  remaining: number;
  limit: number;

Sliding-Window Webhook Rate Limiting with a NestJS Interceptor and In-Memory Counter

typescript nestjs rate-limiting
by codesnips 3 tabs
php
<?php

namespace App\Http\Controllers;

use App\Jobs\ProcessWebhook;
use App\Support\WebhookSignature;

Debounce Duplicate Webhooks in Laravel by Dispatching a Delayed Queued Job

laravel webhooks queues
by codesnips 3 tabs
ruby
require 'sinatra/base'
require 'json'
require_relative 'signature_verifier'

class WebhookApp < Sinatra::Base
  configure do

Verifying Stripe Webhook Signatures in Sinatra with a before Filter

sinatra webhooks stripe
by codesnips 2 tabs
javascript
const crypto = require('crypto');

function computeSignature(secret, timestamp, payload) {
  return crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${payload}`, 'utf8')

Verify Stripe-Style Webhook Signatures With HMAC in Express Before Processing

webhooks hmac security
by codesnips 2 tabs
ruby
class CreateStripeEvents < ActiveRecord::Migration[7.1]
  def change
    create_table :stripe_events do |t|
      t.string :stripe_event_id, null: false
      t.string :event_type, null: false
      t.string :status, null: false, default: "received"

Idempotent Stripe Webhook Processing in Rails with a Durable Event Log

rails stripe webhooks
by codesnips 4 tabs
typescript
import { Queue } from "bullmq";
import { createHash } from "crypto";

export const connection = { host: "127.0.0.1", port: 6379 };

export interface ChargePayload {

BullMQ job idempotency via dedupe id

node redis background-jobs
by codesnips 3 tabs
ruby
module Webhooks
  class StripeController < ApplicationController
    skip_before_action :verify_authenticity_token

    def create
      payload = request.body.read

Webhook signature verification

rails security webhooks
by Alex Kumar 1 tab