t-willm/larawebhook

LaraWebhook is an open-source Laravel package for securely and reliably managing incoming webhooks. It validates signatures, handles retries, and logs errors transparently. Ideal for Stripe, GitHub, Slack, and more!

Fund package maintenance!
:t-willm

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/t-willm/larawebhook


README

Latest Version Tests codecov PHPStan License

LaraWebhook is an open-source Laravel package for handling incoming webhooks in a secure, reliable, and simple way. Validate signatures, manage retries, log events, and integrate popular services (Stripe, GitHub, Slack, etc.) in minutes.

โœจ Features

  • Signature Validation: Verify webhook authenticity (Stripe, GitHub, etc.)
  • Retry Management: Automatically retry failed webhooks with exponential backoff
  • Detailed Logging: Store events and errors for debugging
  • Interactive Dashboard: Modern UI with Alpine.js and Tailwind CSS for log management
  • REST API: Programmatic access to webhook logs with filtering and pagination
  • Replay Webhooks: Re-process failed webhooks from dashboard or API
  • Easy Integration: Minimal configuration, compatible with Laravel 9+
  • Extensible: Add your own validators or services

๐Ÿ“ฆ Installation

  1. Install the package via Composer:

    composer require t-willm/larawebhook
  2. Publish the configuration:

    php artisan vendor:publish --provider="Twillm\LaraWebhook\LaraWebhookServiceProvider"
  3. Configure your signature keys in config/larawebhook.php:

    'stripe' => [
         'secret' => env('STRIPE_WEBHOOK_SECRET'),
         'tolerance' => 300, // Tolerance in seconds
    ],

๐Ÿ›  Usage

Using the Middleware (Recommended)

The easiest way to validate webhooks is using the validate-webhook middleware:

// routes/web.php
Route::post('/stripe-webhook', function () {
    // Webhook is automatically validated and logged
    // Process your webhook here
    $payload = json_decode(request()->getContent(), true);

    // Handle the event
    event(new \App\Events\StripeWebhookReceived($payload));

    return response()->json(['status' => 'success']);
})->middleware('validate-webhook:stripe');

Route::post('/github-webhook', function () {
    // Webhook is automatically validated and logged
    $payload = json_decode(request()->getContent(), true);

    // Handle the event
    event(new \App\Events\GithubWebhookReceived($payload));

    return response()->json(['status' => 'success']);
})->middleware('validate-webhook:github');

What the middleware does:

  • โœ… Validates the webhook signature
  • โœ… Automatically logs the event to the database
  • โœ… Returns 403 for invalid signatures
  • โœ… Returns 400 for missing headers or malformed payloads

Manual Validation (Advanced)

For more control, you can manually validate webhooks:

// app/Http/Controllers/WebhookController.php
use Twillm\Larawebhook\Services\WebhookValidator;
use Illuminate\Http\Request;

public function handleWebhook(Request $request)
{
    $payload = $request->getContent();
    $signature = $request->header('Stripe-Signature');
    $secret = config('larawebhook.services.stripe.webhook_secret');

    $validator = new WebhookValidator($secret);

    try {
        // Validate and log in one call
        $log = $validator->validateAndLog(
            $payload,
            $signature,
            'stripe',
            'payment_intent.succeeded'
        );

        // Process the event
        event(new \App\Events\StripeWebhookReceived(json_decode($payload, true)));

        return response()->json(['status' => 'success']);
    } catch (\Exception $e) {
        return response($e->getMessage(), 403);
    }
}

๐Ÿ”ง Configuration

Modify config/larawebhook.php to:

  • Add services (Stripe, GitHub, etc.)
  • Configure validation tolerance
  • Enable/disable logging

Example:

'services' => [
    'stripe' => [
        'secret' => env('STRIPE_WEBHOOK_SECRET'),
        'tolerance' => 300,
    ],
    'github' => [
        'secret' => env('GITHUB_WEBHOOK_SECRET'),
        'tolerance' => 300,
    ],
],

๐Ÿ“Š Logging

Webhooks are logged in the webhook_logs table with:

  • service (e.g., stripe, github)
  • event (e.g., payment_intent.succeeded)
  • status (success/failed)
  • payload (webhook content)
  • created_at

To view logs:

php artisan tinker
>>> \ThibaudWillm\LaraWebhook\Models\WebhookLog::latest()->get();

๐Ÿ“Š Dashboard & API

LaraWebhook provides a modern dashboard built with Alpine.js and Tailwind CSS to visualize and manage webhook logs.

Access the Dashboard

The dashboard is automatically available at:

http://your-app.test/larawebhook/dashboard

Features:

  • ๐Ÿ“‹ Paginated webhook logs table
  • ๐Ÿ” Filter by service, status, and date
  • ๐Ÿ‘๏ธ View detailed payload and error messages
  • ๐Ÿ”„ Replay failed webhooks
  • ๐Ÿ“ฑ Fully responsive design

API Endpoints

The package also provides REST API endpoints for programmatic access:

Get Webhook Logs

GET /api/larawebhook/logs

Query Parameters:

  • service - Filter by service (stripe, github, etc.)
  • status - Filter by status (success, failed)
  • date - Filter by date (YYYY-MM-DD)
  • per_page - Results per page (default: 10)
  • page - Page number

Example:

curl "https://your-app.test/api/larawebhook/logs?service=stripe&status=failed&per_page=25"

Response:

{
  "data": [
    {
      "id": 1,
      "service": "stripe",
      "event": "payment_intent.succeeded",
      "status": "success",
      "payload": {...},
      "attempt": 0,
      "created_at": "01/01/2024 10:30:00"
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 5,
    "per_page": 10,
    "total": 50
  },
  "links": {
    "first": "...",
    "last": "...",
    "prev": null,
    "next": "..."
  }
}

Replay a Webhook

POST /api/larawebhook/logs/{id}/replay

Example:

curl -X POST "https://your-app.test/api/larawebhook/logs/123/replay" \
  -H "Content-Type: application/json"

Response:

{
  "success": true,
  "message": "Webhook replayed successfully!",
  "log": {
    "id": 124,
    "service": "stripe",
    "event": "payment_intent.succeeded",
    "status": "success",
    "attempt": 1
  }
}

Dashboard Configuration

Customize the dashboard in config/larawebhook.php:

'dashboard' => [
    'enabled' => env('LARAWEBHOOK_DASHBOARD_ENABLED', true),
    'path' => env('LARAWEBHOOK_DASHBOARD_PATH', '/larawebhook/dashboard'),
    'middleware' => env('LARAWEBHOOK_DASHBOARD_MIDDLEWARE', 'web'),
],

Disable the dashboard:

LARAWEBHOOK_DASHBOARD_ENABLED=false

Change the dashboard path:

LARAWEBHOOK_DASHBOARD_PATH=/admin/webhooks

Add authentication middleware:

LARAWEBHOOK_DASHBOARD_MIDDLEWARE=web,auth

๐Ÿงช Tests

Run tests with:

composer test

(Tests cover validation, retries, and logging.)

๐Ÿš€ Release Process

This project uses Release Please for automated releases and changelog management.

How it works

  1. Commit with Conventional Commits format:

    git commit -m "feat: add new webhook validation"
    git commit -m "fix: resolve signature verification bug"
    git commit -m "docs: update installation instructions"
  2. Release Please creates a PR automatically when changes are pushed to master:

    • Generates/updates CHANGELOG.md based on commits
    • Bumps version in .release-please-manifest.json
    • Creates a release PR titled "chore(master): release X.Y.Z"
  3. Review and merge the release PR:

    • Review the generated changelog
    • Merge the PR to trigger the release
  4. Automatic actions on merge:

    • Creates a GitHub Release with tag vX.Y.Z
    • Runs tests and static analysis
    • Packagist syncs automatically (no manual webhook needed)

Conventional Commits format

  • feat: โ†’ New feature (bumps minor version)
  • fix: โ†’ Bug fix (bumps patch version)
  • docs: โ†’ Documentation changes
  • style: โ†’ Code style changes (formatting, etc.)
  • refactor: โ†’ Code refactoring
  • perf: โ†’ Performance improvements
  • test: โ†’ Adding/updating tests
  • chore: โ†’ Maintenance tasks
  • ci: โ†’ CI/CD changes

Breaking changes: Add ! after type or add BREAKING CHANGE: in commit body to bump major version.

Example:

git commit -m "feat!: change webhook validation API"

๐Ÿ“ฑ Telegram Notifications

LaraWebhook supports Telegram notifications for GitHub Actions events:

  • โŒ Test Failures: Get notified when tests fail on push or pull requests
  • ๐Ÿš€ New Releases: Announcement when a new version is published

Setup Instructions

  1. Create a Telegram Bot:

    • Chat with @BotFather on Telegram
    • Send /newbot and follow instructions
    • Save your bot token
  2. Get Your Chat ID (NOT the bot's ID!):

    • Easy method: Chat with @userinfobot to get YOUR Chat ID
    • Alternative: Start a chat with YOUR bot, then visit https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates
    • โš ๏ธ Important: Use YOUR personal Chat ID, not the bot's ID (bots can't message themselves!)
  3. Add GitHub Secrets:

    • Go to repository Settings โ†’ Secrets and variables โ†’ Actions
    • Add two secrets:
      • TELEGRAM_BOT_TOKEN: Your bot token
      • TELEGRAM_CHAT_ID: Your chat ID
  4. Verify: Push changes and watch for notifications!

For detailed setup instructions, see .github/TELEGRAM_SETUP.md

Example Notifications

Test Failure:

โŒ Tests Failed

Repository: t-willm/larawebhook
Branch: feature/new-feature
Commit: abc123def
Author: username
Workflow: View Details

New Release:

๐Ÿš€ New Release Published

Repository: t-willm/larawebhook
Version: v1.5.0
Release Notes: View on GitHub
Packagist: Install Now

๐Ÿค Contributing

  1. Fork the repository
  2. Create a branch (git checkout -b feature/my-feature)
  3. Commit your changes (git commit -am 'Add my feature')
  4. Push the branch (git push origin feature/my-feature)
  5. Open a Pull Request

(See CONTRIBUTING.md for more details.)

๐Ÿ“„ License

This project is licensed under the MIT License. See LICENSE for more information.