cover/Elixir.DaProductAppWeb.Api.V1.TransactionController.html

1
:-(
defmodule DaProductAppWeb.Api.V1.TransactionController do
2
:-(
use DaProductAppWeb, :controller
3
4 alias DaProductApp.Transactions.Service
5
6 action_fallback DaProductAppWeb.FallbackController
7
8 @doc """
9 POST /api/v1/transactions
10 Body: Transaction initiation parameters
11 """
12 def create(conn, params) do
13
:-(
case Service.debit_credit_with_timeouts(params) do
14 {:ok, transaction} ->
15 conn
16 |> put_status(:created)
17
:-(
|> json(%{
18 success: true,
19 data: format_transaction(transaction),
20 message: "Transaction initiated successfully"
21 })
22
23 {:error, reason} ->
24 conn
25 |> put_status(:unprocessable_entity)
26
:-(
|> json(%{
27 success: false,
28 error: format_error(reason),
29 message: "Transaction initiation failed"
30 })
31 end
32 end
33
34 @doc """
35 GET /api/v1/transactions/:org_txn_id
36 """
37 def show(conn, %{"org_txn_id" => org_txn_id}) do
38
:-(
case Service.get_transaction_with_events(org_txn_id) do
39 nil ->
40 conn
41 |> put_status(:not_found)
42
:-(
|> json(%{
43 success: false,
44 error: "not_found",
45 message: "Transaction not found"
46 })
47
48 transaction ->
49 conn
50
:-(
|> json(%{
51 success: true,
52 data: format_transaction_with_events(transaction)
53 })
54 end
55 end
56
57 @doc """
58 POST /api/v1/transactions/:org_txn_id/credit-success
59 Simulate partner credit success callback
60 """
61 def credit_success(conn, %{"org_txn_id" => org_txn_id}) do
62
:-(
case Service.get_transaction_by_org_id(org_txn_id) do
63 nil ->
64 conn
65 |> put_status(:not_found)
66
:-(
|> json(%{success: false, error: "Transaction not found"})
67
68 transaction ->
69
:-(
case Service.handle_credit_success(transaction) do
70 {:ok, updated_transaction} ->
71 conn
72
:-(
|> json(%{
73 success: true,
74 data: format_transaction(updated_transaction),
75 message: "Credit success processed"
76 })
77
78 {:error, reason} ->
79 conn
80 |> put_status(:unprocessable_entity)
81
:-(
|> json(%{success: false, error: format_error(reason)})
82 end
83 end
84 end
85
86 @doc """
87 GET /api/v1/transactions
88 List transactions with optional filters
89 """
90 def index(conn, params) do
91
:-(
filters = build_filters(params)
92
:-(
transactions = Service.list_transactions(filters)
93
94 conn
95
:-(
|> json(%{
96 success: true,
97 data: Enum.map(transactions, &format_transaction/1),
98 total: length(transactions)
99 })
100 end
101
102 # --- helpers ---
103 defp build_filters(params) do
104 %{}
105 |> maybe_add_filter(:status, params["status"])
106 |> maybe_add_filter(:current_state, params["current_state"])
107 |> maybe_add_filter(:payer_addr, params["payer_addr"])
108
:-(
|> maybe_add_filter(:payee_addr, params["payee_addr"])
109 end
110
111
:-(
defp maybe_add_filter(filters, _key, nil), do: filters
112
:-(
defp maybe_add_filter(filters, _key, ""), do: filters
113
:-(
defp maybe_add_filter(filters, key, value), do: Map.put(filters, key, value)
114
115 defp format_error({:validation, changeset}) do
116
:-(
changeset.errors
117
:-(
|> Enum.map(fn {field, {message, _}} -> "#{field}: #{message}" end)
118
:-(
|> Enum.join(", ")
119 end
120
:-(
defp format_error({step, reason}), do: "#{step}: #{inspect(reason)}"
121
:-(
defp format_error(reason) when is_binary(reason), do: reason
122
:-(
defp format_error(reason), do: inspect(reason)
123
124 defp format_transaction(transaction) do
125
:-(
%{
126
:-(
id: transaction.id,
127
:-(
org_txn_id: transaction.org_txn_id,
128
:-(
payer_addr: transaction.payer_addr,
129
:-(
payee_addr: transaction.payee_addr,
130
:-(
payee_mid: transaction.payee_mid,
131
:-(
foreign_amount: transaction.foreign_amount,
132
:-(
foreign_currency: transaction.foreign_currency,
133
:-(
fx_rate: transaction.fx_rate,
134
:-(
markup_pct: transaction.markup_pct,
135
:-(
inr_amount: transaction.inr_amount,
136
:-(
current_state: transaction.current_state,
137
:-(
status: transaction.status,
138
:-(
debit_secured_at: transaction.debit_secured_at,
139
:-(
credit_requested_at: transaction.credit_requested_at,
140
:-(
credit_completed_at: transaction.credit_completed_at,
141
:-(
failure_code: transaction.failure_code,
142
:-(
deemed: transaction.deemed,
143
:-(
chktxn_requested_at: transaction.chktxn_requested_at,
144
:-(
reversal_requested_at: transaction.reversal_requested_at,
145
:-(
finalized_at: transaction.finalized_at,
146
:-(
inserted_at: transaction.inserted_at,
147
:-(
updated_at: transaction.updated_at
148 }
149 end
150
151 defp format_transaction_with_events(transaction) do
152 transaction
153 |> format_transaction()
154
:-(
|> Map.put(:events, Enum.map(transaction.events || [], &format_event/1))
155 end
156
157 defp format_event(event) do
158
:-(
%{
159
:-(
seq: event.seq,
160
:-(
event_type: event.event_type,
161
:-(
payload: event.payload,
162
:-(
hash: Base.encode16(event.hash),
163
:-(
prev_hash: event.prev_hash && Base.encode16(event.prev_hash),
164
:-(
inserted_at: event.inserted_at
165 }
166 end
167 end
Line Hits Source