Class: Payment::DailyIssuesDigestWorker

Inherits:
Object
  • Object
show all
Includes:
Sidekiq::Job, Workers::ErrorReportingConcern
Defined in:
app/workers/payment/daily_issues_digest_worker.rb

Overview

Sidekiq worker: nightly digest of payment issues that need accounting
attention. Replaces the per-event alerts that used to fire from four
different code paths with one consolidated email, so AR doesn't get a
stream of one-off messages interleaved with their inbox.

Scans the last 24 hours for four classes of issue:

  1. Orphan Stripe PaymentIntents — Stripe charged but Heatwave has
    no matching Payment in state authorized/captured. Detected by
    walking each Stripe account's recent succeeded PIs and joining
    against the local Payment table. (Previously emailed by the
    standalone OrphanPaymentIntentReconciliationWorker.)

  2. Overcharged invoices — captured payments on an invoice exceed
    the invoice total. Detected by scanning recently-created invoices
    with attached captured payments and comparing
    #total_captured against Invoice#total. (Previously
    emailed by PaymentCheckerWorker#detect_overcharged_invoices.)

  3. PayPal authorizations expired past the 29-day hard limit
    Payment transitioned to state expired in the last 24 hours.
    The state transition itself happens in
    #attempt_paypal_reauthorization_if_needed during the
    8-hourly PaymentCheckerWorker; this worker only reports.

  4. PayPal reauthorization failures — an OrderTransaction was
    recorded with action reauthorization and success=false in the
    last 24 hours. Same retrospective detection pattern as #3.

Send is skipped entirely when all four scans return empty — never
emails an "all clear."

Constant Summary collapse

WINDOW =
24.hours
CURRENCIES =
%w[USD CAD].freeze

Instance Method Summary collapse

Methods included from Workers::ErrorReportingConcern

#report_worker_error, #report_worker_warning

Instance Method Details

#performObject



43
44
45
46
47
48
49
50
51
52
53
54
# File 'app/workers/payment/daily_issues_digest_worker.rb', line 43

def perform
  issues = {
    orphan_payment_intents: safely(:find_orphan_payment_intents),
    overcharged_invoices:   safely(:find_overcharged_invoices),
    paypal_expired:         safely(:find_paypal_expired_payments),
    paypal_reauth_failed:   safely(:find_paypal_reauth_failures)
  }

  return if issues.values.all?(&:empty?)

  PaymentReconciliationMailer.daily_issues_digest(issues: issues).deliver_later
end