Accrue.Jobs.ReconcileRefundFees (accrue v0.2.0)

Copy Markdown View Source

Daily backstop Oban worker for refund fees that weren't populated at create time (D3-46).

Sweep window

Selects accrue_refunds where fees_settled_at IS NULL AND inserted_at < now() - 24h. The 24h buffer gives Stripe's balance_transaction settlement time to populate before the reconciler tries to pull fees forward — earlier attempts would just re-fail with nil fee_refunded.

Flow per row

  1. Refetch canonical via Processor.retrieve_refund/2 with expand: ["balance_transaction", "charge.balance_transaction"]
  2. Extract fee / fee_refunded from charge.balance_transaction
  3. If both populated: update row with stripe_fee_refunded_amount_minor, merchant_loss_amount_minor, and fees_settled_at = Clock.utc_now()
  4. Emit [:accrue, :billing, :refund, :fees_settled] telemetry
  5. Record refund.fees_settled event

Rows without populated fees are skipped silently — the next sweep will pick them up again.

Schedule via Oban cron in the host app:

config :my_app, Oban,
  plugins: [
    {Oban.Plugins.Cron,
     crontab: [
       {"@daily", Accrue.Jobs.ReconcileRefundFees}
     ]}
  ]