lib/requests/payments/sources/pay_pal.ex

defmodule Requests.Payments.Sources.PayPal do
  @type plan :: %{
          type: String.t(),
          skip_shipping_address: true | false,
          immutable_shipping_address: true | false
        }

  @type t :: %__MODULE__{
          type: String.t(),
          plan: String.t()
        }

  @enforce_keys [:type]
  defstruct [
    :type,
    :plan
  ]

  def build(raw_params) when is_map(raw_params) do
    params =
      Enum.into(raw_params, %{}, fn {key, value} -> {String.to_existing_atom(key), value} end)

    %{
      type: params[:type],
      plan: build_plan(params[:purpose])
    }
  end

  def build(_), do: nil

  defp build_plan(params) when is_map(params) do
    %{
      type: params[:type],
      skip_shipping_address: params[:skip_shipping_address],
      immutable_shipping_address: params[:immutable_shipping_address]
    }
  end

  defp build_plan(_), do: nil
end