# `Accrue.PlanResolver`
[🔗](https://github.com/szTheory/accrue/blob/accrue-v1.1.1/lib/accrue/plan_resolver.ex#L1)

Host-owned resolver for plan metadata that the shared `price_id` facade
does not carry by itself.

Accrue keeps public billing calls app-facing: host apps call
`Accrue.Billing.swap_plan/3` with a stable `price_id`, while the host owns
any catalog knowledge needed to translate that identifier into
processor-specific metadata.

This resolver is required for Braintree swap-plan flows because Braintree
requires both the target `plan_id` and the explicit target amount when a
subscription changes plans.

# `billing_cycle`

```elixir
@type billing_cycle() :: %{unit: interval_unit(), count: pos_integer()}
```

# `currency`

```elixir
@type currency() :: atom() | String.t()
```

# `interval_unit`

```elixir
@type interval_unit() :: :day | :week | :month | :year
```

# `resolved_plan`

```elixir
@type resolved_plan() :: %{
  price_id: String.t(),
  processor: String.t(),
  processor_plan_id: String.t(),
  unit_amount_minor: non_neg_integer(),
  currency: currency(),
  billing_cycle: billing_cycle()
}
```

# `resolve_price`

```elixir
@callback resolve_price(String.t()) :: {:ok, resolved_plan()} | {:error, term()}
```

# `configured?`

```elixir
@spec configured?() :: boolean()
```

# `impl`

```elixir
@spec impl() :: module() | nil
```

# `resolve_price`

```elixir
@spec resolve_price(String.t()) ::
  {:ok, resolved_plan()} | {:error, Accrue.APIError.t()}
```

---

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