mailchimp/transactional
Official PHP client for Mailchimp Transactional (Mandrill) API v1. Send emails, manage templates, allowlists, exports, webhooks, and more with simple POST calls. Requires PHP 7.2+. Install via Composer: mailchimp/transactional.
Install the Package
composer require mailchimp/transactional
Add to composer.json if not using Composer globally:
"require": {
"mailchimp/transactional": "^1.0"
}
Configure API Key
Store your Mailchimp API key in Laravel’s .env:
MAILCHIMP_TRANSACTIONAL_API_KEY=your_api_key_here
MAILCHIMP_TRANSACTIONAL_REGION=us12 # e.g., us12, eu1, etc.
Create a Service Class
In app/Services/MailchimpService.php:
<?php
namespace App\Services;
use MailchimpTransactional\ApiClient;
class MailchimpService
{
protected $client;
public function __construct()
{
$this->client = new ApiClient();
$this->client->setApiKey(config('services.mailchimp.api_key'));
$this->client->setServer(config('services.mailchimp.region'));
}
// Add methods here (see Implementation Patterns)
}
Register in config/services.php
'mailchimp' => [
'api_key' => env('MAILCHIMP_TRANSACTIONAL_API_KEY'),
'region' => env('MAILCHIMP_TRANSACTIONAL_REGION', 'us12'),
],
First Use Case: Send an Email
Bind the service in AppServiceProvider and send a test email:
$mailchimp = app(MailchimpService::class);
$response = $mailchimp->sendEmail([
'message' => [
'to' => [['email' => 'user@example.com']],
'from' => 'sender@example.com',
'subject' => 'Test Email',
'html' => '<p>Hello, world!</p>',
],
]);
$response = $mailchimp->messages->send([
'message' => [
'to' => [['email' => 'user@example.com']],
'from' => 'sender@example.com',
'subject' => 'Welcome!',
'html' => '<p>Your content here.</p>',
],
]);
Create a job (app/Jobs/SendMailchimpEmail.php):
use App\Services\MailchimpService;
class SendMailchimpEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable;
public function handle(MailchimpService $mailchimp)
{
$mailchimp->sendEmail($this->payload);
}
}
Dispatch in a controller:
SendMailchimpEmail::dispatch($emailData)->onQueue('mailchimp');
Publish a template:
$mailchimp->templates->publish([
'name' => 'Welcome Template',
'content' => [
'type' => 'html',
'value' => '<p>Welcome!</p>',
],
]);
Send using a template:
$mailchimp->messages->send([
'message' => [
'to' => [['email' => 'user@example.com']],
'template_id' => 'template_123',
'merge_vars' => [
['name' => 'FIRST_NAME', 'content' => 'John'],
],
],
]);
Configure a route in routes/web.php:
Route::post('/mailchimp/webhook', [MailchimpWebhookController::class, 'handle']);
Handle inbound webhooks (app/Http/Controllers/MailchimpWebhookController.php):
public function handle(Request $request)
{
$payload = $request->getContent();
$signature = $request->header('X-Mailchimp-Signature');
// Verify signature (use \MailchimpTransactional\Webhook::verify())
if (Webhook::verify($payload, $signature, config('services.mailchimp.webhook_secret'))) {
$event = json_decode($payload, true);
// Process event (e.g., update user model)
}
}
$recipients = [
['email' => 'user1@example.com'],
['email' => 'user2@example.com'],
];
$mailchimp->messages->sendMany([
'message' => [
'to' => $recipients,
'from' => 'sender@example.com',
'subject' => 'Batch Send',
'html' => '<p>Batch content.</p>',
],
]);
Add a subscriber:
$mailchimp->lists->addListMember('list_id', [
'email_address' => 'user@example.com',
'merge_fields' => [
'FIRST_NAME' => 'John',
'LAST_NAME' => 'Doe',
],
]);
Wrap API calls in a try-catch:
try {
$response = $mailchimp->messages->send($emailData);
} catch (\MailchimpTransactional\Exception\ApiException $e) {
Log::error('Mailchimp API Error: ' . $e->getMessage());
// Retry logic or notify admin
}
API Key vs. Region Mismatch
setServer() matches your Mailchimp account’s region (e.g., us12, eu1).setServer('us12') for US accounts.Rate Limits
use Symfony\Component\RateLimiter\RateLimiterFactory;
$factory = new RateLimiterFactory();
$limiter = $factory->create($this->client, 100, 'minute');
if (!$limiter->consume()) {
sleep($limiter->wait());
}
Webhook Verification
Webhook::verify() to prevent spoofing..env:
MAILCHIMP_WEBHOOK_SECRET=your_webhook_secret_here
Template IDs
template_name. Fetch IDs via:
$templates = $mailchimp->templates->getAll();
$templateId = $templates['templates'][0]['id'];
Async Deliverability
Enable Debug Mode Configure the client to log requests:
$mailchimp->setDebug(true);
Logs appear in storage/logs/laravel.log.
Inspect Raw Responses Dump the full response object:
dd($response->getBody());
Validate Payloads Use Mailchimp’s API Validator to test payloads before sending.
Custom Middleware Add middleware to the client for logging or transformations:
$mailchimp->getHttpClient()->setDefaultOption('middleware', [
new class implements \GuzzleHttp\Middleware {
public function __invoke(callable $handler) {
return function ($request, $options) {
// Modify request/options (e.g., add headers)
return $handler($request, $options);
};
}
},
]);
Event Dispatching Trigger Laravel events after API calls:
event(new MailchimpEmailSent($response));
Fallback for Failures
Implement a fallback (e.g., send via Laravel’s Mail facade):
try {
$mailchimp->sendEmail($data);
} catch (\Exception $e) {
Mail::send([], [], function ($message) use ($data) {
$message->to($data['to'])->subject($data['subject']);
});
}
Timeouts Default timeout is 10 seconds. Adjust in Guzzle options:
$mailchimp->getHttpClient()->setDefaultOption('timeout', 30);
Proxy Support
How can I help you explore Laravel packages today?