# Test YSP Transaction Processor with Actual Device Packet # This simulates a real POS device sending a sale transaction alias DaProductApp.MercuryISO8583.Packagers.ISOMsg alias DaProductApp.Acquirer.YSP.TransactionProcessor alias DaProductApp.Switch.UpstreamRouter IO.puts("=== Testing YSP Transaction with Actual Device Packet ===") # Real device packet data (Sale transaction - MTI 0200) # This represents what a real POS terminal would send # Using Visa BIN to test that YSP acquirer can handle any card network device_packet_data = %{ mti: "0200", fields: %{ 2 => "4854980600736740", # Primary Account Number (Visa BIN) 3 => "000000", # Processing Code (Sale) 4 => "000000002600", # Transaction Amount ($26.00) 11 => "000453", # System Trace Audit Number (STAN) 12 => "144505", # Local Transaction Time (HHMMSS) 13 => "0924", # Local Transaction Date (MMDD) 14 => "3105", # Expiration Date (YYMM) 22 => "051", # POS Entry Mode (Chip with PIN) 23 => "000", # Card Sequence Number 24 => "782", # Network Identification Number (YSP) 25 => "00", # POS Condition Code (Normal) 35 => "4854980600736740=31052060011790", # Track 2 Data (Visa) 37 => "25267144338", # Retrieval Reference Number 41 => "12345671", # Terminal ID 42 => "123456789012345", # Merchant ID 49 => "840" # Currency Code (USD) } } IO.puts("Device Packet Details:") IO.puts("- MTI: #{device_packet_data.mti} (Sale Request)") IO.puts("- Terminal ID: #{device_packet_data.fields[41]}") IO.puts("- Merchant ID: #{device_packet_data.fields[42]}") IO.puts("- Amount: $#{String.to_integer(device_packet_data.fields[4]) / 100}") IO.puts("- Card Number: #{String.slice(device_packet_data.fields[2], 0..5)}...#{String.slice(device_packet_data.fields[2], -4..-1)}") IO.puts("- NII: #{device_packet_data.fields[24]} (YSP Network)") IO.puts("") # Create ISOMsg from device packet device_message = ISOMsg.new(device_packet_data.mti) # Set all fields from device packet final_message = Enum.reduce(device_packet_data.fields, device_message, fn {field_num, value}, msg -> ISOMsg.set(msg, field_num, value) end) IO.puts("Created ISOMsg from device packet:") IO.puts("MTI: #{final_message.mti}") IO.puts("Fields present: #{Map.keys(final_message.fields) |> Enum.sort() |> Enum.join(", ")}") IO.puts("") # Check upstream router status IO.puts("=== Checking Upstream Router Status ===") router_status = GenServer.call(UpstreamRouter, :get_status) IO.puts("Router Status: #{inspect(router_status)}") # Find which network this will route to ysp_networks = Enum.filter(router_status.networks, fn {name, _} -> String.contains?(to_string(name), "ysp") end) IO.puts("Available YSP Networks:") Enum.each(ysp_networks, fn {name, info} -> IO.puts("- #{name}: #{info.status} (#{info.host}:#{info.port})") end) IO.puts("") # Transaction context context = %{ transaction_trace_id: "DEVICE_TEST_#{:rand.uniform(999999)}", source: "actual_device_simulation", timestamp: DateTime.utc_now() } IO.puts("=== Processing Transaction with YSP TransactionProcessor ===") IO.puts("Trace ID: #{context.transaction_trace_id}") IO.puts("Starting transaction processing...") IO.puts("") try do # Process the transaction result = TransactionProcessor.process_sale(final_message, context) case result do {:ok, response_message, final_transaction} -> IO.puts("✅ TRANSACTION SUCCESSFUL!") IO.puts("") IO.puts("Response Message:") IO.puts("- MTI: #{response_message.mti}") IO.puts("- Response Code: #{ISOMsg.get(response_message, 39)}") IO.puts("- Auth Code: #{ISOMsg.get(response_message, 38)}") IO.puts("- Reference: #{ISOMsg.get(response_message, 37)}") IO.puts("") IO.puts("Final Transaction Record:") IO.puts("- ID: #{final_transaction.id}") IO.puts("- Amount: #{final_transaction.total_amount}") IO.puts("- Response Code: #{final_transaction.response_code}") IO.puts("- Response Message: #{final_transaction.response_message}") IO.puts("- Approval Code: #{final_transaction.approval_code}") IO.puts("- Reference No: #{final_transaction.reference_no}") IO.puts("- Terminal: #{final_transaction.s_tid}") IO.puts("- Merchant: #{final_transaction.s_mid}") IO.puts("") {:error, reason} -> IO.puts("❌ TRANSACTION FAILED!") IO.puts("Reason: #{inspect(reason)}") IO.puts("") other -> IO.puts("❓ UNEXPECTED RESULT!") IO.puts("Result: #{inspect(other)}") IO.puts("") end rescue exception -> IO.puts("💥 EXCEPTION OCCURRED!") IO.puts("Exception: #{inspect(exception)}") IO.puts("Stacktrace:") IO.puts(Exception.format_stacktrace(__STACKTRACE__)) end IO.puts("=== Test Complete ===")