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

Provider registry and helper functions for payment providers.

This module serves as the central point for working with payment providers.
It handles provider lookup, availability checking, and configuration.

## Available Providers

- `:stripe` - Stripe payments (cards, wallets)
- `:paypal` - PayPal payments
- `:razorpay` - Razorpay payments (India)
- `:everypay` - EveryPay payments (Baltics)

## Usage

    # Get a provider module
    provider = Providers.get_provider(:stripe)
    provider.create_checkout_session(invoice, opts)

    # List available providers
    Providers.list_available_providers()
    #=> [:stripe, :paypal]

    # Check if provider is available
    Providers.provider_enabled?(:stripe)
    #=> true

# `all_providers`

```elixir
@spec all_providers() :: [atom()]
```

Returns a list of all provider names.

## Examples

    Providers.all_providers()
    #=> [:stripe, :paypal, :razorpay, :everypay]

# `charge_payment_method`

```elixir
@spec charge_payment_method(map(), Decimal.t(), keyword()) ::
  {:ok, PhoenixKitBilling.Providers.Provider.charge_result()} | {:error, term()}
```

Charges a saved payment method using the appropriate provider.

## Parameters

- `payment_method` - Saved payment method record (must include :provider)
- `amount` - Amount to charge
- `opts` - Options passed to provider

## Returns

- `{:ok, charge_result}` - Charge successful
- `{:error, reason}` - Charge failed

# `create_checkout_session`

```elixir
@spec create_checkout_session(atom() | String.t(), map(), keyword()) ::
  {:ok, PhoenixKitBilling.Providers.Provider.checkout_session()}
  | {:error, term()}
```

Creates a checkout session using the specified provider.

Convenience function that looks up the provider and calls
`create_checkout_session/2`.

## Parameters

- `provider` - Provider name
- `invoice` - Invoice to pay
- `opts` - Options passed to provider

## Returns

- `{:ok, checkout_session}` - Session created
- `{:error, :provider_not_found}` - Provider doesn't exist
- `{:error, :provider_not_available}` - Provider not configured
- `{:error, reason}` - Provider-specific error

# `create_refund`

```elixir
@spec create_refund(atom() | String.t(), String.t(), Decimal.t() | nil, keyword()) ::
  {:ok, PhoenixKitBilling.Providers.Provider.refund_result()} | {:error, term()}
```

Creates a refund using the appropriate provider.

## Parameters

- `provider` - Provider name
- `provider_transaction_id` - Provider's transaction ID
- `amount` - Amount to refund (nil for full refund)
- `opts` - Options

## Returns

- `{:ok, refund_result}` - Refund created
- `{:error, reason}` - Refund failed

# `create_setup_session`

```elixir
@spec create_setup_session(atom() | String.t(), map(), keyword()) ::
  {:ok, PhoenixKitBilling.Providers.Provider.setup_session()} | {:error, term()}
```

Creates a setup session using the specified provider.

## Parameters

- `provider` - Provider name
- `user` - User to save payment method for
- `opts` - Options passed to provider

## Returns

- `{:ok, setup_session}` - Session created
- `{:error, reason}` - Failed

# `enabled_setting_key`

```elixir
@spec enabled_setting_key(atom()) :: String.t()
```

Gets the setting key for a provider's enabled status.

## Examples

    iex> Providers.enabled_setting_key(:stripe)
    "billing_stripe_enabled"

# `get_provider`

```elixir
@spec get_provider(atom() | String.t()) :: module() | nil
```

Returns the provider module for the given provider name.

## Parameters

- `name` - Provider name as atom or string

## Returns

- Provider module if found
- `nil` if provider not found

## Examples

    iex> Providers.get_provider(:stripe)
    PhoenixKitBilling.Providers.Stripe

    iex> Providers.get_provider("paypal")
    PhoenixKitBilling.Providers.PayPal

    iex> Providers.get_provider(:unknown)
    nil

# `handle_webhook_event`

```elixir
@spec handle_webhook_event(atom() | String.t(), map()) ::
  {:ok, PhoenixKitBilling.Providers.Provider.webhook_event()} | {:error, term()}
```

Handles a webhook event for the specified provider.

## Parameters

- `provider` - Provider name
- `payload` - Decoded JSON payload

## Returns

- `{:ok, webhook_event}` - Event parsed
- `{:error, reason}` - Failed to parse

# `list_available_providers`

```elixir
@spec list_available_providers() :: [atom()]
```

Returns a list of available (enabled and configured) provider names.

Checks each provider's `available?/0` callback to determine availability.

## Examples

    iex> Providers.list_available_providers()
    [:stripe, :paypal]

# `provider_enabled?`

```elixir
@spec provider_enabled?(atom() | String.t()) :: boolean()
```

Checks if a provider is enabled and available.

## Parameters

- `name` - Provider name as atom or string

## Returns

- `true` if provider is available
- `false` if provider is not available or not found

## Examples

    iex> Providers.provider_enabled?(:stripe)
    true

    iex> Providers.provider_enabled?(:unknown)
    false

# `provider_exists?`

```elixir
@spec provider_exists?(atom() | String.t()) :: boolean()
```

Checks if a provider exists (regardless of availability).

## Examples

    iex> Providers.provider_exists?(:stripe)
    true

    iex> Providers.provider_exists?(:bitcoin)
    false

# `provider_info`

```elixir
@spec provider_info(atom()) :: PhoenixKitBilling.Providers.Types.ProviderInfo.t()
```

Returns display information for a provider.

## Examples

    iex> Providers.provider_info(:stripe)
    %{name: "Stripe", icon: "stripe", color: "#635BFF"}

# `setting_enabled?`

```elixir
@spec setting_enabled?(atom()) :: boolean()
```

Checks if a provider is enabled in settings.

This is a lower-level check that only looks at the setting,
not whether the provider is fully configured.

## Examples

    iex> Providers.setting_enabled?(:stripe)
    true

# `verify_webhook_signature`

```elixir
@spec verify_webhook_signature(atom() | String.t(), binary(), String.t(), String.t()) ::
  :ok | {:error, term()}
```

Verifies a webhook signature for the specified provider.

## Parameters

- `provider` - Provider name
- `payload` - Raw request body
- `signature` - Signature from headers
- `secret` - Webhook secret

## Returns

- `:ok` - Signature valid
- `{:error, :invalid_signature}` - Signature invalid
- `{:error, :provider_not_found}` - Provider doesn't exist

---

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