lib/requests/payments/sources/card.ex

defmodule Requests.Payments.Sources.Card do
  @moduledoc false

  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(),
          scheme: String.t(),
          scheme_local: 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(),
          card_type: String.t(),
          card_category: String.t(),
          issuer: String.t(),
          issuer_country: String.t(),
          product_id: String.t(),
          product_type: String.t(),
          avs_check: String.t(),
          cvv_check: String.t(),
          payment_account_reference: String.t()
        }

  @enforce_keys [:type, :number, :expiry_month, :expiry_year]
  defstruct [
    :type,
    :number,
    :expiry_month,
    :expiry_year,
    :name,
    :scheme,
    :scheme_local,
    :cvv,
    :stored,
    :billing_address,
    :phone,
    :store_for_future_use,
    :bin,
    :fingerprint,
    :id,
    :last4,
    :card_type,
    :card_category,
    :issuer,
    :issuer_country,
    :product_id,
    :product_type,
    :avs_check,
    :cvv_check,
    :payment_account_reference
  ]

  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],
      scheme: params[:scheme],
      scheme_local: params[:scheme_local],
      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],
      card_type: params[:card_type],
      card_category: params[:card_category],
      issuer: params[:issuer],
      issuer_country: params[:issuer_country],
      product_id: params[:product_id],
      product_type: params[:product_type],
      avs_check: params[:avs_check],
      cvv_check: params[:cvv_check],
      payment_account_reference: params[:payment_account_reference]
    }
  end

  def build(_), do: nil
end