Class: PaymentReconciliationMailer

Inherits:
ApplicationMailer show all
Defined in:
app/mailers/payment_reconciliation_mailer.rb

Overview

ActionMailer: nightly payment-issue digest sent by
Payment::DailyIssuesDigestWorker. Consolidates four classes of issue
that previously emailed separately:

  1. Orphan Stripe PaymentIntents (Stripe charged, Heatwave doesn't know)
  2. Overcharged invoices (captured > invoice total)
  3. PayPal authorizations past the 29-day hard limit (expired)
  4. PayPal reauthorization failures

Each digest is sent to the union of recipients that previously
received the individual alerts. Only sent when at least one section
has content — never sends an "all clear."

Constant Summary collapse

DIGEST_RECIPIENTS =
%w[
  heatwaveteam@warmlyyours.com
  vadepu@warmlyyours.com
  ar@warmlyyours.com
].freeze

Instance Method Summary collapse

Methods inherited from ApplicationMailer

#null_mail

Instance Method Details

#daily_issues_digest(issues:) ⇒ Object

Parameters:

  • issues (Hash{Symbol=>Array<Hash>})

    section name → list of
    issue records. Expected keys:
    :orphan_payment_intents, :overcharged_invoices,
    :paypal_expired, :paypal_reauth_failed. Empty arrays for
    sections with nothing to report are fine.



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'app/mailers/payment_reconciliation_mailer.rb', line 27

def daily_issues_digest(issues:)
  return null_mail if issues.values.all?(&:blank?)

  @issues = issues
  @section_counts = issues.transform_values { |records| records.to_a.size }
  @total_count = @section_counts.values.sum

  mail(
    from: 'Heatwave Team <heatwaveteam@warmlyyours.com>',
    to: DIGEST_RECIPIENTS,
    subject: "Payment issues digest — #{@total_count} item#{'s' unless @total_count == 1} (last 24h)"
  )
end