defmodule Requests.Payments.Payment do
@moduledoc false
alias Customers.BillingAddress
alias Customers.Phone
alias Requests.Payments.Payment.{
AirlineData,
AmountAllocation,
BillingDescriptor,
Risk,
Sender
}
alias Requests.Payments.Sources
alias Requests.Payments.ThreeDS
@derive Jason.Encoder
@type customer :: %{
id: String.t(),
email: String.t(),
name: String.t(),
tax_number: String.t(),
phone: Phone.t()
}
@type item :: %{
name: String.t(),
quantity: String.t(),
unit_price: String.t(),
reference: String.t(),
commodity_code: String.t(),
unit_of_measure: String.t(),
total_amount: String.t(),
tax_amount: String.t(),
discount_amount: String.t(),
wxpay_goods_id: String.t(),
url: String.t(),
image_url: String.t()
}
@type processing :: %{
order_id: String.t(),
tax_amount: integer(),
discount_amount: integer(),
duty_amount: integer(),
shipping_amount: integer(),
shipping_tax_amount: integer(),
aft: true | false,
preferred_scheme: String.t(),
merchant_initiated_reason: String.t(),
campaign_id: integer(),
product_type: String.t(),
open_id: String.t(),
original_order_amount: integer(),
receipt_id: String.t(),
terminal_type: String.t(),
os_type: String.t(),
invoice_id: String.t(),
brand_name: String.t(),
locale: String.t(),
shipping_preference: String.t(),
user_action: String.t(),
set_transaction_context: map(),
airline_data: AirlineData.t(),
purchase_country: String.t(),
custom_payment_method_ids: list(String.t()),
merchant_callback_url: String.t()
}
@type recipient :: %{
dob: String.t(),
account_number: String.t(),
address: BillingAddress.t(),
first_name: String.t(),
last_name: String.t()
}
@type shipping :: %{
address: BillingAddress.t(),
phone: Phone.t(),
from_address_zip: String.t()
}
@type t() :: %__MODULE__{
source: map(),
amount: integer(),
currency: <<_::3>>,
payment_type: String.t(),
merchant_initiated: true | false,
reference: String.t(),
description: String.t(),
authorization_type: String.t(),
capture: true | false,
capture_on: String.t(),
customer: customer(),
billing_descriptor: BillingDescriptor.t(),
shipping: shipping(),
three_d_s: Integrated.t() | StandAlone.t() | ThirdParty.t(),
processing_channel_id: String.t(),
previous_payment_id: String.t(),
risk: Risk.t(),
success_url: String.t(),
failure_url: String.t(),
payment_ip: String.t(),
sender: Sender.t(),
recipient: recipient(),
amount_allocations: list(AmountAllocation.t()),
processing: processing(),
items: list(item()),
metadata: map(),
type: String.t()
}
@enforce_keys [:currency, :processing_channel_id, :source, :type]
defstruct [
:source,
:amount,
:currency,
:payment_type,
:merchant_initiated,
:reference,
:description,
:authorization_type,
:capture,
:capture_on,
:customer,
:billing_descriptor,
:shipping,
:three_d_s,
:"3ds",
:processing_channel_id,
:previous_payment_id,
:risk,
:success_url,
:failure_url,
:payment_ip,
:sender,
:recipient,
:amount_allocations,
:processing,
:items,
:metadata,
:type
]
def build(
%{
currency: currency,
source: source
} = params
)
when is_binary(currency) and is_map(source) do
%__MODULE__{
source: Sources.build(source),
amount: params[:amount],
currency: currency,
payment_type: params[:payment_type],
merchant_initiated: params[:merchant_initiated],
reference: params[:reference],
description: params[:description],
authorization_type: params[:authorization_type],
capture: params[:capture],
capture_on: params[:capture_on],
customer: build_customer(params[:customer]),
billing_descriptor: BillingDescriptor.build(params[:billing_descriptor]),
shipping: build_shipping(params[:shipping]),
"3ds": ThreeDS.build(params[:three_d_s]),
processing_channel_id: params[:processing_channel_id],
previous_payment_id: params[:previous_payment_id],
risk: Risk.build(params[:risk]),
success_url: params[:success_url],
failure_url: params[:failure_url],
payment_ip: params[:payment_ip],
sender: Sender.build(params[:sender]),
recipient: build_recipient(params[:recipient]),
amount_allocations: AmountAllocation.build(params[:amount_allocations]),
processing: build_processing(params[:processing]),
items: build_items(params[:items]),
metadata: params[:metadata],
type: params[:type]
}
end
def build(params) when is_map(params),
do: {:error, "Payment must have currency, processing_channel_id, and source"}
def build(_), do: {:error, "params must be a map"}
defp build_customer(params) when is_map(params) do
%{
id: params[:id],
email: params[:email],
name: params[:name],
tax_number: params[:tax_number],
phone: Phone.build(params[:phone])
}
end
defp build_customer(_), do: nil
defp build_items(items) when is_list(items) do
Enum.into(items, [], &build_item(&1))
end
defp build_items(_), do: nil
defp build_item(params) when is_map(params) do
%{
name: params[:name],
quantity: params[:quantity],
unit_price: params[:unit_price],
reference: params[:reference],
commodity_code: params[:commodity_code],
unit_of_measure: params[:unit_of_measure],
total_amount: params[:total_amount],
tax_amount: params[:tax_amount],
discount_amount: params[:discount_amount],
wxpay_goods_id: params[:wxpay_goods_id],
url: params[:url],
image_url: params[:image_url]
}
end
defp build_item(_), do: nil
defp build_processing(params) when is_map(params) do
%{
order_id: params[:order_id],
tax_amount: params[:tax_amount],
discount_amount: params[:discount_amount],
duty_amount: params[:duty_amount],
shipping_amount: params[:shipping_amount],
shipping_tax_amount: params[:shipping_tax_amount],
aft: params[:aft],
preferred_scheme: params[:preferred_scheme],
merchant_initiated_reason: params[:merchant_initiated_reason],
campaign_id: params[:campaign_id],
product_type: params[:product_type],
open_id: params[:open_id],
original_order_amount: params[:original_order_amount],
receipt_id: params[:receipt_id],
terminal_type: params[:terminal_type],
os_type: params[:os_type],
invoice_id: params[:invoice_id],
brand_name: params[:brand_name],
locale: params[:locale],
shipping_preference: params[:shipping_preference],
user_action: params[:user_action],
set_transaction_context: params[:set_transaction_context],
airline_data: AirlineData.build(params[:airline_data]),
purchase_country: params[:purchase_country],
custom_payment_method_ids: params[:custom_payment_method_ids],
merchant_callback_url: params[:merchant_callback_url]
}
end
defp build_processing(_), do: nil
defp build_recipient(params) when is_map(params) do
%{
dob: params[:dob],
account_number: params[:account_number],
address: BillingAddress.build(params[:address]),
first_name: params[:first_name],
last_name: params[:last_name]
}
end
defp build_recipient(_), do: nil
defp build_shipping(params) when is_map(params) do
%{
address: BillingAddress.build(params[:address]),
phone: Phone.build(params[:phone]),
from_address_zip: params[:from_address_zip]
}
end
defp build_shipping(_), do: nil
end