Email Transparency

This page explains which emails PayCal sends, how each message is assembled and delivered, and how we verify reliability.

Email Principles

PayCal treats transactional email as part of account safety and account continuity, not as marketing infrastructure.

  • Flow-specific templates are used for verification, recovery, account-change, and contact support paths.
  • Email composition is centralized to avoid divergent message logic across controllers.
  • Delivery failures return explicit outcomes so calling flows can fail safely and inform users clearly.

What We Send

Flow Purpose Template Family
Email verification Confirm ownership during account lifecycle events email-verification-*
Recovery email verification Prove destination ownership before sensitive recovery actions email-recovery-email-code-*
Recovery Key Delivery Provide account recovery material email-recovery-key-*
Account recovery transaction Issue account-recovery verification code email-account-recovery-code-*
Email change (old/new inbox) Dual inbox confirmation for account email mutation email-change-code-* and email-change-confirmation-*
Contact support relay Forward support requests to support inbox with normalized content contact-email-*

Delivery Pipeline

PayCal uses a two-layer email stack:

  • PayCal\Domain\EmailGarum: workflow-level orchestration and template selection.
  • PayCal\Domain\EmailTransport: SMTP protocol transport (connect, STARTTLS, AUTH, send, close).

Template rendering is performed via PayCal\Domain\Render::template(), with both HTML and text bodies built for each flow.

Verification links are environment-localized using request host resolution so links remain aligned to the current deployment context.

Support Email Telemetry and Auditability

Contact-support submissions include best-effort telemetry so delivery health can be monitored without blocking user submissions.

  • Aggregate counters are recorded under telemetry:contact:* keys.
  • JSONL event records are appended to rotated logs via PayCal\Domain\ContactSupportTelemetry.
  • Log writing is non-blocking to preserve support-form UX if telemetry storage is degraded.

Verification and Reliability Checks

  • html/tests/Unit/EmailTemplateRenderTest.php verifies all supported templates render with expected placeholder substitution.
  • html/tests/Integration/LiveEmailTemplateSweepTest.php provides opt-in live SMTP end-to-end template coverage.
  • html/tests/Integration/EmailSendTest.php provides opt-in single-message verification for SMTP, DKIM, DMARC, and Message-ID health.
# Opt-in live template sweep
cd html
PAYCAL_RUN_LIVE_EMAIL_SWEEP=1 PAYCAL_LIVE_EMAIL_RECIPIENT=you@example.com \
  ./vendor/bin/phpunit --configuration phpunit.xml tests/Integration/LiveEmailTemplateSweepTest.php

# Opt-in single email stack verification
cd html
PAYCAL_RUN_LIVE_EMAIL=1 PAYCAL_LIVE_EMAIL_RECIPIENT=you@example.com \
  ./vendor/bin/phpunit --configuration phpunit.xml tests/Integration/EmailSendTest.php

Scope Boundary

This page documents transactional and support email behavior for PayCal product operations. It does not document marketing automation because PayCal does not use a marketing email funnel in this codebase.

Last updated: March 21, 2026.