# `Accrue.Money`
[🔗](https://github.com/szTheory/accrue/blob/accrue-v0.3.0/lib/accrue/money.ex#L1)

Accrue's canonical money value type — a thin, opinionated wrapper over the
`:ex_money` currency table.

## Shape

`%Accrue.Money{amount_minor: integer(), currency: atom()}` — amounts are
always stored in the currency's minor unit (cents for USD, yen for JPY,
fils-thousandths for KWD). The currency is always an atom matching the
lowercase ISO 4217 code (`:usd`, `:jpy`, `:kwd`).

## Constructor discipline (D-03)

The primary constructor is `new/2` with an integer in minor units — the
same shape Stripe's API uses, so developers can paste Stripe integers
directly:

    iex> Accrue.Money.new(1000, :usd)
    %Accrue.Money{amount_minor: 1000, currency: :usd}   # $10.00

Passing a `Decimal` or a `float` to `new/2` raises `ArgumentError`. Use
`from_decimal/2` for explicit decimal conversions — the shift to minor
units is currency-exponent aware via ex_money's CLDR table.

## Cross-currency arithmetic (D-04)

Operations on two `Accrue.Money` values with different currencies
raise `Accrue.Money.MismatchedCurrencyError`. There are no silent FX
conversions and no tagged-tuple returns — the failure is loud and
immediate at the call site.

# `t`

```elixir
@type t() :: %Accrue.Money{amount_minor: integer(), currency: atom()}
```

# `add`

```elixir
@spec add(t(), t()) :: t()
```

Addition. Raises `Accrue.Money.MismatchedCurrencyError` on currency
mismatch (D-04).

# `equal?`

```elixir
@spec equal?(t(), t()) :: boolean()
```

Structural equality — same amount_minor AND same currency atom.

# `from_decimal`

```elixir
@spec from_decimal(Decimal.t(), atom()) :: t()
```

Decimal constructor — shifts the value into the currency's minor unit
according to `ex_money`'s CLDR iso_digits for that currency.

Zero-decimal currencies (JPY, KRW) do not shift. Three-decimal currencies
(KWD, BHD) multiply by 1000. Rounding is half-even (banker's rounding),
matching Stripe's default.

# `new`

```elixir
@spec new(integer(), atom()) :: t()
```

Primary integer-minor-unit constructor.

Raises `ArgumentError` when given a float or a `Decimal`. Use
`from_decimal/2` for decimal conversions.

Raises `ArgumentError` if the currency atom is not a known ISO 4217 code.

# `subtract`

```elixir
@spec subtract(t(), t()) :: t()
```

Subtraction. Raises `Accrue.Money.MismatchedCurrencyError` on currency
mismatch (D-04).

# `to_string`

```elixir
@spec to_string(t()) :: String.t()
```

Human-readable formatting. Delegates to `ex_money`'s CLDR-backed
formatter, which handles locale-aware currency symbols and grouping.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
