Accrue.Billing.RefundActions (accrue v0.2.0)

Copy Markdown View Source

Phase 3 Plan 06 refund write surface (BILL-26, D3-45..47).

Ships create_refund/2 with sync best-effort fee math: when the processor response carries an expanded charge.balance_transaction.fee_refunded, the refund row is persisted with stripe_fee_refunded_amount_minor, merchant_loss_amount_minor, and fees_settled_at. When the balance_transaction is not yet populated, those columns stay nil — the webhook backstop in Plan 07 (charge.refund.updated) fills them asynchronously.

Return shape is uniform {:ok, %Refund{}}no tagged variant like {:ok, :pending_fees, _} — because fee settlement state is a property of the row (fees_settled?/1 predicate), not a branch in the caller's control flow (D3-47).

Summary

Functions

Creates a refund for the given %Charge{}. Always returns {:ok, %Refund{}} on success — fee settlement state is tracked via Refund.fees_settled?/1.

Functions

create_refund(charge, opts \\ [])

@spec create_refund(
  Accrue.Billing.Charge.t(),
  keyword()
) :: {:ok, Accrue.Billing.Refund.t()} | {:error, term()}

Creates a refund for the given %Charge{}. Always returns {:ok, %Refund{}} on success — fee settlement state is tracked via Refund.fees_settled?/1.

Options

  • :amount%Accrue.Money{}, defaults to the full charge amount (charge.amount_cents).
  • :reason — refund reason string passed to the processor.
  • :operation_id — deterministic idempotency seed.

create_refund!(charge, opts \\ [])

@spec create_refund!(
  Accrue.Billing.Charge.t(),
  keyword()
) :: Accrue.Billing.Refund.t()

Raising variant of create_refund/2.