Current section
Files
Jump to
Current section
Files
lib/ex_paymob/config.ex
defmodule ExPaymob.Config do
@moduledoc """
Layered configuration resolution for ExPaymob.
Resolution chain (first match wins):
1. Per-request opts (e.g., `secret_key: "sk_..."`)
2. Application env (`config :ex_paymob, secret_key: "sk_..."`)
3. System env (`PAYMOB_SECRET_KEY`)
"""
@base_urls %{
egypt: "https://accept.paymob.com",
uae: "https://uae.paymob.com",
ksa: "https://ksa.paymob.com",
oman: "https://oman.paymob.com"
}
@env_mapping %{
secret_key: "PAYMOB_SECRET_KEY",
public_key: "PAYMOB_PUBLIC_KEY",
hmac_secret: "PAYMOB_HMAC_SECRET",
base_url: "PAYMOB_BASE_URL",
region: "PAYMOB_REGION"
}
@type region :: :egypt | :uae | :ksa | :oman
@doc """
Resolves a configuration key using the layered resolution chain.
"""
@spec resolve(atom(), keyword()) :: term()
def resolve(key, opts \\ []) do
from_opts(key, opts) || from_app_env(key) || from_system_env(key) || default(key)
end
@doc """
Resolves the base URL from config, falling back to region-based URL.
"""
@spec resolve_base_url(keyword()) :: String.t()
def resolve_base_url(opts \\ []) do
case resolve(:base_url, opts) do
nil ->
region = resolve(:region, opts) || :egypt
region = if is_binary(region), do: String.to_existing_atom(region), else: region
Map.fetch!(@base_urls, region)
url ->
url
end
end
@doc """
Returns the configured HTTP client module.
"""
@spec resolve_http_client(keyword()) :: module()
def resolve_http_client(opts \\ []) do
resolve(:http_client, opts) || ExPaymob.Client.ReqAdapter
end
@doc """
Returns the configured JSON library.
"""
@spec resolve_json_library(keyword()) :: module()
def resolve_json_library(opts \\ []) do
resolve(:json_library, opts) || Jason
end
@doc """
Returns the base URL for a given region.
"""
@spec base_url_for_region(region()) :: String.t()
def base_url_for_region(region) do
Map.fetch!(@base_urls, region)
end
defp from_opts(key, opts), do: Keyword.get(opts, key)
defp from_app_env(key), do: Application.get_env(:ex_paymob, key)
defp from_system_env(key) do
case Map.get(@env_mapping, key) do
nil -> nil
env_var -> System.get_env(env_var)
end
end
defp default(:region), do: :egypt
defp default(_), do: nil
end