lib/responses/payment.ex

defmodule Responses.Payment do
  alias Customers.Customer
  alias Requests.Payments.Sources

  @derive Jason.Encoder

  defstruct [
    :id,
    :action_id,
    :amount,
    :currency,
    :approved,
    :status,
    :auth_code,
    :response_code,
    :response_summary,
    :expires_on,
    :three_d_s,
    :risk,
    :source,
    :customer,
    :balances,
    :processed_on,
    :reference,
    :processing,
    :eci,
    :scheme_id,
    :_links
  ]

  def build(params) when is_map(params) do
    %__MODULE__{
      id: params["id"],
      action_id: params["action_id"],
      amount: params["amount"],
      currency: params["currency"],
      approved: params["approved"],
      status: params["status"],
      auth_code: params["auth_code"],
      response_code: params["response_code"],
      response_summary: params["response_summary"],
      expires_on: params["expires_on"],
      three_d_s: build_3ds(params["3ds"]),
      risk: build_risk(params["risk"]),
      source: Sources.build(params["source"]),
      customer: Customer.build(params["customer"]),
      balances: build_balances(params["balances"]),
      processed_on: params["processed_on"],
      reference: params["reference"],
      processing: build_processing(params["processing"]),
      eci: params["eci"],
      scheme_id: params["scheme_id"],
      _links: build_links(params["_links"])
    }
  end

  def build(_), do: nil

  defp build_3ds(params) when is_map(params) do
    %{
      downgraded: params["downgraded"],
      enrolled: params["enrolled"],
      upgrade_reason: params["upgrade_reason"]
    }
  end

  defp build_3ds(_), do: nil

  defp build_balances(params) when is_map(params) do
    %{
      total_authorized: params["total_authorized"],
      total_voided: params["total_voided"],
      available_to_void: params["available_to_void"],
      total_captured: params["total_captured"],
      available_to_capture: params["available_to_capture"],
      total_refunded: params["total_refunded"],
      available_to_refund: params["available_to_refund"]
    }
  end

  defp build_balances(_), do: nil

  defp build_links(links) when is_map(links) do
    %{
      action: build_link(links["action"]),
      authorize: build_link(links["authorize"]),
      capture: build_link(links["capture"]),
      refund: build_link(links["refund"]),
      self: build_link(links["self"]),
      void: build_link(links["void"])
    }
  end

  defp build_link(%{"href" => href}), do: %{href: href}

  defp build_link(link), do: link

  defp build_processing(params) when is_map(params) do
    %{
      retrieval_reference_number: params["retrieval_reference_number"],
      acquirer_transaction_id: params["acquirer_transaction_id"],
      recommendation_code: params["recommendation_code"],
      partner_order_id: params["partner_order_id"],
      partner_session_id: params["partner_session_id"],
      partner_client_token: params["partner_client_token"],
      partner_payment_id: params["partner_payment_id"],
      partner_status: params["partner_status"],
      partner_transaction_id: params["partner_transaction_id"],
      partner_error_codes: params["partner_error_codes"],
      partner_error_message: params["partner_error_message"],
      partner_authorization_code: params["partner_authorization_code"],
      partner_authorization_response_code: params["partner_authorization_response_code"]
    }
  end

  defp build_processing(_), do: nil

  defp build_risk(params) when is_map(params) do
    %{
      flagged: params["flagged"],
      score: params["score"]
    }
  end

  defp build_risk(_), do: nil
end