require 'sinatra/base'
require 'json'
require_relative 'signature_verifier'
class WebhookApp < Sinatra::Base
configure do
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"
import hashlib
import hmac
import time
class SignatureError(Exception):
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
// rawBody: true preserves the exact bytes Stripe signed
const app = await NestFactory.create(AppModule, { rawBody: true });
<?php
namespace App\Controller;
use App\Message\ProcessStripeEvent;
use App\Webhook\StripeSignatureVerifier;
class CreateWebhookEvents < ActiveRecord::Migration[7.1]
def change
create_table :webhook_events do |t|
t.string :event_id, null: false
t.string :source, null: false, default: "stripe"
t.string :event_type, null: false
const express = require('express');
const webhookRouter = require('./webhookRouter');
const apiRouter = require('./apiRouter');
const app = express();
<?php
namespace App\Jobs;
use App\Models\Invoice;
use App\Services\StripeGateway;
package webhook
import (
"encoding/json"
"io"
"net/http"
import hmac
import hashlib
import time
from fastapi import Request, HTTPException, status
const { pool } = require('./db');
async function recordEvent(client, { eventId, type, payload }) {
const { rows } = await client.query(
`INSERT INTO webhook_events (event_id, type, payload, status)
VALUES ($1, $2, $3, 'received')