Skip to content

chimpmatic/mailchimp-webhook-handler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mailchimp Webhook Handler

Latest Version PHP Version License

Parse and handle Mailchimp webhook payloads. Typed events, secret verification, event listeners, zero dependencies, PHP 8.5+.

Author: Chimpmatic

Why This Exists

Mailchimp sends webhook notifications when subscribers join, leave, update their profile, change their email, or get cleaned from your audience. Parsing these payloads means dealing with nested form data, extracting merge fields, and routing events to the right handler.

This library turns raw $_POST data into typed, readonly objects with a clean event listener API.

Built for Contact Form 7 to Mailchimp integrations, but works with any PHP application.

Requirements

  • PHP 8.5 or higher (uses readonly classes and enums)
  • No extensions required (zero dependencies)

A fatal error (E_USER_ERROR) is triggered if loaded on PHP < 8.5. The library will not run on older versions.

Installation

composer require chimpmatic/mailchimp-webhook-handler

Quick Start

use Chimpmatic\WebhookHandler\WebhookHandler;
use Chimpmatic\WebhookHandler\WebhookEvent;
use Chimpmatic\WebhookHandler\WebhookPayload;

$handler = new WebhookHandler();

// Register listeners
$handler->on(WebhookEvent::Subscribe, function (WebhookPayload $payload): void {
    echo "New subscriber: {$payload->email}";
    echo "Name: {$payload->getMergeField('FNAME')} {$payload->getMergeField('LNAME')}";
});

$handler->on(WebhookEvent::Unsubscribe, function (WebhookPayload $payload): void {
    echo "Unsubscribed: {$payload->email} — reason: {$payload->getReason()}";
});

// Handle the incoming webhook
$payload = $handler->handle($_POST);
echo $payload->getSummary();

Supported Events

Event Mailchimp Type Description
Subscribe subscribe New subscriber added
Unsubscribe unsubscribe Subscriber removed
ProfileUpdate profile Subscriber updated their profile
EmailChanged upemail Subscriber changed their email
Cleaned cleaned Email bounced (hard/soft)
Campaign campaign Campaign sent to list

Webhook Endpoint

use Chimpmatic\WebhookHandler\WebhookHandler;
use Chimpmatic\WebhookHandler\WebhookException;

$handler = new WebhookHandler('your-webhook-secret');

// Mailchimp sends a GET request to validate the URL
if ($handler->isValidationRequest($_SERVER['REQUEST_METHOD'])) {
    http_response_code(200);
    exit;
}

// Verify the secret (Mailchimp appends ?secret=... to the URL)
if (!$handler->verifySecret($_GET['secret'] ?? '')) {
    http_response_code(403);
    exit;
}

try {
    $payload = $handler->handle($_POST);
    http_response_code(200);
} catch (WebhookException $e) {
    http_response_code(400);
    echo $e->getMessage();
}

Working with Payloads

$handler->on(WebhookEvent::Subscribe, function (WebhookPayload $payload): void {
    // Basic info
    echo $payload->email;       // "john@example.com"
    echo $payload->audienceId;  // "abc123def4"
    echo $payload->firedAt;     // "2026-03-16 21:00:00"
    echo $payload->event->value; // "subscribe"

    // Merge fields
    echo $payload->getMergeField('FNAME'); // "John"
    echo $payload->getMergeField('LNAME'); // "Doe"

    // Full summary
    echo $payload->getSummary();
    // "[2026-03-16 21:00:00] subscribe — john@example.com (audience: abc123def4)"
});

Email Changed Events

$handler->on(WebhookEvent::EmailChanged, function (WebhookPayload $payload): void {
    echo "Old: {$payload->getOldEmail()}"; // "old@example.com"
    echo "New: {$payload->getNewEmail()}"; // "new@example.com"
});

Listen to All Events

$handler->onAny(function (WebhookPayload $payload): void {
    // Log every webhook
    error_log($payload->getSummary());
});

Parse Without Dispatching

// Just parse, don't trigger listeners
$payload = $handler->parse($_POST);

if ($payload->isSubscribe()) {
    // ...
}

Error Handling

use Chimpmatic\WebhookHandler\WebhookException;

try {
    $handler->parse($_POST);
} catch (WebhookException $e) {
    // Empty payload, missing type, unknown event type, invalid data
}

Related Packages

Links

License

MIT License. Copyright (c) 2026 Chimpmatic.

About

Parse and handle Mailchimp webhook payloads. Typed events, secret verification, event listeners, zero dependencies, PHP 8.5+.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages