defmodule DaProductAppWeb.PaymentNotificationController do use DaProductAppWeb, :controller require Logger import Ecto.Query alias DaProductApp.Transactions.Transaction alias DaProductApp.PosTerminals.PosTerminal alias DaProductApp.Repo def process_payment_success(conn, %{"payment_id" => payment_id, "payment_amount" => payment_amount}) do transaction = from(t in Transaction, where: t.payment_reference_id == ^payment_id or t.transaction_ref_number == ^payment_id, select: %{id: t.id, device_id: t.device_id, transaction_ref_number: t.transaction_ref_number, provider_name: t.provider_name} ) |> Repo.one() case transaction do nil -> Logger.error("[Payment Notification] No transaction found for payment_id: #{payment_id}") conn |> put_status(:not_found) |> json(%{error: "Transaction not found"}) %{id: transaction_id, device_id: device_id, transaction_ref_number: transaction_ref_number, provider_name: provider_name} -> # Directly use transaction_ref_number as request_id #request_id = transaction_ref_number request_id = "UN_" <> transaction_ref_number Logger.info("[Payment Notification] Using request_id: #{request_id} for transaction_id: #{transaction_id}") datetime = formatted_datetime() topic = "/ota/pFppbioOCKlo5c8E/#{device_id}/update" currency = payment_amount["currency"] || "AED" value = payment_amount["value"] || "0" money = :erlang.float_to_binary(from_smallest_unit(value, currency, provider_name), decimals: 2) Logger.info("[Payment Notification] Amount conversion - Original value: #{value}, Currency: #{currency}, Provider: #{provider_name}, Converted money: #{money}") payload = Jason.encode!(%{ broadcast_type: 1, money: money, biz_type: 1, datetime: datetime, ctime: System.system_time(:second), request_id: request_id }) Logger.info("[Payment Notification] Publishing to topic: #{topic} with payload: #{payload}") Logger.info("[Payment Notification] About to publish - Transaction ID: #{transaction_id}, Device ID: #{device_id}, Request ID: #{request_id}, Provider: #{provider_name}") publish_result = Tortoise.publish("phoenix_client_node_devteam", topic, payload, qos: 1) Logger.info("[Payment Notification] Publish result: #{inspect(publish_result)}") json(conn, %{status: "success", message: "Payment notification processed"}) end end defp formatted_datetime do NaiveDateTime.utc_now() |> NaiveDateTime.to_iso8601() |> String.replace(~r/[-:T]/, "") |> String.slice(0..13) end defp from_smallest_unit(amount_str, currency, provider_name) do # Handle both integer and decimal string formats value = case String.contains?(amount_str, ".") do true -> String.to_float(amount_str) false -> String.to_integer(amount_str) end case provider_name do "aani" -> value _ -> case currency do "JPY" -> value _ -> value / 100 end end end end