Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Smtpfast Laravel Laravel Package

smtpfast/smtpfast-laravel

SMTPFast for Laravel integrates the SMTPFast sending service with Laravel's built-in mail system, adding a ready-made transport and simple configuration so you can send transactional email from any Laravel application.

View on GitHub
Deep Wiki
Context7

Getting Started

This is the first release (v0.1.0) of a Laravel mail transport that replaces SMTP with SMTPfast's HTTP API. The value proposition is that nothing about your existing Mailables or Notifications changes — only the mailer.

  1. Install and let Composer resolve Laravel 12/13 (the package requires PHP 8.2+):

    composer require smtpfast/laravel
    
  2. Publish the package config if the service provider exposes one (check the README for the exact tag):

    php artisan vendor:publish --tag=smtpfast-config
    
  3. Switch the default mailer in .env and add the key:

    MAIL_MAILER=smtpfast
    SMTPFAST_API_KEY=sk_live_...
    MAIL_FROM_ADDRESS="[email protected]"
    MAIL_FROM_NAME="${APP_NAME}"
    
  4. Clear cached config, since MAIL_MAILER is read from the config cache:

    php artisan config:clear
    
  5. Smoke test with an existing Mailable, or the fastest possible check:

    Mail::raw('hello', fn ($m) => $m->to('[email protected]')->subject('SMTPfast test'));
    

Where to look first: the README's configuration section (env var names, webhook route/signature header), then config/mail.php to confirm the package registered a smtpfast entry in the mailers array. In the source, the transport/mailer class is the interesting file — it's where API errors are translated (or not) into mail exceptions. The webhook section is a separate concern and can be skipped entirely on day one.

First real use case: point staging at SMTPfast, keep log locally, and send a queued password-reset or receipt email. If that lands with correct From, Reply-To, attachments, and inline images, the migration is effectively done.

Implementation Patterns

Keep the default mailer as the swap point. Set MAIL_MAILER=smtpfast and stop there. Existing Mail::to(...)->send(...), Notification::send(...), and MustVerifyEmail flows all keep working. Resist the urge to touch Mailables during the migration — that's how you lose the ability to A/B against your old provider.

Define a second named mailer for scoped routing. If you only want transactional mail on SMTPfast while marketing mail stays elsewhere, add both entries under mailers and route per message:

Mail::mailer('smtpfast')->to($user)->send(new Receipt($order));

// or on the Mailable
public function mailer(): string { return 'smtpfast'; }

Notifications honor ->mailer() inside the toMail() closure, so mixed-channel notifications can be pinned per-notification.

Always queue. The transport makes an outbound HTTP call, so an unqueued send inside a request adds the API's latency directly to your response time. Implement ShouldQueue on Mailables and notifications, and set $tries/$backoff deliberately — a retry is a second email unless the API supports idempotency keys (check the client's send signature).

Treat the singleton client as the escape hatch, not the norm. The package binds the SMTPfast PHP client as a singleton plus a facade. Use it for things the mail transport doesn't cover (account/suppression lookups, template or domain management). Inject it via the container rather than new-ing it, and wrap it behind your own thin interface so you can fake it in tests:

$this->app->bind(MailAuditContract::class, fn ($app) => new SmtpfastAudit($app->make(SMTPfast::class)));

Webhook handling: verify, then queue. Register the route yourself (typically in routes/api.php or via the package's route registration), verify the signature against the raw request body, return 200 immediately, and hand off to a job:

Route::post('/webhooks/smtpfast', SmtpfastWebhookController::class)
    ->withoutMiddleware([\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class]);

Make the handler idempotent — key on the event ID and upsert, because providers redeliver. Store delivery/bounce events against your own messages table keyed by your own message ID, not the provider's, so a future provider swap doesn't invalidate history.

Testing. Mail::fake() assertions are unchanged and remain the right level for feature tests. If you need to test the transport path itself, Http::fake() the SMTPfast endpoint and assert the payload shape (recipients, From, attachments) — that's the only place the package is actually observable.

Environment matrix. log locally, array in CI, smtpfast in staging and production. Keeping MAIL_MAILER environment-driven means a single .env.example documents both paths and no code branches on environment.

Gotchas and Tips

  • Stale MAIL_HOST / MAIL_PORT / MAIL_USERNAME / MAIL_PASSWORD are ignored but confusing. Leave them out of .env.example, or add a comment. Half of "it's not sending" reports in this class of package are a teammate who re-added MAIL_HOST and assumed it was used.
  • Config cache and Octane. php artisan config:clear after adding SMTPFAST_API_KEY; under Octane run php artisan octane:reload. If you rotate API keys per tenant at runtime via config([...]), be aware the singleton client may already be resolved with the old key — app()->forgetInstance(...) or rebind before sending.
  • Laravel 12/13 only. No 10/11 support, and the constraint will block composer update in mixed monorepos. Check with composer why-not smtpfast/laravel before blaming the update itself.
  • Exceptions are not Symfony\Component\Mailer\Exception\*. Failures surface as HTTP/client exceptions from the SDK, not transport exceptions. Catch broadly around Mail::send() (or let the queue handle it via failed()), and log the API response body — bounce and rejection reasons usually live there, and they're the only way to distinguish "bad recipient" from "bad key".
  • Don't rely on MAIL_FROM_ADDRESS being authoritative. Many API mail providers reject or rewrite From addresses on unverified domains. Verify the sending domain first; a 403 on first send is almost always this, not a bug in the package.
  • v0.1.0 is pre-1.0. Pin ~0.1.0 rather than ^0.1, read the changelog before bumping, and keep the package behind a small internal adapter so reverting to SMTP/SES is a one-file change. Expect envelope changes (config keys, exception types) before 1.0.
  • Webhook signature verification needs the raw body. Using $request->all() after the JSON middleware has parsed and re-encoded the payload will fail verification with a confusing mismatch. Also keep the route out of the web middleware group or you'll get a 419.
  • No built-in failover. Laravel has no failover mailer; if SMTPfast is down you need your own catch-and-retry against a secondary mailer (or a queued job with a second attempt). Decide that up front for anything revenue-critical.
  • Attachments are base64-encoded into the request. Very large attachments can hit API payload limits and will fail differently from SMTP (413 or 422 rather than a size rejection). Prefer signed links for anything over a few MB.
  • Check for a sandbox/test key before pointing staging at production. Burning send reputation — and, on metered plans, credits — from staging test fixtures is a common first-week mistake.
  • Debugging order: php artisan config:show mail → confirm the smtpfast mailer entry exists and the key is populated → send via Mail::raw in tinker → if that fails, hit the client directly with the facade to isolate transport vs. SDK → then look at the API response body.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo