lib/requests/payments/sources/card.ex

defmodule Requests.Payments.Sources.Card do
  alias Customers.BillingAddress
  alias Customers.Phone

  import Utilities, only: [atomize_keys: 1]

  @derive Jason.Encoder

  @type t :: %__MODULE__{
          type: String.t(),
          number: String.t(),
          expiry_month: integer(),
          expiry_year: integer(),
          name: String.t(),
          cvv: String.t(),
          stored: true | false,
          store_for_future_use: true | false,
          billing_address: BillingAddress.t(),
          phone: Phone.t(),
          bin: String.t(),
          fingerprint: String.t(),
          id: String.t(),
          last4: String.t()
        }

  @enforce_keys [:type, :number, :expiry_month, :expiry_year]
  defstruct [
    :type,
    :number,
    :expiry_month,
    :expiry_year,
    :name,
    :cvv,
    :stored,
    :billing_address,
    :phone,
    :store_for_future_use,
    :bin,
    :fingerprint,
    :id,
    :last4
  ]

  def build(raw_params) when is_map(raw_params) do
    params = atomize_keys(raw_params)

    %__MODULE__{
      type: params[:type],
      number: params[:number],
      expiry_month: params[:expiry_month],
      expiry_year: params[:expiry_year],
      name: params[:name],
      cvv: params[:cvv],
      stored: params[:stored],
      billing_address: BillingAddress.build(params[:billing_address]),
      phone: Phone.build(params[:phone]),
      store_for_future_use: params[:store_for_future_use],
      bin: params[:bin],
      fingerprint: params[:fingerprint],
      id: params[:id],
      last4: params[:last4]
    }
  end

  def build(_), do: nil
end