# `PhoenixKitBilling.Errors`
[🔗](https://github.com/BeamLabEU/phoenix_kit_billing/blob/0.5.1/lib/phoenix_kit_billing/errors.ex#L1)

Central mapping from the error atoms returned by the billing module's
context, payment providers, and webhook handlers to translated
human-readable strings.

Keeping the API layer locale-agnostic means callers and integration
consumers can pattern-match on atoms and decide their own presentation.
Anything user-facing (flash messages, error banners) goes through
`message/1`, which wraps each mapping in `gettext/1` using the
module's own `PhoenixKitBilling.Gettext` backend so the strings are
extractable into `priv/gettext`.

## Supported reason shapes

  * plain atoms — `:not_found`, `:card_declined`, `:invalid_signature`, etc.
  * `%Ecto.Changeset{}` — formatted as `"field: message; ..."` so a
    changeset returned alongside domain atoms in a shared `{:error, _}`
    branch still renders readably
  * strings — passed through unchanged (legacy / interpolated messages)
  * anything else — rendered as `"Unexpected error: <inspect>"` so
    nothing silently surfaces a raw struct

## Example

    iex> PhoenixKitBilling.Errors.message(:card_declined)
    "The card was declined."

# `error`

```elixir
@type error() ::
  :already_paid
  | :already_refunded
  | :authentication_failed
  | :can_only_delete_drafts
  | :card_declined
  | :currency_in_use
  | :duplicate_event
  | :event_log_failed
  | :exceeds_paid_amount
  | :exceeds_remaining
  | :has_active_subscriptions
  | :has_subscriptions
  | :invalid_amount
  | :invalid_format
  | :invalid_json
  | :invalid_payload
  | :invalid_response
  | :invalid_signature
  | :invalid_timestamp
  | :invoice_not_editable
  | :invoice_not_found
  | :invoice_not_paid
  | :invoice_not_payable
  | :invoice_not_sendable
  | :invoice_not_voidable
  | :is_default
  | :max_retries_exceeded
  | :missing_reference
  | :no_charge_id
  | :no_payment_method
  | :no_payments
  | :no_plan
  | :no_raw_body
  | :no_recipient_email
  | :no_signature
  | :no_user
  | :not_a_payment
  | :not_a_refund
  | :not_configured
  | :not_found
  | :not_payable
  | :not_refundable
  | :not_supported
  | :order_not_cancellable
  | :order_not_editable
  | :order_not_payable
  | :order_not_refundable
  | :payment_method_expired
  | :payment_method_not_usable
  | :processing_error
  | :provider_not_available
  | :provider_not_found
  | :receipt_already_generated
  | :receipt_not_generated
  | :receipt_not_sendable
  | :request_failed
  | :requires_action
  | :signature_mismatch
  | :subscription_type_not_found
  | :timestamp_too_old
  | :transaction_not_found
  | :unknown_event
```

# `message`

```elixir
@spec message(error() | term()) :: String.t()
```

Translates an error reason (atom, string, or any term) into a
user-facing string via gettext.

---

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