Guardian missing $30 PAC fee on order

Objective

  • After a Pay at Close (PAC) fee is waived on an inspection by manually adjusting a charge, Attik’s job totals, PAC payment/fee display, and ISN order_total must all reflect the same amount the closing company should bill.
  • Eliminate false “overpayment” states (e.g. Attik showing ~$30 more paid than ISN) so internal teams and ISN settlement stay aligned without manual reconciliation.

Background

  • On inspection 1008591900, a PAC payment was added while pending, then the client requested a waiver of the $30 PAC fee.
  • Operations waived the fee by adding a separate -$30 charge (negative amount) to offset the inspection/PAC fee—not via a dedicated PAC waiver flow.
  • The ISN order now shows the correct total for settlement: $401.92.
  • Attik still shows $431.92 as paid plus a $30 PAC transaction fee line, producing a $30 overpayment relative to ISN and making it unclear whether ISN will bill the closing company correctly.
  • Internal terminology: the team says “Guardian” here but means ISN for this PAC payment (Guardian/CardPointe is card/ACH; PAC fees go to ISN in order_total, not to Guardian APIs).
  • Initial Slack context: attik-talk thread
  • Root cause (code audit): there is no PAC fee waiver path. A negative charge only lowers inspection.total from charges; it does not remove or zero the linked pac_fee Fee row, clear payment.feeAmount, or consistently refresh PAC payment.amount. syncTotalsOnInspection in src/util/functions/forecast/syncTotalsOnInspections.ts can still count the $30 fee in totalFees / totalPaidWithFees when the PAC payment is not excluded as pending. updatePACOrderTotal in src/util/functions/isn/handlePACUpdates.ts can send ISN order_total from inspection.total + Fee.amount (via _feeId), so ISN may match $401.92 while Attik UI and totals still show the waived fee.

Scope

Backend

  • PAC create and ISN sync: src/routes/isnPayments.ts (create order, PUT update-order), src/util/functions/isn/isnPayAtCloseOrderTotal.ts (isnPayAtCloseOrderTotal, payAtClosePaymentAmountTowardJob), src/util/functions/isn/handlePACUpdates.ts (charge-change hook from src/events/streamHandlers/inspectionStream.ts).
  • Totals and overpayment: src/util/functions/forecast/syncTotalsOnInspections.ts (total, totalPaid, totalFees, totalWithFees, totalPaidWithFees, remainingBalance, principalSurplusPaidOverCharges).
  • Fee records: src/models/feeSchema.ts, src/util/constants/feeTypes.ts (pac_fee), PAC fee creation on create in isnPayments.ts.
  • Related validation (fee fallback pattern): src/util/functions/isn/validatePACThreshold.ts already falls back to payAtCloseFlatFee when _feeId is missing—updatePACOrderTotal does not; align behavior is in scope.
  • Decision needed: First-class “waive PAC fee” (or equivalent) vs. detecting operational negative-charge waivers and reconciling Fee + payment + ISN automatically. Also whether to fix data for 1008591900 as part of this work or separately.

Frontend

  • Inspection payments UI: src/app/tools/inspections/[id]/components/ServicesPayments.tsx (totals header: total / Payments / Balance; PAC payment rows and fee line via getPaymentFeeAmount).
  • Client pay-beta (PAC fee display): src/app/client/job/[slug]/pay-beta/components/PayAtCloseTab.tsx, PaymentBetaClient.tsx (payAtCloseFlatFee in displayed totals).
  • Negative balance / overpayment display: src/app/client/job/[slug]/pay/PaymentPageClient.tsx (negative remainingBalance).
  • Ensure displayed paid/balance/PAC fee lines match backend totals after waiver (no orphaned $30 PAC fee when ISN order_total excludes it).

References

  • Example inspection: 1008591900
  • Slack: attik-talk thread
  • Backend entry points: src/routes/isnPayments.ts, src/util/functions/isn/handlePACUpdates.ts, src/util/functions/forecast/syncTotalsOnInspections.ts

Please authenticate to join the conversation.

Upvoters
Status

Planned

Board
🏠

Main App

Date

10 days ago

Author

Linear

Subscribe to post

Get notified by email when there are changes.