acquire-core-x/app/ui/index.html
hyeongwoo-choi 19acf4ed96 업무화면 고도화: MDI 탭·그리드(정렬/페이징/CSV/합계/배지)·상세팝업·마스터-디테일
- MDI 탭바: 화면 다중 오픈/전환/닫기 (상태 유지, 레거시 업무포털 방식)
- 그리드 컴포넌트: 컬럼 정렬, 페이징(1/34), CSV 저장, 금액 합계행, 상태 한글배지
  (접수/대사/정산완료/취소/보류), 행 hover·클릭
- 매입 상세 팝업: 행 클릭 → 매입원장 + 승인/정산/원장(복식기표) 연계조회
  + 보류(ACQ_HOLD)·취소(ACQ_CANCEL) 실 tpcall XA 액션 (상태별 버튼 활성화)
- 가맹점 관리(QR0301): 마스터 그리드 ↔ 상세폼, 신규등록/정보수정/상태변경
  실 tpcall(MM_MERCH_REG/UPD/STATUS) + 확장마스터/변경이력 연계
- 매입목록 필터 확장(상태), 해시 딥링크(#q=/#s=), 거래저널 전화면 공유
- 검증: 헤드리스 스크린샷 3종(대시보드/매입목록/가맹점관리) 렌더 확인

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 03:35:45 +00:00

4834 lines
108 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title>ACQUIRE-CORE-X 매입업무포털</title>
<style>
/* Xplatform(UXStudio) 풍 내부 업무화면 */
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; font-family: "Malgun Gothic", "맑은 고딕", Dotum, sans-serif; font-size: 12px; color: #222; }
body { display: flex; flex-direction: column; background: #e8ebef; }
#titlebar { height: 44px; background: linear-gradient(#2c5d8f, #1d4269); color: #fff; display: flex; align-items: center; padding: 0 14px; flex-shrink: 0; }
#titlebar .logo { font-size: 16px; font-weight: bold; letter-spacing: 1px; }
#titlebar .sub { margin-left: 12px; font-size: 11px; color: #bcd3e8; }
#titlebar .right { margin-left: auto; font-size: 11px; color: #d6e4f2; }
#titlebar .right b { color: #ffd27f; }
#main { flex: 1; display: flex; min-height: 0; }
#menuwrap { width: 232px; background: #f4f6f8; border-right: 1px solid #b8c2cc; display: flex; flex-direction: column; flex-shrink: 0; }
#menusearch { padding: 6px; border-bottom: 1px solid #ccd4dc; }
#menusearch input { width: 100%; height: 24px; border: 1px solid #9aa8b5; padding: 0 8px; font-size: 12px; }
#menu { flex: 1; overflow-y: auto; }
#menu .grp { padding: 7px 10px; background: #dbe3ea; border-bottom: 1px solid #c3cdd6; font-weight: bold; color: #2c4a66; cursor: pointer; display: flex; }
#menu .grp .cnt { margin-left: auto; font-weight: normal; color: #7b8a99; font-size: 10px; }
#menu .grp::before { content: "▸ "; color: #7b8a99; }
#menu .grp.open::before { content: "▾ "; }
#menu .itm { padding: 5px 8px 5px 22px; border-bottom: 1px solid #e6eaee; cursor: pointer; color: #333;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: none; }
#menu .grp.open + .itms .itm, #menu .itms.show .itm { display: block; }
#menu .itm:hover { background: #e8f0f8; }
#menu .itm.on { background: #cfe0f0; color: #14487c; font-weight: bold; }
#menu .itm .cd { color: #888; font-size: 10px; margin-right: 5px; font-family: Consolas, monospace; }
#content { flex: 1; display: flex; flex-direction: column; min-width: 0; }
/* MDI 탭바 */
#tabbar { min-height: 30px; background: #d5dce3; border-bottom: 1px solid #a9b4bf; display: flex; align-items: flex-end; padding: 4px 8px 0; flex-wrap: wrap; gap: 2px; flex-shrink: 0; }
#tabbar .tab { padding: 5px 8px 4px 14px; background: #e9edf1; border: 1px solid #a9b4bf; border-bottom: none; color: #55677a; cursor: pointer; display: flex; align-items: center; max-width: 210px; }
#tabbar .tab.on { background: #fff; font-weight: bold; color: #1d4269; }
#tabbar .tab .tnm { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
#tabbar .tab .x { margin-left: 8px; color: #98a4b0; font-weight: bold; padding: 0 3px; }
#tabbar .tab .x:hover { color: #c22; }
#work { flex: 1; overflow: auto; padding: 12px; }
.tabpane { display: none; }
.tabpane.on { display: block; }
.panel { background: #fff; border: 1px solid #b0bac4; margin-bottom: 12px; }
.panel h3 { font-size: 12px; padding: 6px 10px; background: #eef2f6; border-bottom: 1px solid #ccd4dc; color: #1d4269; display: flex; align-items: center; }
.panel h3::before { content: ""; width: 4px; height: 12px; background: #2c5d8f; margin-right: 6px; flex-shrink: 0; }
.panel .bd { padding: 10px; }
table.frm { border-collapse: collapse; width: 100%; }
table.frm th { background: #f0f3f6; border: 1px solid #d3dae1; padding: 5px 8px; text-align: right; width: 150px; font-weight: normal; color: #445; }
table.frm td { border: 1px solid #d3dae1; padding: 3px 6px; }
table.frm input[type=text], table.frm select { width: 100%; max-width: 280px; height: 22px; border: 1px solid #9aa8b5; padding: 0 6px; font-size: 12px; background:#fff; }
table.frm input[readonly] { background: #f0f3f6; color: #667; }
table.frm .fldcd { color: #98a4b0; font-size: 10px; margin-left: 8px; font-family: Consolas, monospace; }
.btnrow { margin-top: 10px; text-align: right; }
button { height: 26px; padding: 0 14px; margin-left: 6px; background: linear-gradient(#fdfdfd, #dfe5ea); border: 1px solid #8fa0b0; cursor: pointer; font-size: 12px; }
button.pri { background: linear-gradient(#3f76ad, #29578a); color: #fff; border-color: #1d4269; font-weight: bold; }
button.warn { background: linear-gradient(#e8a54a, #c8862c); color: #fff; border-color: #a06a1e; }
button.dang { background: linear-gradient(#d95f5f, #b23c3c); color: #fff; border-color: #8f2b2b; }
button:hover { filter: brightness(1.06); }
button:disabled { opacity: .5; cursor: default; }
/* 그리드 */
.gtools { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; color: #556; }
.gtools .sp { flex: 1; }
.gtools button { height: 22px; padding: 0 10px; margin: 0; font-size: 11px; }
table.grd { border-collapse: collapse; width: 100%; }
table.grd th { background: #dfe6ec; border: 1px solid #b8c2cc; padding: 4px 6px; color: #2c4a66; cursor: pointer; user-select: none; white-space: nowrap; }
table.grd th .sa { color: #29578a; margin-left: 3px; }
table.grd td { border: 1px solid #d3dae1; padding: 3px 6px; background: #fff; white-space: nowrap; }
table.grd tr:nth-child(even) td { background: #f7fafc; }
table.grd tr.rw:hover td { background: #e8f2fb; cursor: pointer; }
table.grd tr.sum td { background: #eef3f8; font-weight: bold; border-top: 2px solid #a9b4bf; }
.num { text-align: right; font-family: Consolas, monospace; }
.ok { color: #0a7d2c; font-weight: bold; }
.err { color: #c22; font-weight: bold; }
.bdg { display: inline-block; padding: 1px 7px; border-radius: 2px; font-size: 11px; color: #fff; }
.bA { background: #3a7bbf; } .bM { background: #d98a2b; } .bS { background: #2b9e4e; }
.bC { background: #c24444; } .bH { background: #7c8a99; } .bV { background: #8f2b8f; }
.cards { display: flex; gap: 10px; flex-wrap: wrap; }
.card { flex: 1; min-width: 128px; border: 1px solid #c6d0da; background: #f7fafd; padding: 8px 10px; }
.card .cl { font-size: 11px; color: #667; }
.card .cv { font-size: 16px; font-weight: bold; color: #1d4269; margin-top: 4px; text-align: right; font-family: Consolas, monospace; }
/* 팝업(모달) */
#ovl { position: fixed; inset: 0; background: rgba(20,30,40,.45); display: none; z-index: 50; }
#ovl.show { display: block; }
#pop { position: absolute; top: 6%; left: 50%; transform: translateX(-50%); width: 880px; max-height: 86%;
overflow: auto; background: #eef1f4; border: 2px solid #2c5d8f; box-shadow: 0 8px 30px rgba(0,0,0,.35); }
#pop .phd { background: linear-gradient(#2c5d8f, #1d4269); color: #fff; padding: 8px 12px; font-weight: bold; display: flex; }
#pop .phd .x { margin-left: auto; cursor: pointer; padding: 0 6px; }
#pop .pbd { padding: 12px; }
#statusbar { height: 24px; background: #d5dce3; border-top: 1px solid #a9b4bf; display: flex; align-items: center; padding: 0 10px; font-size: 11px; color: #345; flex-shrink: 0; }
#statusbar .dot { width: 8px; height: 8px; border-radius: 50%; background: #23a54a; margin-right: 6px; }
</style>
</head>
<body>
<div id="titlebar">
<span class="logo">ACQUIRE-CORE-X</span>
<span class="sub">글로벌 매입업무포털 (Enduro/X · ECPG/PostgreSQL · XA)</span>
<span class="right">사용자: <b>매입운영1팀</b> | 영업일 <span id="bizdate"></span> | 전체화면 <b id="scrcnt">-</b></span>
</div>
<div id="main">
<div id="menuwrap">
<div id="menusearch"><input id="q" placeholder="화면/서비스 검색 (예: 매입, SETTLE)"></div>
<div id="menu"></div>
</div>
<div id="content">
<div id="tabbar"></div>
<div id="work"></div>
<div id="statusbar"><span class="dot"></span><span id="stmsg">TP 모니터 연결됨 — 게이트웨이 /api/call</span></div>
</div>
</div>
<div id="ovl"><div id="pop"><div class="phd"><span id="ptit">상세</span><span class="x" onclick="closePop()"></span></div><div class="pbd" id="pbd"></div></div></div>
<script>
/* === 화면 매니페스트 (인라인; 재생성: tools/gen_screens.py) === */
/* 자동생성 화면 매니페스트 - tools/gen_screens.py 가 svc 소스에서 추출 */
const SVC_SCREENS = [
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQUIRE",
"desc": "* ACQUIRE.pgc - ac 모듈 서비스 ACQUIRE (one service = one file).",
"in": [
"T_MERCHANT",
"T_AMOUNT",
"T_BIZDATE"
],
"out": [
"T_PURCHASE_ID",
"T_FEE",
"T_NET"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_AMTFIX",
"desc": "금액 확정 정정: 직전 금액 조회 후 하우스 25bps 로 절대 재계산, 증감(delta) 회신.",
"in": [
"T_PURCHASE_ID",
"T_AMOUNT"
],
"out": [
"T_DELTA",
"T_FEE",
"T_NET"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_APPRLINK",
"desc": "* ACQ_APPRLINK.pgc - ac 모듈 서비스 ACQ_APPRLINK (one service = one file).",
"in": [
"T_PURCHASE_ID"
],
"out": []
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_APPRMAP",
"desc": "* ACQ_APPRMAP.pgc - ac 모듈 서비스 ACQ_APPRMAP (one service = one file).",
"in": [
"T_PURCHASE_ID"
],
"out": [
"T_COUNT"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_CANCEL",
"desc": "* ACQ_CANCEL.pgc - ac 모듈 서비스 ACQ_CANCEL (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_AMOUNT",
"T_BIZDATE",
"T_REASON"
],
"out": [
"T_CANCEL_ID"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_CORRECT",
"desc": "* ACQ_CORRECT.pgc - ac 모듈 서비스 ACQ_CORRECT (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_AMOUNT",
"T_MERCHANT"
],
"out": [
"T_FEE",
"T_NET"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_DATECHG",
"desc": "* ACQ_DATECHG.pgc - ac 모듈 서비스 ACQ_DATECHG (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_BIZDATE"
],
"out": []
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_DDC",
"desc": "* ACQ_DDC.pgc - ac 모듈 서비스 ACQ_DDC (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_FX_AMT",
"T_CCY",
"T_BIZDATE"
],
"out": [
"T_AMOUNT"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_DUPCHK",
"desc": "* ACQ_DUPCHK.pgc - ac 모듈 서비스 ACQ_DUPCHK (one service = one file).",
"in": [
"T_MERCHANT",
"T_BIZDATE",
"T_AMOUNT"
],
"out": [
"T_COUNT"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_EDC",
"desc": "* ACQ_EDC.pgc - ac 모듈 서비스 ACQ_EDC (one service = one file).",
"in": [
"T_MERCHANT",
"T_AMOUNT",
"T_BIZDATE"
],
"out": [
"T_PURCHASE_ID",
"T_FEE",
"T_NET"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_EDI",
"desc": "* ACQ_EDI.pgc - ac 모듈 서비스 ACQ_EDI (one service = one file).",
"in": [
"T_MERCHANT",
"T_DOCNO",
"T_BIZDATE",
"T_AMOUNT"
],
"out": []
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_FEEADJ",
"desc": "* ACQ_FEEADJ.pgc - ac 모듈 서비스 ACQ_FEEADJ (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_DELTA",
"T_BIZDATE",
"T_REASON"
],
"out": [
"T_ADJ"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_FOREIGN",
"desc": "* ACQ_FOREIGN.pgc - ac 모듈 서비스 ACQ_FOREIGN (one service = one file).",
"in": [
"T_MERCHANT",
"T_AMOUNT",
"T_BIZDATE",
"T_CCY"
],
"out": [
"T_PURCHASE_ID",
"T_FEE"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_HOLD",
"desc": "매입 보류: 접수/대사(A,M) 상태만 보류로 전이, 반영 건수를 T_RC 로.",
"in": [
"T_PURCHASE_ID"
],
"out": [
"T_RC"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_INSTALL",
"desc": "* ACQ_INSTALL.pgc - ac 모듈 서비스 ACQ_INSTALL (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_INSTALL_N",
"T_AMOUNT",
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_ISSUERCLS",
"desc": "* ACQ_ISSUERCLS.pgc - ac 모듈 서비스 ACQ_ISSUERCLS (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_ISSUER"
],
"out": []
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_LIMITCHK",
"desc": "* ACQ_LIMITCHK.pgc - ac 모듈 서비스 ACQ_LIMITCHK (one service = one file).",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_GROSS",
"T_RC"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_MERCHSUM",
"desc": "* ACQ_MERCHSUM.pgc - ac 모듈 서비스 ACQ_MERCHSUM (one service = one file).",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_PARTIAL",
"desc": "* ACQ_PARTIAL.pgc - ac 모듈 서비스 ACQ_PARTIAL (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_AMOUNT",
"T_BIZDATE"
],
"out": [
"T_CANCEL_ID"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_RECLASS",
"desc": "업종/분류 재지정: category 갱신 후 같은 가맹점에서 동일 분류 건수를 집계 회신.",
"in": [
"T_PURCHASE_ID",
"T_CATEGORY"
],
"out": [
"T_COUNT"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_REFUND",
"desc": "* ACQ_REFUND.pgc - ac 모듈 서비스 ACQ_REFUND (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_AMOUNT",
"T_BIZDATE",
"T_REASON"
],
"out": [
"T_CANCEL_ID"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_RELEASE",
"desc": "보류 해제: 직전 상태를 조회한 뒤 H->A 전이, 이전 상태를 함께 회신.",
"in": [
"T_PURCHASE_ID"
],
"out": [
"T_RC"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_REPROC",
"desc": "* ACQ_REPROC.pgc - ac 모듈 서비스 ACQ_REPROC (one service = one file).",
"in": [
"T_PURCHASE_ID"
],
"out": []
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_SETTLELINK",
"desc": "정산 연계: 가맹점 미지정 시 매입에서 조회, settlement 링크 행(status='LINKED') 생성.",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_SETTLE_ID"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_STATUS",
"desc": "* ACQ_STATUS.pgc - ac 모듈 서비스 ACQ_STATUS (one service = one file).",
"in": [
"T_PURCHASE_ID"
],
"out": []
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_TAXINV",
"desc": "* ACQ_TAXINV.pgc - ac 모듈 서비스 ACQ_TAXINV (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_AMOUNT",
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_TAX"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_UNMATCH",
"desc": "* ACQ_UNMATCH.pgc - ac 모듈 서비스 ACQ_UNMATCH (one service = one file).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_VOID",
"desc": "* ACQ_VOID.pgc - ac 모듈 서비스 ACQ_VOID (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_AMOUNT",
"T_BIZDATE"
],
"out": [
"T_CANCEL_ID"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_WHT",
"desc": "* ACQ_WHT.pgc - ac 모듈 서비스 ACQ_WHT (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_BIZDATE"
],
"out": [
"T_TAX"
]
},
{
"mod": "ac",
"modnm": "매입",
"svc": "ACQ_XFERLINK",
"desc": "* ACQ_XFERLINK.pgc - ac 모듈 서비스 ACQ_XFERLINK (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_AMOUNT",
"T_BIZDATE"
],
"out": []
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH",
"desc": "승인 접수: 한도 점검 후 authorization 원장 기록 + 한도 차감.",
"in": [
"T_KEY1",
"T_MERCHANT",
"T_AMOUNT",
"T_BIZDATE"
],
"out": [
"T_ID1",
"T_RC"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_APPROVE",
"desc": "승인 확정(pending->approved): dbio 래퍼로 상태만 A 로 확정.",
"in": [
"T_ID1"
],
"out": []
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_CANCEL",
"desc": "승인 전체 취소 + 한도 원복.",
"in": [
"T_ID1",
"T_AMOUNT",
"T_KEY1",
"T_BIZDATE",
"T_REASON"
],
"out": [
"T_CANCEL_ID"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_CAPTURE",
"desc": "승인 매입확정(capture): 상태 A->M(매입대상).",
"in": [
"T_ID1"
],
"out": [
"T_RC"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_DECLINE",
"desc": "승인 거절 처리: 거절 사유와 함께 상태 D 로 갱신.",
"in": [
"T_ID1",
"T_REASON"
],
"out": []
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_HISTORY",
"desc": "카드 승인 이력 건수 조회.",
"in": [
"T_KEY1"
],
"out": [
"T_COUNT"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_HOLD",
"desc": "승인 보류: 승인/예비(A,P) 상태만 보류(H)로 전이, 반영 건수를 T_RC 로.",
"in": [
"T_ID1"
],
"out": [
"T_RC"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_PARTCXL",
"desc": "부분 취소: 승인 금액 감액 + 한도 부분 원복.",
"in": [
"T_ID1",
"T_AMOUNT",
"T_KEY1",
"T_BIZDATE"
],
"out": [
"T_CANCEL_ID",
"T_AMOUNT"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_RELEASE",
"desc": "보류 해제: 직전 상태를 조회한 뒤 H->A 전이, 이전 상태를 함께 회신.",
"in": [
"T_ID1"
],
"out": [
"T_RC"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_RETRY",
"desc": "거절 승인 재시도 (상태 D->A 재승인).",
"in": [
"T_ID1",
"T_AMOUNT",
"T_KEY1"
],
"out": [
"T_RC"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_REVERSE",
"desc": "승인 역전(reversal) + 한도 원복.",
"in": [
"T_ID1",
"T_AMOUNT",
"T_KEY1"
],
"out": []
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_ROUTE",
"desc": "승인 라우팅(발급사 BIN 기준 라우팅 코드 산출).",
"in": [
"T_KEY1"
],
"out": [
"T_ARG1"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_STATUS",
"desc": "승인 상태 조회 (dbio).",
"in": [
"T_ID1"
],
"out": []
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_SUMMARY",
"desc": "가맹점 당일 승인 집계 upsert (dbio).",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "AUTH_VOID",
"desc": "당일 승인 무효화(void) + 한도 원복.",
"in": [
"T_ID1",
"T_AMOUNT",
"T_KEY1",
"T_BIZDATE"
],
"out": [
"T_CANCEL_ID"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "BLACKLIST_CHK",
"desc": "블랙리스트 카드 조회.",
"in": [
"T_KEY1"
],
"out": [
"T_RC"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "CARD_VALIDATE",
"desc": "카드번호 Luhn 검증 (common lib).",
"in": [
"T_KEY1"
],
"out": [
"T_RC"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "DCC_QUOTE",
"desc": "해외승인 DCC 환산 견적(통화 -> 원화).",
"in": [
"T_FX_AMT",
"T_CCY"
],
"out": [
"T_AMOUNT",
"T_ARG1"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "FRAUD_DETECT",
"desc": "부정거래 스코어링 + 위험시 fraud_log 기록.",
"in": [
"T_ID1",
"T_AMOUNT",
"T_KEY1",
"T_BIZDATE"
],
"out": [
"T_ARG1",
"T_ID2",
"T_RC"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "INSTALL_AUTH",
"desc": "할부 승인: 개월 수만큼 분할 승인 레코드.",
"in": [
"T_KEY1",
"T_MERCHANT",
"T_AMOUNT",
"T_INSTALL_N",
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "LIMIT_CHK",
"desc": "카드 한도 점검 (사용가능 여부만 리턴).",
"in": [
"T_KEY1",
"T_AMOUNT"
],
"out": [
"T_AMT1",
"T_AMT2",
"T_RC"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "LIMIT_DEC",
"desc": "한도 차감(사용금액 증가).",
"in": [
"T_AMOUNT",
"T_KEY1"
],
"out": []
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "LIMIT_INQ",
"desc": "한도 조회 (가용한도 계산).",
"in": [
"T_KEY1"
],
"out": [
"T_AMT1",
"T_AMT2",
"T_AMT3"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "LIMIT_RST",
"desc": "한도 사용금액 초기화(일마감 원복).",
"in": [
"T_KEY1"
],
"out": []
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "LIMIT_SET",
"desc": "카드 한도 설정/등록 (dbio upsert).",
"in": [
"T_AMT1",
"T_KEY1"
],
"out": []
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "LIMIT_TEMP",
"desc": "임시 한도 상향 (temp_limit 저장 + 당일 상향).",
"in": [
"T_KEY1",
"T_AMT1"
],
"out": []
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "PREAUTH",
"desc": "예비승인(pre-authorization) 기록.",
"in": [
"T_KEY1",
"T_MERCHANT",
"T_BIZDATE",
"T_AMOUNT"
],
"out": [
"T_ID2"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "PREAUTH_COMPLETE",
"desc": "예비승인 확정: preauth 소진 + 본승인 생성.",
"in": [
"T_ID2",
"T_BIZDATE"
],
"out": [
"T_ID1"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "STANDIN",
"desc": "발급사 무응답 시 대리승인(STANDIN, 소액 한도 내).",
"in": [
"T_KEY1",
"T_MERCHANT",
"T_AMOUNT",
"T_BIZDATE"
],
"out": [
"T_RC",
"T_ID1"
]
},
{
"mod": "au",
"modnm": "승인/한도",
"svc": "VELOCITY_CHK",
"desc": "속도(velocity) 점검: 당일 카드 승인건수/합계.",
"in": [
"T_KEY1",
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS",
"T_RC"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_AGGREGATE",
"desc": "마감 총계 재집계 후 close_log 반영.",
"in": [
"T_ID1",
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_ALERT",
"desc": "미마감 경보: 당일 대사완료(M) 미전기 매입 건수.",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_RC"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_APPROVE",
"desc": "마감 승인: 상태 A.",
"in": [
"T_ID1"
],
"out": []
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_ARCHIVE",
"desc": "마감 아카이브: 승인/완료 마감을 보관 상태로(memo 표시).",
"in": [
"T_ID1"
],
"out": [
"T_COUNT"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_BALVERIFY",
"desc": "잔액 검증: 스냅샷 net 합 vs close_log total 비교.",
"in": [
"T_ID1"
],
"out": [
"T_AMT2",
"T_AMT3",
"T_DELTA"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_CANCEL",
"desc": "마감 취소: 상태 X.",
"in": [
"T_ID1"
],
"out": []
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_CONFIRM",
"desc": "마감 확정: 상태 C.",
"in": [
"T_ID1"
],
"out": []
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_DAILY",
"desc": "일 마감: 당일 매입 집계 후 마감이력(DAILY) 생성.",
"in": [
"T_BIZDATE"
],
"out": [
"T_ID1"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_DIFFCHK",
"desc": "차액 점검: close_log total vs 스냅샷 gross 합.",
"in": [
"T_ID1"
],
"out": [
"T_DELTA",
"T_RC"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_INQUIRY",
"desc": "마감 조회: close_type/기간/상태/총건수 반환.",
"in": [
"T_ID1"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_LOCK",
"desc": "기간 잠금: cl_period_lock upsert(locked=true) + 마감 L.",
"in": [
"T_ID1",
"T_STR1",
"T_BIZDATE"
],
"out": []
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_MIDCLOSE",
"desc": "중간 마감: 당일 중간 스냅 마감이력(MID) 생성.",
"in": [
"T_BIZDATE"
],
"out": [
"T_ID1",
"T_COUNT"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_MONTHLY",
"desc": "월 마감: 해당 월(YYYY-MM) 매입 집계 후 마감이력(MONTHLY).",
"in": [
"T_BIZDATE",
"T_STR1"
],
"out": [
"T_ID1"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_PERIOD",
"desc": "기간 마감 개시(open): close_log 를 O 상태로 등록.",
"in": [
"T_BIZDATE",
"T_STR1",
"T_STR2"
],
"out": [
"T_ID1"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_PURGE",
"desc": "취소 마감 정리: 오래된 X 상태 마감과 그 스냅샷 삭제.",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_QUARTER",
"desc": "분기 마감: 분기 프리픽스(YYYY-MM LIKE)로 집계.",
"in": [
"T_BIZDATE",
"T_STR1"
],
"out": [
"T_ID1"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_RECLOSE",
"desc": "재마감: 상태 R 로 표시하고 총계 재집계.",
"in": [
"T_ID1",
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_RECON",
"desc": "마감 대사: 실제 매입건수 vs close_log txn_count 대사.",
"in": [
"T_ID1",
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_DELTA",
"T_RC"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_REPORT",
"desc": "마감 리포트: 특정 마감의 스냅샷 건수/총매출.",
"in": [
"T_ID1"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_RESTORE",
"desc": "마감 복원: 취소(X) 마감을 개시(O) 상태로 되돌림.",
"in": [
"T_ID1"
],
"out": []
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_ROLLBACK",
"desc": "마감 롤백: 스냅샷 삭제 + 상태 O 로 복귀.",
"in": [
"T_ID1"
],
"out": [
"T_COUNT"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_SEQ",
"desc": "마감 순번 발번(dbio upsert).",
"in": [
"T_STR2"
],
"out": [
"T_ID2"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_SNAPSHOT",
"desc": "마감 스냅샷: merchant_summary 를 close_id 로 고정 복사.",
"in": [
"T_ID1",
"T_BIZDATE",
"T_STR1"
],
"out": [
"T_COUNT"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_STATS",
"desc": "마감 통계: close_type 별 마감 건수/총액.",
"in": [
"T_STR2"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_STATUS",
"desc": "마감 상태 조회(dbio getter).",
"in": [
"T_ID1"
],
"out": []
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_SUMMARY",
"desc": "마감 요약: 스냅샷 gross/fee/net 합계 반환.",
"in": [
"T_ID1"
],
"out": [
"T_GROSS",
"T_FEE",
"T_NET"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_UNCLOSED",
"desc": "미마감일 점검: close_log 없는 매입 영업일 건수.",
"in": [],
"out": [
"T_COUNT"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_UNLOCK",
"desc": "기간 잠금 해제.",
"in": [
"T_STR1",
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_VERIFY",
"desc": "마감 검증: close_log 총건수 vs 실제 매입건수 비교.",
"in": [
"T_ID1",
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_RC"
]
},
{
"mod": "cl",
"modnm": "마감",
"svc": "CL_YEAREND",
"desc": "연말 마감: 연도(YYYY) 프리픽스로 집계.",
"in": [
"T_BIZDATE"
],
"out": [
"T_ID1"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_ADDDAYS",
"desc": "* CM_ADDDAYS.pgc - cm 모듈 서비스 CM_ADDDAYS (one service = one file).",
"in": [
"T_STR1",
"T_ARG1"
],
"out": [
"T_STR3"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_AMT_ROUND",
"desc": "금액 반올림 (순수 계산): 단위(T_ARG1)로 반올림. */",
"in": [
"T_AMOUNT",
"T_ARG1"
],
"out": [
"T_AMT1"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_AMT_SPLIT",
"desc": "금액 균등 분할 (순수 계산): n등분 + 잔액. */",
"in": [
"T_AMOUNT",
"T_ARG1"
],
"out": [
"T_AMT1",
"T_AMT2",
"T_COUNT"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_BIZDAY",
"desc": "* CM_BIZDAY.pgc - cm 모듈 서비스 CM_BIZDAY (one service = one file).",
"in": [],
"out": [
"T_BIZDATE"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_CACHE_INV",
"desc": "캐시 무효화 (순수 처리: 버전 증가 표시). */",
"in": [
"T_STR1"
],
"out": [
"T_RC",
"T_MSG"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_CACHE_LOAD",
"desc": "* CM_CACHE_LOAD.pgc - cm 모듈 서비스 CM_CACHE_LOAD (one service = one file).",
"in": [
"T_STR1"
],
"out": [
"T_COUNT"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_CHECKDIGIT",
"desc": "* CM_CHECKDIGIT.pgc - cm 모듈 서비스 CM_CHECKDIGIT (one service = one file).",
"in": [
"T_STR2"
],
"out": [
"T_ARG1",
"T_STR4"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_CODE",
"desc": "* CM_CODE.pgc - cm 모듈 서비스 CM_CODE (one service = one file).",
"in": [
"T_STR1",
"T_STR2"
],
"out": [
"T_RC"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_CODENAME",
"desc": "* CM_CODENAME.pgc - cm 모듈 서비스 CM_CODENAME (one service = one file).",
"in": [
"T_STR1",
"T_STR2"
],
"out": [
"T_STR3"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_CRC",
"desc": "* CM_CRC.pgc - cm 모듈 서비스 CM_CRC (one service = one file).",
"in": [
"T_STR1"
],
"out": [
"T_STR4",
"T_ARG1"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_ERRMSG",
"desc": "* CM_ERRMSG.pgc - cm 모듈 서비스 CM_ERRMSG (one service = one file).",
"in": [
"T_STR1",
"T_STR2"
],
"out": [
"T_MSG"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_FMT_AMT",
"desc": "* CM_FMT_AMT.pgc - cm 모듈 서비스 CM_FMT_AMT (one service = one file).",
"in": [
"T_AMOUNT"
],
"out": [
"T_STR4"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_FMT_DATE",
"desc": "날짜 포맷 변환 (순수 계산): YYYYMMDD -> YYYY-MM-DD. */",
"in": [
"T_STR1"
],
"out": [
"T_STR3"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_FX",
"desc": "* CM_FX.pgc - cm 모듈 서비스 CM_FX (one service = one file).",
"in": [
"T_CCY",
"T_BIZDATE"
],
"out": [
"T_ARG1"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_FX_CONV",
"desc": "환율 환산 (cm_fx_rate + compute): 외화 -> 원화. */",
"in": [
"T_CCY",
"T_BIZDATE",
"T_FX_AMT"
],
"out": [
"T_AMOUNT",
"T_ARG1"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_HOLIDAY_CHK",
"desc": "* CM_HOLIDAY_CHK.pgc - cm 모듈 서비스 CM_HOLIDAY_CHK (one service = one file).",
"in": [
"T_STR1"
],
"out": [
"T_RC"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_INTEREST",
"desc": "단리 이자 계산 (순수 계산): 원금*연이율(bps)*일수/(10000*365). */",
"in": [
"T_AMOUNT",
"T_ARG1",
"T_ARG2"
],
"out": [
"T_AMT1"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_LOG",
"desc": "* CM_LOG.pgc - cm 모듈 서비스 CM_LOG (one service = one file).",
"in": [
"T_SVCNAME",
"T_MSG",
"T_BIZDATE"
],
"out": [
"T_ID1"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_LUHN",
"desc": "* CM_LUHN.pgc - cm 모듈 서비스 CM_LUHN (one service = one file).",
"in": [
"T_STR5"
],
"out": [
"T_RC"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_MASK",
"desc": "카드번호 마스킹 (순수 계산): 앞6 뒤4 노출. */",
"in": [
"T_STR5"
],
"out": [
"T_STR4"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_MONTHEND",
"desc": "* CM_MONTHEND.pgc - cm 모듈 서비스 CM_MONTHEND (one service = one file).",
"in": [
"T_STR1"
],
"out": [
"T_STR3",
"T_ARG1"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_NETTING_CALC",
"desc": "네팅 계산 (순수 계산): 차변-대변. */",
"in": [
"T_AMT1",
"T_AMT2"
],
"out": [
"T_NET",
"T_RC"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_NEXTBIZ",
"desc": "* CM_NEXTBIZ.pgc - cm 모듈 서비스 CM_NEXTBIZ (one service = one file).",
"in": [
"T_STR1"
],
"out": [
"T_STR3"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_PARAM",
"desc": "* CM_PARAM.pgc - cm 모듈 서비스 CM_PARAM (one service = one file).",
"in": [
"T_STR1"
],
"out": [
"T_STR3"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_PARAM_SET",
"desc": "* CM_PARAM_SET.pgc - cm 모듈 서비스 CM_PARAM_SET (one service = one file).",
"in": [
"T_STR1",
"T_STR3"
],
"out": []
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_PING",
"desc": "* CM_PING.pgc - cm 모듈 서비스 CM_PING (one service = one file).",
"in": [],
"out": [
"T_MSG",
"T_RC"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_PRORATE",
"desc": "일할 계산 (순수 계산): 금액*사용일/총일. */",
"in": [
"T_AMOUNT",
"T_ARG1",
"T_ARG2"
],
"out": [
"T_AMT1"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_SEQ",
"desc": "* CM_SEQ.pgc - cm 모듈 서비스 CM_SEQ (one service = one file).",
"in": [
"T_KEY1"
],
"out": [
"T_ARG1"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_STATUS",
"desc": "모듈 상태: 파라미터 건수 조회로 DB 연결 확인. */",
"in": [],
"out": [
"T_COUNT",
"T_RC",
"T_STATUS"
]
},
{
"mod": "cm",
"modnm": "공통",
"svc": "CM_WEEKDAY",
"desc": "* CM_WEEKDAY.pgc - cm 모듈 서비스 CM_WEEKDAY (one service = one file).",
"in": [
"T_STR1"
],
"out": [
"T_ARG1",
"T_STR3",
"T_RC"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_ACCTSUM",
"desc": "계정 잔액 재집계(dbio) 후 잔액 반환.",
"in": [
"T_KEY1",
"T_BIZDATE"
],
"out": [
"T_NET"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_ACQPOST",
"desc": "매입 전기: 차변 RECV=amount, 대변 MERCH_PAY=net + FEE_INC=fee.",
"in": [
"T_BIZDATE",
"T_MERCHANT",
"T_AMOUNT",
"T_FEE",
"T_NET",
"T_PURCHASE_ID"
],
"out": [
"T_ID1"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_ADJUST",
"desc": "조정 전표: 부호에 따라 차변/대변 단일 분개.",
"in": [
"T_KEY1",
"T_BIZDATE",
"T_MERCHANT",
"T_DELTA",
"T_PURCHASE_ID"
],
"out": [
"T_ID1"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_APPLY",
"desc": "전표 전기확정(P): 라인들의 계정잔액을 잔액테이블에 반영.",
"in": [
"T_ID1",
"T_BIZDATE"
],
"out": []
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_BALCHK",
"desc": "전표 단위 대차 균형 점검 (차변합 vs 대변합).",
"in": [
"T_ID1"
],
"out": [
"T_AMT2",
"T_AMT3",
"T_RC"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_CARRY",
"desc": "이월: 당일 계정잔액을 익영업일 개시잔액으로 이월(upsert).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_CLOSE_LINK",
"desc": "마감연계: 전표 라인 closed + 전표 상태 S(마감연계).",
"in": [
"T_ID1"
],
"out": [
"T_COUNT"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_CONFIRM",
"desc": "전표 확정: 대차 균형이면 P로 확정, 아니면 실패.",
"in": [
"T_ID1"
],
"out": [
"T_RC"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_CORRECT",
"desc": "원장 라인 금액 정정.",
"in": [
"T_ID1",
"T_AMOUNT"
],
"out": []
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_CREDIT",
"desc": "기존 전표에 대변(C) 분개 1줄 추가.",
"in": [
"T_ID1",
"T_AMOUNT",
"T_KEY1",
"T_BIZDATE",
"T_MERCHANT"
],
"out": []
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_DAILYSUM",
"desc": "당일 계정별 잔액 일괄 재집계(전 계정 upsert).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_DEBIT",
"desc": "기존 전표에 차변(D) 분개 1줄 추가.",
"in": [
"T_ID1",
"T_AMOUNT",
"T_KEY1",
"T_BIZDATE",
"T_MERCHANT"
],
"out": []
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_DIFFCHK",
"desc": "당일 전체 대차 차액 점검(총차변-총대변).",
"in": [
"T_BIZDATE"
],
"out": [
"T_AMT2",
"T_AMT3",
"T_DELTA",
"T_RC"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_DOUBLE",
"desc": "신규 전표 즉시 전기(posted): 차변/대변 + 양 계정잔액 반영.",
"in": [
"T_KEY1",
"T_KEY2",
"T_BIZDATE",
"T_MERCHANT",
"T_AMOUNT",
"T_PURCHASE_ID"
],
"out": [
"T_ID1"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_FEEPOST",
"desc": "수수료수익 전기: 차변 RECV=fee, 대변 FEE_INC=fee.",
"in": [
"T_BIZDATE",
"T_MERCHANT",
"T_FEE",
"T_PURCHASE_ID"
],
"out": [
"T_ID1"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_INQUIRY",
"desc": "전표 상태 조회(dbio).",
"in": [
"T_ID1"
],
"out": []
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_JOURNAL",
"desc": "당일 분개(원장 라인) 건수 조회.",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_MERCHBAL",
"desc": "가맹점 잔액 재집계(dbio).",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": []
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_MONTHLYSUM",
"desc": "월 계정과목별 차/대 집계 건수 조회(YYYY-MM).",
"in": [
"T_STR1",
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_POST",
"desc": "전표 작성(draft) + 차변/대변 균형 분개 2줄.",
"in": [
"T_KEY1",
"T_KEY2",
"T_BIZDATE",
"T_MERCHANT",
"T_PURCHASE_ID",
"T_AMOUNT"
],
"out": [
"T_ID1"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_RECALC",
"desc": "계정 잔액 원장 라인 기준 재계산(dbio).",
"in": [
"T_KEY1",
"T_BIZDATE"
],
"out": []
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_REVERSE",
"desc": "역분개 전표: 원전표 라인의 차/대를 뒤집어 신규 전표에 복사.",
"in": [
"T_ID1",
"T_BIZDATE"
],
"out": [
"T_ID2",
"T_COUNT"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_ROLLFWD",
"desc": "전 계정 잔액 익일 이월(개시잔액 롤포워드).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_SETTLEPOST",
"desc": "정산 전기: 차변 MERCH_PAY, 대변 CASH (net).",
"in": [
"T_BIZDATE",
"T_MERCHANT",
"T_NET",
"T_PURCHASE_ID"
],
"out": [
"T_ID1"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_STATS",
"desc": "당일 전표/원장 통계(전표수, 총차변).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_STATUS",
"desc": "전표 상태 직접 변경(setter).",
"in": [
"T_ID1",
"T_STATUS"
],
"out": []
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_TRANSFER",
"desc": "계정간 대체: 출금계정 대변, 입금계정 차변(균형).",
"in": [
"T_KEY1",
"T_KEY2",
"T_BIZDATE",
"T_MERCHANT",
"T_AMOUNT"
],
"out": [
"T_ID1"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_TRIALBAL",
"desc": "계정별 시산표 산출 후 lg_trial_bal upsert.",
"in": [
"T_KEY1",
"T_BIZDATE"
],
"out": [
"T_AMT2",
"T_AMT3",
"T_DELTA"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_UNSETTLED",
"desc": "미마감(status=posted) 원장 라인 건수.",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "lg",
"modnm": "원장",
"svc": "LG_VOUCHER",
"desc": "빈 전표 헤더 생성(작성 상태).",
"in": [
"T_PURCHASE_ID",
"T_STR2",
"T_BIZDATE",
"T_MSG"
],
"out": [
"T_ID1"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_ACK",
"desc": "* MG_ACK.pgc - mg 모듈 서비스 MG_ACK (one service = one file).",
"in": [
"T_ID1"
],
"out": [
"T_STATUS"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_BITMAP",
"desc": "* MG_BITMAP.pgc - mg 모듈 서비스 MG_BITMAP (one service = one file).",
"in": [
"T_ARG1",
"T_ID1"
],
"out": [
"T_STR6"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_CHANAUTH",
"desc": "채널 인증: UP/SIGNON 상태만 통과. */",
"in": [
"T_CHANNEL"
],
"out": [
"T_RC",
"T_STATUS"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_CHANSTAT",
"desc": "* MG_CHANSTAT.pgc - mg 모듈 서비스 MG_CHANSTAT (one service = one file).",
"in": [
"T_CHANNEL"
],
"out": [
"T_STATUS"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_CONFIRM",
"desc": "* MG_CONFIRM.pgc - mg 모듈 서비스 MG_CONFIRM (one service = one file).",
"in": [
"T_ID1"
],
"out": [
"T_STATUS"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_CONVERT",
"desc": "* MG_CONVERT.pgc - mg 모듈 서비스 MG_CONVERT (one service = one file).",
"in": [
"T_CHANNEL",
"T_STR1",
"T_STR3",
"T_BIZDATE",
"T_AMOUNT"
],
"out": [
"T_STR1",
"T_ID1"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_DEQUEUE",
"desc": "* MG_DEQUEUE.pgc - mg 모듈 서비스 MG_DEQUEUE (one service = one file).",
"in": [],
"out": [
"T_COUNT",
"T_ID2",
"T_ARG1",
"T_CHANNEL",
"T_STR3"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_ECHO",
"desc": "* MG_ECHO.pgc - mg 모듈 서비스 MG_ECHO (one service = one file).",
"in": [
"T_CHANNEL",
"T_BIZDATE"
],
"out": [
"T_ID1",
"T_STATUS"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_ERRMSG",
"desc": "* MG_ERRMSG.pgc - mg 모듈 서비스 MG_ERRMSG (one service = one file).",
"in": [
"T_CHANNEL",
"T_STR1",
"T_STR3",
"T_BIZDATE",
"T_RC"
],
"out": [
"T_ID1"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_HEALTH",
"desc": "게이트웨이 헬스: 활성 채널 수 조회. */",
"in": [],
"out": [
"T_COUNT",
"T_RC"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_ISO8583",
"desc": "* MG_ISO8583.pgc - mg 모듈 서비스 MG_ISO8583 (one service = one file).",
"in": [
"T_CHANNEL",
"T_STR3",
"T_BIZDATE",
"T_AMOUNT"
],
"out": [
"T_STR1",
"T_STR4",
"T_AMOUNT",
"T_ID1"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_KEYEXCH",
"desc": "키 교환: 키버전 채번 + 세션키 갱신. */",
"in": [
"T_CHANNEL",
"T_KEY1"
],
"out": [
"T_ARG2"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_LOG",
"desc": "* MG_LOG.pgc - mg 모듈 서비스 MG_LOG (one service = one file).",
"in": [
"T_CHANNEL",
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_MAC",
"desc": "simple additive 4-hex MAC/checksum over a buffer (전문 무결성 데모). */",
"in": [
"T_STR3",
"T_ID1"
],
"out": [
"T_KEY1"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_NACK",
"desc": "* MG_NACK.pgc - mg 모듈 서비스 MG_NACK (one service = one file).",
"in": [
"T_ID1",
"T_RC"
],
"out": [
"T_STATUS"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_PACK",
"desc": "고정길이 전문 조립 (순수 계산): MTI(4)+처리코드(6)+금액(12). */",
"in": [
"T_STR1",
"T_STR4",
"T_AMOUNT"
],
"out": [
"T_STR3",
"T_COUNT"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_PARSE",
"desc": "* MG_PARSE.pgc - mg 모듈 서비스 MG_PARSE (one service = one file).",
"in": [
"T_STR3"
],
"out": [
"T_STR1",
"T_STR4",
"T_COUNT"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_QUEUE",
"desc": "* MG_QUEUE.pgc - mg 모듈 서비스 MG_QUEUE (one service = one file).",
"in": [
"T_CHANNEL",
"T_STR1",
"T_STR3",
"T_BIZDATE",
"T_ARG1"
],
"out": [
"T_ID2",
"T_ARG1"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_RECV",
"desc": "* MG_RECV.pgc - mg 모듈 서비스 MG_RECV (one service = one file).",
"in": [
"T_CHANNEL",
"T_STR1",
"T_STR3",
"T_STR5",
"T_BIZDATE",
"T_AMOUNT"
],
"out": [
"T_ARG1",
"T_ID1"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_RESEND",
"desc": "전문 재전송: STAN 으로 원전문 찾아 큐에 적재. */",
"in": [
"T_ARG1",
"T_CHANNEL",
"T_STR1",
"T_STR3",
"T_BIZDATE"
],
"out": [
"T_ID2"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_RETRY",
"desc": "큐 재시도: retry_cnt +1, status=Q. */",
"in": [
"T_ID2"
],
"out": [
"T_COUNT"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_ROUTE",
"desc": "* MG_ROUTE.pgc - mg 모듈 서비스 MG_ROUTE (one service = one file).",
"in": [
"T_CHANNEL",
"T_STR1"
],
"out": [
"T_RC",
"T_STR3"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_SEND",
"desc": "* MG_SEND.pgc - mg 모듈 서비스 MG_SEND (one service = one file).",
"in": [
"T_CHANNEL",
"T_STR1",
"T_STR3",
"T_BIZDATE",
"T_AMOUNT"
],
"out": [
"T_ARG1",
"T_ID1"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_SESSION",
"desc": "* MG_SESSION.pgc - mg 모듈 서비스 MG_SESSION (one service = one file).",
"in": [],
"out": [
"T_ARG2"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_SIGNOFF",
"desc": "* MG_SIGNOFF.pgc - mg 모듈 서비스 MG_SIGNOFF (one service = one file).",
"in": [
"T_CHANNEL"
],
"out": [
"T_STATUS"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_SIGNON",
"desc": "* MG_SIGNON.pgc - mg 모듈 서비스 MG_SIGNON (one service = one file).",
"in": [
"T_CHANNEL",
"T_KEY1"
],
"out": [
"T_STATUS"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_STAN",
"desc": "* MG_STAN.pgc - mg 모듈 서비스 MG_STAN (one service = one file).",
"in": [],
"out": [
"T_ARG1"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_STATS",
"desc": "채널 당일 통계: 수신/송신/오류 건수. */",
"in": [
"T_CHANNEL",
"T_BIZDATE"
],
"out": [
"T_ARG1",
"T_ARG2",
"T_ARG3",
"T_GROSS"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_STATUS",
"desc": "* MG_STATUS.pgc - mg 모듈 서비스 MG_STATUS (one service = one file).",
"in": [
"T_ID1"
],
"out": [
"T_STATUS"
]
},
{
"mod": "mg",
"modnm": "전문게이트웨이",
"svc": "MG_UNPACK",
"desc": "* MG_UNPACK.pgc - mg 모듈 서비스 MG_UNPACK (one service = one file).",
"in": [
"T_STR3"
],
"out": [
"T_STR1",
"T_STR4",
"T_AMOUNT"
]
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_BIN_INQ",
"desc": "기능: BIN 조회.",
"in": [
"T_KEY1"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_BIN_REG",
"desc": "기능: BIN 마스터 등록.",
"in": [
"T_KEY1",
"T_ISSUER",
"T_STR5"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_CODE_CACHE",
"desc": "기능: 코드그룹의 활성 코드 수 (캐시 워밍 시뮬).",
"in": [
"T_STR1"
],
"out": [
"T_COUNT"
]
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_CODE_INQ",
"desc": "기능: 공통코드 조회.",
"in": [
"T_STR1",
"T_KEY1"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_CODE_REG",
"desc": "기능: 공통코드 등록.",
"in": [
"T_STR1",
"T_KEY1",
"T_STR2"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_CONFIRM",
"desc": "기능: 가맹점 승인 확정 (상태 ACTIVE + 이력).",
"in": [
"T_MERCHANT"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_FEERATE_HIST",
"desc": "기능: 수수료율 변경 이력 건수 (dbio).",
"in": [
"T_MERCHANT"
],
"out": [
"T_COUNT"
]
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_FEERATE_INQ",
"desc": "기능: 수수료율 조회 (dbio).",
"in": [
"T_MERCHANT",
"T_STR4"
],
"out": [
"T_ARG1"
]
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_FEERATE_SET",
"desc": "기능: 수수료율 설정 (dbio upsert + 이력).",
"in": [
"T_MERCHANT",
"T_STR4",
"T_ARG1"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_FX_INQ",
"desc": "기능: 환율 조회 + 금액 환산 (rate_bps는 100 기준 bps).",
"in": [
"T_CCY",
"T_FX_AMT"
],
"out": [
"T_ARG2",
"T_AMOUNT"
]
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_FX_REG",
"desc": "기능: 환율 마스터 upsert.",
"in": [
"T_CCY",
"T_ARG2"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_HOLIDAY_REG",
"desc": "기능: 공휴일 마스터 등록.",
"in": [
"T_BIZDATE",
"T_STR1"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_ISSUER_INQ",
"desc": "기능: 발급사 조회.",
"in": [
"T_ISSUER"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_ISSUER_REG",
"desc": "기능: 발급사 마스터 등록.",
"in": [
"T_ISSUER",
"T_STR1",
"T_STR2"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_LIMIT_INQ",
"desc": "기능: 가맹점 한도 조회.",
"in": [
"T_MERCHANT"
],
"out": [
"T_AMT1",
"T_AMT2",
"T_AMT3"
]
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_LIMIT_SET",
"desc": "기능: 가맹점 한도 설정 (upsert).",
"in": [
"T_MERCHANT",
"T_AMT1",
"T_AMT2",
"T_AMT3"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_MCC_REG",
"desc": "기능: MCC 업종 마스터 등록.",
"in": [
"T_STR6",
"T_STR1",
"T_ARG1"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_MERCH_ACCT",
"desc": "기능: 정산계좌 변경 (직접 UPDATE + 이력).",
"in": [
"T_MERCHANT",
"T_STR3"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_MERCH_BULK",
"desc": "기능: 가맹점 대량 등록 (T_COUNT개 파생 생성).",
"in": [
"T_MERCHANT",
"T_STR2",
"T_COUNT"
],
"out": [
"T_COUNT"
]
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_MERCH_DEL",
"desc": "기능: 가맹점 논리 삭제 (상태 DELETED + 이력).",
"in": [
"T_MERCHANT"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_MERCH_GRADE",
"desc": "기능: 가맹점 등급 변경 (dbio + 이력).",
"in": [
"T_MERCHANT",
"T_STR2"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_MERCH_INQ",
"desc": "기능: 가맹점 마스터 조회 (dbio).",
"in": [
"T_MERCHANT"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_MERCH_REG",
"desc": "기능: 가맹점 확장 마스터 등록 (dbio upsert + 이력).",
"in": [
"T_MERCHANT",
"T_STR1",
"T_STR2",
"T_STR3"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_MERCH_STATUS",
"desc": "기능: 가맹점 상태 변경 (dbio + 이력).",
"in": [
"T_MERCHANT",
"T_STATUS"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_MERCH_SUM",
"desc": "기능: 상태별 가맹점 수 집계 (ACTIVE 기준).",
"in": [
"T_STATUS"
],
"out": [
"T_COUNT"
]
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_MERCH_UPD",
"desc": "기능: 가맹점명/계좌 수정 (직접 UPDATE + 이력).",
"in": [
"T_MERCHANT",
"T_STR1",
"T_STR3"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_STATUS",
"desc": "기능: 서비스 상태 (전체 가맹점 수, RC=0).",
"in": [],
"out": [
"T_COUNT",
"T_RC"
]
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_TERMINAL_INQ",
"desc": "기능: 단말 조회.",
"in": [
"T_STR5"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_TERMINAL_REG",
"desc": "기능: 단말 마스터 등록.",
"in": [
"T_STR5",
"T_MERCHANT",
"T_STR6"
],
"out": []
},
{
"mod": "mm",
"modnm": "마스터",
"svc": "MM_VALIDATE",
"desc": "기능: 가맹점 마스터 정합성 검사 (존재+수수료율 존재).",
"in": [
"T_MERCHANT"
],
"out": [
"T_RC"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_ACCTCHK",
"desc": "지급계좌 유효성 점검: dbio 로 계좌 상태/잔액을 읽어 ACTIVE 여부를 회신.",
"in": [
"T_KEY1"
],
"out": [
"T_RC",
"T_AMT1"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_ADJUST",
"desc": "지급 조정: py_adjust 에 증감(delta)을 기록하고 지급건 net 에 즉시 반영.",
"in": [
"T_ID1",
"T_DELTA",
"T_BIZDATE",
"T_REASON"
],
"out": [
"T_ADJ"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_ADVANCE",
"desc": "선지급(advance): 선지급 수수료(1%)를 공제한 지급건(ADVANCE 채널)을 생성.",
"in": [
"T_MERCHANT",
"T_KEY1",
"T_AMOUNT",
"T_BIZDATE"
],
"out": [
"T_ID1",
"T_FEE",
"T_NET"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_APPROVE",
"desc": "지급 승인: 금액을 먼저 조회한 뒤 요청(R) 상태만 승인(A)으로 전이하고 금액을",
"in": [
"T_ID1"
],
"out": [
"T_AMOUNT",
"T_RC"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_BULK",
"desc": "대량 지급 생성: 동일 금액의 지급건(BULK 채널)을 N건 반복 등록.",
"in": [
"T_MERCHANT",
"T_KEY1",
"T_AMOUNT",
"T_COUNT",
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_CANCEL",
"desc": "지급 취소: 취소 조정(-amount)을 py_adjust 에 기록하고 지급건 상태 C 로 전이.",
"in": [
"T_ID1",
"T_AMOUNT",
"T_BIZDATE",
"T_REASON"
],
"out": [
"T_ADJ"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_CLOSE",
"desc": "일마감: 당일 지급완료(P)건을 마감(X)으로 일괄 전환하고 전환 건수를 회신.",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_CONFIRM",
"desc": "지급 확정(confirm): 지급 파일 상태를 확정(C)으로 전이하고 확정 시각 기록.",
"in": [
"T_ID2"
],
"out": []
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_FEEDED",
"desc": "수수료 공제(fee deduction): bps 로 수수료를 산출해 fee/net 을 재계산·갱신.",
"in": [
"T_ID1",
"T_AMOUNT",
"T_ARG1"
],
"out": [
"T_FEE",
"T_NET"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_FILEGEN",
"desc": "지급 파일 헤더 생성: 당일 승인(A) 지급건 집계 -> py_file.",
"in": [
"T_BIZDATE"
],
"out": [
"T_ID2",
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_HISTORY",
"desc": "가맹점 지급 이력 건수: 해당 가맹점의 전체 지급건 수를 집계해 회신.",
"in": [
"T_MERCHANT"
],
"out": [
"T_COUNT"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_HOLD",
"desc": "지급 보류: 이미 지급완료(P)/마감(X)된 건은 보류 불가 - dbio 로 현재 상태를",
"in": [
"T_ID1"
],
"out": [
"T_RC"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_INQUIRY",
"desc": "지급 단건 상세 조회: 가맹점/계좌/금액/수수료/순액/상태를 한 번에 회신.",
"in": [
"T_ID1"
],
"out": [
"T_AMOUNT",
"T_FEE",
"T_NET"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_INT",
"desc": "선지급 이자 계산: 일할(days) * bps 로 이자와 차감 후 순액을 산출(순수 계산).",
"in": [
"T_AMOUNT",
"T_ARG1",
"T_ARG2"
],
"out": [
"T_AMT1",
"T_NET"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_MERCHSUM",
"desc": "가맹점 당일 지급 집계: py_payout 집계 후 dbio 로 py_summary upsert.",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_NETOFF",
"desc": "상계(net-off): 지급건의 net 을 조회해 차감액을 반영하고 갱신.",
"in": [
"T_ID1",
"T_AMOUNT"
],
"out": [
"T_NET"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_RECON",
"desc": "지급-파일 대사: 특정 file_id 에 편성된 지급 건수/합계를 확인.",
"in": [
"T_ID2"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_REJECT",
"desc": "지급 반려: 상태를 반려(J)로 전이하고 반려 사유를 reject_reason 에 기록.",
"in": [
"T_ID1",
"T_REASON"
],
"out": []
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_RELEASE",
"desc": "보류 해제: 직전 상태를 조회하여 보류(H)가 아니면 무효 처리, 보류면 dbio 로",
"in": [
"T_ID1"
],
"out": [
"T_RC"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_REMIT",
"desc": "실지급 송금: 계좌 잔액을 확인해 부족하면 거절, 충분하면 차감 후 상태 P.",
"in": [
"T_ID1",
"T_NET",
"T_KEY1"
],
"out": [
"T_RC"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_REPROC",
"desc": "재처리: 직전 상태를 조회한 뒤 실패/보류/취소(J,H,C) -> 요청(R) 전이, 이전 상태 회신.",
"in": [
"T_ID1"
],
"out": [
"T_RC"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_RESULT",
"desc": "지급 결과 반영: 편성/요청(F,R) 상태만 지급완료(P)로 전이, 반영 건수를 T_RC 로.",
"in": [
"T_ID1"
],
"out": [
"T_RC"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_RETRY",
"desc": "실패 지급 재시도: 실패/보류(J,H) 건만 요청(R)으로 되돌리고 retry_count 증가.",
"in": [
"T_ID1"
],
"out": [
"T_RC"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_REVERSE",
"desc": "지급 역분개(reverse): 상태 V(역분개)로 전이하고 계좌 잔액을 원복.",
"in": [
"T_ID1",
"T_AMOUNT",
"T_KEY1"
],
"out": []
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_SCHEDULE",
"desc": "지급 예약 등록: 지정 실행일로 py_schedule 예약(S) 레코드를 생성.",
"in": [
"T_ID1",
"T_BIZDATE"
],
"out": [
"T_ID2"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_SPLIT",
"desc": "지급 분할: 금액을 N건으로 나눠 각각의 지급건(SPLIT 채널)으로 생성.",
"in": [
"T_MERCHANT",
"T_KEY1",
"T_AMOUNT",
"T_COUNT",
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_STATEMENT",
"desc": "가맹점 지급 명세: 당일 지급완료(P) 건의 건수/금액/수수료/순액을 집계.",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS",
"T_FEE",
"T_NET"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_STATUS",
"desc": "지급 상태 조회: dbio 로 단건 상태를 읽어 회신.",
"in": [
"T_ID1"
],
"out": []
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_SUMMARY",
"desc": "가맹점 일별 지급 집계 조회: py_summary 에서 건수/금액을 읽어 회신(무행 시 0).",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "py",
"modnm": "지급",
"svc": "PAY_XFERLINK",
"desc": "이체 연계: 지급건에 대한 XFER 원장 엔트리를 py_ledger 에 기록.",
"in": [
"T_ID1",
"T_AMOUNT",
"T_BIZDATE"
],
"out": []
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_3WAY",
"desc": "3-way 대사: 승인+매입+원장 모두 존재 시 MATCHED. */",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_BIZDATE"
],
"out": [
"T_RC"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_ACQ_DEP",
"desc": "매입-입금(원장) 대사: 원장 합계와 net 비교. */",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_BIZDATE"
],
"out": [
"T_GROSS",
"T_RC"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_ALERT",
"desc": "* RC_ALERT.pgc - rc 모듈 서비스 RC_ALERT (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_BIZDATE",
"T_MSG",
"T_STR1"
],
"out": [
"T_ID1"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_AMTDIFF",
"desc": "금액 차이 대사: 기대(net) vs 실제(원장합) 차이 기록. */",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_BIZDATE"
],
"out": [
"T_DELTA"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_APPR_ACQ",
"desc": "* RC_APPR_ACQ.pgc - rc 모듈 서비스 RC_APPR_ACQ (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_BIZDATE"
],
"out": [
"T_ID1",
"T_RC"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_AUTOFIX",
"desc": "자동 보정: 예외 해소 + 보정 원장. */",
"in": [
"T_PURCHASE_ID",
"T_AMOUNT",
"T_BIZDATE"
],
"out": []
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_BYDATE",
"desc": "* RC_BYDATE.pgc - rc 모듈 서비스 RC_BYDATE (one service = one file).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_BYISSUER",
"desc": "* RC_BYISSUER.pgc - rc 모듈 서비스 RC_BYISSUER (one service = one file).",
"in": [
"T_BIZDATE",
"T_ISSUER"
],
"out": [
"T_COUNT"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_BYMERCH",
"desc": "* RC_BYMERCH.pgc - rc 모듈 서비스 RC_BYMERCH (one service = one file).",
"in": [
"T_BIZDATE",
"T_MERCHANT"
],
"out": [
"T_GROSS"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_CNTDIFF",
"desc": "건수 차이 대사: 매입 건수 vs 대사 로그 건수. */",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_CONFIRM",
"desc": "* RC_CONFIRM.pgc - rc 모듈 서비스 RC_CONFIRM (one service = one file).",
"in": [
"T_PURCHASE_ID"
],
"out": []
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_DELAY",
"desc": "* RC_DELAY.pgc - rc 모듈 서비스 RC_DELAY (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_BIZDATE"
],
"out": [
"T_ID1"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_DIFFRPT",
"desc": "* RC_DIFFRPT.pgc - rc 모듈 서비스 RC_DIFFRPT (one service = one file).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_DELTA"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_EXCEPTION",
"desc": "* RC_EXCEPTION.pgc - rc 모듈 서비스 RC_EXCEPTION (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_BIZDATE",
"T_REASON"
],
"out": [
"T_ID1"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_HOLD",
"desc": "* RC_HOLD.pgc - rc 모듈 서비스 RC_HOLD (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_BIZDATE"
],
"out": []
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_LEDGERLINK",
"desc": "* RC_LEDGERLINK.pgc - rc 모듈 서비스 RC_LEDGERLINK (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_BIZDATE"
],
"out": []
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_MANUAL",
"desc": "* RC_MANUAL.pgc - rc 모듈 서비스 RC_MANUAL (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_BIZDATE"
],
"out": [
"T_ID1"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_PARTIAL",
"desc": "* RC_PARTIAL.pgc - rc 모듈 서비스 RC_PARTIAL (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_AMOUNT",
"T_BIZDATE"
],
"out": [
"T_ID1"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_PROGRESS",
"desc": "* RC_PROGRESS.pgc - rc 모듈 서비스 RC_PROGRESS (one service = one file).",
"in": [
"T_BIZDATE"
],
"out": [
"T_RC"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_RELEASE",
"desc": "* RC_RELEASE.pgc - rc 모듈 서비스 RC_RELEASE (one service = one file).",
"in": [
"T_PURCHASE_ID"
],
"out": []
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_REMATCH",
"desc": "* RC_REMATCH.pgc - rc 모듈 서비스 RC_REMATCH (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_BIZDATE"
],
"out": []
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_REPROC",
"desc": "재처리: EXCEPTION 대사 로그를 MATCHED 로 되돌림. */",
"in": [
"T_PURCHASE_ID"
],
"out": []
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_RETURN",
"desc": "반품 대사: 반품 원장 + 음수 대사 로그. */",
"in": [
"T_PURCHASE_ID",
"T_AMOUNT",
"T_BIZDATE"
],
"out": [
"T_ID1"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_ROLLBACK",
"desc": "* RC_ROLLBACK.pgc - rc 모듈 서비스 RC_ROLLBACK (one service = one file).",
"in": [
"T_PURCHASE_ID"
],
"out": []
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_STATS",
"desc": "* RC_STATS.pgc - rc 모듈 서비스 RC_STATS (one service = one file).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_RC"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_STATUS",
"desc": "* RC_STATUS.pgc - rc 모듈 서비스 RC_STATUS (one service = one file).",
"in": [
"T_PURCHASE_ID"
],
"out": []
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_SUMMARY",
"desc": "* RC_SUMMARY.pgc - rc 모듈 서비스 RC_SUMMARY (one service = one file).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_TOLERANCE",
"desc": "허용오차 대사: |차이| <= 허용치면 MATCHED. */",
"in": [
"T_PURCHASE_ID",
"T_DELTA",
"T_ARG1",
"T_BIZDATE"
],
"out": [
"T_RC"
]
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RC_UNMATCH",
"desc": "* RC_UNMATCH.pgc - rc 모듈 서비스 RC_UNMATCH (one service = one file).",
"in": [
"T_BIZDATE"
],
"out": []
},
{
"mod": "rc",
"modnm": "대사",
"svc": "RECONCILE",
"desc": "* RECONCILE.pgc - rc 모듈 서비스 RECONCILE (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_BIZDATE"
],
"out": []
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "SETTLE",
"desc": "* SETTLE.pgc - st 모듈 서비스 SETTLE (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_SETTLE_ID"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_ADJUST",
"desc": "* ST_ADJUST.pgc - st 모듈 서비스 ST_ADJUST (one service = one file).",
"in": [
"T_SETTLE_ID",
"T_PURCHASE_ID",
"T_DELTA",
"T_BIZDATE",
"T_REASON"
],
"out": [
"T_ADJ"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_ADVANCE",
"desc": "선지급 예약: 지급 레코드(SCHEDULED) 생성 (dbio). */",
"in": [
"T_NET",
"T_MERCHANT",
"T_BIZDATE",
"T_KEY1"
],
"out": [
"T_ID1"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_BANDRATE",
"desc": "* ST_BANDRATE.pgc - st 모듈 서비스 ST_BANDRATE (one service = one file).",
"in": [
"T_AMOUNT",
"T_STR1"
],
"out": [
"T_RC"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_BYMERCH",
"desc": "* ST_BYMERCH.pgc - st 모듈 서비스 ST_BYMERCH (one service = one file).",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_CANCEL",
"desc": "정산 취소: 상태 CANCELLED + 취소 조정 (dbio). */",
"in": [
"T_PURCHASE_ID",
"T_BIZDATE"
],
"out": []
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_CAP",
"desc": "수수료 상한 적용: 상한 초과분을 감액 조정 (dbio). */",
"in": [
"T_SETTLE_ID",
"T_PURCHASE_ID",
"T_FEE",
"T_ARG1",
"T_BIZDATE"
],
"out": [
"T_FEE",
"T_DELTA"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_CONFIRM",
"desc": "* ST_CONFIRM.pgc - st 모듈 서비스 ST_CONFIRM (one service = one file).",
"in": [
"T_PURCHASE_ID"
],
"out": []
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_DELAYINT",
"desc": "* ST_DELAYINT.pgc - st 모듈 서비스 ST_DELAYINT (one service = one file).",
"in": [
"T_SETTLE_ID",
"T_PURCHASE_ID",
"T_NET",
"T_ARG1",
"T_ARG2",
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_AMOUNT"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_DIFFCHK",
"desc": "* ST_DIFFCHK.pgc - st 모듈 서비스 ST_DIFFCHK (one service = one file).",
"in": [
"T_PURCHASE_ID"
],
"out": [
"T_DELTA",
"T_RC"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_FXCONV",
"desc": "외화 환산: fx * rate/100 = KRW. */",
"in": [
"T_FX_AMT",
"T_ARG1"
],
"out": [
"T_AMOUNT"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_HOLD",
"desc": "* ST_HOLD.pgc - st 모듈 서비스 ST_HOLD (one service = one file).",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": []
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_LEDGERLINK",
"desc": "* ST_LEDGERLINK.pgc - st 모듈 서비스 ST_LEDGERLINK (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_BIZDATE"
],
"out": []
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_MDR",
"desc": "* ST_MDR.pgc - st 모듈 서비스 ST_MDR (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_FEE",
"T_BIZDATE"
],
"out": []
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_MONTHLY",
"desc": "* ST_MONTHLY.pgc - st 모듈 서비스 ST_MONTHLY (one service = one file).",
"in": [
"T_MERCHANT",
"T_KEY1"
],
"out": [
"T_GROSS"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_NETTING",
"desc": "* ST_NETTING.pgc - st 모듈 서비스 ST_NETTING (one service = one file).",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_GROSS"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_OFFSET",
"desc": "상계: 음수 조정으로 채권 상계 기록 (dbio). */",
"in": [
"T_SETTLE_ID",
"T_PURCHASE_ID",
"T_AMOUNT",
"T_BIZDATE"
],
"out": [
"T_ADJ"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_PAYDATE",
"desc": "* ST_PAYDATE.pgc - st 모듈 서비스 ST_PAYDATE (one service = one file).",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": []
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_RATEAPPLY",
"desc": "* ST_RATEAPPLY.pgc - st 모듈 서비스 ST_RATEAPPLY (one service = one file).",
"in": [
"T_SETTLE_ID",
"T_PURCHASE_ID",
"T_AMOUNT",
"T_MERCHANT",
"T_BIZDATE",
"T_STR1"
],
"out": [
"T_FEE",
"T_RC"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_RECALC",
"desc": "* ST_RECALC.pgc - st 모듈 서비스 ST_RECALC (one service = one file).",
"in": [
"T_PURCHASE_ID"
],
"out": [
"T_NET"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_RELAYFEE",
"desc": "중계 수수료: 구간요율 조회 후 정산 상세 기록 (dbio). */",
"in": [
"T_SETTLE_ID",
"T_PURCHASE_ID",
"T_AMOUNT",
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_FEE"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_RELEASE",
"desc": "* ST_RELEASE.pgc - st 모듈 서비스 ST_RELEASE (one service = one file).",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": []
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_REPORT",
"desc": "* ST_REPORT.pgc - st 모듈 서비스 ST_REPORT (one service = one file).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_SPLIT",
"desc": "분할 지급: net 을 n 회로 나눠 지급 레코드 생성 (dbio 루프). */",
"in": [
"T_NET",
"T_INSTALL_N",
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_STATS",
"desc": "* ST_STATS.pgc - st 모듈 서비스 ST_STATS (one service = one file).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS",
"T_AMT1"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_STATUS",
"desc": "* ST_STATUS.pgc - st 모듈 서비스 ST_STATUS (one service = one file).",
"in": [
"T_PURCHASE_ID"
],
"out": []
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_VANFEE",
"desc": "VAN 수수료: 구간요율 조회 후 정산 상세 기록 (dbio). */",
"in": [
"T_SETTLE_ID",
"T_PURCHASE_ID",
"T_AMOUNT",
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_FEE"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_VAT",
"desc": "* ST_VAT.pgc - st 모듈 서비스 ST_VAT (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_FEE",
"T_BIZDATE"
],
"out": [
"T_TAX"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_WHT",
"desc": "* ST_WHT.pgc - st 모듈 서비스 ST_WHT (one service = one file).",
"in": [
"T_SETTLE_ID",
"T_PURCHASE_ID",
"T_FEE",
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_TAX"
]
},
{
"mod": "st",
"modnm": "정산/수수료",
"svc": "ST_XFERLINK",
"desc": "* ST_XFERLINK.pgc - st 모듈 서비스 ST_XFERLINK (one service = one file).",
"in": [
"T_PURCHASE_ID",
"T_NET",
"T_BIZDATE"
],
"out": []
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_AMOUNT",
"desc": "기능: 금액 유효성(0<amt<=규칙 AMT_MAX) 검증 (RC 1=0/음수,2=상한초과).",
"in": [
"T_AMOUNT"
],
"out": [
"T_RC",
"T_ARG1"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_ANOMALY",
"desc": "기능: 이상거래 탐지 후 의심거래 적재 (dbio).",
"in": [
"T_PURCHASE_ID",
"T_BIZDATE"
],
"out": [
"T_RC",
"T_ID1"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_APPR_ACQ",
"desc": "기능: 승인-매입 매칭 검증 (RC 1=승인 없음).",
"in": [
"T_PURCHASE_ID"
],
"out": [
"T_COUNT",
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_BALANCE",
"desc": "기능: 가맹점 순액 대차 검증 (sum(purchase.net) vs sum(settlement.net)).",
"in": [
"T_MERCHANT",
"T_BIZDATE"
],
"out": [
"T_GROSS",
"T_NET",
"T_DELTA",
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_BATCH_CHK",
"desc": "기능: 배치 정합(purchase 건수 vs merchant_summary.txn_count).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_GROSS",
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_BIN",
"desc": "기능: BIN 유효성 검증 vs mm_bin (RC 1=미등록,2=비활성).",
"in": [
"T_KEY1"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_CARD",
"desc": "기능: 카드번호 Luhn 검증 (RC 1=체크섬 불일치).",
"in": [
"T_STR1"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_CODEVAL",
"desc": "기능: 공통코드 유효성 검증 vs mm_code (RC 1=미존재).",
"in": [
"T_STR3",
"T_KEY1"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_CONFIRM",
"desc": "기능: 의심거래 종결 확정 (status CLOSED by suspect_id).",
"in": [
"T_ID1"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_CROSSCHK",
"desc": "기능: 교차검증(매입+가맹점+승인 동시 존재, RC 비트합).",
"in": [
"T_PURCHASE_ID"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_DATE",
"desc": "기능: 영업일 유효성(미래일자 금지) 검증 (RC 1=미래).",
"in": [
"T_BIZDATE"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_DUP",
"desc": "기능: 중복 매입 검증 (동일 가맹점/금액/영업일 2건 이상 → RC 1).",
"in": [
"T_MERCHANT",
"T_BIZDATE",
"T_AMOUNT"
],
"out": [
"T_COUNT",
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_DUPAUTH",
"desc": "기능: 중복 승인 검증 (approval 2건 이상 → RC 1).",
"in": [
"T_PURCHASE_ID"
],
"out": [
"T_COUNT",
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_EXPIRY",
"desc": "기능: 카드 유효기간(YYYYMM) vs 영업일 검증 (RC 1=만료).",
"in": [
"T_STR2",
"T_BIZDATE"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_FEE",
"desc": "기능: 수수료 재계산 정합 검증 (저장 fee vs MDR 재계산, RC 1=불일치).",
"in": [
"T_PURCHASE_ID"
],
"out": [
"T_RC",
"T_FEE",
"T_DELTA"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_FORMAT",
"desc": "기능: 가맹점ID 형식(길이 4~16) 검증 (RC 1=형식 위반).",
"in": [
"T_MERCHANT"
],
"out": [
"T_COUNT",
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_LEDGER",
"desc": "기능: 원장 합계 정합 검증 (sum(ledger) vs purchase.net, RC 1=불일치).",
"in": [
"T_PURCHASE_ID",
"T_BIZDATE"
],
"out": [
"T_RC",
"T_GROSS"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_LIMIT",
"desc": "기능: 매입금액 vs 가맹점 일한도 검증 (RC 1=초과).",
"in": [
"T_MERCHANT",
"T_AMOUNT"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_MERCH",
"desc": "기능: 가맹점 상태 검증 (merchant.status != ACTIVE → RC 1).",
"in": [
"T_MERCHANT"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_REFINTEG",
"desc": "기능: 참조무결성(purchase.merchant_id ∈ merchant) 검증.",
"in": [
"T_PURCHASE_ID"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_REPORT",
"desc": "기능: 심각도별 의심거래 건수 리포트.",
"in": [
"T_STR4",
"T_BIZDATE"
],
"out": [
"T_COUNT"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_REQUIRED",
"desc": "기능: 필수필드(가맹점/금액) 존재 검증 (RC 비트합).",
"in": [
"T_MERCHANT",
"T_AMOUNT"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_RULE",
"desc": "기능: 검증 규칙 등록/갱신 (dbio upsert).",
"in": [
"T_STR3",
"T_STR1",
"T_STR4",
"T_ARG1"
],
"out": []
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_SALES",
"desc": "기능: 매입 원거래 존재 검증 (RC 1=미존재).",
"in": [
"T_PURCHASE_ID",
"T_BIZDATE"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_SETTLE",
"desc": "기능: 정산금액 정합 검증 (settlement.net vs purchase.net, RC 1=불일치).",
"in": [
"T_PURCHASE_ID"
],
"out": [
"T_RC",
"T_NET"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_STATUS",
"desc": "기능: 서비스 상태 (전체 OPEN 의심거래 수, RC=0).",
"in": [],
"out": [
"T_COUNT",
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_STATUS_CHK",
"desc": "기능: 매입 상태 유효값 검증 (허용집합 밖 → RC 1).",
"in": [
"T_PURCHASE_ID"
],
"out": [
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_SUMMARY",
"desc": "기능: 당일 미결(OPEN) 의심거래 요약 (dbio).",
"in": [
"T_BIZDATE"
],
"out": [
"T_COUNT",
"T_RC"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_THRESHOLD",
"desc": "기능: 규칙 임계치 검사 (dbio get_rule; amount>threshold → RC 1).",
"in": [
"T_STR3",
"T_AMOUNT"
],
"out": [
"T_RC",
"T_ARG1"
]
},
{
"mod": "vl",
"modnm": "정합성검증",
"svc": "VL_TOLERANCE",
"desc": "기능: 금액 허용오차(amount == fee+net ± tol) 검증 (RC 1=초과).",
"in": [
"T_PURCHASE_ID",
"T_ARG1"
],
"out": [
"T_RC",
"T_DELTA"
]
}
];
</script>
<script>
window.onerror = function(m, src, line){
var e=document.getElementById('stmsg');
if(e){ e.textContent='JS 오류: '+m+' ('+(src||'').split('/').pop()+':'+line+')'; e.style.color='#c22'; }
};
/* ───────── 공통 ───────── */
const today = new Date().toISOString().slice(0,10).replace(/-/g,'');
document.getElementById('bizdate').textContent = today;
const fmtN = v => (v===null||v===undefined||v==='') ? '' : (/^-?\d+$/.test(String(v)) ? Number(v).toLocaleString('ko-KR') : v);
const STMAP = { A:['접수','bA'], M:['대사','bM'], S:['정산완료','bS'], C:['취소','bC'], H:['보류','bH'], V:['VOID','bV'],
ACTIVE:['정상','bS'], HOLD:['보류','bH'], PENDING:['심사중','bM'], SETTLED:['지급완료','bS'] };
const badge = v => { const m=STMAP[v]; return m? `<span class="bdg ${m[1]}">${m[0]}</span>` : v; };
const setStatus = (m, err) => { const e=document.getElementById('stmsg'); e.textContent=m; e.style.color=err?'#c22':'#345'; };
async function runQuery(sql){ try { return await (await fetch('api/query?q='+encodeURIComponent(sql))).json(); } catch(e){ return {ok:false,error:String(e)}; } }
async function callSvc(svc, fields, tx){
const p = new URLSearchParams({svc, _tx: tx?1:0});
Object.entries(fields||{}).forEach(([k,v])=>{ if(v!=='') p.append(k,v); });
try { return await (await fetch('api/call?'+p.toString())).json(); } catch(e){ return {ok:false,error:String(e)}; }
}
const LBL = {
T_MERCHANT:"가맹점번호", T_AMOUNT:"금액(원)", T_FEE:"수수료", T_NET:"정산액", T_STATUS:"상태",
T_PURCHASE_ID:"매입번호", T_BIZDATE:"영업일자", T_SETTLE_ID:"정산번호", T_MSG:"메시지",
T_CANCEL_ID:"취소번호", T_INSTALL_N:"할부개월", T_TAX:"세액", T_FX_AMT:"외화금액", T_COUNT:"건수",
T_REASON:"사유", T_CATEGORY:"업종분류", T_ISSUER:"발급사", T_CHANNEL:"채널", T_CCY:"통화",
T_ADJ:"조정번호", T_DELTA:"증감액", T_SVCNAME:"서비스명", T_RC:"결과코드", T_GROSS:"총액", T_DOCNO:"문서번호",
T_KEY1:"키1(카드/계좌)", T_KEY2:"키2", T_ID1:"번호1", T_ID2:"번호2",
};
for (let i=1;i<=8;i++){ LBL['T_ARG'+i]='인자'+i; LBL['T_STR'+i]='문자'+i; }
for (let i=1;i<=4;i++){ LBL['T_AMT'+i]='금액'+i; }
const DEF = {
T_MERCHANT:"M0001", T_AMOUNT:"1000000", T_BIZDATE:today, T_PURCHASE_ID:"1001", T_SETTLE_ID:"3001",
T_CANCEL_ID:"1", T_ADJ:"1", T_ID1:"5001", T_ID2:"1", T_INSTALL_N:"3", T_COUNT:"10",
T_CCY:"KRW", T_CHANNEL:"POS", T_ISSUER:"BC", T_CATEGORY:"5411", T_STATUS:"A",
T_KEY1:"4111111111111111", T_STR5:"4111111111111111", T_FEE:"2500", T_DOCNO:"D0001",
T_SVCNAME:"ACQUIRE", T_GROSS:"0", T_DELTA:"0", T_TAX:"0", T_FX_AMT:"0",
};
const dflt = f => DEF[f] !== undefined ? DEF[f] : (/T_(ARG|AMT)/.test(f) ? "0" : "");
const READONLY = /(_INQ|_CHK|STATUS|SUMMARY|STATS|HISTORY|REPORT|_SUM|BALCHK|LUHN|CRC|WEEKDAY|MONTHEND|BIZDAY|CODENAME|VALIDATE|PROGRESS|VERIFY|DIFFCHK|INQUIRY|TRIALBAL)/;
/* ───────── 그리드 컴포넌트 (정렬·페이징·CSV·합계·행클릭) ───────── */
const __G = {}; let __gid = 0;
function grid(el, data, opt={}){
if (!data.ok) { el.innerHTML = `<span class="err">${data.error||'조회 실패'}</span>`; return; }
const id = 'g' + (++__gid);
const g = { el, data, opt, st: { sort: null, dir: 1, page: 0, psz: opt.psz || 15 } };
__G[id] = g;
const sorted = () => {
let view = [...g.data.rows];
if (g.st.sort !== null) {
const i = g.st.sort;
view.sort((a,b) => { const x=a[i], y=b[i];
return (/^-?\d+$/.test(x) && /^-?\d+$/.test(y) ? Number(x)-Number(y) : String(x).localeCompare(String(y))) * g.st.dir; });
}
return view;
};
g.render = () => {
const { cols, rows } = g.data, st = g.st;
const view = sorted();
const np = Math.max(1, Math.ceil(view.length / st.psz));
if (st.page >= np) st.page = np - 1;
const pg = view.slice(st.page*st.psz, (st.page+1)*st.psz);
const isNum = cols.map((_,i) => rows.length > 0 && rows.every(r => r[i]==='' || /^-?\d+$/.test(r[i])));
const doSum = cols.map((c,i) => isNum[i] && /금액|수수료|정산액|지급액|건수|합계|세액/.test(c));
let h = `<div class="gtools"><span>총 <b>${rows.length.toLocaleString()}</b>건</span><span class="sp"></span>
<button onclick="__G['${id}'].csv()">CSV 저장</button>
<button onclick="__G['${id}'].pg(-1)">◀ 이전</button><span>${st.page+1} / ${np}</span><button onclick="__G['${id}'].pg(1)">다음 ▶</button></div>`;
h += '<table class="grd"><tr>' + cols.map((c,i) =>
`<th onclick="__G['${id}'].sort(${i})">${c}${st.sort===i ? `<span class="sa">${st.dir>0?'▲':'▼'}</span>`:''}</th>`).join('') + '</tr>';
h += pg.map((r,ri) => `<tr class="${opt.onRow?'rw':''}" ${opt.onRow?`onclick="__G['${id}'].row(${st.page*st.psz+ri})"`:''}>` +
r.map((v,i) => `<td class="${isNum[i]?'num':''}">${cols[i]==='상태'?badge(v):fmtN(v)}</td>`).join('') + '</tr>').join('');
if (doSum.some(Boolean) && rows.length > 1)
h += '<tr class="sum">' + cols.map((c,i) => doSum[i]
? `<td class="num">${fmtN(rows.reduce((s,r)=>s+Number(r[i]||0),0))}</td>`
: `<td>${i===0?'합계':''}</td>`).join('') + '</tr>';
h += '</table>';
el.innerHTML = h;
};
g.sort = i => { g.st.dir = (g.st.sort===i) ? -g.st.dir : 1; g.st.sort = i; g.render(); };
g.pg = d => { g.st.page = Math.max(0, g.st.page + d); g.render(); };
g.row = i => { opt.onRow(sorted()[i]); };
g.csv = () => {
const csv = '' + [g.data.cols.join(','), ...g.data.rows.map(r=>r.map(v=>`"${String(v).replace(/"/g,'""')}"`).join(','))].join('\n');
const a = document.createElement('a');
a.href = URL.createObjectURL(new Blob([csv], {type:'text/csv;charset=utf-8'}));
a.download = (opt.name||'grid') + '_' + today + '.csv'; a.click();
};
g.render();
}
/* ───────── MDI 탭 ───────── */
const TABS = {}; let activeTab = null;
const tabbar = document.getElementById('tabbar'), work = document.getElementById('work');
function openTab(key, title, renderFn){
if (TABS[key]) return focusTab(key);
const pane = document.createElement('div'); pane.className = 'tabpane'; work.appendChild(pane);
const tab = document.createElement('span'); tab.className = 'tab';
tab.innerHTML = `<span class="tnm">${title}</span><span class="x">✕</span>`;
tab.onclick = e => { if (!e.target.classList.contains('x')) focusTab(key); };
tab.querySelector('.x').onclick = e => { e.stopPropagation(); closeTab(key); };
tabbar.appendChild(tab);
TABS[key] = { pane, tab, title };
renderFn(pane);
focusTab(key);
}
function focusTab(key){
Object.entries(TABS).forEach(([k,t]) => { t.pane.classList.toggle('on', k===key); t.tab.classList.toggle('on', k===key); });
activeTab = key;
}
function closeTab(key){
const t = TABS[key]; if (!t) return;
t.pane.remove(); t.tab.remove(); delete TABS[key];
if (activeTab === key) { const ks = Object.keys(TABS); if (ks.length) focusTab(ks[ks.length-1]); else activeTab = null; }
}
/* ───────── 매입 상세 팝업 (연계조회 + 보류/취소 액션) ───────── */
function closePop(){ document.getElementById('ovl').classList.remove('show'); }
async function openPurchaseDetail(pid){
const ovl = document.getElementById('ovl'), bd = document.getElementById('pbd');
document.getElementById('ptit').textContent = `매입 상세조회 — 매입번호 ${pid}`;
bd.innerHTML = '조회 중 ...'; ovl.classList.add('show');
const [p, ap, st, lg] = await Promise.all([
runQuery(`select p.purchase_id 매입번호, p.biz_date 영업일, p.merchant_id 가맹점번호, m.name 상호, p.amount 매입금액, p.fee 수수료, p.net 정산액, p.status 상태, p.channel 채널, p.issuer 발급사, p.category 업종, to_char(p.created_at,'YYYY-MM-DD HH24:MI:SS') 접수시각 from purchase p join merchant m on m.merchant_id=p.merchant_id where p.purchase_id=${pid}`),
runQuery(`select approval_id 승인번호, case when approved then '승인' else '거절' end 결과, to_char(approved_at,'YYYY-MM-DD HH24:MI:SS') 승인시각 from approval where purchase_id=${pid}`),
runQuery(`select settlement_id 정산번호, net 지급액, status 상태, to_char(settled_at,'YYYY-MM-DD HH24:MI') 지급시각 from settlement where purchase_id=${pid}`),
runQuery(`select ledger_id 전표번호, entry_type 유형, amount 금액, biz_date 영업일 from ledger where purchase_id=${pid} order by ledger_id`),
]);
let info = '<span class="err">매입 없음</span>', stv = '';
if (p.ok && p.rows.length) {
stv = p.rows[0][p.cols.indexOf('상태')];
info = '<table class="frm">' + p.cols.map((c,i) =>
`<tr><th>${c}</th><td>${c==='상태'?badge(p.rows[0][i]):fmtN(p.rows[0][i])}</td></tr>`).join('') + '</table>';
}
bd.innerHTML = `
<div style="display:flex;gap:12px">
<div class="panel" style="flex:1"><h3>매입 원장</h3><div class="bd">${info}</div></div>
<div style="flex:1.2">
<div class="panel"><h3>승인 연계</h3><div class="bd" id="pp_ap"></div></div>
<div class="panel"><h3>정산 연계</h3><div class="bd" id="pp_st"></div></div>
<div class="panel"><h3>원장 기표 (복식)</h3><div class="bd" id="pp_lg"></div></div>
</div>
</div>
<div class="btnrow">
<button class="warn" ${['A','M'].includes(stv)?'':'disabled'} onclick="actHold(${pid})">보류 처리 (ACQ_HOLD)</button>
<button class="dang" ${['A','M','H'].includes(stv)?'':'disabled'} onclick="actCancel(${pid})">매입 취소 (ACQ_CANCEL·XA)</button>
<button onclick="closePop()">닫기</button>
</div>`;
grid(document.getElementById('pp_ap'), ap, {psz:3});
grid(document.getElementById('pp_st'), st, {psz:3});
grid(document.getElementById('pp_lg'), lg, {psz:5});
}
async function actHold(pid){
const j = await callSvc('ACQ_HOLD', {T_PURCHASE_ID: pid}, true);
jlog('POP', 'ACQ_HOLD', true, j);
alert(j.ok ? `보류 처리 완료 (반영 ${(j.fields||{}).T_RC||0}건)` : `실패: ${j.error}`);
openPurchaseDetail(pid);
}
async function actCancel(pid){
const reason = prompt('취소 사유를 입력하세요', '가맹점 요청');
if (reason === null) return;
const j = await callSvc('ACQ_CANCEL', {T_PURCHASE_ID: pid, T_BIZDATE: today, T_REASON: reason}, true);
jlog('POP', 'ACQ_CANCEL', true, j);
alert(j.ok ? `취소 접수 완료 (취소번호 ${(j.fields||{}).T_CANCEL_ID||'-'})` : `실패: ${j.error}`);
openPurchaseDetail(pid);
}
/* ───────── 거래 저널 ───────── */
const journal = [];
function jlog(cd, svc, tx, j){
journal.unshift({ t:new Date().toLocaleTimeString('ko-KR'), cd, svc, tx: tx?'Y':'N', ok: j.ok,
sum: j.ok ? Object.entries(j.fields||{}).slice(0,4).map(([k,v])=>`${k}=${v}`).join(' ') : (j.error||'').slice(0,70) });
document.querySelectorAll('.jgrid').forEach(renderJournalIn);
}
function renderJournalIn(g){
g.innerHTML = '<tr><th>시각</th><th>화면</th><th>서비스</th><th>XA</th><th>결과</th><th>요약</th></tr>' +
journal.slice(0,30).map(r=>`<tr><td>${r.t}</td><td>${r.cd}</td><td>${r.svc}</td><td>${r.tx}</td>
<td class="${r.ok?'ok':'err'}">${r.ok?'정상':'오류'}</td><td>${r.sum}</td></tr>`).join('');
}
/* ───────── 조회/현황 화면 정의 ───────── */
const QSCREENS = [
{cd:'HM0001', nm:'운영 대시보드', dash:true},
{cd:'QR0101', nm:'매입 목록 조회', filters:[['from','시작일','2026-07-01'],['to','종료일','2026-07-19'],['merch','가맹점번호(선택)',''],['st','상태(선택)','']],
detail:true,
sql:f=>`select p.purchase_id 매입번호, p.biz_date 영업일, p.merchant_id 가맹점번호, m.name 상호, p.amount 매입금액, p.fee 수수료, p.net 정산액, p.status 상태, p.channel 채널, p.issuer 발급사 from purchase p join merchant m on m.merchant_id=p.merchant_id where p.biz_date between '${f.from}' and '${f.to}' ${f.merch?`and p.merchant_id='${f.merch}'`:''} ${f.st?`and p.status='${f.st}'`:''} order by p.purchase_id desc limit 500`},
{cd:'QR0201', nm:'정산 목록 조회', filters:[['from','시작일','2026-07-01'],['to','종료일','2026-07-19']],
sql:f=>`select s.settlement_id 정산번호, s.biz_date 영업일, s.merchant_id 가맹점번호, m.name 상호, s.net 지급액, s.status 상태, to_char(s.settled_at,'MM-DD HH24:MI') 지급시각 from settlement s join merchant m on m.merchant_id=s.merchant_id where s.biz_date between '${f.from}' and '${f.to}' order by s.settlement_id desc limit 500`},
{cd:'QR0301', nm:'가맹점 관리', merch:true},
{cd:'QR0401', nm:'일자별 실적 집계', filters:[['from','시작일','2026-06-20'],['to','종료일','2026-07-19']],
sql:f=>`select biz_date 영업일, count(*) 건수, sum(amount) 매입금액, sum(fee) 수수료, sum(net) 정산액, count(*) filter (where status='S') 정산완료, count(*) filter (where status in ('A','M')) 진행중 from purchase where biz_date between '${f.from}' and '${f.to}' group by biz_date order by biz_date desc limit 200`},
{cd:'QR0501', nm:'원장 조회', filters:[['from','시작일','2026-07-10'],['to','종료일','2026-07-19']],
sql:f=>`select l.ledger_id 전표번호, l.biz_date 영업일, l.entry_type 유형, l.purchase_id 매입번호, l.amount 금액 from ledger l where l.biz_date between '${f.from}' and '${f.to}' order by l.ledger_id desc limit 500`},
{cd:'QR0601', nm:'채널·발급사 분석', filters:[['from','시작일','2026-07-01'],['to','종료일','2026-07-19']],
sql:f=>`select channel 채널, issuer 발급사, count(*) 건수, sum(amount) 매입금액, round(avg(amount)) 평균금액 from purchase where biz_date between '${f.from}' and '${f.to}' group by channel, issuer order by 4 desc limit 200`},
];
function renderQueryIn(pane, q){
const fid = 'qf' + q.cd;
const f = (q.filters||[]).map(([id,label,dv]) =>
`<tr><th>${label}</th><td><input type="text" id="${fid}_${id}" value="${dv}"></td></tr>`).join('');
pane.innerHTML = `
<div class="panel"><h3>${q.cd} · ${q.nm}${q.detail?' — <span style="font-weight:normal;color:#667">행 클릭 = 상세 팝업(승인·정산·원장 연계, 보류/취소 처리)</span>':''}</h3><div class="bd">
<table class="frm">${f||'<tr><th>조건</th><td style="color:#889">전체 조회</td></tr>'}</table>
<div class="btnrow"><button class="pri" id="${fid}_run">조회</button></div>
</div></div>
<div class="panel"><h3>조회 결과</h3><div class="bd" id="${fid}_grid" style="overflow:auto">조회 중 ...</div></div>`;
const run = async () => {
const fv = {}; (q.filters||[]).forEach(([id]) => { fv[id] = document.getElementById(`${fid}_${id}`).value || ''; });
setStatus('조회 중 ...');
const j = await runQuery(q.sql(fv));
grid(document.getElementById(`${fid}_grid`), j, {
name: q.cd, psz: 15,
onRow: q.detail ? (r => openPurchaseDetail(r[0])) : null,
});
setStatus(j.ok ? `${q.nm}${j.rows.length}건 조회` : '조회 실패', !j.ok);
};
document.getElementById(`${fid}_run`).onclick = run;
run();
}
/* ───────── 운영 대시보드 ───────── */
async function renderDashIn(pane){
pane.innerHTML = `
<div class="panel"><h3>HM0001 · 운영 대시보드 — 글로벌 매입 현황</h3><div class="bd"><div class="cards" id="dcards">로딩...</div></div></div>
<div class="panel"><h3>최근 매입 거래 <span style="font-weight:normal;color:#667">— 행 클릭 시 상세</span></h3><div class="bd" id="drecent" style="overflow:auto">로딩...</div></div>
<div style="display:flex; gap:12px">
<div class="panel" style="flex:1"><h3>당월 가맹점 TOP 7</h3><div class="bd" id="dtop">로딩...</div></div>
<div class="panel" style="flex:1"><h3>최근 7영업일 실적</h3><div class="bd" id="ddaily">로딩...</div></div>
</div>`;
const k = await runQuery(`select to_char((select max(biz_date) from purchase),'YYYY-MM-DD') 기준일,(select count(*) from purchase where biz_date=(select max(biz_date) from purchase)) 오늘건수,(select coalesce(sum(amount),0) from purchase where biz_date=(select max(biz_date) from purchase)) 오늘매입액,(select count(*) from purchase where date_trunc('month',biz_date)=date_trunc('month',(select max(biz_date) from purchase))) 당월건수,(select coalesce(sum(amount),0) from purchase where date_trunc('month',biz_date)=date_trunc('month',(select max(biz_date) from purchase))) 당월매입액,(select count(*) from merchant where status='ACTIVE') 활성가맹점,(select count(*) from purchase where status in ('A','M','H')) 미정산건`);
document.getElementById('dcards').innerHTML = k.ok
? k.cols.map((n,i)=>`<div class="card"><div class="cl">${n}</div><div class="cv">${fmtN(k.rows[0][i])}</div></div>`).join('')
: `<span class="err">${k.error}</span>`;
const r = await runQuery(`select p.purchase_id 매입번호, p.biz_date 영업일, m.name 가맹점, p.amount 금액, p.fee 수수료, p.status 상태, p.channel 채널, p.issuer 발급사 from purchase p join merchant m on m.merchant_id=p.merchant_id order by p.purchase_id desc limit 40`);
grid(document.getElementById('drecent'), r, {psz:10, name:'recent', onRow: rr => openPurchaseDetail(rr[0])});
const t = await runQuery(`select m.name 가맹점, count(*) 건수, sum(p.amount) 매입금액 from purchase p join merchant m on m.merchant_id=p.merchant_id where date_trunc('month',p.biz_date)=date_trunc('month',(select max(biz_date) from purchase)) group by m.name order by 3 desc limit 7`);
grid(document.getElementById('dtop'), t, {psz:7});
const d = await runQuery(`select biz_date 영업일, count(*) 건수, sum(amount) 매입금액, sum(net) 정산액 from purchase group by biz_date order by biz_date desc limit 7`);
grid(document.getElementById('ddaily'), d, {psz:7});
setStatus('대시보드 로드 완료 — 운영 데이터 기준');
}
/* ───────── 가맹점 관리 (마스터-디테일 + CRUD tpcall) ───────── */
async function renderMerchIn(pane){
pane.innerHTML = `
<div style="display:flex; gap:12px">
<div class="panel" style="flex:1.3"><h3>QR0301 · 가맹점 목록 <span style="font-weight:normal;color:#667">— 행 클릭 = 상세</span></h3>
<div class="bd" id="mgrid" style="overflow:auto">로딩...</div></div>
<div style="flex:1">
<div class="panel"><h3>가맹점 상세 / 등록·수정 (tpcall · XA)</h3><div class="bd">
<table class="frm">
<tr><th>가맹점번호<span class="fldcd">T_MERCHANT</span></th><td><input type="text" id="mf_id" value=""></td></tr>
<tr><th>상호<span class="fldcd">T_STR1</span></th><td><input type="text" id="mf_nm" value=""></td></tr>
<tr><th>업종/구분<span class="fldcd">T_STR2</span></th><td><input type="text" id="mf_cat" value="일반"></td></tr>
<tr><th>정산계좌<span class="fldcd">T_STR3</span></th><td><input type="text" id="mf_acct" value="110-234-567890"></td></tr>
<tr><th>상태<span class="fldcd">T_STATUS</span></th><td><select id="mf_st"><option>ACTIVE</option><option>HOLD</option><option>PENDING</option><option>CLOSED</option></select></td></tr>
</table>
<div class="btnrow">
<button class="pri" onclick="merchReg()">신규등록 (MM_MERCH_REG)</button>
<button onclick="merchUpd()">정보수정 (MM_MERCH_UPD)</button>
<button class="warn" onclick="merchSt()">상태변경 (MM_MERCH_STATUS)</button>
</div>
</div></div>
<div class="panel"><h3>확장 마스터 / 변경 이력</h3><div class="bd" id="mhist">가맹점을 선택하세요</div></div>
</div>
</div>
<div class="panel"><h3>거래 저널</h3><div class="bd"><table class="grd jgrid"></table></div></div>`;
renderJournalIn(pane.querySelector('.jgrid'));
loadMerchGrid();
}
async function loadMerchGrid(){
const j = await runQuery(`select m.merchant_id 가맹점번호, m.name 상호, m.mdr_bps "MDR(bp)", m.daily_limit 일한도, m.status 상태, coalesce(t.cnt,0) 누적건수, coalesce(t.amt,0) 누적매입액 from merchant m left join (select merchant_id, count(*) cnt, sum(amount) amt from purchase group by merchant_id) t on t.merchant_id=m.merchant_id order by m.merchant_id limit 300`);
const el = document.getElementById('mgrid');
if (el) grid(el, j, {psz:14, name:'merchants', onRow: r => selectMerch(r)});
}
async function selectMerch(r){
document.getElementById('mf_id').value = r[0];
document.getElementById('mf_nm').value = r[1];
document.getElementById('mf_st').value = STMAP[r[4]] ? r[4] : 'ACTIVE';
const h = await runQuery(`select 'EXT' 구분, coalesce(biz_name,'-') 내용1, coalesce(settle_acct,'-') 내용2, coalesce(to_char(updated_at,'MM-DD HH24:MI'),'') 시각 from mm_merchant_ext where merchant_id='${r[0]}' union all select 'HIST', coalesce(chg_type,'-'), coalesce(chg_detail,'-'), to_char(chg_at,'MM-DD HH24:MI') from mm_merch_hist where merchant_id='${r[0]}' limit 20`);
const el = document.getElementById('mhist');
if (h.ok && h.rows.length) grid(el, h, {psz:8});
else el.innerHTML = '<span style="color:#889">확장 마스터/이력 없음 — 신규등록으로 생성</span>';
}
const mf = k => document.getElementById('mf_'+k).value.trim();
async function merchReg(){
const j = await callSvc('MM_MERCH_REG', { T_MERCHANT: mf('id'), T_STR1: mf('nm'), T_STR2: mf('cat'), T_STR3: mf('acct') }, true);
jlog('QR0301','MM_MERCH_REG',true,j); alert(j.ok?'등록 완료':'실패: '+j.error); loadMerchGrid(); selectMerch([mf('id'), mf('nm'),'','','ACTIVE']);
}
async function merchUpd(){
const j = await callSvc('MM_MERCH_UPD', { T_MERCHANT: mf('id'), T_STR1: mf('nm'), T_STR3: mf('acct') }, true);
jlog('QR0301','MM_MERCH_UPD',true,j); alert(j.ok?'수정 완료':'실패: '+j.error); loadMerchGrid(); selectMerch([mf('id'), mf('nm'),'','','ACTIVE']);
}
async function merchSt(){
const j = await callSvc('MM_MERCH_STATUS', { T_MERCHANT: mf('id'), T_STATUS: document.getElementById('mf_st').value }, true);
jlog('QR0301','MM_MERCH_STATUS',true,j); alert(j.ok?'상태변경 완료':'실패: '+j.error); loadMerchGrid();
}
/* ───────── 서비스 실행 화면 (330종) ───────── */
const byMod = {}; SVC_SCREENS.forEach(s => { (byMod[s.mod] = byMod[s.mod] || []).push(s); });
const bySvc = Object.fromEntries(SVC_SCREENS.map(s => [s.svc, s]));
document.getElementById('scrcnt').textContent = SVC_SCREENS.length + QSCREENS.length;
function scrCode(s){ const i = byMod[s.mod].indexOf(s); return s.mod.toUpperCase() + String(i+1).padStart(2,'0') + '01'; }
function renderSvcIn(pane, s, nm, note){
const cd = scrCode(s), fid = 'sf' + s.svc;
const useTx = !READONLY.test(s.svc);
const rows = (s.in.length ? s.in : []).map((f,i) =>
`<tr><th>${LBL[f]||f}<span class="fldcd">${f}</span></th>
<td><input type="text" id="${fid}_${i}" data-fld="${f}" value="${dflt(f)}"></td></tr>`).join('')
|| `<tr><th>입력</th><td style="color:#889">입력 필드 없음 — 즉시 실행</td></tr>`;
pane.innerHTML = `
<div class="panel"><h3>${cd} · ${nm || s.svc} — <span style="font-weight:normal;color:#667">${s.desc || note || ''}</span></h3>
<div class="bd">
<table class="frm">
<tr><th>서비스명</th><td><b>${s.svc}</b> <span class="fldcd">(${s.modnm} 모듈 · ${s.mod}_svr)</span></td></tr>
${rows}
<tr><th>글로벌 XA</th><td><label><input type="checkbox" id="${fid}_tx" ${useTx?'checked':''}> tpbegin / tpcommit (2PC)</label></td></tr>
</table>
<div style="margin-top:6px;color:#889">응답 필드: ${s.out.length ? s.out.map(f=>LBL[f]||f).join(', ') : '-'}</div>
<div class="btnrow"><button class="pri" id="${fid}_run">실행 (tpcall)</button></div>
</div>
</div>
<div class="panel"><h3>처리 결과 (응답 전문 UBF)</h3>
<div class="bd"><table class="grd" id="${fid}_res"><tr><th style="width:200px">필드</th><th>값</th></tr>
<tr><td colspan="2" style="color:#999">실행 전</td></tr></table></div></div>
<div class="panel"><h3>거래 저널</h3><div class="bd"><table class="grd jgrid"></table></div></div>`;
renderJournalIn(pane.querySelector('.jgrid'));
document.getElementById(`${fid}_run`).onclick = async () => {
const fields = {};
s.in.forEach((f,i) => { const v = document.getElementById(`${fid}_${i}`).value; if (v!=='') fields[f]=v; });
const tx = document.getElementById(`${fid}_tx`).checked;
setStatus(`tpcall("${s.svc}") 호출 중 ...`);
const j = await callSvc(s.svc, fields, tx);
const g = document.getElementById(`${fid}_res`);
g.innerHTML = '<tr><th style="width:200px">필드</th><th>값</th></tr>';
if (j.ok) {
const f = j.fields || {};
if (!Object.keys(f).length) g.innerHTML += '<tr><td colspan="2">(응답 필드 없음 — 정상 처리)</td></tr>';
for (const [k,v] of Object.entries(f))
g.innerHTML += `<tr><td>${LBL[k.replace('#','')]||k} <span class="fldcd">${k}</span></td><td class="num">${k==='T_STATUS'?badge(v):fmtN(v)}</td></tr>`;
setStatus(`tpcall("${s.svc}") 정상 처리${tx?' · XA tpcommit(2PC)':''}`);
} else {
g.innerHTML += `<tr><td>오류</td><td class="err">${j.error||'unknown'}</td></tr>`;
setStatus(`tpcall("${s.svc}") 실패`, true);
}
jlog(cd, s.svc, tx, j);
};
}
/* ───────── 메뉴 ───────── */
const menuEl = document.getElementById('menu');
function addGroup(title, items, open){
const gd = document.createElement('div'); gd.className = 'grp' + (open?' open':'');
gd.innerHTML = `${title}<span class="cnt">${items.length}</span>`;
const wrap = document.createElement('div'); wrap.className = 'itms';
gd.onclick = () => gd.classList.toggle('open');
menuEl.appendChild(gd); menuEl.appendChild(wrap);
items.forEach(({cd, nm, key, open: openFn}) => {
const it = document.createElement('div'); it.className = 'itm';
it.innerHTML = `<span class="cd">${cd}</span>${nm}`;
it.dataset.k = (cd+' '+nm+' '+key).toLowerCase();
it.onclick = e => { e.stopPropagation(); openFn(); };
wrap.appendChild(it);
});
}
const openQueryTab = q => openTab('q:'+q.cd, q.nm, pane =>
q.dash ? renderDashIn(pane) : q.merch ? renderMerchIn(pane) : renderQueryIn(pane, q));
const openSvcTab = (s, nm, note) => openTab('s:'+s.svc, nm || s.svc, pane => renderSvcIn(pane, s, nm, note));
addGroup('조회/현황 (운영)', QSCREENS.map(q => ({cd:q.cd, nm:q.nm, key:q.cd, open:()=>openQueryTab(q)})), true);
const FAVS = [
{ svc:"ACQUIRE", nm:"매입 접수(정산체인)", note:"글로벌 XA: ACQUIRE→RECONCILE→SETTLE 체인 후 2PC 커밋" },
{ svc:"ACQ_STATUS", nm:"매입 상태조회" },
{ svc:"ACQ_MERCHSUM", nm:"가맹점 매입집계" },
{ svc:"LIMIT_INQ", nm:"한도 조회" },
{ svc:"ST_MDR", nm:"MDR 수수료 산출" },
{ svc:"LG_BALCHK", nm:"원장 잔액검증" },
{ svc:"CL_DAILY", nm:"일마감 처리" },
{ svc:"CM_LUHN", nm:"카드번호 검증(Luhn)" },
];
addGroup('★ 주요 업무', FAVS.filter(f=>bySvc[f.svc]).map(f=>({cd:scrCode(bySvc[f.svc]), nm:f.nm, key:f.svc, open:()=>openSvcTab(bySvc[f.svc], f.nm, f.note)})), true);
Object.keys(byMod).sort().forEach(m =>
addGroup(`${byMod[m][0].modnm} (${m}) 업무`, byMod[m].map(s=>({cd:scrCode(s), nm:s.svc, key:s.svc+' '+s.desc, open:()=>openSvcTab(s)})), false));
document.getElementById('q').addEventListener('input', e => {
const q = e.target.value.trim().toLowerCase();
document.querySelectorAll('#menu .itms').forEach(w => w.classList.toggle('show', !!q));
document.querySelectorAll('#menu .itm').forEach(it =>
it.style.display = (!q || it.dataset.k.includes(q)) ? (q ? 'block' : '') : 'none');
});
/* 시작: 대시보드 (+ 해시로 특정 화면: #q=QR0101 / #s=ACQUIRE / #m=1 가맹점관리) */
setTimeout(() => {
openQueryTab(QSCREENS[0]);
const h = location.hash;
if (h.startsWith('#q=')) { const q = QSCREENS.find(x=>x.cd===h.slice(3)); if (q) openQueryTab(q); }
if (h.startsWith('#s=')) { const s = bySvc[h.slice(3)]; if (s) openSvcTab(s); }
}, 0);
</script>
</body>
</html>