From c658ac4c43865f482d0c737e8179911dfef58822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=AD=EC=B6=98=EC=95=BD=EA=B5=AD?= Date: Sat, 11 Apr 2026 10:47:37 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=98=81=EC=88=98=EC=A6=9D=20=EC=9D=B8?= =?UTF-8?q?=EC=87=84=EB=A5=BC=20TCP=E2=86=92DLL=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TCP 소켓(PRINTSTART/PRINTEND) 대신 AllThatPayCatReqMC(iCmd=2)로 DLL→MMF 경유 인쇄. GW 포트 변경에 영향받지 않음. - ProcessPrint: TCP 소켓 제거, DLL CatReqMC(2) 호출로 대체 - FindGWPort: 8080/7779 포트 제외 로직 추가 - 실패 시 FindGWPort+ConnectDLL 재연결 후 1회 재시도 - build.bat, test_print_dll.ps1 추가 (DLL 인쇄 단독 테스트용) Co-Authored-By: Claude Opus 4.6 --- PaymentBridge.cs | 93 ++++++++++++++++++++++++++++++++++++++- PaymentBridge.exe | Bin 27136 -> 31744 bytes build.bat | 8 ++++ test_print_dll.ps1 | 105 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 build.bat create mode 100644 test_print_dll.ps1 diff --git a/PaymentBridge.cs b/PaymentBridge.cs index 780e7b8..1542df5 100644 --- a/PaymentBridge.cs +++ b/PaymentBridge.cs @@ -110,7 +110,9 @@ namespace PaymentBridge var addr = parts[1]; if (addr.Contains(":")) { - GW_PORT = addr.Split(':')[1]; + string port = addr.Split(':')[1]; + if (port == "8080" || port == "7779") continue; // 웹UI/Bridge 포트 제외 + GW_PORT = port; Log("GW Port found: " + GW_PORT); break; } @@ -220,6 +222,12 @@ namespace PaymentBridge var data = json.Deserialize(body); responseString = ProcessCashReceipt("B2", data); } + else if (path == "/api/print" && request.HttpMethod == "POST") + { + var body = ReadBody(request); + var data = json.Deserialize(body); + responseString = ProcessPrint(data); + } else { responseString = json.Serialize(new { ok = false, error = "Unknown endpoint" }); @@ -419,6 +427,89 @@ namespace PaymentBridge Console.WriteLine(message); } + static string ProcessPrint(dynamic data) + { + // POS에서 받은 영수증 데이터를 DLL 경유로 인쇄 (MMF → AllthatpayClient → 프린터) + // data: { text: "영수증텍스트", qr_url: "https://...", qr_points: 100 } + + try + { + string text = ""; + string qrUrl = ""; + int qrPoints = 0; + + try { text = data["text"] ?? ""; } catch { } + try { qrUrl = data["qr_url"] ?? ""; } catch { } + try { qrPoints = Convert.ToInt32(data["qr_points"]); } catch { } + + if (string.IsNullOrEmpty(text)) + return json.Serialize(new { ok = false, error = "text is empty" }); + + // QR 적립 안내 텍스트 추가 + if (!string.IsNullOrEmpty(qrUrl) && qrPoints > 0) + { + text += "\n------------------------------------------------\n"; + text += " ★ 마일리지 적립 ★\n"; + text += " QR 스캔하고 " + qrPoints.ToString("N0") + "P 받으세요!\n"; + text += " (유효기간: 30일)\n"; + text += "------------------------------------------------\n"; + } + + // EUC-KR 인코딩 + Encoding eucKr = Encoding.GetEncoding("euc-kr"); + byte[] textBytes = eucKr.GetBytes(text); + + // 패킷 조립: text + FS×4 + ATQR_URL (DLL 방식 — PRINTSTART/END 불필요) + var packet = new System.Collections.Generic.List(); + packet.AddRange(textBytes); + + // QR 코드 추가 (ATQR_ 프로토콜) + if (!string.IsNullOrEmpty(qrUrl)) + { + byte fs = 0x1C; + packet.Add(fs); packet.Add(fs); packet.Add(fs); packet.Add(fs); + packet.AddRange(Encoding.ASCII.GetBytes("ATQR_" + qrUrl)); + } + + byte[] buf = packet.ToArray(); + + // DLL 미연결 시 재연결 + if (!isConnected) + { + FindGWPort(); + ConnectDLL(); + } + + // DLL 경유 인쇄 (iCmd=2) + int result = AllThatPayCatReqMC(2, buf, buf.Length); + + if (result != 0) + { + Log("Print OK (DLL): " + text.Length + " chars, QR=" + (!string.IsNullOrEmpty(qrUrl))); + return json.Serialize(new { ok = true, method = "dll", has_qr = !string.IsNullOrEmpty(qrUrl), bytes_sent = buf.Length }); + } + + // DLL 실패 → 재연결 후 1회 재시도 + Log("Print DLL failed, reconnecting..."); + FindGWPort(); + ConnectDLL(); + + result = AllThatPayCatReqMC(2, buf, buf.Length); + if (result != 0) + { + Log("Print OK (DLL retry): " + text.Length + " chars, QR=" + (!string.IsNullOrEmpty(qrUrl))); + return json.Serialize(new { ok = true, method = "dll_retry", has_qr = !string.IsNullOrEmpty(qrUrl), bytes_sent = buf.Length }); + } + + return json.Serialize(new { ok = false, error = "DLL CatReqMC(2) returned 0" }); + } + catch (Exception ex) + { + Log("ProcessPrint error: " + ex.Message); + return json.Serialize(new { ok = false, error = ex.Message }); + } + } + static void Cleanup() { try diff --git a/PaymentBridge.exe b/PaymentBridge.exe index 9db5958923a4b27876f63a96cd6e9b11c37e8a0a..ad6d6d35346f6ef5cfba59a4ce1bad326d280ac3 100644 GIT binary patch literal 31744 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 Ba=rin diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..38b4cea --- /dev/null +++ b/build.bat @@ -0,0 +1,8 @@ +@echo off +cd /d "%~dp0" +C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /nologo /platform:x86 /target:winexe /win32icon:shc.ico /reference:System.dll /reference:System.Drawing.dll /reference:System.Windows.Forms.dll /reference:System.Web.Extensions.dll /out:PaymentBridge.exe PaymentBridge.cs +if %errorlevel%==0 ( + echo BUILD SUCCESS +) else ( + echo BUILD FAILED +) diff --git a/test_print_dll.ps1 b/test_print_dll.ps1 new file mode 100644 index 0000000..49551be --- /dev/null +++ b/test_print_dll.ps1 @@ -0,0 +1,105 @@ +# 32비트 PowerShell에서 AllthatModule.dll iCmd=2 영수증출력 테스트 +# 실행: C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File test_print_dll.ps1 + +Add-Type -TypeDefinition @" +using System; +using System.Runtime.InteropServices; + +public class AllThatPay { + private const string DLL = @"C:\Program Files (x86)\AllthatpayClient\AllthatModule.dll"; + + [DllImport(DLL, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern int AllThatPayOpenModule(string gwIp, string gwPort, string atpIp, string atpPort, string bizNo, string ediType, int optFlag); + + [DllImport(DLL, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern int AllThatPayCloseModule(); + + [DllImport(DLL, CallingConvention = CallingConvention.StdCall)] + public static extern int AllThatPayCatReqMC(int iCmd, byte[] pInBuf, int iInLength); + + [DllImport(DLL, CallingConvention = CallingConvention.StdCall)] + public static extern int AllThatPayRetCon(); + + [DllImport(DLL, CallingConvention = CallingConvention.StdCall)] + public static extern IntPtr AllThatPayRetData(int iPosition); +} +"@ + +# --- GW 포트 자동 탐지 --- +$gwPort = $null +$proc = Get-Process -Name "AllthatpayClient" -ErrorAction SilentlyContinue | Select-Object -First 1 +if ($proc) { + $netstat = netstat -ano 2>$null + foreach ($line in $netstat) { + if ($line -match "LISTENING" -and $line -match "\s$($proc.Id)\s*$") { + if ($line -match ":(\d+)\s") { + $port = [int]$Matches[1] + if ($port -ne 8080 -and $port -ne 7779) { + $gwPort = $port.ToString() + break + } + } + } + } +} + +if (-not $gwPort) { + Write-Host "[ERROR] GW port not found" -ForegroundColor Red + exit 1 +} +Write-Host "[INFO] GW Port: $gwPort" -ForegroundColor Cyan + +# --- DLL 연결 --- +$r = [AllThatPay]::AllThatPayOpenModule("127.0.0.1", $gwPort, "", "", "8134500294", "P01", 0) +Write-Host "[INFO] OpenModule: $r (1=OK)" -ForegroundColor $(if ($r -eq 1) {"Green"} else {"Red"}) + +if ($r -ne 1) { + Write-Host "[ERROR] OpenModule failed" -ForegroundColor Red + exit 1 +} + +# --- 영수증 텍스트 (EUC-KR) --- +$eucKr = [System.Text.Encoding]::GetEncoding("euc-kr") + +$text = "================================================`n" +$text += " [ 청 춘 약 국 ]`n" +$text += " 경기 양주시 양주역로 7-3 1층`n" +$text += " TEL: 033-481-7390`n" +$text += "================================================`n" +$text += "`n" +$text += " ** DLL iCmd=2 인쇄 테스트 **`n" +$text += " 시간: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')`n" +$text += "`n" +$text += "------------------------------------------------`n" +$text += " ★ 마일리지 적립 ★`n" +$text += " QR 스캔하고 100P 받으세요!`n" +$text += " (유효기간: 30일)`n" +$text += "------------------------------------------------`n" +$text += "`n`n" + +$textBytes = $eucKr.GetBytes($text) + +# --- QR 코드 추가: FS×4 + ATQR_URL (명세서 CMD 2 규격) --- +$qrUrl = "https://shc.pharmq.kr/claim?t=test_dll_print" +[byte]$fs = 0x1C +$qrTag = $eucKr.GetBytes("ATQR_" + $qrUrl) + +$buf = New-Object System.Collections.Generic.List[byte] +$buf.AddRange($textBytes) +$buf.Add($fs); $buf.Add($fs); $buf.Add($fs); $buf.Add($fs) +$buf.AddRange($qrTag) +$packet = $buf.ToArray() + +Write-Host "[INFO] iCmd=2 send ($($packet.Length) bytes, text=$($textBytes.Length) + QR=$($qrTag.Length))..." -ForegroundColor Yellow + +# --- iCmd=2 영수증출력 --- +try { + $pr = [AllThatPay]::AllThatPayCatReqMC(2, $packet, $packet.Length) + Write-Host "[INFO] CatReqMC(2): $pr" -ForegroundColor $(if ($pr -ne 0) {"Green"} else {"Red"}) +} catch { + Write-Host "[ERROR] CatReqMC exception: $_" -ForegroundColor Red +} + +# --- 정리 --- +try { [AllThatPay]::AllThatPayCloseModule() | Out-Null } catch {} +Write-Host "[DONE]" -ForegroundColor Cyan