mailbino / laravel
Laravel SDK for Mailbino: mail driver and API client
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.0
- illuminate/mail: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
Requires (Dev)
- orchestra/testbench: ^9.0|^10.0|^11.0
- phpunit/phpunit: ^11.0|^12.0
README
Laravel SDK for Mailbino: transactional email that's easy to test.
Provides both a Laravel mail driver (use Mail::send() as usual) and a direct API client for Mailbino-specific features like tags, metadata, scoping, and test mode.
Installation
composer require mailbino/laravel
Configuration
Add your API token to .env:
MAIL_MAILER=mailbino MAILBINO_API_TOKEN=mbn_live_xxxxxxxxxxxx
Optionally publish the config file:
php artisan vendor:publish --tag=mailbino-config
Mail driver setup
Add the mailbino mailer to config/mail.php:
'mailers' => [ 'mailbino' => [ 'transport' => 'mailbino', ], // ... ],
That's it. All Mail::send() calls now go through Mailbino.
Usage
Standard Laravel Mail (zero changes needed)
Mail::to($user)->send(new WelcomeMail($user));
With Mailbino-specific features
Use custom headers to pass tags, metadata, and scoping through the standard mail interface:
Mail::to($user)->send(new InvoiceMail($invoice)); // In your Mailable's headers() method: public function headers(): Headers { return new Headers( text: [ 'X-Mailbino-Tags' => 'invoice, billing', 'X-Mailbino-Scope-Type' => 'invoice', 'X-Mailbino-Scope-Id' => $this->invoice->id, 'X-Mailbino-Metadata' => json_encode(['amount' => $this->invoice->total]), ], ); }
Available headers:
| Header | Description |
|---|---|
X-Mailbino-Tags |
Comma-separated tags |
X-Mailbino-Scope-Type |
Scope type (e.g. order, user) |
X-Mailbino-Scope-Id |
Scope ID |
X-Mailbino-Metadata |
JSON-encoded metadata object |
X-Mailbino-Test-Recipient |
Override test recipient for this message |
X-Mailbino-External-Id |
Your own message ID (UUID) |
Direct API client
For full control, use the Mailbino facade:
use Mailbino\Laravel\Facades\Mailbino; // Send an email $result = Mailbino::send([ 'from' => 'noreply@m.yourapp.com', 'from_name' => 'Your App', 'to' => ['email' => 'user@example.com', 'name' => 'John'], 'subject' => 'Your invoice is ready', 'html' => '<h1>Invoice</h1>', 'tags' => ['invoice'], 'metadata' => ['invoice_id' => 'INV-123'], 'scope_type' => 'invoice', 'scope_id' => 'INV-123', ]); // $result = ['message_id' => '...', 'status' => 'queued'] // Query messages $messages = Mailbino::messages(['status' => 'delivered', 'to_email' => 'user@example.com']); // Get a specific message $message = Mailbino::message('a1b2c3d4-...'); // Get message events $events = Mailbino::events('a1b2c3d4-...');
Test Mode
Mailbino has built-in test mode. Enable it in the Mailbino dashboard and all emails are redirected to your test recipients with a banner showing the original address.
Option 1: Dashboard
Enable test mode on your app in the Mailbino dashboard and add your test recipients there.
Option 2: Environment variable
Set a global test recipient in .env:
MAILBINO_TEST_RECIPIENT=developer@company.com
This sends test_recipient on every API call. Combined with test mode on the app, all emails land in your inbox.
The environment variable only selects the recipient. It never enables test mode. When test mode is disabled in the Mailbino dashboard, Mailbino sends to the real recipient.
Option 3: Per-message
// Via mail headers 'X-Mailbino-Test-Recipient' => 'developer@company.com' // Via direct API Mailbino::send([ // ... 'test_recipient' => 'developer@company.com', ]);
Webhooks
Set the signing secret shown in the Mailbino app settings:
MAILBINO_WEBHOOK_SECRET=whsec_xxxxxxxxxxxx
Verify the raw request body before processing an event:
use Mailbino\Laravel\Webhooks\WebhookVerifier; $event = app(WebhookVerifier::class)->verify( $request->getContent(), $request->headers->all(), );
The verifier checks the signature, rejects stale requests and returns the decoded payload. The default timestamp tolerance is 300 seconds and can be changed with MAILBINO_WEBHOOK_TOLERANCE.
Error Handling
use Mailbino\Laravel\MailbinoException; try { Mailbino::send([...]); } catch (MailbinoException $e) { $e->statusCode; // 422 $e->apiError; // "Domain not verified." $e->apiMessage; // "The sender domain for..." }
License
MIT