Skip to main content

Email sending schema

Business overview

Email notifications support our core journeys: onboarding, purchases, support, and re‑engagement. This document describes when each email is sent, to whom, and what content/template is used in Farfalla. Use it to align teams and troubleshoot issues.

Scope

  • Channel: Email (excludes Slack notifications)
  • Product areas: Storefront, Commerce, Identity/Access, Support, Reporting
  • Source: Notification classes and jobs in farfalla

Delivery & localization

  • Delivery: Laravel Notifications via ->notify() / Notification::route('mail', ...). Some messages run queued (ShouldQueue) and some immediate (notifyNow).
  • From address: usually no-reply@{tenant.domain}; exceptions noted below.
  • Templates: Blade Markdown templates under resources/views/mail/** or the vendor notification template vendor.notifications.email.
  • Locale: most emails respect tenant language (tenant()->lang) and translation keys.

Trigger map (what, when, to whom, template)

Purchases and invoices

  • Issue purchase invoice

    • Trigger: Order approved with content items and invoice email enabled.
    • Class: App\Notifications\IssueInvoice
    • Sender: no-reply@{tenant.domain}
    • Recipient: Buyer (order->user)
    • Template: mail.issue.invoice
    • Content: Purchased issues (cover, reader link), help/FAQ links, app banners, recommended issues.
  • Plan/subscription invoice

    • Trigger: Order approved with subscription items and invoice email enabled.
    • Class: App\Notifications\PlanInvoice
    • Sender: no-reply@{tenant.domain}
    • Recipient: Subscriber (order->user)
    • Template: mail.plan.invoice
    • Content: Plan and coupon details, account/library/FAQ links, app banners.
  • Gift purchase status

    • Trigger: Gift orders; subject and template vary by order status (pending, approved, cancelled).
    • Class: App\Notifications\GiftInvoice
    • Sender: no-reply@{tenant.domain}
    • Recipient: Buyer
    • Templates: mail.gift.invoice-pending, mail.gift.invoice-success, mail.gift.invoice-rejected
    • Content: Issue, coupon, destination link (redeem or congrats), app banners.
  • Sale notification (tenant)

    • Trigger: Sale notification job dispatches an email with sale data.
    • Class: App\Notifications\NewSaleNotification
    • Sender: no-reply@{tenant.domain}
    • Recipient: Configured email(s) in the job context
    • Template: mail.new-sale
    • Content: Sale metadata payload.

Shipping

  • Shipping status update
    • Trigger: ShippingNote::dispatchNotification() on status changes (e.g., in‑transit, pickup, delivered, completed, cancelled).
    • Class: App\Notifications\ShippingNoteNotification
    • Sender: no-reply@{tenant.domain}
    • Recipient: Buyer (order->user)
    • Template: mail.shipping.note
    • Subject: Based on status translation (e.g., mail.shipping-note.status.delivered.title).
    • Content: Product list, shipping totals, addresses, costs.

Identity & access

  • Welcome

    • Trigger: After user registration.
    • Class: App\Notifications\WelcomeNotification
    • Sender: no-reply@{tenant.domain}
    • Recipient: New user
    • Template: vendor.notifications.email
    • Content: Either “get started” (social login validated) or “verify email” (hash link).
  • Password reset

    • Trigger: Password reset request.User::sendPasswordResetNotification($token)
    • Class: App\Notifications\CustomResetPassword
    • Sender: no-reply@{tenant.domain}
    • Recipient: User
    • Template: vendor.notifications.email
    • Content: Reset CTA and explanatory lines.
  • Login token (apps)

    • Trigger: Publica Network temporary login code generation.
    • Class: App\Notifications\LoginTokenNotification
    • Sender: no-reply@{tenant.domain}
    • Recipient: End user email
    • Template: mail.login-token
    • Content: One‑time code, expiration minutes, magic link, tenant/app assets.

Lifecycle & engagement

  • Lifecycle drip
    • Trigger: Scheduled job N days after signup for users without active subscription.
    • Class: App\Notifications\LifecycleNotification
    • Sender: tenant('mails.notifications')
    • Recipient: Target user cohort
    • Template: mail.lifecycle-email
    • Content: Configurable subject/body from LifecycleEmail record.

Reports & exports

  • Export ready
    • Trigger: Export file generated; job creates a temporary URL (valid ~1 week).
    • Class: App\Notifications\ExportReportGenerated
    • Sender: no-reply@{platform.final_domain} (Publica.la)
    • Recipient: Requesting user email
    • Template: vendor.notifications.email
    • Content: Subject from job options, body message, download CTA.

Billing & finance

  • Unpaid invoices (tenant)
    • Trigger: Scheduled job; tenant with unpaid invoices.
    • Class: App\Notifications\UnpaidInvoices
    • Sender: admin@publica.la
    • Recipient: Tenant owner email and billing contact (tenant->meta.mails['payments'])
    • Template: vendor.notifications.email
    • Content: Blocking date, link to billing settings.

Marketplace & holds

  • Reserved issue available (PPU)
    • Trigger: Budget available for reserved issue; batch job per tenant.
    • Class: App\Notifications\IssueAvailable
    • Sender: default
    • Recipient: User with qualifying hold
    • Template: mail.issue.available
    • Content: Issue name and details with links.

Gateways

  • Duplicate subscription detected (MercadoPago)
    • Trigger: MercadoPago subscription event detects duplicate.
    • Class: App\Notifications\MPDuplicateSubscriptionNotification
    • Sender: no-reply@{tenant.domain}
    • Recipient: Affected user
    • Template: vendor.notifications.email
    • Content: Cancel/refund notice and CTA to subscribe again.

Support

  • Storefront support request

    • Trigger: End‑user submits help form.
    • Class: App\Notifications\UserSupportRequest
    • Sender: End‑user email (From)
    • Recipient: Tenant support recipients (routed addresses)
    • Template: mail.support-request
    • Content: Subject, message, user email, registration date, subscription status, dashboard shortcut URL.
  • App support request (Reader apps)

    • Trigger: App support flow in mobile/desktop.
    • Class: App\Notifications\AppSupportRequest
    • Sender: End‑user email (From)
    • Recipient: Tenant support recipients
    • Template: mail.app-support-request
    • Content: App/device/versions, tenant context, user metadata, message.

Templates reference (views)

  • mail.issue.invoice
  • mail.plan.invoice
  • mail.gift.invoice-pending, mail.gift.invoice-success, mail.gift.invoice-rejected
  • mail.shipping.note
  • mail.login-token
  • mail.lifecycle-email
  • mail.support-request
  • mail.app-support-request
  • mail.issue.available
  • mail.new-sale
  • vendor.notifications.email (common generic layout)

Operational notes

  • Queueing: Most notifications implement ShouldQueue. Jobs like lifecycle, exports, unpaid invoices, and PPU holds batch work per tenant.
  • Localization: Several notifications call ->locale(tenant()->lang ?? 'en') at dispatch.
  • From/Reply‑To: Support requests deliberately use the end‑user’s address in the From header to ease ticket replies.
  • Download links: Export links use temporary URLs with a 1‑week expiry.

Troubleshooting

  • Not received: Verify mail driver configuration, queue workers, and that the notification/job is enabled and dispatched.
  • Wrong language: Confirm tenant lang and where ->locale(...) is applied on dispatch.
  • Wrong sender: Check per‑notification from(...) and tenant domain settings.
  • Template mismatch: Ensure the expected Blade view exists and parameters are provided by the notification constructor.
X

Graph View