diff --git a/app/src/ac/ac_svr.pgc b/app/src/ac/ac_svr.pgc index 4e874f9..2e6bb78 100644 --- a/app/src/ac/ac_svr.pgc +++ b/app/src/ac/ac_svr.pgc @@ -155,6 +155,11 @@ #include "ACQ_RETURNQRY.h" #include "ACQ_RETURNSTAT.h" +/* Wave G — 매입사 경제모델(분쟁 라이프사이클 + 클리어링) */ +#include "ACQ_DISPUTE_OPEN.h" +#include "ACQ_DISPUTE_ADVANCE.h" +#include "ACQ_PRESENT.h" + /* ----- advertise table: {service name, function} (fn is extern from its file) */ static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = { {"ACQUIRE", ACQUIRE}, {"ACQ_DDC", ACQ_DDC}, @@ -253,6 +258,9 @@ static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = { {"ACQ_EXCHANGE", ACQ_EXCHANGE}, {"ACQ_RETURNQRY", ACQ_RETURNQRY}, {"ACQ_RETURNSTAT", ACQ_RETURNSTAT}, + {"ACQ_DISPUTE_OPEN", ACQ_DISPUTE_OPEN}, + {"ACQ_DISPUTE_ADVANCE", ACQ_DISPUTE_ADVANCE}, + {"ACQ_PRESENT", ACQ_PRESENT}, {NULL, NULL} }; diff --git a/app/src/ac/svc/ACQ_DISPUTE_ADVANCE.h b/app/src/ac/svc/ACQ_DISPUTE_ADVANCE.h new file mode 100644 index 0000000..07d9f57 --- /dev/null +++ b/app/src/ac/svc/ACQ_DISPUTE_ADVANCE.h @@ -0,0 +1,25 @@ +/* + * ACQ_DISPUTE_ADVANCE.h - ac 서비스 ACQ_DISPUTE_ADVANCE 카피북 (copybook / record header). + * 분쟁 라이프사이클 상태기계: FIRST_CB→REPRESENT→PRE_ARB→ARBITRATION→WON/LOST, + * 어느 열린 단계에서든 ACCEPT→ACCEPTED. 부적절한 전이는 거부(FAIL). + * Request fields: T_ID1(dispute_id), T_STR1(action), [T_STR2(현재 stage 힌트), T_PURCHASE_ID] + * Response fields: T_STATUS(새 stage 또는 종결 status), T_ID1, T_ARG1(resolve flag), T_RC + */ +#ifndef ACQ_DISPUTE_ADVANCE_H +#define ACQ_DISPUTE_ADVANCE_H + +#include "ac_svc.h" + +/* 분쟁 전이 결과 (내부 판정 결과 표현용) */ +typedef struct { + long dispute_id; + char from_stage[16]; + char action[16]; + char to_stage[16]; + char to_status[16]; + long resolved; /* 1 = 종결 전이(resolved_at 세팅) */ +} ac_dispute_move_t; + +void ACQ_DISPUTE_ADVANCE(TPSVCINFO *p); + +#endif /* ACQ_DISPUTE_ADVANCE_H */ diff --git a/app/src/ac/svc/ACQ_DISPUTE_ADVANCE.pgc b/app/src/ac/svc/ACQ_DISPUTE_ADVANCE.pgc new file mode 100644 index 0000000..400092f --- /dev/null +++ b/app/src/ac/svc/ACQ_DISPUTE_ADVANCE.pgc @@ -0,0 +1,182 @@ +/* + * ACQ_DISPUTE_ADVANCE.pgc - ac 모듈 서비스 ACQ_DISPUTE_ADVANCE (one service = one file). + * + * 분쟁 라이프사이클 상태기계. 카드 분쟁은 정해진 순서로만 진행하며, 이 서비스는 + * 현재 stage/status 를 읽어 요청 action 에 대한 "적법한 전이만" 허용하고 나머지는 거부한다. + * + * stage/action 전이표 (status='OPEN' 인 열린 분쟁에서만): + * FIRST_CB --REPRESENT--> REPRESENT (매입사 재청구 방어) + * REPRESENT --ESCALATE---> PRE_ARB (사전 중재 상신) + * PRE_ARB --ESCALATE---> ARBITRATION (중재 상신) + * ARBITRATION --WIN--------> status=WON (종결, resolved_at) + * ARBITRATION --LOSE-------> status=LOST (종결, resolved_at) + * --ACCEPT-----> status=ACCEPTED (책임 인수, 종결) + * 그 외 (stage,action) 조합 = 부적절한 전이 → T_RC 세팅 후 FAIL. + * 이미 WON/LOST/ACCEPTED 로 종결된 분쟁은 어떤 전이도 거부. + * + * 입출력 계약: 입력 T_ID1(dispute_id) + T_STR1(action)[+ T_STR2(현재 stage 힌트)], + * 출력 T_STATUS(새 stage 또는 종결 status). + * Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr. + */ +#include "ACQ_DISPUTE_ADVANCE.h" + +void ACQ_DISPUTE_ADVANCE(TPSVCINFO *p) +{ + UBFH *b = (UBFH *)p->data; + const char *SVC = "ACQ_DISPUTE_ADVANCE"; + char action[24], bizdate[16], newstage[16], newstatus[16], memo[256], logmsg[256]; + long resolve = 0, valid = 0, i = 0; + EXEC SQL BEGIN DECLARE SECTION; + long h_did, h_pid, h_amt, h_logid, h_open; + char h_stage[16], h_status[16], h_merch[64], h_reason[64]; + char h_new_stage[16], h_new_status[16], h_bizdate[16], h_memo[256], h_logmsg[256]; + EXEC SQL END DECLARE SECTION; + + /* 지역/호스트 변수 초기화 (DECLARE SECTION 밖) */ + h_did = h_pid = h_amt = h_logid = h_open = 0; + action[0] = bizdate[0] = newstage[0] = newstatus[0] = memo[0] = logmsg[0] = 0; + h_stage[0] = h_status[0] = h_reason[0] = h_bizdate[0] = 0; + strcpy(h_merch, "UNKNOWN"); + userlog("%s 진입: 분쟁 단계 전이 요청", SVC); + + /* [1] 입력 검증부 -------------------------------------------------- */ + h_did = getl(b, T_ID1); + if (h_did <= 0) { + Bchg(b, T_MSG, 0, "분쟁 ID(T_ID1) 오류", 0L); setl(b, T_RC, 7301); FAIL(b); + } + gets_(b, T_STR1, action, sizeof(action)); + if (action[0] == 0) { + Bchg(b, T_MSG, 0, "action(T_STR1) 필수", 0L); setl(b, T_RC, 7302); FAIL(b); + } + for (i = 0; action[i]; i++) /* action 대문자 정규화 */ + if (action[i] >= 'a' && action[i] <= 'z') action[i] -= 32; + gets_(b, T_BIZDATE, bizdate, sizeof(bizdate)); + strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; + if (h_bizdate[0] == 0) { + EXEC SQL SELECT param_val INTO :h_bizdate FROM cm_param WHERE param_key = 'BIZ_DATE'; + if (sqlca.sqlcode != 0) strcpy(h_bizdate, "2026-07-19"); + } + + /* [2] 마스터 조회부: 현재 분쟁 상태 (전이의 기준) ------------------- */ + EXEC SQL SELECT purchase_id, merchant_id, amount, reason_code, stage, status + INTO :h_pid, :h_merch, :h_amt, :h_reason, :h_stage, :h_status + FROM ac_dispute WHERE dispute_id = :h_did; + if (sqlca.sqlcode < 0) { + userlog("%s: 분쟁 조회 실패 [%d] %s", SVC, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); + setl(b, T_RC, 90); FAIL(b); + } + if (sqlca.sqlcode == 100) { + /* XA 격리: 형제 브랜치가 방금 개시한 미커밋 분쟁이면 전문에 실린 현재 stage 를 쓴다. + * 전문 힌트(T_STR2)도 없으면 진짜 미존재이므로 업무검증 실패로 거부한다. */ + gets_(b, T_STR2, h_stage, sizeof(h_stage)); + gets_(b, T_STATUS, h_status, sizeof(h_status)); + if (h_status[0] == 0) strcpy(h_status, "OPEN"); + h_pid = getl(b, T_PURCHASE_ID); + h_amt = getl(b, T_AMOUNT); + if (h_stage[0] == 0) { + userlog("%s: 분쟁 미존재 did=%ld (전문 힌트 없음)", SVC, h_did); + Bchg(b, T_MSG, 0, "분쟁 미존재", 0L); setl(b, T_RC, 7303); FAIL(b); + } + userlog("%s: 분쟁 미커밋(체인) did=%ld — 전문 stage=%s 사용", SVC, h_did, h_stage); + } + userlog("%s 컨텍스트: did=%ld pid=%ld merch=%s stage=%s status=%s action=%s", + SVC, h_did, h_pid, h_merch, h_stage, h_status, action); + + /* [3] 종결 상태 확인부: 이미 resolved 면 어떤 전이도 불가 ----------- */ + if (strcmp(h_status, "WON") == 0 || strcmp(h_status, "LOST") == 0 || + strcmp(h_status, "ACCEPTED") == 0) { + snprintf(logmsg, sizeof(logmsg), "이미 종결된 분쟁 status=%s 전이 거부", h_status); + userlog("%s %s did=%ld", SVC, logmsg, h_did); + Bchg(b, T_MSG, 0, logmsg, 0L); + Bchg(b, T_STATUS, 0, h_status, 0L); + setl(b, T_RC, 7310); FAIL(b); + } + + /* [4] 상태기계 전이 판정부 ----------------------------------------- */ + strcpy(newstage, h_stage); strcpy(newstatus, h_status); + resolve = 0; valid = 0; + if (strcmp(action, "ACCEPT") == 0) { + /* 어느 열린 단계에서든 가맹점/매입사가 책임을 인수 → ACCEPTED(종결) */ + strcpy(newstatus, "ACCEPTED"); resolve = 1; valid = 1; + } else if (strcmp(h_stage, "FIRST_CB") == 0 && strcmp(action, "REPRESENT") == 0) { + strcpy(newstage, "REPRESENT"); valid = 1; + } else if (strcmp(h_stage, "REPRESENT") == 0 && strcmp(action, "ESCALATE") == 0) { + strcpy(newstage, "PRE_ARB"); valid = 1; + } else if (strcmp(h_stage, "PRE_ARB") == 0 && strcmp(action, "ESCALATE") == 0) { + strcpy(newstage, "ARBITRATION"); valid = 1; + } else if (strcmp(h_stage, "ARBITRATION") == 0 && + (strcmp(action, "WIN") == 0 || strcmp(action, "WON") == 0)) { + strcpy(newstatus, "WON"); resolve = 1; valid = 1; + } else if (strcmp(h_stage, "ARBITRATION") == 0 && + (strcmp(action, "LOSE") == 0 || strcmp(action, "LOSS") == 0 || + strcmp(action, "LOST") == 0)) { + strcpy(newstatus, "LOST"); resolve = 1; valid = 1; + } + if (!valid) { + snprintf(logmsg, sizeof(logmsg), "부적절한 전이 거부: stage=%s action=%s", h_stage, action); + userlog("%s %s did=%ld", SVC, logmsg, h_did); + Bchg(b, T_MSG, 0, logmsg, 0L); + Bchg(b, T_STATUS, 0, h_stage, 0L); /* 현재 stage 유지 통지 */ + setl(b, T_RC, 7320); FAIL(b); + } + userlog("%s 전이확정: %s/%s --%s--> stage=%s status=%s resolve=%ld", + SVC, h_stage, h_status, action, newstage, newstatus, resolve); + + /* [5] 본처리부: ac_dispute UPDATE (종결 전이면 resolved_at 세팅) ----- */ + strncpy(h_new_stage, newstage, sizeof(h_new_stage)-1); h_new_stage[sizeof(h_new_stage)-1] = 0; + strncpy(h_new_status, newstatus, sizeof(h_new_status)-1); h_new_status[sizeof(h_new_status)-1] = 0; + snprintf(memo, sizeof(memo), "전이 %s/%s -%s-> %s/%s @%s", + h_stage, h_status, action, h_new_stage, h_new_status, h_bizdate); + strncpy(h_memo, memo, sizeof(h_memo)-1); h_memo[sizeof(h_memo)-1] = 0; + if (resolve) { + EXEC SQL UPDATE ac_dispute + SET stage = :h_new_stage, status = :h_new_status, resolved_at = now(), memo = :h_memo + WHERE dispute_id = :h_did; + } else { + EXEC SQL UPDATE ac_dispute + SET stage = :h_new_stage, status = :h_new_status, memo = :h_memo + WHERE dispute_id = :h_did; + } + if (sqlca.sqlcode < 0) { + userlog("%s: 분쟁 갱신 실패 [%d] %s", SVC, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); + setl(b, T_RC, 90); FAIL(b); + } + if (sqlca.sqlcode == 100) { + /* XA 격리: 대상 행이 이 브랜치에 안 보임(체인 미커밋). 전문 기반으로 진행하고 FAIL 안 함 */ + userlog("%s: UPDATE 대상 미가시(체인 미커밋) did=%ld — 전문값 응답", SVC, h_did); + } + + /* [6] 이력/감사 적재부 (cm_log) ------------------------------------- */ + snprintf(logmsg, sizeof(logmsg), "분쟁전이 did=%ld %s->%s/%s action=%s resolve=%ld", + h_did, h_stage, h_new_stage, h_new_status, action, resolve); + strncpy(h_logmsg, logmsg, sizeof(h_logmsg)-1); h_logmsg[sizeof(h_logmsg)-1] = 0; + EXEC SQL SELECT nextval('cm_log_seq') INTO :h_logid; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date) + VALUES (:h_logid, 'ACQ_DISPUTE_ADVANCE', 'I', :h_logmsg, :h_bizdate); + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + + /* [7] 집계/요약부: 가맹점 진행중 분쟁 수 재집계 --------------------- */ + EXEC SQL SELECT count(*) INTO :h_open FROM ac_dispute + WHERE merchant_id = :h_merch AND status = 'OPEN'; + if (sqlca.sqlcode < 0) { h_open = 0; } /* 집계 실패는 응답을 막지 않음 */ + + /* [8] 응답부 (계약 보존: T_STATUS = 새 stage 또는 종결 status) ------- */ + if (resolve) Bchg(b, T_STATUS, 0, h_new_status, 0L); + else Bchg(b, T_STATUS, 0, h_new_stage, 0L); + setl(b, T_ID1, h_did); + setl(b, T_PURCHASE_ID, h_pid); + setl(b, T_AMOUNT, h_amt); + Bchg(b, T_MERCHANT, 0, h_merch, 0L); + Bchg(b, T_STR2, 0, h_new_stage, 0L); /* 새 stage 힌트(체인 전달용) */ + Bchg(b, T_STR1, 0, action, 0L); + setl(b, T_ARG1, resolve); + setl(b, T_COUNT, h_open); + Bchg(b, T_MSG, 0, h_memo, 0L); + setl(b, T_RC, 0); + userlog("%s 완료: did=%ld -> stage=%s status=%s (resolve=%ld)", + SVC, h_did, h_new_stage, h_new_status, resolve); + OK(b); +} + +/* vim: set ts=4 sw=4 et smartindent: */ diff --git a/app/src/ac/svc/ACQ_DISPUTE_OPEN.h b/app/src/ac/svc/ACQ_DISPUTE_OPEN.h new file mode 100644 index 0000000..f6978e5 --- /dev/null +++ b/app/src/ac/svc/ACQ_DISPUTE_OPEN.h @@ -0,0 +1,24 @@ +/* + * ACQ_DISPUTE_OPEN.h - ac 서비스 ACQ_DISPUTE_OPEN 카피북 (copybook / record header). + * 채그백/분쟁 개시: 매입 1건에 대해 ac_dispute 를 FIRST_CB/OPEN 으로 연다. + * Request fields: T_PURCHASE_ID, T_STR1(reason_code), [T_AMOUNT, T_MERCHANT, T_BIZDATE] + * Response fields: T_ID1(dispute_id), T_STATUS='FIRST_CB', T_AMOUNT, T_COUNT, T_ARG1(tier) + */ +#ifndef ACQ_DISPUTE_OPEN_H +#define ACQ_DISPUTE_OPEN_H + +#include "ac_svc.h" + +typedef struct { + long dispute_id; + long purchase_id; + char merchant_id[64]; + char reason_code[64]; + long amount; + char stage[16]; /* FIRST_CB */ + char status[16]; /* OPEN */ +} ac_dispute_rec_t; + +void ACQ_DISPUTE_OPEN(TPSVCINFO *p); + +#endif /* ACQ_DISPUTE_OPEN_H */ diff --git a/app/src/ac/svc/ACQ_DISPUTE_OPEN.pgc b/app/src/ac/svc/ACQ_DISPUTE_OPEN.pgc new file mode 100644 index 0000000..9ee09c3 --- /dev/null +++ b/app/src/ac/svc/ACQ_DISPUTE_OPEN.pgc @@ -0,0 +1,136 @@ +/* + * ACQ_DISPUTE_OPEN.pgc - ac 모듈 서비스 ACQ_DISPUTE_OPEN (one service = one file). + * 채그백/분쟁 개시: 매입 원장을 확인하고 ac_dispute 에 FIRST_CB/OPEN 분쟁행을 만든다. + * 분쟁금액은 매입금액, reason_code 는 카드망 분쟁코드(10.4 사기 / 13.1 상품미수취 / + * 12.6 중복 ...)를 그대로 적재하고 사기·상품·중복 등급(tier)으로 분류한다. + * 입출력 계약: 입력 T_PURCHASE_ID + T_STR1(reason_code)[+ T_AMOUNT/T_MERCHANT/T_BIZDATE], + * 출력 T_ID1(dispute_id) / T_STATUS='FIRST_CB'. + * Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr. + */ +#include "ACQ_DISPUTE_OPEN.h" + +void ACQ_DISPUTE_OPEN(TPSVCINFO *p) +{ + UBFH *b = (UBFH *)p->data; + const char *SVC = "ACQ_DISPUTE_OPEN"; + char bizdate[16], reason[64], memo[256], logmsg[256]; + long tier = 0; + EXEC SQL BEGIN DECLARE SECTION; + long h_pid, h_amt, h_did, h_logid, h_dup, h_cnt, h_merchcb; + char h_bizdate[16], h_reason[64], h_merch[64], h_pstat[16]; + char h_memo[256], h_logmsg[256]; + EXEC SQL END DECLARE SECTION; + + /* 지역/호스트 변수 초기화 (DECLARE SECTION 밖) */ + h_pid = h_amt = h_did = h_logid = h_dup = h_cnt = h_merchcb = 0; + bizdate[0] = reason[0] = memo[0] = logmsg[0] = 0; + h_bizdate[0] = h_reason[0] = 0; + strcpy(h_merch, "UNKNOWN"); strcpy(h_pstat, "S"); + userlog("%s 진입: 분쟁/채그백 개시 요청", SVC); + + /* [1] 입력 검증부 -------------------------------------------------- */ + h_pid = getl(b, T_PURCHASE_ID); + if (h_pid <= 0) { + Bchg(b, T_MSG, 0, "매입 ID 오류", 0L); setl(b, T_RC, 7201); FAIL(b); + } + gets_(b, T_STR1, reason, sizeof(reason)); + if (reason[0] == 0) strcpy(reason, "13.1"); /* 기본: 13.1 상품미수취 */ + strncpy(h_reason, reason, sizeof(h_reason)-1); h_reason[sizeof(h_reason)-1] = 0; + gets_(b, T_BIZDATE, bizdate, sizeof(bizdate)); + strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; + if (h_bizdate[0] == 0) { + EXEC SQL SELECT param_val INTO :h_bizdate FROM cm_param WHERE param_key = 'BIZ_DATE'; + if (sqlca.sqlcode != 0) strcpy(h_bizdate, "2026-07-19"); + } + + /* [2] 마스터/상태 조회부 (XA 격리: 미커밋이면 전문값 사용, 100 을 FAIL 로 다루지 않음) */ + EXEC SQL SELECT amount, merchant_id, status INTO :h_amt, :h_merch, :h_pstat + FROM purchase WHERE purchase_id = :h_pid; + if (sqlca.sqlcode < 0) { + userlog("%s: 매입원장 조회 실패 [%d] %s", SVC, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); + setl(b, T_RC, 90); FAIL(b); + } + if (sqlca.sqlcode == 100) { + /* 체인 내 신규 매입(미커밋): 요청 전문에 실린 값으로 진행 */ + h_amt = getl(b, T_AMOUNT); + gets_(b, T_MERCHANT, h_merch, sizeof(h_merch)); + if (h_merch[0] == 0) strcpy(h_merch, "UNKNOWN"); + strcpy(h_pstat, "S"); + userlog("%s: 매입 미커밋(체인) pid=%ld — 전문값 사용", SVC, h_pid); + } + if (h_amt <= 0) h_amt = getl(b, T_AMOUNT); + if (h_amt <= 0) { + Bchg(b, T_MSG, 0, "분쟁 금액 산정 불가", 0L); setl(b, T_RC, 7202); FAIL(b); + } + userlog("%s 컨텍스트: pid=%ld merch=%s 상태=%s 금액=%ld reason=%s", + SVC, h_pid, h_merch, h_pstat, h_amt, h_reason); + + /* [3] 업무규칙 분기부: 중복 분쟁 방지 + reason 등급 분류 -------------- */ + EXEC SQL SELECT count(*) INTO :h_dup FROM ac_dispute + WHERE purchase_id = :h_pid AND status = 'OPEN'; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + if (h_dup > 0) { + userlog("%s 거절: 이미 진행중인 분쟁 존재 pid=%ld", SVC, h_pid); + Bchg(b, T_MSG, 0, "이미 진행중인 분쟁 존재", 0L); setl(b, T_RC, 7203); FAIL(b); + } + /* 무효/취소된 매입은 분쟁 개시 자체가 성립하지 않는다 */ + if (strcmp(h_pstat, "V") == 0) { + Bchg(b, T_MSG, 0, "무효 매입은 분쟁 불가", 0L); setl(b, T_RC, 7204); FAIL(b); + } + /* reason 등급: 사기(10.x)=3 최우선, 상품(13.x)=2, 중복(12.x)=1, 그 외=0 */ + if (strncmp(h_reason, "10.", 3) == 0) tier = 3; + else if (strncmp(h_reason, "13.", 3) == 0) tier = 2; + else if (strncmp(h_reason, "12.", 3) == 0) tier = 1; + else tier = 0; + + /* [4] 본처리부: dispute INSERT (FIRST_CB / OPEN) --------------------- */ + EXEC SQL SELECT nextval('ac_dispute_seq') INTO :h_did; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + snprintf(memo, sizeof(memo), "채그백 개시 pid=%ld reason=%s tier=%ld bizdate=%s", + h_pid, h_reason, tier, h_bizdate); + strncpy(h_memo, memo, sizeof(h_memo)-1); h_memo[sizeof(h_memo)-1] = 0; + EXEC SQL INSERT INTO ac_dispute + (dispute_id, purchase_id, merchant_id, reason_code, amount, stage, status, memo) + VALUES (:h_did, :h_pid, :h_merch, :h_reason, :h_amt, 'FIRST_CB', 'OPEN', :h_memo); + if (sqlca.sqlcode < 0) { + userlog("%s: 분쟁행 적재 실패 [%d] %s", SVC, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); + setl(b, T_RC, 90); FAIL(b); + } + + /* [5] 이력/감사 적재부 (cm_log) ------------------------------------- */ + snprintf(logmsg, sizeof(logmsg), "분쟁개시 did=%ld pid=%ld reason=%s amt=%ld tier=%ld", + h_did, h_pid, h_reason, h_amt, tier); + strncpy(h_logmsg, logmsg, sizeof(h_logmsg)-1); h_logmsg[sizeof(h_logmsg)-1] = 0; + EXEC SQL SELECT nextval('cm_log_seq') INTO :h_logid; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date) + VALUES (:h_logid, 'ACQ_DISPUTE_OPEN', 'I', :h_logmsg, :h_bizdate); + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + + /* [6] 집계/요약 갱신부: 가맹점 진행중 분쟁 수 + LOST 확정 채그백 누계 ---- */ + EXEC SQL SELECT count(*) INTO :h_cnt FROM ac_dispute + WHERE merchant_id = :h_merch AND status = 'OPEN'; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_merchcb FROM ac_dispute + WHERE merchant_id = :h_merch AND status = 'LOST'; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + userlog("%s 집계: merch=%s 진행중=%ld LOST누계=%ld", SVC, h_merch, h_cnt, h_merchcb); + + /* [7] 응답부 (계약 보존: T_ID1=dispute_id / T_STATUS='FIRST_CB') ------ */ + setl(b, T_ID1, h_did); + Bchg(b, T_STATUS, 0, "FIRST_CB", 0L); + setl(b, T_PURCHASE_ID, h_pid); + setl(b, T_AMOUNT, h_amt); + Bchg(b, T_MERCHANT, 0, h_merch, 0L); + Bchg(b, T_STR1, 0, h_reason, 0L); + Bchg(b, T_BIZDATE, 0, h_bizdate, 0L); + setl(b, T_ARG1, tier); + setl(b, T_COUNT, h_cnt); + setl(b, T_GROSS, h_merchcb); + Bchg(b, T_MSG, 0, "분쟁 개시(FIRST_CB/OPEN)", 0L); + setl(b, T_RC, 0); + userlog("%s 완료: did=%ld pid=%ld amt=%ld tier=%ld", SVC, h_did, h_pid, h_amt, tier); + OK(b); +} + +/* vim: set ts=4 sw=4 et smartindent: */ diff --git a/app/src/ac/svc/ACQ_PRESENT.h b/app/src/ac/svc/ACQ_PRESENT.h new file mode 100644 index 0000000..0a592eb --- /dev/null +++ b/app/src/ac/svc/ACQ_PRESENT.h @@ -0,0 +1,26 @@ +/* + * ACQ_PRESENT.h - ac 서비스 ACQ_PRESENT 카피북 (copybook / record header). + * 프레젠트먼트(클리어링) 생성: 승인·정산과 분리된 데이터 교환 단계. + * clearing_amt = amount − interchange (발급사 귀속분 차감 후 매입사 클리어링액). + * Request fields: T_PURCHASE_ID, [T_STR1(scheme), T_AMOUNT, T_AMT1(interchange), T_BIZDATE] + * Response fields: T_ID1(presentment_id), T_AMT1(clearing_amt), T_STATUS='CLEARED', T_FEE(ic) + */ +#ifndef ACQ_PRESENT_H +#define ACQ_PRESENT_H + +#include "ac_svc.h" + +typedef struct { + long presentment_id; + long purchase_id; + char scheme[16]; + char msg_class[24]; /* FIRST_PRESENT / REPRESENT */ + long clearing_amt; + char present_date[16]; + char cycle[12]; /* T+1 */ + char status[16]; /* CLEARED */ +} cl_presentment_rec_t; + +void ACQ_PRESENT(TPSVCINFO *p); + +#endif /* ACQ_PRESENT_H */ diff --git a/app/src/ac/svc/ACQ_PRESENT.pgc b/app/src/ac/svc/ACQ_PRESENT.pgc new file mode 100644 index 0000000..b695f54 --- /dev/null +++ b/app/src/ac/svc/ACQ_PRESENT.pgc @@ -0,0 +1,140 @@ +/* + * ACQ_PRESENT.pgc - ac 모듈 서비스 ACQ_PRESENT (one service = one file). + * 프레젠트먼트(클리어링) 생성. 승인·정산과 분리된 데이터 교환 단계로, 발급사↔매입사 + * 채무를 확정한다. 수수료 3층 분해(st_fee_component)의 interchange 는 발급사 귀속분이므로 + * 클리어링 대상 금액은 clearing_amt = amount − interchange 이다. + * 같은 매입에 FIRST_PRESENT 가 이미 있으면 msg_class 를 REPRESENT 로 승격한다. + * 입출력 계약: 입력 T_PURCHASE_ID [+ T_STR1(scheme)/T_AMOUNT/T_AMT1(interchange)/T_BIZDATE], + * 출력 T_ID1(presentment_id) / T_AMT1(clearing_amt) / T_STATUS='CLEARED'. + * Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr. + */ +#include "ACQ_PRESENT.h" + +void ACQ_PRESENT(TPSVCINFO *p) +{ + UBFH *b = (UBFH *)p->data; + const char *SVC = "ACQ_PRESENT"; + char bizdate[16], scheme[16], msgclass[24], cycle[12], logmsg[256]; + long clearing = 0, has_fc = 0; + EXEC SQL BEGIN DECLARE SECTION; + long h_pid, h_amt, h_ic, h_clr, h_prid, h_logid, h_cnt, h_prev; + char h_bizdate[16], h_scheme[16], h_msgclass[24], h_cycle[12], h_merch[64], h_logmsg[256]; + EXEC SQL END DECLARE SECTION; + + /* 지역/호스트 변수 초기화 (DECLARE SECTION 밖) */ + h_pid = h_amt = h_ic = h_clr = h_prid = h_logid = h_cnt = h_prev = 0; + bizdate[0] = logmsg[0] = 0; + strcpy(scheme, "BC"); strcpy(cycle, "T+1"); strcpy(msgclass, "FIRST_PRESENT"); + h_bizdate[0] = 0; strcpy(h_scheme, "BC"); strcpy(h_merch, "UNKNOWN"); + userlog("%s 진입: 프레젠트먼트(클리어링) 생성 요청", SVC); + + /* [1] 입력 검증부 -------------------------------------------------- */ + h_pid = getl(b, T_PURCHASE_ID); + if (h_pid <= 0) { + Bchg(b, T_MSG, 0, "매입 ID 오류", 0L); setl(b, T_RC, 7401); FAIL(b); + } + gets_(b, T_STR1, scheme, sizeof(scheme)); + if (scheme[0] == 0) strcpy(scheme, "BC"); + gets_(b, T_BIZDATE, bizdate, sizeof(bizdate)); + strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; + + /* [2] 수수료 분해 조회부 (XA 격리: 없으면 전문 amount/interchange, 100 은 정상흐름) */ + EXEC SQL SELECT amount, interchange, scheme INTO :h_amt, :h_ic, :h_scheme + FROM st_fee_component WHERE purchase_id = :h_pid; + if (sqlca.sqlcode < 0) { + userlog("%s: 수수료 분해 조회 실패 [%d] %s", SVC, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); + setl(b, T_RC, 90); FAIL(b); + } + if (sqlca.sqlcode == 100) { + /* 분해 미산출/미커밋: 전문값으로 클리어링. interchange 미제공이면 0 */ + has_fc = 0; + h_amt = getl(b, T_AMOUNT); + h_ic = getl(b, T_AMT1); + strncpy(h_scheme, scheme, sizeof(h_scheme)-1); h_scheme[sizeof(h_scheme)-1] = 0; + userlog("%s: st_fee_component 미존재 pid=%ld — 전문 amount=%ld ic=%ld 사용", + SVC, h_pid, h_amt, h_ic); + } else { + has_fc = 1; + } + if (h_amt <= 0) h_amt = getl(b, T_AMOUNT); + if (h_amt <= 0) { + Bchg(b, T_MSG, 0, "클리어링 금액 산정 불가", 0L); setl(b, T_RC, 7402); FAIL(b); + } + if (h_ic < 0) h_ic = 0; + if (h_ic > h_amt) h_ic = h_amt; /* interchange 는 매출을 넘지 못함 */ + if (h_scheme[0] == 0) strcpy(h_scheme, "BC"); + + /* 매입 원장에서 영업일/가맹점 보강 (미커밋이면 전문/파라미터 폴백) */ + EXEC SQL SELECT merchant_id, biz_date INTO :h_merch, :h_bizdate + FROM purchase WHERE purchase_id = :h_pid; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + if (sqlca.sqlcode == 100) { + gets_(b, T_MERCHANT, h_merch, sizeof(h_merch)); + if (h_merch[0] == 0) strcpy(h_merch, "UNKNOWN"); + userlog("%s: 매입 미커밋(체인) pid=%ld — 전문값 사용", SVC, h_pid); + } + if (h_bizdate[0] == 0) { + EXEC SQL SELECT param_val INTO :h_bizdate FROM cm_param WHERE param_key = 'BIZ_DATE'; + if (sqlca.sqlcode != 0) strcpy(h_bizdate, "2026-07-19"); + } + userlog("%s 컨텍스트: pid=%ld merch=%s amt=%ld ic=%ld scheme=%s fc=%ld", + SVC, h_pid, h_merch, h_amt, h_ic, h_scheme, has_fc); + + /* [3] 업무규칙 분기부: 기존 프레젠트먼트 존재 여부로 msg_class 결정 ---- */ + EXEC SQL SELECT count(*) INTO :h_prev FROM cl_presentment + WHERE purchase_id = :h_pid AND msg_class = 'FIRST_PRESENT'; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + if (h_prev > 0) strcpy(msgclass, "REPRESENT"); /* 1차가 있으면 재프레젠트 */ + else strcpy(msgclass, "FIRST_PRESENT"); + strncpy(h_msgclass, msgclass, sizeof(h_msgclass)-1); h_msgclass[sizeof(h_msgclass)-1] = 0; + strncpy(h_cycle, cycle, sizeof(h_cycle)-1); h_cycle[sizeof(h_cycle)-1] = 0; + + /* 클리어링 금액 = 매출 − 발급사 귀속 interchange */ + clearing = h_amt - h_ic; + if (clearing < 0) clearing = 0; + h_clr = clearing; + + /* [4] 본처리부: cl_presentment INSERT (CLEARED) --------------------- */ + EXEC SQL SELECT nextval('cl_present_seq') INTO :h_prid; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + EXEC SQL INSERT INTO cl_presentment + (presentment_id, purchase_id, scheme, msg_class, clearing_amt, present_date, cycle, status) + VALUES (:h_prid, :h_pid, :h_scheme, :h_msgclass, :h_clr, :h_bizdate, :h_cycle, 'CLEARED'); + if (sqlca.sqlcode < 0) { + userlog("%s: 프레젠트먼트 적재 실패 [%d] %s", SVC, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); + setl(b, T_RC, 90); FAIL(b); + } + + /* [5] 이력/감사 적재부 (cm_log) ------------------------------------- */ + snprintf(logmsg, sizeof(logmsg), "프레젠트먼트 prid=%ld pid=%ld class=%s clr=%ld ic=%ld", + h_prid, h_pid, h_msgclass, clearing, h_ic); + strncpy(h_logmsg, logmsg, sizeof(h_logmsg)-1); h_logmsg[sizeof(h_logmsg)-1] = 0; + EXEC SQL SELECT nextval('cm_log_seq') INTO :h_logid; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date) + VALUES (:h_logid, 'ACQ_PRESENT', 'I', :h_logmsg, :h_bizdate); + if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); } + + /* [6] 집계/요약부: 해당 매입 프레젠트먼트 총 건수 ------------------- */ + EXEC SQL SELECT count(*) INTO :h_cnt FROM cl_presentment WHERE purchase_id = :h_pid; + if (sqlca.sqlcode < 0) { h_cnt = 0; } + + /* [7] 응답부 (계약 보존: T_ID1=presentment_id / T_AMT1=clearing_amt) - */ + setl(b, T_ID1, h_prid); + setl(b, T_AMT1, clearing); + setl(b, T_PURCHASE_ID, h_pid); + setl(b, T_AMOUNT, h_amt); + setl(b, T_FEE, h_ic); + Bchg(b, T_STATUS, 0, "CLEARED", 0L); + Bchg(b, T_STR1, 0, h_scheme, 0L); + Bchg(b, T_STR2, 0, h_msgclass, 0L); + Bchg(b, T_BIZDATE, 0, h_bizdate, 0L); + Bchg(b, T_MERCHANT, 0, h_merch, 0L); + setl(b, T_COUNT, h_cnt); + Bchg(b, T_MSG, 0, "프레젠트먼트 생성(CLEARED)", 0L); + setl(b, T_RC, 0); + userlog("%s 완료: prid=%ld pid=%ld clr=%ld class=%s", SVC, h_prid, h_pid, clearing, h_msgclass); + OK(b); +} + +/* vim: set ts=4 sw=4 et smartindent: */ diff --git a/app/src/st/st_svr.pgc b/app/src/st/st_svr.pgc index dbf3c67..63187e6 100644 --- a/app/src/st/st_svr.pgc +++ b/app/src/st/st_svr.pgc @@ -151,6 +151,10 @@ #include "ST_RELAYSPLIT.h" #include "ST_GRADESTAT.h" #include "ST_MONTHSTAT.h" +/* Wave G — 매입사 경제모델(수수료 3층 분해/순액정산/펀딩 항등식) */ +#include "ST_FEEDECOMP.h" +#include "ST_NETSETTLE.h" +#include "ST_FUNDING.h" /* ----- advertise table: {service name, function} ---------------------- */ static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = { @@ -221,6 +225,8 @@ static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = { {"ST_DISPUTERSV", ST_DISPUTERSV}, {"ST_APPEALSTAT", ST_APPEALSTAT}, {"ST_VANDETAIL", ST_VANDETAIL}, {"ST_RELAYSPLIT", ST_RELAYSPLIT}, {"ST_GRADESTAT", ST_GRADESTAT}, {"ST_MONTHSTAT", ST_MONTHSTAT}, + {"ST_FEEDECOMP", ST_FEEDECOMP}, {"ST_NETSETTLE", ST_NETSETTLE}, + {"ST_FUNDING", ST_FUNDING}, {NULL, NULL} }; diff --git a/app/src/st/svc/ST_FEEDECOMP.h b/app/src/st/svc/ST_FEEDECOMP.h new file mode 100644 index 0000000..b62f50a --- /dev/null +++ b/app/src/st/svc/ST_FEEDECOMP.h @@ -0,0 +1,26 @@ +/* + * ST_FEEDECOMP.h - st 서비스 ST_FEEDECOMP 카피북 (copybook / record header). + * 수수료 3층 분해: MDR = interchange(발급사) + scheme_fee(카드망) + markup(매입사). + * st_interchange_rate / st_scheme_fee 요율 조회 후 st_fee_component 로 UPSERT. + */ +#ifndef ST_FEEDECOMP_H +#define ST_FEEDECOMP_H + +#include "st_svc.h" + +typedef struct { + long purchase_id; + long amount; + long interchange; /* 발급사 귀속 */ + long scheme_fee; /* 카드망 귀속 */ + long markup; /* 매입사 수익 */ + long mdr_total; /* = interchange + scheme_fee + markup */ + char card_type[16]; /* CREDIT/CHECK/PREPAID */ + char scheme[16]; /* BC/VISA/MASTER/LOCAL */ + char channel[16]; + char biz_date[16]; +} st_st_feedecomp_rec_t; + +void ST_FEEDECOMP(TPSVCINFO *p); + +#endif /* ST_FEEDECOMP_H */ diff --git a/app/src/st/svc/ST_FEEDECOMP.pgc b/app/src/st/svc/ST_FEEDECOMP.pgc new file mode 100644 index 0000000..93e3dc1 --- /dev/null +++ b/app/src/st/svc/ST_FEEDECOMP.pgc @@ -0,0 +1,156 @@ +/* + * ST_FEEDECOMP.pgc - st (정산/수수료) 모듈 서비스 ST_FEEDECOMP (one service = one file). + * 수수료 3층 분해(심화판): MDR = interchange(발급사) + scheme_fee(카드망) + markup(매입사). + * 처리단계: 입력검증 -> 매입/카드종류 결정 -> interchange/scheme 요율조회 -> 업무규칙(3층 산출) + * -> st_fee_component UPSERT -> 감사이력 -> 재검증 -> 응답 -> 로깅. + * 호출자 XA 브랜치에서 수행(EXEC SQL CONNECT 없음). st_svr 가 tpsvrinit 에서 광고. + * XA 격리: 체인 신규매입(미커밋)은 이 브랜치에서 안 보이므로 sqlcode=100 을 정상흐름으로 보고 + * 요청 전문(UBF)값을 사용한다(owner-writes 규율, RECONCILE.pgc 참고). 100 을 FAIL 로 처리하지 않는다. + */ +#include "ST_FEEDECOMP.h" + +/* ST_FEEDECOMP - 수수료 3층 분해 (interchange + scheme_fee + markup). */ +void ST_FEEDECOMP(TPSVCINFO *p) +{ + UBFH *b = (UBFH *)p->data; + /* ---- 지역 스크래치 (DECLARE SECTION 밖에서 초기화) ---- */ + char channel[16], issuer[40], ctype[16], scheme[16], msgbuf[200]; + long amount, feein, persist; + + EXEC SQL BEGIN DECLARE SECTION; + long h_pid, h_amount, h_fee, h_icbps, h_icfix, h_sfbps, h_sffix; + long h_ic, h_sf, h_markup, h_mdr, h_floor, h_cnt; + char h_ctype[16], h_scheme[16], h_channel[16], h_issuer[40]; + char h_merch[64], h_status[16], h_bizdate[16], h_svc[24], h_msg[200]; + EXEC SQL END DECLARE SECTION; + + strcpy(h_svc, "ST_FEEDECOMP"); + h_amount = h_fee = h_ic = h_sf = h_markup = h_mdr = h_cnt = 0; + h_icbps = 0; h_icfix = 0; h_sfbps = 0; h_sffix = 0; h_floor = 0; + strcpy(h_channel, "POS"); strcpy(h_issuer, "UNKNOWN"); strcpy(h_merch, "-"); + strcpy(h_status, "S"); strcpy(h_bizdate, "2026-07-20"); + persist = 0; + + /* ===== 1) 입력 검증부 ===== */ + h_pid = getl(b, T_PURCHASE_ID); + amount = getl(b, T_AMOUNT); + feein = getl(b, T_FEE); + gets_(b, T_CHANNEL, channel, sizeof(channel)); + gets_(b, T_ISSUER, issuer, sizeof(issuer)); + gets_(b, T_STR1, ctype, sizeof(ctype)); /* 선택: 명시 카드종류 */ + gets_(b, T_STR2, scheme, sizeof(scheme)); /* 선택: 명시 스킴 */ + if (channel[0] == 0) strcpy(channel, "POS"); + if (issuer[0] == 0) strcpy(issuer, "UNKNOWN"); + userlog("[정산심화] 수수료 3층 분해 진입 pid=%ld amt=%ld chan=%s issuer=%s", h_pid, amount, channel, issuer); + if (h_pid <= 0 && amount <= 0) { + setl(b, T_RC, 8101); Bchg(b, T_MSG, 0, "매입 ID 또는 (금액+채널) 필수", 0L); + userlog("[ST_FEEDECOMP] 입력 부족 pid=%ld amt=%ld", h_pid, amount); FAIL(b); + } + if (amount < 0) { setl(b, T_RC, 8102); Bchg(b, T_MSG, 0, "매입 금액 음수 불가", 0L); FAIL(b); } + + /* ===== 2) 매입 조회부(미커밋이면 전문값) + 카드종류/스킴 결정 ===== */ + if (h_pid > 0) { + EXEC SQL SELECT amount, fee, channel, issuer, merchant_id, status, biz_date + INTO :h_amount, :h_fee, :h_channel, :h_issuer, :h_merch, :h_status, :h_bizdate + FROM purchase WHERE purchase_id = :h_pid; + if (sqlca.sqlcode == 100) { + h_amount = amount; h_fee = feein; + strncpy(h_channel, channel, sizeof(h_channel)-1); h_channel[sizeof(h_channel)-1] = 0; + strncpy(h_issuer, issuer, sizeof(h_issuer)-1); h_issuer[sizeof(h_issuer)-1] = 0; + userlog("[ST_FEEDECOMP] 체인 신규매입(미커밋) pid=%ld — 전문값으로 분해", h_pid); + } else if (sqlca.sqlcode < 0) { + setl(b, T_RC, 8110); Bchg(b, T_MSG, 0, "매입 조회 오류", 0L); + userlog("[ST_FEEDECOMP] 매입 조회 오류 [%d]", sqlca.sqlcode); FAIL(b); + } + } else { + h_amount = amount; h_fee = feein; + strncpy(h_channel, channel, sizeof(h_channel)-1); h_channel[sizeof(h_channel)-1] = 0; + strncpy(h_issuer, issuer, sizeof(h_issuer)-1); h_issuer[sizeof(h_issuer)-1] = 0; + } + if (h_amount <= 0) { setl(b, T_RC, 8103); Bchg(b, T_MSG, 0, "분해 대상 금액이 0 이하", 0L); FAIL(b); } + /* 카드종류: 명시값 우선, 없으면 매입ID 규칙(하위 3자리 % 10 < 3 → 체크카드) */ + if (ctype[0] == 0) strcpy(ctype, (h_pid > 0 && (h_pid % 10) < 3) ? "CHECK" : "CREDIT"); + if (scheme[0] == 0) strcpy(scheme, "BC"); + strncpy(h_ctype, ctype, sizeof(h_ctype)-1); h_ctype[sizeof(h_ctype)-1] = 0; + strncpy(h_scheme, scheme, sizeof(h_scheme)-1); h_scheme[sizeof(h_scheme)-1] = 0; + + /* ===== 3) interchange 요율 조회부 (card_type×channel×SALE) ===== */ + EXEC SQL SELECT rate_bps, fixed_fee INTO :h_icbps, :h_icfix FROM st_interchange_rate + WHERE card_type = :h_ctype AND mcc = 'DEFAULT' AND channel = :h_channel AND txn_type = 'SALE'; + if (sqlca.sqlcode == 100) { + /* 채널 미매핑 → DEFAULT 채널 요율로 폴백 */ + EXEC SQL SELECT rate_bps, fixed_fee INTO :h_icbps, :h_icfix FROM st_interchange_rate + WHERE card_type = :h_ctype AND mcc = 'DEFAULT' AND channel = 'DEFAULT' AND txn_type = 'SALE'; + if (sqlca.sqlcode == 100) { h_icbps = 130; h_icfix = 0; + userlog("[ST_FEEDECOMP] interchange 요율 미존재 ctype=%s chan=%s — 기본 130bp 적용", h_ctype, h_channel); } + else if (sqlca.sqlcode < 0) { setl(b, T_RC, 8120); Bchg(b, T_MSG, 0, "interchange 요율 조회 오류", 0L); FAIL(b); } + } else if (sqlca.sqlcode < 0) { setl(b, T_RC, 8120); Bchg(b, T_MSG, 0, "interchange 요율 조회 오류", 0L); FAIL(b); } + + /* ===== 4) scheme fee 요율 조회부 (scheme×SALE) ===== */ + EXEC SQL SELECT rate_bps, fixed_fee INTO :h_sfbps, :h_sffix FROM st_scheme_fee + WHERE scheme = :h_scheme AND txn_type = 'SALE'; + if (sqlca.sqlcode == 100) { h_sfbps = 11; h_sffix = 0; + userlog("[ST_FEEDECOMP] scheme 요율 미존재 scheme=%s — 기본 11bp 적용", h_scheme); } + else if (sqlca.sqlcode < 0) { setl(b, T_RC, 8130); Bchg(b, T_MSG, 0, "scheme 요율 조회 오류", 0L); FAIL(b); } + + /* ===== 5) 업무규칙 분기부 (3층 산출) ===== */ + h_ic = h_amount * h_icbps / 10000 + h_icfix; /* 발급사 귀속 */ + h_sf = h_amount * h_sfbps / 10000 + h_sffix; /* 카드망 귀속 */ + h_floor = h_amount * 8 / 10000; /* 매입사 최소 마진 8bp */ + h_markup = h_fee - h_ic - h_sf; /* 기존 flat fee 잔여 = markup */ + if (h_markup < h_floor) { + h_markup = h_floor; + userlog("[ST_FEEDECOMP] markup 하한(8bp) 적용 fee=%ld ic=%ld sf=%ld floor=%ld", h_fee, h_ic, h_sf, h_floor); + } + h_mdr = h_ic + h_sf + h_markup; /* MDR 합계 */ + userlog("[ST_FEEDECOMP] 3층분해 ic=%ld(%ldbp) sf=%ld(%ldbp) markup=%ld mdr=%ld", + h_ic, h_icbps, h_sf, h_sfbps, h_markup, h_mdr); + + /* ===== 6) 본처리부 (st_fee_component UPSERT) — 매입ID 있을 때만 영속 ===== */ + if (h_pid > 0) { + EXEC SQL INSERT INTO st_fee_component + (purchase_id, amount, interchange, scheme_fee, markup, mdr_total, card_type, scheme) + VALUES (:h_pid, :h_amount, :h_ic, :h_sf, :h_markup, :h_mdr, :h_ctype, :h_scheme) + ON CONFLICT (purchase_id) DO UPDATE SET + amount = excluded.amount, interchange = excluded.interchange, + scheme_fee = excluded.scheme_fee, markup = excluded.markup, + mdr_total = excluded.mdr_total, card_type = excluded.card_type, + scheme = excluded.scheme, computed_at = now(); + if (sqlca.sqlcode < 0) { + setl(b, T_RC, 8140); Bchg(b, T_MSG, 0, "수수료 분해 UPSERT 실패", 0L); + userlog("[ST_FEEDECOMP] st_fee_component UPSERT 실패 [%d]", sqlca.sqlcode); FAIL(b); + } + persist = 1; + } else { + userlog("[ST_FEEDECOMP] 매입ID 없음 — 미리보기(preview) 계산만 수행(영속 생략)"); + } + + /* ===== 7) 감사이력 적재부 (cm_log) + 재검증 ===== */ + snprintf(msgbuf, sizeof(msgbuf), "ST_FEEDECOMP pid=%ld amt=%ld ic=%ld sf=%ld markup=%ld mdr=%ld ctype=%s", + h_pid, h_amount, h_ic, h_sf, h_markup, h_mdr, h_ctype); + strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0; + EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date) + VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate); + if (sqlca.sqlcode < 0) { setl(b, T_RC, 8150); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); } + if (persist) { + EXEC SQL SELECT count(*) INTO :h_cnt FROM st_fee_component WHERE purchase_id = :h_pid; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 8151); Bchg(b, T_MSG, 0, "분해 재검증 조회 오류", 0L); FAIL(b); } + if (h_cnt <= 0) { setl(b, T_RC, 8152); Bchg(b, T_MSG, 0, "분해 미적재(보상 롤백)", 0L); FAIL(b); } + } + + /* ===== 8) 응답부 (출력 필드 설정) ===== */ + setl(b, T_AMT1, h_ic); /* interchange */ + setl(b, T_AMT2, h_sf); /* scheme_fee */ + setl(b, T_AMT3, h_markup); /* markup */ + setl(b, T_FEE, h_mdr); /* mdr_total */ + Bchg(b, T_STR1, 0, h_ctype, 0L); + Bchg(b, T_STR2, 0, h_scheme, 0L); + Bchg(b, T_SVCNAME, 0, "ST_FEEDECOMP", 0L); + setl(b, T_RC, 0); + + /* ===== 9) 완료 로깅 ===== */ + userlog("[정산심화] 수수료 3층 분해 완료 rc=0 pid=%ld mdr=%ld persist=%ld", h_pid, h_mdr, persist); + OK(b); +} + +/* vim: set ts=4 sw=4 et smartindent: */ diff --git a/app/src/st/svc/ST_FUNDING.h b/app/src/st/svc/ST_FUNDING.h new file mode 100644 index 0000000..928b072 --- /dev/null +++ b/app/src/st/svc/ST_FUNDING.h @@ -0,0 +1,26 @@ +/* + * ST_FUNDING.h - st 서비스 ST_FUNDING 카피북 (copybook / record header). + * 가맹점 펀딩 항등식: 총매출 − 환불 − 채그백 − 수수료 − 리저브 = 입금. + * gross(S)/refunds(C)/chargebacks(ac_dispute LOST)/fees(st_fee_component)/reserve(st_reserve) + * 조회 후 deposit 산출 → st_merchant_funding UPSERT. + */ +#ifndef ST_FUNDING_H +#define ST_FUNDING_H + +#include "st_svc.h" + +typedef struct { + char merchant_id[64]; + char biz_date[16]; + long gross_sales; + long refunds; + long chargebacks; + long fees; /* MDR 합계 */ + long reserve; + long deposit; /* 실제 입금액 */ + char funding_model[16]; +} st_st_funding_rec_t; + +void ST_FUNDING(TPSVCINFO *p); + +#endif /* ST_FUNDING_H */ diff --git a/app/src/st/svc/ST_FUNDING.pgc b/app/src/st/svc/ST_FUNDING.pgc new file mode 100644 index 0000000..9c4c2dc --- /dev/null +++ b/app/src/st/svc/ST_FUNDING.pgc @@ -0,0 +1,155 @@ +/* + * ST_FUNDING.pgc - st (정산/수수료) 모듈 서비스 ST_FUNDING (one service = one file). + * 가맹점 펀딩 항등식(심화판): 총매출(S) − 환불(C) − 채그백(ac_dispute LOST) − 수수료 + * (st_fee_component) − 리저브(st_reserve) = 입금(deposit) → st_merchant_funding UPSERT. + * 처리단계: 입력검증 -> 가맹점 마스터조회 -> 매출/환불/채그백/수수료/리저브 집계 + * -> 업무규칙(항등식/음수보정) -> st_merchant_funding UPSERT -> 감사이력 -> 재검증 -> 응답 -> 로깅. + * 호출자 XA 브랜치에서 수행(EXEC SQL CONNECT 없음). st_svr 가 tpsvrinit 에서 광고. + * XA 격리: 채그백/수수료/리저브는 본 브랜치에서 조회 가능한 커밋행 기준으로 집계한다. + */ +#include "ST_FUNDING.h" + +/* ST_FUNDING - 가맹점 펀딩 항등식(총매출-환불-채그백-수수료-리저브=입금). */ +void ST_FUNDING(TPSVCINFO *p) +{ + UBFH *b = (UBFH *)p->data; + /* ---- 지역 스크래치 (DECLARE SECTION 밖에서 초기화) ---- */ + char merch[64], bizdate[16], model[16], msgbuf[200]; + + EXEC SQL BEGIN DECLARE SECTION; + long h_mcnt, h_gross, h_refunds, h_cb, h_fees, h_reserve, h_deposit; + long h_scnt, h_ccnt, h_mdr, h_limit, h_chk; + char h_merch[64], h_bizdate[16], h_model[16], h_mstatus[16], h_svc[24], h_msg[200]; + EXEC SQL END DECLARE SECTION; + + strcpy(h_svc, "ST_FUNDING"); + h_mcnt = h_gross = h_refunds = h_cb = h_fees = h_reserve = h_deposit = 0; + h_scnt = h_ccnt = h_chk = 0; h_mdr = 25; h_limit = 0; + strcpy(h_mstatus, "ACTIVE"); strcpy(h_model, "NET_DAILY"); + + /* ===== 1) 입력 검증부 ===== */ + gets_(b, T_MERCHANT, merch, sizeof(merch)); + gets_(b, T_BIZDATE, bizdate, sizeof(bizdate)); + gets_(b, T_STR1, model, sizeof(model)); /* 선택: 펀딩모델 */ + if (model[0] == 0) strcpy(model, "NET_DAILY"); + userlog("[정산심화] 가맹점 펀딩 항등식 진입 merch=%s biz=%s model=%s", merch, bizdate, model); + if (merch[0] == 0) { + setl(b, T_RC, 8301); Bchg(b, T_MSG, 0, "가맹점 ID(merchant_id) 필수", 0L); + userlog("[ST_FUNDING] 가맹점 ID 누락"); FAIL(b); + } + if (strlen(bizdate) < 8) { + setl(b, T_RC, 8302); Bchg(b, T_MSG, 0, "영업일자(biz_date) 형식 오류", 0L); + userlog("[ST_FUNDING] 영업일 검증 실패 val=[%s]", bizdate); FAIL(b); + } + strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0; + strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; + strncpy(h_model, model, sizeof(h_model)-1); h_model[sizeof(h_model)-1] = 0; + + /* ===== 2) 가맹점 마스터 조회부 ===== */ + EXEC SQL SELECT mdr_bps, daily_limit, status + INTO :h_mdr, :h_limit, :h_mstatus FROM merchant WHERE merchant_id = :h_merch; + if (sqlca.sqlcode == 100) { + strcpy(h_mstatus, "NOMERCH"); h_mdr = 25; h_limit = 0; + userlog("[ST_FUNDING] 가맹점 마스터 미존재 mid=[%s] 기본정책 적용", h_merch); + } else if (sqlca.sqlcode < 0) { + setl(b, T_RC, 8310); Bchg(b, T_MSG, 0, "가맹점 마스터 조회 오류", 0L); FAIL(b); + } + + /* ===== 3) 매출/환불/채그백/수수료/리저브 집계부 ===== */ + /* 총매출(S) + 환불(C) — 상태별 분기 집계 */ + EXEC SQL SELECT + coalesce(sum(CASE WHEN status = 'S' THEN amount ELSE 0 END),0), + coalesce(sum(CASE WHEN status = 'C' THEN amount ELSE 0 END),0), + coalesce(sum(CASE WHEN status = 'S' THEN 1 ELSE 0 END),0), + coalesce(sum(CASE WHEN status = 'C' THEN 1 ELSE 0 END),0), + count(*) + INTO :h_gross, :h_refunds, :h_scnt, :h_ccnt, :h_mcnt + FROM purchase WHERE merchant_id = :h_merch AND biz_date = :h_bizdate; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 8320); Bchg(b, T_MSG, 0, "매출/환불 집계 오류", 0L); FAIL(b); } + /* 수수료(MDR 합계) = st_fee_component.mdr_total */ + EXEC SQL SELECT coalesce(sum(fc.mdr_total),0) INTO :h_fees + FROM st_fee_component fc JOIN purchase p ON p.purchase_id = fc.purchase_id + WHERE p.merchant_id = :h_merch AND p.biz_date = :h_bizdate; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 8321); Bchg(b, T_MSG, 0, "수수료 집계 오류", 0L); FAIL(b); } + /* 채그백 = 확정손실(ac_dispute LOST) 금액 */ + EXEC SQL SELECT coalesce(sum(d.amount),0) INTO :h_cb + FROM ac_dispute d JOIN purchase p ON p.purchase_id = d.purchase_id + WHERE p.merchant_id = :h_merch AND p.biz_date = :h_bizdate AND d.status = 'LOST'; + if (sqlca.sqlcode < 0) { setl(b, T_RC, 8322); Bchg(b, T_MSG, 0, "채그백 집계 오류", 0L); FAIL(b); } + /* 리저브 = 당일 유보액(없으면 0) */ + EXEC SQL SELECT reserve_amt INTO :h_reserve FROM st_reserve + WHERE merchant_id = :h_merch AND biz_date = :h_bizdate; + if (sqlca.sqlcode == 100) { h_reserve = 0; + userlog("[ST_FUNDING] 리저브 미설정 mid=%s biz=%s — 0 처리", h_merch, h_bizdate); } + else if (sqlca.sqlcode < 0) { setl(b, T_RC, 8323); Bchg(b, T_MSG, 0, "리저브 조회 오류", 0L); FAIL(b); } + userlog("[ST_FUNDING] 집계 gross=%ld refunds=%ld cb=%ld fees=%ld reserve=%ld (S=%ld C=%ld)", + h_gross, h_refunds, h_cb, h_fees, h_reserve, h_scnt, h_ccnt); + + /* ===== 4) 업무규칙 분기부 (항등식/음수보정) ===== */ + if (h_gross <= 0) { + Bchg(b, T_STATUS, 0, "NODATA", 0L); + setl(b, T_AMT1, 0); setl(b, T_AMT2, 0); setl(b, T_AMT3, 0); + Bchg(b, T_SVCNAME, 0, "ST_FUNDING", 0L); setl(b, T_RC, 0); + userlog("[ST_FUNDING] 당일 매출 없음 merch=%s biz=%s — 무처리 종료", h_merch, h_bizdate); + OK(b); + } + h_deposit = h_gross - h_refunds - h_cb - h_fees - h_reserve; /* 펀딩 항등식 */ + if (h_deposit < 0) + userlog("[ST_FUNDING] 입금액 음수(차감 초과) merch=%s deposit=%ld — 익일 이월 대상", h_merch, h_deposit); + + /* ===== 5) 본처리부 (st_merchant_funding UPSERT) ===== */ + EXEC SQL INSERT INTO st_merchant_funding + (funding_id, merchant_id, biz_date, gross_sales, refunds, chargebacks, + fees, reserve, deposit, funding_model, status) + VALUES (nextval('st_funding_seq'), :h_merch, :h_bizdate, :h_gross, :h_refunds, :h_cb, + :h_fees, :h_reserve, :h_deposit, :h_model, 'FUNDED') + ON CONFLICT (merchant_id, biz_date) DO UPDATE SET + gross_sales = excluded.gross_sales, refunds = excluded.refunds, + chargebacks = excluded.chargebacks, fees = excluded.fees, + reserve = excluded.reserve, deposit = excluded.deposit, + funding_model = excluded.funding_model, status = 'FUNDED', funded_at = now(); + if (sqlca.sqlcode < 0) { + setl(b, T_RC, 8330); Bchg(b, T_MSG, 0, "펀딩 UPSERT 실패", 0L); + userlog("[ST_FUNDING] st_merchant_funding UPSERT 실패 [%d]", sqlca.sqlcode); FAIL(b); + } + + /* ===== 6) 감사이력 적재부 (cm_log) ===== */ + snprintf(msgbuf, sizeof(msgbuf), "ST_FUNDING merch=%s biz=%s gross=%ld fees=%ld cb=%ld deposit=%ld", + h_merch, h_bizdate, h_gross, h_fees, h_cb, h_deposit); + strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0; + EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date) + VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate); + if (sqlca.sqlcode < 0) { setl(b, T_RC, 8340); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); } + + /* ===== 7) 재검증부 (항등식 검산 — 적재행 재조회) ===== */ + EXEC SQL SELECT deposit INTO :h_chk FROM st_merchant_funding + WHERE merchant_id = :h_merch AND biz_date = :h_bizdate; + if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) { + setl(b, T_RC, 8350); Bchg(b, T_MSG, 0, "펀딩 적재 재검증 실패", 0L); + userlog("[ST_FUNDING] 재검증 실패 code=%d", sqlca.sqlcode); FAIL(b); + } + if (h_chk != h_deposit) { + setl(b, T_RC, 8351); Bchg(b, T_MSG, 0, "펀딩 항등식 불일치(보상 롤백)", 0L); + userlog("[ST_FUNDING] 항등식 불일치 chk=%ld deposit=%ld", h_chk, h_deposit); FAIL(b); + } + + /* ===== 8) 응답부 (출력 필드 설정) ===== */ + setl(b, T_AMT1, h_gross); /* gross */ + setl(b, T_AMT2, h_fees); /* fees */ + setl(b, T_AMT3, h_deposit); /* deposit */ + setl(b, T_AMT4, h_reserve); /* reserve(참고) */ + setl(b, T_GROSS, h_gross); + setl(b, T_FEE, h_fees); + setl(b, T_NET, h_deposit); + setl(b, T_COUNT, h_mcnt); + Bchg(b, T_STATUS, 0, "FUNDED", 0L); + Bchg(b, T_SVCNAME, 0, "ST_FUNDING", 0L); + setl(b, T_RC, 0); + + /* ===== 9) 완료 로깅 ===== */ + userlog("[정산심화] 가맹점 펀딩 완료 merch=%s biz=%s gross=%ld fees=%ld deposit=%ld", + h_merch, h_bizdate, h_gross, h_fees, h_deposit); + OK(b); +} + +/* vim: set ts=4 sw=4 et smartindent: */ diff --git a/app/src/st/svc/ST_NETSETTLE.h b/app/src/st/svc/ST_NETSETTLE.h new file mode 100644 index 0000000..a4859f1 --- /dev/null +++ b/app/src/st/svc/ST_NETSETTLE.h @@ -0,0 +1,25 @@ +/* + * ST_NETSETTLE.h - st 서비스 ST_NETSETTLE 카피북 (copybook / record header). + * 발급사(회원 BIN)별 순액정산 배치. 해당 영업일의 st_fee_component+purchase 를 + * 회원사 BIN 별로 집계(gross/interchange/scheme) → net=gross-ic-sf → st_net_settlement UPSERT. + */ +#ifndef ST_NETSETTLE_H +#define ST_NETSETTLE_H + +#include "st_svc.h" + +typedef struct { + char biz_date[16]; + char issuer[40]; /* 선택: 특정 발급사(bank_code)만 정산 */ + char member_bin[16]; + long txn_count; + long gross_amt; + long interchange_amt; + long scheme_fee_amt; + long net_amt; + char direction[16]; /* RECEIVE/PAY */ +} st_st_netsettle_rec_t; + +void ST_NETSETTLE(TPSVCINFO *p); + +#endif /* ST_NETSETTLE_H */ diff --git a/app/src/st/svc/ST_NETSETTLE.pgc b/app/src/st/svc/ST_NETSETTLE.pgc new file mode 100644 index 0000000..c21a258 --- /dev/null +++ b/app/src/st/svc/ST_NETSETTLE.pgc @@ -0,0 +1,144 @@ +/* + * ST_NETSETTLE.pgc - st (정산/수수료) 모듈 서비스 ST_NETSETTLE (one service = one file). + * 발급사(회원 BIN)별 순액정산 배치(심화판). 해당 영업일의 st_fee_component+purchase 를 + * 회원사(st_member_bank) BIN 별로 집계 → gross/interchange/scheme 합산, net=gross-ic-sf + * → st_net_settlement UPSERT(ON CONFLICT scheme,member_bin,biz_date). + * 처리단계: 입력검증 -> 참가회원사/대상건 조회 -> 업무규칙(대상유무) -> 순액배치 UPSERT(집합기반) + * -> 결과 커서순회 로깅 -> 감사이력 -> 총계 재집계 -> 응답 -> 로깅. + * 호출자 XA 브랜치에서 수행(EXEC SQL CONNECT 없음). st_svr 가 tpsvrinit 에서 광고. + * 쓰기 소유자 단일화(owner-writes): 순액배치 UPSERT 는 집합기반 단일 문장으로 수행한다. + */ +#include "ST_NETSETTLE.h" + +/* ST_NETSETTLE - 발급사별 순액정산 배치. */ +void ST_NETSETTLE(TPSVCINFO *p) +{ + UBFH *b = (UBFH *)p->data; + /* ---- 지역 스크래치 (DECLARE SECTION 밖에서 초기화) ---- */ + char bizdate[16], issuer[40], msgbuf[200]; + long rows = 0; + + EXEC SQL BEGIN DECLARE SECTION; + long h_members, h_srccnt, h_upcnt, h_tcnt, h_tgross, h_tic, h_tsf, h_tnet; + long h_rcnt, h_rgross, h_rnet; + char h_bizdate[16], h_issuer[40], h_bin[16], h_dir[16], h_svc[24], h_msg[200]; + EXEC SQL END DECLARE SECTION; + + strcpy(h_svc, "ST_NETSETTLE"); + h_members = h_srccnt = h_upcnt = 0; + h_tcnt = h_tgross = h_tic = h_tsf = h_tnet = 0; + h_rcnt = h_rgross = h_rnet = 0; + strcpy(h_bin, "-"); strcpy(h_dir, "RECEIVE"); + + /* ===== 1) 입력 검증부 ===== */ + gets_(b, T_BIZDATE, bizdate, sizeof(bizdate)); + gets_(b, T_ISSUER, issuer, sizeof(issuer)); /* 선택: 특정 발급사만 */ + if (strlen(bizdate) < 8) { + setl(b, T_RC, 8201); Bchg(b, T_MSG, 0, "영업일자(biz_date) 형식 오류", 0L); + userlog("[ST_NETSETTLE] 영업일 검증 실패 val=[%s]", bizdate); FAIL(b); + } + strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; + strncpy(h_issuer, issuer, sizeof(h_issuer)-1); h_issuer[sizeof(h_issuer)-1] = 0; + userlog("[정산심화] 발급사별 순액정산 배치 진입 biz=%s issuer=[%s]", h_bizdate, h_issuer); + + /* ===== 2) 참가 회원사/대상건 조회부 ===== */ + EXEC SQL SELECT count(*) INTO :h_members FROM st_member_bank + WHERE role IN ('ISSUER', 'BOTH') AND (:h_issuer = '' OR bank_code = :h_issuer); + if (sqlca.sqlcode < 0) { setl(b, T_RC, 8210); Bchg(b, T_MSG, 0, "회원사 조회 오류", 0L); FAIL(b); } + EXEC SQL SELECT count(*) INTO :h_srccnt + FROM st_fee_component fc JOIN purchase p ON p.purchase_id = fc.purchase_id + JOIN st_member_bank mb ON mb.bank_code = p.issuer + WHERE p.biz_date = :h_bizdate AND (:h_issuer = '' OR p.issuer = :h_issuer); + if (sqlca.sqlcode < 0) { setl(b, T_RC, 8211); Bchg(b, T_MSG, 0, "정산 대상 조회 오류", 0L); FAIL(b); } + userlog("[ST_NETSETTLE] 참가 회원사=%ld 대상 분해건=%ld", h_members, h_srccnt); + + /* ===== 3) 업무규칙 분기부 (대상 유무) ===== */ + if (h_srccnt <= 0) { + Bchg(b, T_STATUS, 0, "NODATA", 0L); + setl(b, T_ARG1, 0); setl(b, T_AMT1, 0); setl(b, T_AMT2, 0); + Bchg(b, T_SVCNAME, 0, "ST_NETSETTLE", 0L); setl(b, T_RC, 0); + userlog("[ST_NETSETTLE] 대상 없음 biz=%s — 무처리 종료", h_bizdate); + OK(b); + } + + /* ===== 4) 본처리부: 발급사 BIN×영업일 순액배치 UPSERT (집합기반 단일문장) ===== + * net_amt = gross - interchange - scheme_fee (부호=수취/지급 방향). */ + EXEC SQL INSERT INTO st_net_settlement + (net_id, scheme, member_bin, biz_date, txn_count, + gross_amt, interchange_amt, scheme_fee_amt, net_amt, direction, status) + SELECT nextval('st_netset_seq'), 'BC', mb.bin, p.biz_date, count(*), + coalesce(sum(fc.amount),0), coalesce(sum(fc.interchange),0), coalesce(sum(fc.scheme_fee),0), + coalesce(sum(fc.amount - fc.interchange - fc.scheme_fee),0), + CASE WHEN coalesce(sum(fc.amount - fc.interchange - fc.scheme_fee),0) >= 0 + THEN 'RECEIVE' ELSE 'PAY' END, + 'SETTLED' + FROM st_fee_component fc + JOIN purchase p ON p.purchase_id = fc.purchase_id + JOIN st_member_bank mb ON mb.bank_code = p.issuer + WHERE p.biz_date = :h_bizdate AND (:h_issuer = '' OR p.issuer = :h_issuer) + GROUP BY mb.bin, p.biz_date + ON CONFLICT (scheme, member_bin, biz_date) DO UPDATE SET + txn_count = excluded.txn_count, gross_amt = excluded.gross_amt, + interchange_amt = excluded.interchange_amt, scheme_fee_amt = excluded.scheme_fee_amt, + net_amt = excluded.net_amt, direction = excluded.direction, settled_at = now(); + if (sqlca.sqlcode < 0) { + setl(b, T_RC, 8220); Bchg(b, T_MSG, 0, "순액정산 배치 UPSERT 실패", 0L); + userlog("[ST_NETSETTLE] st_net_settlement UPSERT 실패 [%d]", sqlca.sqlcode); FAIL(b); + } + h_upcnt = sqlca.sqlerrd[2]; /* 처리 행수 */ + userlog("[ST_NETSETTLE] 순액배치 UPSERT 처리행=%ld", h_upcnt); + + /* ===== 5) 결과 커서 순회 로깅부 (같은 XA 브랜치 — 방금 UPSERT 가시) ===== */ + EXEC SQL DECLARE cur_netset CURSOR FOR + SELECT member_bin, txn_count, gross_amt, net_amt, direction + FROM st_net_settlement + WHERE biz_date = :h_bizdate + AND (:h_issuer = '' OR member_bin IN (SELECT bin FROM st_member_bank WHERE bank_code = :h_issuer)) + ORDER BY member_bin; + EXEC SQL OPEN cur_netset; + for (;;) { + EXEC SQL FETCH cur_netset INTO :h_bin, :h_rcnt, :h_rgross, :h_rnet, :h_dir; + if (sqlca.sqlcode == 100) break; + if (sqlca.sqlcode < 0) { EXEC SQL CLOSE cur_netset; setl(b, T_RC, 8230); + Bchg(b, T_MSG, 0, "순액정산 결과 순회 오류", 0L); FAIL(b); } + rows++; + userlog("[ST_NETSETTLE] BIN=%s cnt=%ld gross=%ld net=%ld dir=%s", + h_bin, h_rcnt, h_rgross, h_rnet, h_dir); + } + EXEC SQL CLOSE cur_netset; + + /* ===== 6) 감사이력 적재부 (cm_log) ===== */ + snprintf(msgbuf, sizeof(msgbuf), "ST_NETSETTLE biz=%s members=%ld src=%ld upsert=%ld rows=%ld", + h_bizdate, h_members, h_srccnt, h_upcnt, rows); + strncpy(h_msg, msgbuf, sizeof(h_msg)-1); h_msg[sizeof(h_msg)-1] = 0; + EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date) + VALUES (nextval('cm_log_seq'), :h_svc, 'I', :h_msg, :h_bizdate); + if (sqlca.sqlcode < 0) { setl(b, T_RC, 8240); Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L); FAIL(b); } + + /* ===== 7) 총계 재집계부 ===== */ + EXEC SQL SELECT coalesce(sum(txn_count),0), coalesce(sum(gross_amt),0), + coalesce(sum(interchange_amt),0), coalesce(sum(scheme_fee_amt),0), + coalesce(sum(net_amt),0) + INTO :h_tcnt, :h_tgross, :h_tic, :h_tsf, :h_tnet + FROM st_net_settlement + WHERE biz_date = :h_bizdate + AND (:h_issuer = '' OR member_bin IN (SELECT bin FROM st_member_bank WHERE bank_code = :h_issuer)); + if (sqlca.sqlcode < 0) { setl(b, T_RC, 8250); Bchg(b, T_MSG, 0, "순액정산 총계 재집계 오류", 0L); FAIL(b); } + + /* ===== 8) 응답부 (출력 필드 설정) ===== */ + setl(b, T_ARG1, h_tcnt); /* txn_count 총계 */ + setl(b, T_AMT1, h_tgross); /* gross 총계 */ + setl(b, T_AMT2, h_tnet); /* net 총계 */ + setl(b, T_AMT3, h_tic); /* interchange 총계(참고) */ + setl(b, T_COUNT, rows); /* 정산 BIN 수 */ + Bchg(b, T_STATUS, 0, "SETTLED", 0L); + Bchg(b, T_SVCNAME, 0, "ST_NETSETTLE", 0L); + setl(b, T_RC, 0); + + /* ===== 9) 완료 로깅 ===== */ + userlog("[정산심화] 발급사별 순액정산 완료 biz=%s bins=%ld txn=%ld gross=%ld net=%ld", + h_bizdate, rows, h_tcnt, h_tgross, h_tnet); + OK(b); +} + +/* vim: set ts=4 sw=4 et smartindent: */ diff --git a/app/ui/callgraph.js b/app/ui/callgraph.js index e51e0f4..76f04f5 100644 --- a/app/ui/callgraph.js +++ b/app/ui/callgraph.js @@ -1,2 +1,2 @@ /* 자동생성: tools/gen_callgraph.py — svc tpcall 호출그래프 (레이아웃 사전계산). 손대지 말 것. */ -window.CALLGRAPH = {"MODULES":[{"id":"ac","nm":"매입","svc":133,"in":2,"out":57},{"id":"au","nm":"승인/한도","svc":133,"in":30,"out":17},{"id":"cl","nm":"마감","svc":133,"in":1,"out":50},{"id":"cm","nm":"공통","svc":133,"in":73,"out":0},{"id":"lg","nm":"원장","svc":133,"in":71,"out":7},{"id":"mg","nm":"전문게이트웨이","svc":133,"in":16,"out":7},{"id":"mm","nm":"마스터","svc":133,"in":1,"out":28},{"id":"py","nm":"지급","svc":133,"in":9,"out":24},{"id":"rc","nm":"대사","svc":133,"in":16,"out":54},{"id":"st","nm":"정산/수수료","svc":133,"in":36,"out":27},{"id":"vl","nm":"정합성검증","svc":133,"in":81,"out":65}],"MODEDGES":[{"f":"ac","t":"rc","c":5},{"f":"ac","t":"vl","c":7},{"f":"ac","t":"au","c":6},{"f":"ac","t":"lg","c":10},{"f":"ac","t":"st","c":15},{"f":"ac","t":"mg","c":4},{"f":"ac","t":"py","c":5},{"f":"ac","t":"cm","c":4},{"f":"ac","t":"mm","c":1},{"f":"au","t":"ac","c":2},{"f":"au","t":"cm","c":7},{"f":"au","t":"mg","c":8},{"f":"cl","t":"vl","c":30},{"f":"cl","t":"lg","c":18},{"f":"cl","t":"st","c":2},{"f":"lg","t":"vl","c":6},{"f":"lg","t":"cl","c":1},{"f":"mg","t":"cm","c":6},{"f":"mg","t":"au","c":1},{"f":"mm","t":"cm","c":16},{"f":"mm","t":"vl","c":8},{"f":"mm","t":"au","c":2},{"f":"mm","t":"st","c":2},{"f":"py","t":"lg","c":11},{"f":"py","t":"st","c":6},{"f":"py","t":"mg","c":4},{"f":"py","t":"cm","c":3},{"f":"rc","t":"vl","c":25},{"f":"rc","t":"lg","c":8},{"f":"rc","t":"cm","c":13},{"f":"rc","t":"st","c":7},{"f":"rc","t":"au","c":1},{"f":"st","t":"lg","c":16},{"f":"st","t":"py","c":4},{"f":"st","t":"vl","c":5},{"f":"st","t":"cm","c":2},{"f":"vl","t":"cm","c":22},{"f":"vl","t":"au","c":20},{"f":"vl","t":"lg","c":8},{"f":"vl","t":"st","c":4},{"f":"vl","t":"rc","c":11}],"NODES":[{"id":"ACQUIRE","m":"ac","x":773.4,"y":130.8,"d":1},{"id":"ACQ_ALERTDUP","m":"ac","x":592.8,"y":203.7,"d":1},{"id":"ACQ_AMTFIX","m":"ac","x":947.0,"y":361.0,"d":1},{"id":"ACQ_APPRGAP","m":"ac","x":934.1,"y":850.2,"d":1},{"id":"ACQ_APPRLINK","m":"ac","x":940.0,"y":612.8,"d":1},{"id":"ACQ_APPRMAP","m":"ac","x":944.9,"y":347.6,"d":1},{"id":"ACQ_CANCEL","m":"ac","x":773.9,"y":443.1,"d":3},{"id":"ACQ_CB_OPEN","m":"ac","x":945.8,"y":349.9,"d":1},{"id":"ACQ_CB_REVERSE","m":"ac","x":904.8,"y":219.3,"d":1},{"id":"ACQ_CLAIMREG","m":"ac","x":882.8,"y":203.4,"d":1},{"id":"ACQ_CORRAPPR","m":"ac","x":947.0,"y":767.0,"d":1},{"id":"ACQ_CORRECT","m":"ac","x":731.7,"y":735.6,"d":1},{"id":"ACQ_DDC","m":"ac","x":710.8,"y":799.0,"d":1},{"id":"ACQ_DUPCHK","m":"ac","x":516.9,"y":305.5,"d":1},{"id":"ACQ_EDC","m":"ac","x":879.2,"y":773.7,"d":1},{"id":"ACQ_EDI","m":"ac","x":698.1,"y":674.6,"d":1},{"id":"ACQ_EDIRESEND","m":"ac","x":783.1,"y":259.1,"d":1},{"id":"ACQ_ESCROW","m":"ac","x":946.0,"y":242.5,"d":1},{"id":"ACQ_ESCROWREL","m":"ac","x":676.5,"y":372.6,"d":1},{"id":"ACQ_EXCHANGE","m":"ac","x":804.5,"y":831.6,"d":1},{"id":"ACQ_FEEADJ","m":"ac","x":367.9,"y":557.3,"d":1},{"id":"ACQ_FEERECALC","m":"ac","x":937.1,"y":461.5,"d":1},{"id":"ACQ_FOREIGN","m":"ac","x":469.8,"y":587.6,"d":1},{"id":"ACQ_FXCONVERT","m":"ac","x":434.6,"y":744.5,"d":1},{"id":"ACQ_FXRATE","m":"ac","x":519.0,"y":759.2,"d":1},{"id":"ACQ_GUARANTEE","m":"ac","x":283.6,"y":170.1,"d":1},{"id":"ACQ_HOLD","m":"ac","x":950.0,"y":166.4,"d":1},{"id":"ACQ_INSTALL","m":"ac","x":946.5,"y":357.3,"d":1},{"id":"ACQ_INSTCXL","m":"ac","x":947.2,"y":344.2,"d":1},{"id":"ACQ_LIMITCHK","m":"ac","x":943.2,"y":494.7,"d":1},{"id":"ACQ_LIMITEXC","m":"ac","x":945.1,"y":670.3,"d":1},{"id":"ACQ_MERCHSUM","m":"ac","x":516.7,"y":183.7,"d":1},{"id":"ACQ_NETCALC","m":"ac","x":668.2,"y":905.6,"d":1},{"id":"ACQ_PARTCXL","m":"ac","x":609.0,"y":649.2,"d":2},{"id":"ACQ_PARTRFND","m":"ac","x":942.6,"y":498.4,"d":1},{"id":"ACQ_PROMO","m":"ac","x":949.8,"y":117.6,"d":1},{"id":"ACQ_REFUND","m":"ac","x":776.8,"y":518.3,"d":2},{"id":"ACQ_RELEASE","m":"ac","x":777.3,"y":471.7,"d":1},{"id":"ACQ_REMATCH","m":"ac","x":943.7,"y":526.4,"d":1},{"id":"ACQ_REPROC","m":"ac","x":643.9,"y":437.4,"d":1},{"id":"ACQ_RESERVE","m":"ac","x":942.7,"y":508.5,"d":1},{"id":"ACQ_RESERVECXL","m":"ac","x":949.9,"y":656.1,"d":1},{"id":"ACQ_RETURN","m":"ac","x":897.8,"y":297.3,"d":1},{"id":"ACQ_SETTLELINK","m":"ac","x":564.7,"y":464.2,"d":2},{"id":"ACQ_SPLITPAY","m":"ac","x":118.1,"y":149.7,"d":1},{"id":"ACQ_TAXCXL","m":"ac","x":789.0,"y":138.4,"d":1},{"id":"ACQ_TAXINV","m":"ac","x":920.4,"y":470.1,"d":1},{"id":"ACQ_TAXREVERSE","m":"ac","x":776.3,"y":394.7,"d":1},{"id":"ACQ_UNMATCH","m":"ac","x":939.6,"y":648.0,"d":1},{"id":"ACQ_VELOCITY","m":"ac","x":947.6,"y":914.9,"d":1},{"id":"ACQ_VOID","m":"ac","x":946.0,"y":236.6,"d":1},{"id":"ACQ_WHT","m":"ac","x":719.9,"y":243.0,"d":2},{"id":"ACQ_XFERLINK","m":"ac","x":632.0,"y":224.3,"d":1},{"id":"AUTH","m":"au","x":626.4,"y":773.8,"d":3},{"id":"AUTH_AMT_ADJUST","m":"au","x":945.3,"y":931.3,"d":1},{"id":"AUTH_APPROVE","m":"au","x":901.7,"y":934.0,"d":1},{"id":"AUTH_CANCEL","m":"au","x":937.2,"y":641.7,"d":2},{"id":"AUTH_CAPTURE","m":"au","x":853.8,"y":939.2,"d":1},{"id":"AUTH_DECLINE","m":"au","x":780.3,"y":671.2,"d":1},{"id":"AUTH_DUP_CHK","m":"au","x":931.7,"y":856.5,"d":1},{"id":"AUTH_EXPIRE_CHK","m":"au","x":937.0,"y":790.9,"d":1},{"id":"AUTH_HISTORY","m":"au","x":918.4,"y":345.8,"d":3},{"id":"AUTH_HOLD","m":"au","x":942.7,"y":521.2,"d":1},{"id":"AUTH_PARTAPPR","m":"au","x":949.4,"y":882.4,"d":1},{"id":"AUTH_PARTCXL","m":"au","x":914.7,"y":937.2,"d":1},{"id":"AUTH_RELEASE","m":"au","x":937.8,"y":638.1,"d":1},{"id":"AUTH_RESEND","m":"au","x":723.5,"y":805.4,"d":1},{"id":"AUTH_RETRY","m":"au","x":696.6,"y":613.9,"d":1},{"id":"AUTH_REVERSE","m":"au","x":947.2,"y":828.4,"d":1},{"id":"AUTH_STATUS","m":"au","x":788.1,"y":208.8,"d":2},{"id":"AUTH_SUMMARY","m":"au","x":941.1,"y":686.9,"d":1},{"id":"AUTH_VOID","m":"au","x":946.7,"y":921.7,"d":1},{"id":"BIN_ROUTE_INQ","m":"au","x":878.2,"y":596.8,"d":1},{"id":"BLACKLIST_CHK","m":"au","x":942.0,"y":903.4,"d":1},{"id":"CANCEL_STATUS","m":"au","x":941.3,"y":546.0,"d":1},{"id":"CARD_EXPIRE_CHK","m":"au","x":765.2,"y":902.3,"d":1},{"id":"CARD_LOST_REG","m":"au","x":732.0,"y":755.3,"d":1},{"id":"CARD_STOLEN_REG","m":"au","x":656.3,"y":619.2,"d":1},{"id":"CARD_VALIDATE","m":"au","x":942.0,"y":701.6,"d":1},{"id":"CL_AMTXCHECK","m":"cl","x":889.7,"y":295.7,"d":1},{"id":"CL_APPRDELEG","m":"cl","x":803.8,"y":937.3,"d":1},{"id":"CL_APPRFINAL","m":"cl","x":789.4,"y":942.2,"d":1},{"id":"CL_APPRL1","m":"cl","x":381.5,"y":924.3,"d":1},{"id":"CL_APPRL2","m":"cl","x":607.8,"y":940.1,"d":4},{"id":"CL_APPROVE","m":"cl","x":580.0,"y":934.8,"d":1},{"id":"CL_APPRREJECT","m":"cl","x":550.0,"y":945.0,"d":1},{"id":"CL_APPRREQ","m":"cl","x":685.9,"y":944.2,"d":1},{"id":"CL_APPRSTAT","m":"cl","x":603.0,"y":940.2,"d":1},{"id":"CL_BALVERIFY","m":"cl","x":574.8,"y":815.1,"d":1},{"id":"CL_CANCEL","m":"cl","x":639.6,"y":448.2,"d":1},{"id":"CL_CHKALL","m":"cl","x":580.5,"y":661.2,"d":1},{"id":"CL_CHKPENDING","m":"cl","x":732.6,"y":512.6,"d":1},{"id":"CL_CHKUNMATCH","m":"cl","x":859.4,"y":536.0,"d":1},{"id":"CL_CHKVOID","m":"cl","x":663.9,"y":683.0,"d":1},{"id":"CL_CHNVERIFY","m":"cl","x":890.9,"y":690.3,"d":1},{"id":"CL_CNTVERIFY","m":"cl","x":848.4,"y":717.7,"d":1},{"id":"CL_CNTXCHECK","m":"cl","x":630.5,"y":727.8,"d":1},{"id":"CL_CORPCLOSE","m":"cl","x":706.3,"y":944.6,"d":1},{"id":"CL_CORPVERIFY","m":"cl","x":800.1,"y":324.7,"d":1},{"id":"CL_DAILY","m":"cl","x":527.1,"y":948.2,"d":2},{"id":"CL_DAYVERIFY","m":"cl","x":534.7,"y":944.9,"d":1},{"id":"CL_DIFFCHK","m":"cl","x":661.7,"y":257.3,"d":1},{"id":"CL_DIVCLOSE","m":"cl","x":427.7,"y":937.7,"d":1},{"id":"CL_DUPCHK","m":"cl","x":482.6,"y":408.4,"d":1},{"id":"CL_ESCALATE","m":"cl","x":826.0,"y":945.1,"d":1},{"id":"CL_FEECROSS","m":"cl","x":584.8,"y":713.3,"d":1},{"id":"CL_FEEVERIFY","m":"cl","x":505.0,"y":569.3,"d":1},{"id":"CL_FORCECLOSE","m":"cl","x":670.5,"y":949.9,"d":1},{"id":"CL_HALFCLOSE","m":"cl","x":556.8,"y":944.3,"d":1},{"id":"CL_HYVERIFY","m":"cl","x":842.7,"y":616.3,"d":1},{"id":"CL_LOCK","m":"cl","x":498.7,"y":945.2,"d":1},{"id":"CL_MAINCLOSE","m":"cl","x":655.4,"y":944.5,"d":1},{"id":"CL_MERCLOSE","m":"cl","x":420.7,"y":929.1,"d":1},{"id":"CL_MERXCHECK","m":"cl","x":701.9,"y":945.2,"d":1},{"id":"CL_MIDCLOSE","m":"cl","x":794.6,"y":941.6,"d":1},{"id":"CL_MONTHLY","m":"cl","x":166.2,"y":927.8,"d":1},{"id":"CL_MONVERIFY","m":"cl","x":792.8,"y":595.7,"d":1},{"id":"CL_NETCROSS","m":"cl","x":865.4,"y":235.8,"d":1},{"id":"CL_NETVERIFY","m":"cl","x":700.9,"y":528.3,"d":1},{"id":"CL_POSTTRIG","m":"cl","x":416.7,"y":694.2,"d":1},{"id":"CL_PRECHECK","m":"cl","x":773.1,"y":941.5,"d":1},{"id":"CL_QTRVERIFY","m":"cl","x":819.0,"y":938.2,"d":1},{"id":"CL_QUARTER","m":"cl","x":611.9,"y":940.1,"d":1},{"id":"CL_RECLOSE","m":"cl","x":637.8,"y":397.0,"d":1},{"id":"CL_RECON","m":"cl","x":712.1,"y":824.1,"d":1},{"id":"CL_ROLLBACK","m":"cl","x":679.7,"y":621.5,"d":1},{"id":"CL_SEGVERIFY","m":"cl","x":925.1,"y":558.5,"d":1},{"id":"CL_SEMIMONTH","m":"cl","x":319.5,"y":950.0,"d":1},{"id":"CL_SNAPSHOT","m":"cl","x":361.7,"y":929.3,"d":1},{"id":"CL_SNAPXCHECK","m":"cl","x":785.9,"y":943.0,"d":1},{"id":"CL_STCROSS","m":"cl","x":815.6,"y":593.4,"d":1},{"id":"CL_TENDAY","m":"cl","x":463.1,"y":936.7,"d":1},{"id":"CL_TRIGSETTLE","m":"cl","x":665.9,"y":582.9,"d":1},{"id":"CL_VERIFY","m":"cl","x":838.4,"y":906.7,"d":1},{"id":"CL_WEEKLY","m":"cl","x":173.1,"y":930.6,"d":1},{"id":"CL_WEEKVERIFY","m":"cl","x":409.6,"y":617.5,"d":1},{"id":"CL_YEAREND","m":"cl","x":618.7,"y":947.6,"d":1},{"id":"CL_YEARVERIFY","m":"cl","x":154.1,"y":266.8,"d":1},{"id":"CM_ADDDAYS","m":"cm","x":553.1,"y":944.7,"d":1},{"id":"CM_AMT_ROUND","m":"cm","x":494.5,"y":389.9,"d":3},{"id":"CM_BATDEP_CHK","m":"cm","x":330.0,"y":939.8,"d":1},{"id":"CM_BATDEP_SET","m":"cm","x":407.0,"y":940.9,"d":1},{"id":"CM_BATHIST_CNT","m":"cm","x":193.2,"y":948.7,"d":1},{"id":"CM_BATLAST","m":"cm","x":326.3,"y":907.9,"d":4},{"id":"CM_BATRERUN_REQ","m":"cm","x":414.1,"y":941.7,"d":1},{"id":"CM_BATSCHD_DEL","m":"cm","x":504.7,"y":698.2,"d":1},{"id":"CM_BATSCHD_REG","m":"cm","x":338.1,"y":607.1,"d":1},{"id":"CM_BIZDAY","m":"cm","x":243.4,"y":476.7,"d":8},{"id":"CM_BIZDAY_ADD","m":"cm","x":392.6,"y":938.7,"d":1},{"id":"CM_BIZDAY_CNT","m":"cm","x":614.3,"y":948.4,"d":1},{"id":"CM_CACHE_INV","m":"cm","x":285.5,"y":942.0,"d":1},{"id":"CM_CACHE_LOAD","m":"cm","x":278.6,"y":943.0,"d":1},{"id":"CM_CHECKDIGIT","m":"cm","x":290.1,"y":804.7,"d":1},{"id":"CM_CODE","m":"cm","x":601.4,"y":949.0,"d":2},{"id":"CM_CODEGRP_REG","m":"cm","x":364.4,"y":946.3,"d":1},{"id":"CM_CRC","m":"cm","x":116.9,"y":752.5,"d":2},{"id":"CM_ERRMSG","m":"cm","x":379.0,"y":637.7,"d":1},{"id":"CM_FX","m":"cm","x":327.1,"y":852.8,"d":6},{"id":"CM_FX_CONV","m":"cm","x":453.5,"y":533.2,"d":5},{"id":"CM_FX_CROSS","m":"cm","x":581.7,"y":949.2,"d":2},{"id":"CM_FX_INVERT","m":"cm","x":112.4,"y":946.9,"d":1},{"id":"CM_FX_MARGIN","m":"cm","x":166.3,"y":946.4,"d":1},{"id":"CM_FX_PUBLISH","m":"cm","x":543.0,"y":927.2,"d":1},{"id":"CM_FX_TRIANGLE","m":"cm","x":255.1,"y":949.4,"d":1},{"id":"CM_FX_VALID","m":"cm","x":516.4,"y":640.8,"d":2},{"id":"CM_HASH_DJB2","m":"cm","x":292.8,"y":939.8,"d":1},{"id":"CM_HASH_FNV","m":"cm","x":128.0,"y":532.1,"d":1},{"id":"CM_HASH_SUM","m":"cm","x":95.6,"y":933.8,"d":2},{"id":"CM_HOLIDAY_CHK","m":"cm","x":508.8,"y":948.0,"d":3},{"id":"CM_LOG","m":"cm","x":430.1,"y":524.3,"d":44},{"id":"CM_LUHN","m":"cm","x":739.4,"y":465.9,"d":8},{"id":"CM_MONTHEND","m":"cm","x":351.8,"y":689.7,"d":1},{"id":"CM_MSG_RENDER","m":"cm","x":386.5,"y":881.8,"d":1},{"id":"CM_NEXTBIZ","m":"cm","x":201.8,"y":656.9,"d":1},{"id":"CM_NOTI_HIST","m":"cm","x":404.4,"y":942.4,"d":1},{"id":"CM_NOTI_QUOTA","m":"cm","x":298.0,"y":789.8,"d":1},{"id":"CM_NOTI_RETRY","m":"cm","x":321.3,"y":568.3,"d":1},{"id":"CM_NOTI_SEND","m":"cm","x":231.4,"y":171.1,"d":4},{"id":"CM_NOTI_TMPL","m":"cm","x":384.8,"y":704.9,"d":1},{"id":"CM_PARAM","m":"cm","x":432.1,"y":943.4,"d":4},{"id":"CM_PREVBIZ","m":"cm","x":238.6,"y":759.1,"d":1},{"id":"CM_SEQ","m":"cm","x":133.1,"y":394.1,"d":7},{"id":"CM_SEQ_ALLOC","m":"cm","x":461.4,"y":872.1,"d":1},{"id":"CM_SEQ_DAILY","m":"cm","x":443.1,"y":940.6,"d":1},{"id":"CM_SEQ_MULTI","m":"cm","x":585.5,"y":834.8,"d":1},{"id":"CM_SEQ_RESET","m":"cm","x":405.7,"y":838.0,"d":1},{"id":"CM_SEQ_STAMP","m":"cm","x":418.1,"y":800.7,"d":1},{"id":"CM_SEQ_TYPED","m":"cm","x":365.2,"y":590.4,"d":1},{"id":"CM_STATUS","m":"cm","x":203.3,"y":419.2,"d":3},{"id":"FRAUD_DETECT","m":"au","x":857.2,"y":721.6,"d":8},{"id":"FRAUD_RULE_AMT","m":"au","x":930.5,"y":286.0,"d":1},{"id":"FRAUD_RULE_NIGHT","m":"au","x":941.5,"y":616.6,"d":1},{"id":"INSTALL_AUTH","m":"au","x":939.4,"y":824.4,"d":1},{"id":"LG_ACCRUEREV","m":"lg","x":247.1,"y":636.0,"d":1},{"id":"LG_ACCTSUM","m":"lg","x":140.1,"y":875.2,"d":3},{"id":"LG_ACQPOST","m":"lg","x":59.6,"y":663.4,"d":1},{"id":"LG_ADJUST","m":"lg","x":333.6,"y":508.1,"d":3},{"id":"LG_ALLOWANCE","m":"lg","x":296.8,"y":676.5,"d":1},{"id":"LG_ALLOWRECALC","m":"lg","x":67.2,"y":927.3,"d":1},{"id":"LG_BADDEBT","m":"lg","x":225.9,"y":576.6,"d":1},{"id":"LG_BADDEBTRCV","m":"lg","x":225.5,"y":459.5,"d":1},{"id":"LG_BALCERT","m":"lg","x":65.6,"y":940.4,"d":1},{"id":"LG_BALCHK","m":"lg","x":276.7,"y":671.8,"d":22},{"id":"LG_BALPROOF","m":"lg","x":290.0,"y":941.7,"d":1},{"id":"LG_BLACKENTRY","m":"lg","x":148.8,"y":776.7,"d":1},{"id":"LG_BSSUMMARY","m":"lg","x":59.3,"y":893.7,"d":1},{"id":"LG_CLOSE_LINK","m":"lg","x":592.4,"y":896.6,"d":4},{"id":"LG_CORPSUM","m":"lg","x":442.4,"y":866.3,"d":3},{"id":"LG_CORRECT","m":"lg","x":496.0,"y":744.8,"d":2},{"id":"LG_DEPTSUM","m":"lg","x":388.6,"y":867.4,"d":3},{"id":"LG_DOUBLE","m":"lg","x":179.1,"y":779.5,"d":1},{"id":"LG_DUPSCAN","m":"lg","x":264.3,"y":942.4,"d":1},{"id":"LG_FEEACCRUE","m":"lg","x":68.5,"y":726.0,"d":1},{"id":"LG_FEEPOST","m":"lg","x":92.5,"y":659.9,"d":2},{"id":"LG_HALFCLOSE","m":"lg","x":60.1,"y":932.9,"d":1},{"id":"LG_INQUIRY","m":"lg","x":799.3,"y":268.1,"d":3},{"id":"LG_JOURNAL","m":"lg","x":78.9,"y":945.3,"d":1},{"id":"LG_MERCHBAL","m":"lg","x":534.2,"y":802.3,"d":2},{"id":"LG_MERCHPROOF","m":"lg","x":238.0,"y":943.3,"d":2},{"id":"LG_MONTHCLOSE","m":"lg","x":122.3,"y":939.8,"d":1},{"id":"LG_MONTHLYSUM","m":"lg","x":59.6,"y":937.6,"d":2},{"id":"LG_NETPOS","m":"lg","x":235.6,"y":936.8,"d":1},{"id":"LG_PARTREVERSE","m":"lg","x":425.7,"y":501.9,"d":2},{"id":"LG_PERIODTB","m":"lg","x":370.4,"y":870.3,"d":2},{"id":"LG_PLSUMMARY","m":"lg","x":61.0,"y":836.2,"d":1},{"id":"LG_POST","m":"lg","x":352.6,"y":317.3,"d":28},{"id":"LG_PREPAIDAMORT","m":"lg","x":113.9,"y":917.0,"d":1},{"id":"LG_PREPAIDPOST","m":"lg","x":221.4,"y":893.4,"d":2},{"id":"LG_QTRCLOSE","m":"lg","x":62.1,"y":857.6,"d":1},{"id":"LG_RECALC","m":"lg","x":286.6,"y":878.3,"d":6},{"id":"LG_REDADJUST","m":"lg","x":271.3,"y":619.3,"d":1},{"id":"LG_REDBLACKNET","m":"lg","x":211.3,"y":847.1,"d":1},{"id":"LG_REDENTRY","m":"lg","x":204.3,"y":741.5,"d":2},{"id":"LG_REPOST","m":"lg","x":261.9,"y":705.9,"d":1},{"id":"LG_REVERSE","m":"lg","x":612.6,"y":273.5,"d":19},{"id":"LG_ROLLTB","m":"lg","x":311.3,"y":914.4,"d":2},{"id":"LG_SETTLEPOST","m":"lg","x":385.8,"y":456.8,"d":2},{"id":"LG_SPANTB","m":"lg","x":248.2,"y":941.3,"d":2},{"id":"LG_STATUS","m":"lg","x":597.5,"y":396.0,"d":2},{"id":"LG_SUSPENSE","m":"lg","x":105.6,"y":834.7,"d":1},{"id":"LG_THREEWAY","m":"lg","x":334.1,"y":178.8,"d":1},{"id":"LG_TRANSFER","m":"lg","x":199.7,"y":872.5,"d":1},{"id":"LG_TRIALBAL","m":"lg","x":155.8,"y":881.6,"d":7},{"id":"LG_UNEARNPOST","m":"lg","x":118.1,"y":870.1,"d":2},{"id":"LG_UNEARNRECOG","m":"lg","x":71.7,"y":936.6,"d":1},{"id":"LG_VOIDVOUCHER","m":"lg","x":731.3,"y":423.7,"d":1},{"id":"LG_VOUCHER","m":"lg","x":149.0,"y":650.0,"d":1},{"id":"LG_WEEKCLOSE","m":"lg","x":250.7,"y":940.5,"d":1},{"id":"LG_WRITEOFF","m":"lg","x":209.8,"y":473.2,"d":1},{"id":"LG_XFERPOST","m":"lg","x":171.8,"y":713.3,"d":1},{"id":"LG_YEARCLOSE","m":"lg","x":68.6,"y":720.1,"d":1},{"id":"LIMIT_CHK","m":"au","x":679.8,"y":470.6,"d":10},{"id":"LIMIT_DEC","m":"au","x":886.6,"y":824.1,"d":10},{"id":"LIMIT_EXHAUST_LST","m":"au","x":768.4,"y":641.6,"d":1},{"id":"LIMIT_FREEZE","m":"au","x":639.8,"y":566.9,"d":1},{"id":"LIMIT_OVER_ALERT","m":"au","x":444.2,"y":604.8,"d":1},{"id":"LIMIT_RST","m":"au","x":856.0,"y":729.8,"d":13},{"id":"MG_ACK","m":"mg","x":51.7,"y":682.5,"d":1},{"id":"MG_BITMAP","m":"mg","x":63.4,"y":511.6,"d":1},{"id":"MG_BMPPARSE","m":"mg","x":61.0,"y":735.4,"d":1},{"id":"MG_CHANFAILOVER","m":"mg","x":57.1,"y":493.8,"d":1},{"id":"MG_CHANHEALTH","m":"mg","x":52.6,"y":762.7,"d":1},{"id":"MG_CHANOPEN","m":"mg","x":52.9,"y":728.0,"d":1},{"id":"MG_CHANPING","m":"mg","x":58.7,"y":565.6,"d":2},{"id":"MG_CHANSTAT","m":"mg","x":64.6,"y":818.4,"d":1},{"id":"MG_CHANSWITCH","m":"mg","x":58.4,"y":652.9,"d":1},{"id":"MG_DECODE","m":"mg","x":59.4,"y":554.7,"d":1},{"id":"MG_ENCODE","m":"mg","x":52.6,"y":710.4,"d":1},{"id":"MG_ERRREQUEUE","m":"mg","x":58.5,"y":601.9,"d":1},{"id":"MG_ERRRETRY","m":"mg","x":106.0,"y":541.2,"d":1},{"id":"MG_FROMISO","m":"mg","x":50.0,"y":757.4,"d":1},{"id":"MG_ISO8583","m":"mg","x":64.9,"y":544.9,"d":1},{"id":"MG_KEYCHECK","m":"mg","x":56.2,"y":866.9,"d":1},{"id":"MG_KEYLOAD","m":"mg","x":56.5,"y":510.9,"d":1},{"id":"MG_LOADBAL","m":"mg","x":60.4,"y":592.3,"d":1},{"id":"MG_LOG","m":"mg","x":681.0,"y":778.5,"d":6},{"id":"MG_MAC","m":"mg","x":57.7,"y":871.5,"d":1},{"id":"MG_MACGEN","m":"mg","x":54.1,"y":708.0,"d":1},{"id":"MG_MACSESSION","m":"mg","x":55.4,"y":912.6,"d":1},{"id":"MG_MACVERIFY","m":"mg","x":57.1,"y":571.0,"d":1},{"id":"MG_NACK","m":"mg","x":58.5,"y":624.5,"d":1},{"id":"MG_PACK","m":"mg","x":58.3,"y":612.4,"d":1},{"id":"MG_PARSE","m":"mg","x":115.7,"y":705.3,"d":9},{"id":"MG_REASM","m":"mg","x":55.8,"y":917.5,"d":1},{"id":"MG_RECV","m":"mg","x":52.2,"y":805.9,"d":1},{"id":"MG_RESEND","m":"mg","x":466.6,"y":384.4,"d":2},{"id":"MG_RESNDONE","m":"mg","x":50.2,"y":781.9,"d":1},{"id":"MG_ROUTE","m":"mg","x":55.3,"y":743.4,"d":4},{"id":"MG_SEND","m":"mg","x":272.2,"y":574.9,"d":19},{"id":"MG_SEQFILL","m":"mg","x":54.5,"y":777.1,"d":1},{"id":"MG_SEQNEXT","m":"mg","x":54.8,"y":877.9,"d":1},{"id":"MG_STAN","m":"mg","x":96.0,"y":675.8,"d":3},{"id":"MG_TOISO","m":"mg","x":58.2,"y":583.6,"d":1},{"id":"MG_UNPACK","m":"mg","x":55.6,"y":739.1,"d":1},{"id":"MM_ACCT_REG","m":"mm","x":419.5,"y":424.8,"d":1},{"id":"MM_ACCT_VERIFY","m":"mm","x":439.0,"y":405.4,"d":1},{"id":"MM_APPLY_APPROVE","m":"mm","x":52.0,"y":327.7,"d":1},{"id":"MM_APPLY_REG","m":"mm","x":51.5,"y":313.6,"d":1},{"id":"MM_BIN_REG","m":"mm","x":488.6,"y":284.6,"d":1},{"id":"MM_BIZNO_CHECK","m":"mm","x":50.2,"y":678.0,"d":1},{"id":"MM_CHK_LIMIT","m":"mm","x":272.6,"y":409.4,"d":1},{"id":"MM_CODE_REG","m":"mm","x":168.0,"y":237.3,"d":1},{"id":"MM_CONTRACT_AMEND","m":"mm","x":56.6,"y":240.2,"d":1},{"id":"MM_CONTRACT_NEW","m":"mm","x":53.3,"y":290.2,"d":1},{"id":"MM_CONTRACT_RENEW","m":"mm","x":58.5,"y":573.3,"d":1},{"id":"MM_FEERATE_SET","m":"mm","x":333.2,"y":258.3,"d":1},{"id":"MM_GRADE_ADJUST","m":"mm","x":57.5,"y":245.0,"d":1},{"id":"MM_ISSUER_REG","m":"mm","x":265.6,"y":304.2,"d":1},{"id":"MM_LIMIT_SET","m":"mm","x":373.7,"y":414.5,"d":1},{"id":"MM_MCC_REG","m":"mm","x":335.4,"y":156.3,"d":1},{"id":"MM_MCC_UPD","m":"mm","x":318.6,"y":224.0,"d":1},{"id":"MM_MERCH_CLOSE","m":"mm","x":180.5,"y":513.0,"d":1},{"id":"MM_MERCH_DORMANT","m":"mm","x":54.0,"y":236.4,"d":1},{"id":"MM_MERCH_GRADE","m":"mm","x":59.6,"y":405.5,"d":1},{"id":"MM_MERCH_INQ","m":"mm","x":316.6,"y":188.3,"d":1},{"id":"MM_MERCH_PAUSE","m":"mm","x":85.9,"y":219.5,"d":1},{"id":"MM_MERCH_REG","m":"mm","x":60.1,"y":370.1,"d":1},{"id":"MM_MERCH_RESUME","m":"mm","x":200.7,"y":484.9,"d":1},{"id":"MM_MERCH_STATUS","m":"mm","x":65.1,"y":298.3,"d":1},{"id":"MM_MERCH_UPD","m":"mm","x":59.3,"y":356.7,"d":1},{"id":"MM_RATE_APPROVE","m":"mm","x":232.9,"y":78.2,"d":1},{"id":"MM_RATE_REQ","m":"mm","x":278.1,"y":508.2,"d":1},{"id":"MM_RISK_SCORE","m":"mm","x":179.2,"y":419.0,"d":1},{"id":"MM_RISK_SET","m":"mm","x":59.3,"y":163.9,"d":1},{"id":"MM_TERMINAL_REG","m":"mm","x":57.1,"y":388.3,"d":1},{"id":"MM_TERM_INSTALL","m":"mm","x":60.5,"y":447.7,"d":1},{"id":"MM_VALIDATE","m":"mm","x":112.4,"y":369.0,"d":5},{"id":"NOAUTH_CAPTURE","m":"au","x":934.9,"y":885.0,"d":1},{"id":"PAY_ACCTCHK","m":"py","x":137.6,"y":111.7,"d":11},{"id":"PAY_ACCTVERIFY","m":"py","x":65.3,"y":190.9,"d":1},{"id":"PAY_ADJUST","m":"py","x":434.6,"y":99.2,"d":1},{"id":"PAY_APPRBULK","m":"py","x":302.5,"y":60.5,"d":1},{"id":"PAY_APPROVE","m":"py","x":232.4,"y":57.6,"d":1},{"id":"PAY_BANKFILE","m":"py","x":175.4,"y":303.5,"d":1},{"id":"PAY_BANKVERIFY","m":"py","x":67.3,"y":62.7,"d":1},{"id":"PAY_CANCEL","m":"py","x":316.3,"y":132.9,"d":2},{"id":"PAY_CHARGEBACK","m":"py","x":432.2,"y":89.6,"d":1},{"id":"PAY_CLOSE","m":"py","x":192.8,"y":137.4,"d":1},{"id":"PAY_COMBINE","m":"py","x":74.0,"y":54.6,"d":1},{"id":"PAY_CONFIRM","m":"py","x":179.8,"y":217.7,"d":1},{"id":"PAY_FAILRSN","m":"py","x":71.6,"y":102.5,"d":3},{"id":"PAY_FILEGEN","m":"py","x":467.5,"y":87.4,"d":7},{"id":"PAY_FILEREBUILD","m":"py","x":59.9,"y":249.1,"d":1},{"id":"PAY_HOLD","m":"py","x":720.3,"y":290.0,"d":3},{"id":"PAY_MERGE","m":"py","x":60.4,"y":65.1,"d":1},{"id":"PAY_NETOFF","m":"py","x":200.1,"y":167.0,"d":1},{"id":"PAY_RECLAIM","m":"py","x":389.7,"y":111.7,"d":2},{"id":"PAY_REFUND","m":"py","x":296.5,"y":60.9,"d":1},{"id":"PAY_RELEASE","m":"py","x":517.0,"y":437.6,"d":3},{"id":"PAY_REMIT","m":"py","x":64.9,"y":133.4,"d":1},{"id":"PAY_REPROC","m":"py","x":66.5,"y":57.1,"d":1},{"id":"PAY_REQUEUE","m":"py","x":76.3,"y":455.6,"d":1},{"id":"PAY_RESULT","m":"py","x":139.7,"y":203.7,"d":1},{"id":"PAY_RESVMODIFY","m":"py","x":98.5,"y":370.6,"d":1},{"id":"PAY_RETRY","m":"py","x":66.4,"y":142.0,"d":1},{"id":"PAY_RETRYONE","m":"py","x":100.8,"y":57.7,"d":1},{"id":"PAY_REVERSE","m":"py","x":410.8,"y":83.9,"d":2},{"id":"PAY_ROLLFWD","m":"py","x":84.4,"y":442.5,"d":1},{"id":"PAY_SCHEDULE","m":"py","x":60.5,"y":348.5,"d":1},{"id":"PAY_SPLIT","m":"py","x":65.8,"y":135.7,"d":1},{"id":"PAY_SPLITEVEN","m":"py","x":56.0,"y":66.3,"d":1},{"id":"PAY_SPLITRATIO","m":"py","x":236.2,"y":57.1,"d":1},{"id":"PAY_URGENT","m":"py","x":95.5,"y":51.5,"d":1},{"id":"PAY_VOIDONE","m":"py","x":383.4,"y":134.7,"d":1},{"id":"PAY_XFERLINK","m":"py","x":355.5,"y":359.0,"d":2},{"id":"PREAUTH","m":"au","x":942.1,"y":896.3,"d":1},{"id":"PREAUTH_CANCEL","m":"au","x":654.1,"y":864.8,"d":1},{"id":"PREAUTH_COMPLETE","m":"au","x":928.2,"y":932.0,"d":1},{"id":"PREAUTH_EXTEND","m":"au","x":870.3,"y":552.0,"d":1},{"id":"PREAUTH_INQ","m":"au","x":940.3,"y":620.8,"d":1},{"id":"PREAUTH_PARTUSE","m":"au","x":941.2,"y":933.6,"d":1},{"id":"RC_3WAY","m":"rc","x":450.1,"y":134.6,"d":2},{"id":"RC_4WAY","m":"rc","x":207.1,"y":50.7,"d":1},{"id":"RC_ACQMATCH","m":"rc","x":606.5,"y":53.7,"d":1},{"id":"RC_ACQ_DEP","m":"rc","x":156.3,"y":361.5,"d":1},{"id":"RC_ALERT","m":"rc","x":210.7,"y":50.2,"d":1},{"id":"RC_AMTDIFF","m":"rc","x":479.5,"y":57.2,"d":1},{"id":"RC_APPRGAP","m":"rc","x":762.5,"y":53.1,"d":1},{"id":"RC_APPRMATCH","m":"rc","x":602.4,"y":55.4,"d":1},{"id":"RC_APPR_ACQ","m":"rc","x":404.1,"y":57.8,"d":1},{"id":"RC_AUTOFIX","m":"rc","x":515.0,"y":52.8,"d":1},{"id":"RC_CLOSEDAY","m":"rc","x":569.9,"y":57.6,"d":1},{"id":"RC_CNTDIFF","m":"rc","x":318.2,"y":151.9,"d":1},{"id":"RC_CONFIRM","m":"rc","x":499.1,"y":52.5,"d":1},{"id":"RC_DEPGAP","m":"rc","x":134.7,"y":100.0,"d":1},{"id":"RC_DEPMATCH","m":"rc","x":382.7,"y":229.6,"d":1},{"id":"RC_DUPCHK","m":"rc","x":634.5,"y":331.0,"d":3},{"id":"RC_ESCALATE","m":"rc","x":650.4,"y":663.8,"d":2},{"id":"RC_EXCEPTION","m":"rc","x":711.5,"y":322.7,"d":7},{"id":"RC_EXCNOTIFY","m":"rc","x":91.6,"y":119.1,"d":1},{"id":"RC_FEEDIFF","m":"rc","x":457.1,"y":307.4,"d":1},{"id":"RC_FEERECON","m":"rc","x":473.1,"y":195.5,"d":1},{"id":"RC_FIXFEE","m":"rc","x":337.5,"y":52.0,"d":1},{"id":"RC_FIXFX","m":"rc","x":328.8,"y":535.9,"d":1},{"id":"RC_FIXROUND","m":"rc","x":444.1,"y":340.6,"d":1},{"id":"RC_FXDIFF","m":"rc","x":575.4,"y":116.9,"d":1},{"id":"RC_FXRECON","m":"rc","x":709.1,"y":50.3,"d":1},{"id":"RC_HOLDCLR","m":"rc","x":495.5,"y":52.5,"d":1},{"id":"RC_HOLDSET","m":"rc","x":409.4,"y":50.0,"d":1},{"id":"RC_LEDGERBAL","m":"rc","x":212.5,"y":354.5,"d":1},{"id":"RC_LEDGERLINK","m":"rc","x":396.7,"y":64.5,"d":1},{"id":"RC_LIMITCHK","m":"rc","x":493.5,"y":100.0,"d":1},{"id":"RC_MANUAL","m":"rc","x":411.9,"y":58.6,"d":1},{"id":"RC_NOTIFY","m":"rc","x":314.8,"y":61.7,"d":1},{"id":"RC_ORPHAN","m":"rc","x":635.1,"y":190.0,"d":1},{"id":"RC_OVERAMT","m":"rc","x":546.0,"y":56.7,"d":1},{"id":"RC_PAYLEDGER","m":"rc","x":168.4,"y":62.6,"d":1},{"id":"RC_PAYMATCH","m":"rc","x":310.8,"y":61.3,"d":1},{"id":"RC_PROGRESS","m":"rc","x":97.4,"y":435.6,"d":1},{"id":"RC_RECORR","m":"rc","x":398.9,"y":342.0,"d":1},{"id":"RC_REDIFF","m":"rc","x":615.5,"y":55.6,"d":1},{"id":"RC_REFULL","m":"rc","x":688.3,"y":261.8,"d":1},{"id":"RC_REFUNDREC","m":"rc","x":723.7,"y":72.5,"d":1},{"id":"RC_RELEASE","m":"rc","x":397.0,"y":57.7,"d":1},{"id":"RC_REMATCH","m":"rc","x":719.0,"y":287.1,"d":2},{"id":"RC_REPROC","m":"rc","x":496.3,"y":449.7,"d":2},{"id":"RC_RERUN","m":"rc","x":508.4,"y":55.0,"d":1},{"id":"RC_ROUNDDIFF","m":"rc","x":473.6,"y":213.1,"d":1},{"id":"RC_SNAPSHOT","m":"rc","x":166.6,"y":660.9,"d":1},{"id":"RC_STATUS","m":"rc","x":300.7,"y":165.0,"d":1},{"id":"RC_SUMCHK","m":"rc","x":501.8,"y":53.1,"d":1},{"id":"RC_TOLERANCE","m":"rc","x":625.3,"y":50.2,"d":1},{"id":"RC_UNDERAMT","m":"rc","x":651.4,"y":50.3,"d":1},{"id":"RC_UNMATCH","m":"rc","x":755.6,"y":408.0,"d":4},{"id":"RECONCILE","m":"rc","x":657.7,"y":91.9,"d":2},{"id":"RISK_SCORE_INQ","m":"au","x":772.5,"y":162.6,"d":1},{"id":"SETTLE","m":"st","x":644.4,"y":290.3,"d":3},{"id":"STANDIN","m":"au","x":701.9,"y":698.7,"d":2},{"id":"STANDIN_SETTLE","m":"au","x":930.7,"y":876.2,"d":1},{"id":"ST_ADJREVERSE","m":"st","x":725.5,"y":53.1,"d":1},{"id":"ST_ADJUST","m":"st","x":585.4,"y":166.0,"d":10},{"id":"ST_APPROVE","m":"st","x":849.9,"y":55.4,"d":1},{"id":"ST_APPROVEALL","m":"st","x":656.0,"y":51.0,"d":1},{"id":"ST_CANCEL","m":"st","x":747.5,"y":327.6,"d":2},{"id":"ST_CAPCHECK","m":"st","x":721.6,"y":54.4,"d":1},{"id":"ST_CHARGEBACK","m":"st","x":858.4,"y":216.2,"d":2},{"id":"ST_COLLATERAL","m":"st","x":200.8,"y":84.7,"d":1},{"id":"ST_CONFIRM","m":"st","x":425.9,"y":64.1,"d":1},{"id":"ST_CXLRECALC","m":"st","x":804.4,"y":50.6,"d":1},{"id":"ST_DAILYCLOSE","m":"st","x":357.4,"y":523.1,"d":2},{"id":"ST_DIFFCHK","m":"st","x":690.7,"y":58.0,"d":1},{"id":"ST_DISPUTE","m":"st","x":647.7,"y":50.9,"d":1},{"id":"ST_GRPSETTLE","m":"st","x":503.3,"y":162.4,"d":1},{"id":"ST_HOLD","m":"st","x":672.6,"y":361.7,"d":3},{"id":"ST_HOLDAMT","m":"st","x":729.0,"y":54.9,"d":1},{"id":"ST_INSTANTPAY","m":"st","x":712.1,"y":59.4,"d":1},{"id":"ST_LEDGERLINK","m":"st","x":732.3,"y":51.4,"d":1},{"id":"ST_LIMITCHK","m":"st","x":781.5,"y":56.7,"d":1},{"id":"ST_LOCKBATCH","m":"st","x":556.0,"y":59.8,"d":1},{"id":"ST_MDR","m":"st","x":592.0,"y":216.7,"d":9},{"id":"ST_MERCHRATE","m":"st","x":433.6,"y":65.2,"d":1},{"id":"ST_NETTING","m":"st","x":519.6,"y":175.1,"d":1},{"id":"ST_NEXTPAYDT","m":"st","x":413.6,"y":437.5,"d":1},{"id":"ST_OFFSET","m":"st","x":772.6,"y":101.5,"d":1},{"id":"ST_PAYDATE","m":"st","x":543.2,"y":121.2,"d":1},{"id":"ST_PAYSTATUS","m":"st","x":764.6,"y":52.9,"d":1},{"id":"ST_PRECONFIRM","m":"st","x":831.3,"y":52.2,"d":1},{"id":"ST_PROMOAPPLY","m":"st","x":709.7,"y":59.7,"d":1},{"id":"ST_RATEAPPLY","m":"st","x":795.3,"y":57.4,"d":1},{"id":"ST_RATECARD","m":"st","x":815.5,"y":56.9,"d":1},{"id":"ST_RECALC","m":"st","x":846.7,"y":284.5,"d":2},{"id":"ST_REFUNDCALC","m":"st","x":878.2,"y":245.8,"d":2},{"id":"ST_RELEASE","m":"st","x":604.7,"y":492.9,"d":3},{"id":"ST_RERUN","m":"st","x":786.6,"y":55.8,"d":1},{"id":"ST_SPLIT","m":"st","x":203.2,"y":66.1,"d":1},{"id":"ST_STATUS","m":"st","x":654.0,"y":189.8,"d":3},{"id":"ST_TAXINVCHK","m":"st","x":679.9,"y":59.0,"d":1},{"id":"ST_UNLOCK","m":"st","x":841.9,"y":52.7,"d":1},{"id":"ST_VAT","m":"st","x":835.9,"y":53.2,"d":1},{"id":"ST_VATADJUST","m":"st","x":208.4,"y":200.8,"d":1},{"id":"ST_VATDETAIL","m":"st","x":704.4,"y":61.1,"d":1},{"id":"ST_VOIDRECALC","m":"st","x":820.0,"y":98.9,"d":1},{"id":"ST_WHT","m":"st","x":709.9,"y":147.4,"d":2},{"id":"ST_XFERLINK","m":"st","x":232.8,"y":298.6,"d":1},{"id":"TOKEN_VERIFY","m":"au","x":866.3,"y":668.2,"d":1},{"id":"VELOCITY_CHK","m":"au","x":941.3,"y":937.2,"d":1},{"id":"VELOCITY_DAY","m":"au","x":780.4,"y":940.1,"d":1},{"id":"VL_AMOUNT","m":"vl","x":618.9,"y":165.8,"d":8},{"id":"VL_ANOMALY","m":"vl","x":852.5,"y":549.9,"d":1},{"id":"VL_APPRAMT","m":"vl","x":406.7,"y":271.2,"d":2},{"id":"VL_APPRNOPUR","m":"vl","x":943.1,"y":246.8,"d":2},{"id":"VL_APPR_ACQ","m":"vl","x":622.6,"y":274.2,"d":2},{"id":"VL_AXLEDGDC","m":"vl","x":851.8,"y":761.5,"d":1},{"id":"VL_AXPURAPPR","m":"vl","x":713.3,"y":227.4,"d":2},{"id":"VL_AXPURSETT","m":"vl","x":945.2,"y":129.3,"d":1},{"id":"VL_AXSETTPAY","m":"vl","x":370.3,"y":379.1,"d":4},{"id":"VL_BALANCE","m":"vl","x":739.8,"y":612.2,"d":2},{"id":"VL_BATCH_CHK","m":"vl","x":421.5,"y":249.9,"d":2},{"id":"VL_BIN","m":"vl","x":593.5,"y":417.8,"d":4},{"id":"VL_CANCELMIS","m":"vl","x":720.1,"y":569.4,"d":1},{"id":"VL_CARD","m":"vl","x":931.6,"y":114.7,"d":1},{"id":"VL_CHANSPLIT","m":"vl","x":918.0,"y":617.7,"d":1},{"id":"VL_CODEVAL","m":"vl","x":389.0,"y":191.7,"d":3},{"id":"VL_CROSSCHK","m":"vl","x":565.0,"y":294.3,"d":5},{"id":"VL_DAYLIMIT","m":"vl","x":887.7,"y":474.2,"d":1},{"id":"VL_DUP","m":"vl","x":542.3,"y":343.2,"d":3},{"id":"VL_DUPAPPR","m":"vl","x":939.3,"y":431.1,"d":1},{"id":"VL_DUPAUTH","m":"vl","x":629.8,"y":375.1,"d":1},{"id":"VL_DUPLEDGR","m":"vl","x":298.4,"y":737.5,"d":1},{"id":"VL_DUPPAY","m":"vl","x":894.6,"y":160.3,"d":1},{"id":"VL_DUPPURCH","m":"vl","x":564.9,"y":317.7,"d":3},{"id":"VL_DUPSETTLE","m":"vl","x":945.5,"y":112.9,"d":1},{"id":"VL_EXPIRY","m":"vl","x":727.2,"y":735.8,"d":2},{"id":"VL_FEE","m":"vl","x":459.5,"y":474.8,"d":3},{"id":"VL_FEERECALC","m":"vl","x":543.9,"y":500.3,"d":1},{"id":"VL_FORMAT","m":"vl","x":943.6,"y":228.3,"d":1},{"id":"VL_FXCHK","m":"vl","x":529.2,"y":368.4,"d":2},{"id":"VL_INSTCHK","m":"vl","x":940.5,"y":434.1,"d":1},{"id":"VL_LEDGBAL","m":"vl","x":440.1,"y":686.1,"d":2},{"id":"VL_LEDGENTRY","m":"vl","x":935.3,"y":174.9,"d":1},{"id":"VL_LEDGER","m":"vl","x":214.3,"y":772.3,"d":8},{"id":"VL_LIMIT","m":"vl","x":869.3,"y":497.8,"d":2},{"id":"VL_LONGOPEN","m":"vl","x":833.6,"y":485.7,"d":1},{"id":"VL_MDRRATE","m":"vl","x":925.6,"y":57.6,"d":1},{"id":"VL_MERCH","m":"vl","x":107.1,"y":249.4,"d":3},{"id":"VL_NEGBAL","m":"vl","x":705.4,"y":161.6,"d":1},{"id":"VL_NEGFEE","m":"vl","x":802.4,"y":192.2,"d":1},{"id":"VL_NEGNET","m":"vl","x":721.0,"y":414.3,"d":2},{"id":"VL_NIGHTTXN","m":"vl","x":874.1,"y":603.5,"d":1},{"id":"VL_OUTLIER","m":"vl","x":793.1,"y":592.4,"d":1},{"id":"VL_OVERLIMIT","m":"vl","x":943.2,"y":478.5,"d":2},{"id":"VL_PURNOAPPR","m":"vl","x":935.1,"y":418.5,"d":3},{"id":"VL_REFINTEG","m":"vl","x":943.3,"y":486.6,"d":1},{"id":"VL_REPORT","m":"vl","x":848.5,"y":302.4,"d":1},{"id":"VL_REQUIRED","m":"vl","x":905.8,"y":840.6,"d":1},{"id":"VL_RIAPPR","m":"vl","x":842.8,"y":92.8,"d":2},{"id":"VL_RICANCEL","m":"vl","x":940.2,"y":413.1,"d":1},{"id":"VL_RIFX","m":"vl","x":410.5,"y":600.9,"d":1},{"id":"VL_RIINSTALL","m":"vl","x":939.1,"y":405.7,"d":1},{"id":"VL_RILEDGER","m":"vl","x":853.4,"y":384.3,"d":1},{"id":"VL_RIMERCH","m":"vl","x":704.3,"y":877.6,"d":2},{"id":"VL_RIPAY","m":"vl","x":510.5,"y":130.7,"d":2},{"id":"VL_RIPURCH","m":"vl","x":817.1,"y":372.3,"d":1},{"id":"VL_RISETTLE","m":"vl","x":810.7,"y":359.8,"d":2},{"id":"VL_RITAXINV","m":"vl","x":942.3,"y":62.3,"d":1},{"id":"VL_RULECOUNT","m":"vl","x":936.3,"y":439.9,"d":1},{"id":"VL_SALES","m":"vl","x":589.5,"y":769.8,"d":3},{"id":"VL_SETTLE","m":"vl","x":767.6,"y":108.5,"d":7},{"id":"VL_SPIKEAMT","m":"vl","x":944.8,"y":146.6,"d":1},{"id":"VL_STATUS_CHK","m":"vl","x":301.9,"y":424.3,"d":2},{"id":"VL_SUMFEE","m":"vl","x":937.1,"y":458.2,"d":1},{"id":"VL_SUMFEECHK","m":"vl","x":505.0,"y":495.8,"d":3},{"id":"VL_SUMGROSS","m":"vl","x":326.5,"y":275.2,"d":3},{"id":"VL_SUMMARY","m":"vl","x":939.5,"y":334.9,"d":1},{"id":"VL_SUMNETCHK","m":"vl","x":935.5,"y":450.8,"d":1},{"id":"VL_SUMRECON","m":"vl","x":669.7,"y":653.8,"d":4},{"id":"VL_SUMTXNCNT","m":"vl","x":364.0,"y":430.6,"d":3},{"id":"VL_SUSPACT","m":"vl","x":911.1,"y":66.4,"d":1},{"id":"VL_SUSPESCAL","m":"vl","x":944.1,"y":484.1,"d":1},{"id":"VL_THRESHOLD","m":"vl","x":936.4,"y":374.9,"d":1},{"id":"VL_VELOCITY","m":"vl","x":845.5,"y":828.7,"d":2},{"id":"VL_ZERONET","m":"vl","x":905.4,"y":110.1,"d":1}],"EDGES":[["ACQUIRE","RECONCILE"],["ACQ_ALERTDUP","VL_DUPPURCH"],["ACQ_AMTFIX","VL_AMOUNT"],["ACQ_APPRLINK","LIMIT_DEC"],["ACQ_APPRMAP","AUTH_CANCEL"],["ACQ_CANCEL","LIMIT_RST"],["ACQ_CANCEL","LG_REVERSE"],["ACQ_CANCEL","ST_CANCEL"],["ACQ_CB_OPEN","ST_CHARGEBACK"],["ACQ_CB_REVERSE","LG_REVERSE"],["ACQ_CLAIMREG","ST_DISPUTE"],["ACQ_CORRECT","LG_CORRECT"],["ACQ_DDC","MG_LOG"],["ACQ_DUPCHK","VL_DUP"],["ACQ_EDC","MG_LOG"],["ACQ_EDI","MG_SEND"],["ACQ_EDIRESEND","MG_RESEND"],["ACQ_ESCROW","PAY_HOLD"],["ACQ_ESCROWREL","PAY_RELEASE"],["ACQ_EXCHANGE","CM_FX_CROSS"],["ACQ_FEEADJ","LG_ADJUST"],["ACQ_FEERECALC","ST_RECALC"],["ACQ_FOREIGN","CM_FX_CONV"],["ACQ_FXCONVERT","CM_FX"],["ACQ_FXRATE","CM_FX_VALID"],["ACQ_GUARANTEE","ST_COLLATERAL"],["ACQ_HOLD","PAY_HOLD"],["ACQ_INSTALL","VL_INSTCHK"],["ACQ_INSTCXL","LIMIT_RST"],["ACQ_LIMITCHK","VL_LIMIT"],["ACQ_LIMITEXC","VL_OVERLIMIT"],["ACQ_MERCHSUM","MM_MERCH_INQ"],["ACQ_NETCALC","LG_NETPOS"],["ACQ_PARTCXL","LIMIT_RST"],["ACQ_PARTCXL","LG_PARTREVERSE"],["ACQ_PARTRFND","ST_REFUNDCALC"],["ACQ_PROMO","ST_PROMOAPPLY"],["ACQ_REFUND","LIMIT_RST"],["ACQ_REFUND","LG_REVERSE"],["ACQ_RELEASE","PAY_RELEASE"],["ACQ_REMATCH","RC_REMATCH"],["ACQ_REPROC","RC_REPROC"],["ACQ_RESERVE","ST_HOLD"],["ACQ_RESERVECXL","ST_RELEASE"],["ACQ_RETURN","RC_REFUNDREC"],["ACQ_SETTLELINK","ST_MDR"],["ACQ_SETTLELINK","LG_BALCHK"],["ACQ_SPLITPAY","ST_SPLIT"],["ACQ_TAXCXL","ST_ADJUST"],["ACQ_TAXINV","ST_ADJUST"],["ACQ_TAXREVERSE","LG_REVERSE"],["ACQ_UNMATCH","RC_UNMATCH"],["ACQ_VELOCITY","VL_VELOCITY"],["ACQ_VOID","LG_VOIDVOUCHER"],["ACQ_WHT","ST_WHT"],["ACQ_WHT","ST_ADJUST"],["ACQ_XFERLINK","PAY_XFERLINK"],["AUTH","LIMIT_DEC"],["AUTH","FRAUD_DETECT"],["AUTH_AMT_ADJUST","LIMIT_DEC"],["AUTH_APPROVE","LIMIT_DEC"],["AUTH_CANCEL","LIMIT_RST"],["AUTH_CAPTURE","ACQ_APPRGAP"],["AUTH_DECLINE","CM_LOG"],["AUTH_DUP_CHK","FRAUD_DETECT"],["AUTH_EXPIRE_CHK","LIMIT_RST"],["AUTH_HOLD","LIMIT_CHK"],["AUTH_PARTAPPR","LIMIT_DEC"],["AUTH_PARTCXL","LIMIT_RST"],["AUTH_RELEASE","LIMIT_RST"],["AUTH_RESEND","MG_SEND"],["AUTH_RETRY","MG_SEND"],["AUTH_REVERSE","LIMIT_RST"],["AUTH_VOID","LIMIT_RST"],["BLACKLIST_CHK","FRAUD_DETECT"],["CARD_LOST_REG","MG_SEND"],["CARD_STOLEN_REG","MG_SEND"],["CARD_VALIDATE","CM_LUHN"],["FRAUD_DETECT","MG_LOG"],["INSTALL_AUTH","LIMIT_DEC"],["LIMIT_CHK","CM_LOG"],["LIMIT_DEC","MG_LOG"],["LIMIT_EXHAUST_LST","CM_LOG"],["LIMIT_FREEZE","CM_LOG"],["LIMIT_OVER_ALERT","CM_LOG"],["LIMIT_RST","MG_LOG"],["NOAUTH_CAPTURE","ACQ_CORRAPPR"],["PREAUTH","LIMIT_DEC"],["PREAUTH_CANCEL","LIMIT_RST"],["PREAUTH_COMPLETE","LIMIT_DEC"],["PREAUTH_EXTEND","LIMIT_CHK"],["PREAUTH_PARTUSE","LIMIT_RST"],["STANDIN","LIMIT_CHK"],["STANDIN","MG_LOG"],["STANDIN_SETTLE","LIMIT_DEC"],["TOKEN_VERIFY","CM_LUHN"],["VELOCITY_CHK","FRAUD_DETECT"],["CL_AMTXCHECK","VL_AXPURSETT"],["CL_APPRDELEG","CL_APPRSTAT"],["CL_APPRL1","CL_APPRL2"],["CL_APPRL2","CL_APPRFINAL"],["CL_APPROVE","CL_APPRL2"],["CL_APPRREJECT","CL_ESCALATE"],["CL_APPRREQ","CL_APPRL2"],["CL_BALVERIFY","VL_LEDGBAL"],["CL_CANCEL","LG_REVERSE"],["CL_CHKALL","VL_CROSSCHK"],["CL_CHKPENDING","VL_LONGOPEN"],["CL_CHKUNMATCH","VL_PURNOAPPR"],["CL_CHKVOID","VL_CANCELMIS"],["CL_CHNVERIFY","VL_CHANSPLIT"],["CL_CNTVERIFY","VL_RULECOUNT"],["CL_CNTXCHECK","VL_AXSETTPAY"],["CL_CORPCLOSE","LG_CORPSUM"],["CL_CORPVERIFY","VL_REPORT"],["CL_DAILY","VL_SALES"],["CL_DAILY","LG_CLOSE_LINK"],["CL_DAYVERIFY","VL_SALES"],["CL_DIFFCHK","VL_AMOUNT"],["CL_DIVCLOSE","LG_DEPTSUM"],["CL_DUPCHK","VL_DUP"],["CL_FEECROSS","VL_SUMFEECHK"],["CL_FEEVERIFY","VL_FEE"],["CL_FORCECLOSE","LG_CLOSE_LINK"],["CL_HALFCLOSE","LG_ROLLTB"],["CL_HYVERIFY","VL_SUMFEE"],["CL_MAINCLOSE","LG_CLOSE_LINK"],["CL_MERCLOSE","LG_MERCHPROOF"],["CL_MERXCHECK","VL_RIMERCH"],["CL_MIDCLOSE","LG_MERCHBAL"],["CL_MONTHLY","LG_MONTHLYSUM"],["CL_MONVERIFY","VL_SUMMARY"],["CL_NETCROSS","VL_SETTLE"],["CL_NETVERIFY","VL_NEGNET"],["CL_POSTTRIG","ST_DAILYCLOSE"],["CL_PRECHECK","VL_REQUIRED"],["CL_QTRVERIFY","VL_SUMRECON"],["CL_QUARTER","LG_PERIODTB"],["CL_RECLOSE","LG_REVERSE"],["CL_RECON","VL_SUMRECON"],["CL_ROLLBACK","LG_REVERSE"],["CL_SEGVERIFY","VL_SUMNETCHK"],["CL_SEMIMONTH","LG_CORPSUM"],["CL_SNAPSHOT","LG_TRIALBAL"],["CL_SNAPXCHECK","VL_AXLEDGDC"],["CL_STCROSS","VL_RISETTLE"],["CL_TENDAY","LG_DEPTSUM"],["CL_TRIGSETTLE","SETTLE"],["CL_VERIFY","VL_BALANCE"],["CL_WEEKLY","LG_ACCTSUM"],["CL_WEEKVERIFY","VL_SUMTXNCNT"],["CL_YEAREND","LG_SPANTB"],["CL_YEARVERIFY","VL_SUMGROSS"],["CM_ADDDAYS","CM_HOLIDAY_CHK"],["CM_BATDEP_CHK","CM_BATLAST"],["CM_BATDEP_SET","CM_BATLAST"],["CM_BATHIST_CNT","CM_BATLAST"],["CM_BATRERUN_REQ","CM_BATLAST"],["CM_BATSCHD_DEL","CM_LOG"],["CM_BATSCHD_REG","CM_LOG"],["CM_BIZDAY_ADD","CM_HOLIDAY_CHK"],["CM_BIZDAY_CNT","CM_HOLIDAY_CHK"],["CM_CACHE_INV","CM_PARAM"],["CM_CACHE_LOAD","CM_PARAM"],["CM_CODE","CM_PARAM"],["CM_CODEGRP_REG","CM_PARAM"],["CM_ERRMSG","CM_LOG"],["CM_FX_CONV","CM_FX"],["CM_FX_CROSS","CM_FX"],["CM_FX_INVERT","CM_FX"],["CM_FX_MARGIN","CM_FX"],["CM_FX_PUBLISH","CM_LOG"],["CM_FX_TRIANGLE","CM_FX"],["CM_MONTHEND","CM_BIZDAY"],["CM_MSG_RENDER","CM_LOG"],["CM_NEXTBIZ","CM_BIZDAY"],["CM_NOTI_QUOTA","CM_LOG"],["CM_NOTI_RETRY","CM_LOG"],["CM_NOTI_SEND","CM_LOG"],["CM_NOTI_TMPL","CM_LOG"],["CM_PREVBIZ","CM_BIZDAY"],["CM_SEQ","CM_LOG"],["CM_SEQ_ALLOC","CM_LOG"],["CM_SEQ_DAILY","CM_LOG"],["CM_SEQ_MULTI","CM_LOG"],["CM_SEQ_RESET","CM_LOG"],["CM_SEQ_STAMP","CM_LOG"],["CM_SEQ_TYPED","CM_LOG"],["LG_ACCRUEREV","LG_POST"],["LG_ACCTSUM","LG_RECALC"],["LG_ACQPOST","LG_BALCHK"],["LG_ADJUST","LG_BALCHK"],["LG_ALLOWANCE","LG_POST"],["LG_ALLOWRECALC","LG_ACCTSUM"],["LG_BADDEBT","LG_POST"],["LG_BADDEBTRCV","LG_POST"],["LG_BALCERT","LG_BALCHK"],["LG_BALPROOF","LG_BALCHK"],["LG_BLACKENTRY","LG_BALCHK"],["LG_BSSUMMARY","VL_LEDGER"],["LG_CLOSE_LINK","CL_LOCK"],["LG_CORPSUM","LG_RECALC"],["LG_CORRECT","LG_BALCHK"],["LG_DEPTSUM","LG_RECALC"],["LG_DOUBLE","LG_BALCHK"],["LG_FEEACCRUE","LG_FEEPOST"],["LG_FEEPOST","LG_BALCHK"],["LG_HALFCLOSE","LG_TRIALBAL"],["LG_MERCHBAL","LG_RECALC"],["LG_MERCHPROOF","LG_RECALC"],["LG_MONTHCLOSE","LG_TRIALBAL"],["LG_MONTHLYSUM","LG_RECALC"],["LG_PARTREVERSE","LG_POST"],["LG_PERIODTB","VL_LEDGER"],["LG_PLSUMMARY","VL_LEDGER"],["LG_POST","LG_BALCHK"],["LG_PREPAIDAMORT","LG_PREPAIDPOST"],["LG_PREPAIDPOST","LG_BALCHK"],["LG_QTRCLOSE","LG_TRIALBAL"],["LG_REDADJUST","LG_POST"],["LG_REDBLACKNET","LG_REDENTRY"],["LG_REDENTRY","LG_BALCHK"],["LG_REPOST","LG_POST"],["LG_REVERSE","LG_BALCHK"],["LG_ROLLTB","VL_LEDGER"],["LG_SETTLEPOST","LG_BALCHK"],["LG_SPANTB","VL_LEDGER"],["LG_SUSPENSE","LG_BALCHK"],["LG_TRANSFER","LG_BALCHK"],["LG_TRIALBAL","VL_LEDGER"],["LG_UNEARNPOST","LG_BALCHK"],["LG_UNEARNRECOG","LG_UNEARNPOST"],["LG_VOUCHER","LG_BALCHK"],["LG_WEEKCLOSE","LG_TRIALBAL"],["LG_WRITEOFF","LG_POST"],["LG_XFERPOST","LG_BALCHK"],["LG_YEARCLOSE","LG_TRIALBAL"],["MG_ACK","MG_SEND"],["MG_BITMAP","MG_PARSE"],["MG_BMPPARSE","MG_PARSE"],["MG_CHANFAILOVER","MG_ROUTE"],["MG_CHANHEALTH","MG_CHANPING"],["MG_CHANOPEN","MG_ROUTE"],["MG_CHANSWITCH","MG_ROUTE"],["MG_DECODE","MG_PARSE"],["MG_ENCODE","MG_SEND"],["MG_ERRREQUEUE","MG_SEND"],["MG_ERRRETRY","MG_SEND"],["MG_FROMISO","MG_PARSE"],["MG_ISO8583","MG_PARSE"],["MG_KEYCHECK","CM_HASH_DJB2"],["MG_KEYLOAD","CM_HASH_FNV"],["MG_LOADBAL","MG_CHANPING"],["MG_MAC","CM_CRC"],["MG_MACGEN","CM_HASH_SUM"],["MG_MACSESSION","CM_HASH_SUM"],["MG_MACVERIFY","CM_CRC"],["MG_NACK","MG_SEND"],["MG_PACK","MG_SEND"],["MG_PARSE","AUTH"],["MG_REASM","MG_PARSE"],["MG_RECV","MG_PARSE"],["MG_RESEND","MG_SEND"],["MG_RESNDONE","MG_SEND"],["MG_ROUTE","MG_CHANSTAT"],["MG_SEND","MG_STAN"],["MG_SEQFILL","MG_STAN"],["MG_SEQNEXT","MG_STAN"],["MG_TOISO","MG_SEND"],["MG_UNPACK","MG_PARSE"],["MM_ACCT_REG","CM_LUHN"],["MM_ACCT_VERIFY","CM_LUHN"],["MM_APPLY_APPROVE","MM_VALIDATE"],["MM_APPLY_REG","CM_SEQ"],["MM_BIN_REG","VL_BIN"],["MM_BIZNO_CHECK","CM_CHECKDIGIT"],["MM_CHK_LIMIT","LIMIT_CHK"],["MM_CODE_REG","VL_CODEVAL"],["MM_CONTRACT_AMEND","CM_SEQ"],["MM_CONTRACT_NEW","CM_SEQ"],["MM_CONTRACT_RENEW","CM_SEQ"],["MM_FEERATE_SET","ST_MDR"],["MM_GRADE_ADJUST","VL_MERCH"],["MM_ISSUER_REG","VL_BIN"],["MM_LIMIT_SET","LIMIT_CHK"],["MM_MCC_REG","VL_CODEVAL"],["MM_MCC_UPD","VL_CODEVAL"],["MM_MERCH_CLOSE","CM_LOG"],["MM_MERCH_DORMANT","CM_LOG"],["MM_MERCH_GRADE","VL_MERCH"],["MM_MERCH_PAUSE","CM_LOG"],["MM_MERCH_REG","MM_VALIDATE"],["MM_MERCH_RESUME","CM_LOG"],["MM_MERCH_STATUS","MM_VALIDATE"],["MM_MERCH_UPD","MM_VALIDATE"],["MM_RATE_APPROVE","ST_MDR"],["MM_RATE_REQ","CM_LOG"],["MM_RISK_SCORE","CM_LOG"],["MM_RISK_SET","VL_MERCH"],["MM_TERMINAL_REG","CM_SEQ"],["MM_TERM_INSTALL","CM_SEQ"],["MM_VALIDATE","CM_LOG"],["PAY_ACCTCHK","LG_POST"],["PAY_ACCTVERIFY","PAY_ACCTCHK"],["PAY_ADJUST","ST_ADJUST"],["PAY_APPRBULK","PAY_FILEGEN"],["PAY_APPROVE","PAY_FILEGEN"],["PAY_BANKFILE","MG_SEND"],["PAY_BANKVERIFY","PAY_ACCTCHK"],["PAY_CANCEL","LG_REVERSE"],["PAY_CANCEL","ST_ADJUST"],["PAY_CHARGEBACK","LG_REVERSE"],["PAY_CLOSE","LG_POST"],["PAY_COMBINE","PAY_ACCTCHK"],["PAY_CONFIRM","LG_POST"],["PAY_FILEGEN","PAY_ACCTCHK"],["PAY_FILEREBUILD","PAY_ACCTCHK"],["PAY_HOLD","ST_HOLD"],["PAY_MERGE","PAY_ACCTCHK"],["PAY_NETOFF","LG_POST"],["PAY_RECLAIM","LG_REVERSE"],["PAY_RECLAIM","ST_ADJUST"],["PAY_REFUND","LG_REVERSE"],["PAY_RELEASE","ST_RELEASE"],["PAY_REMIT","MG_SEND"],["PAY_REPROC","PAY_FAILRSN"],["PAY_REQUEUE","MG_SEND"],["PAY_RESULT","LG_POST"],["PAY_RESVMODIFY","CM_BIZDAY"],["PAY_RETRY","PAY_FAILRSN"],["PAY_RETRYONE","PAY_FAILRSN"],["PAY_REVERSE","LG_REVERSE"],["PAY_REVERSE","ST_ADJUST"],["PAY_ROLLFWD","CM_BIZDAY"],["PAY_SCHEDULE","CM_BIZDAY"],["PAY_SPLIT","PAY_ACCTCHK"],["PAY_SPLITEVEN","PAY_ACCTCHK"],["PAY_SPLITRATIO","PAY_ACCTCHK"],["PAY_URGENT","PAY_ACCTCHK"],["PAY_VOIDONE","LG_REVERSE"],["PAY_XFERLINK","MG_SEND"],["RC_3WAY","VL_APPR_ACQ"],["RC_3WAY","LG_THREEWAY"],["RC_4WAY","VL_CROSSCHK"],["RC_ACQMATCH","VL_AXPURAPPR"],["RC_ACQ_DEP","VL_LEDGER"],["RC_ALERT","CM_NOTI_SEND"],["RC_AMTDIFF","VL_AMOUNT"],["RC_APPRGAP","VL_APPRNOPUR"],["RC_APPRMATCH","VL_RIAPPR"],["RC_APPR_ACQ","VL_APPRAMT"],["RC_AUTOFIX","LG_POST"],["RC_CLOSEDAY","ST_LOCKBATCH"],["RC_CNTDIFF","VL_SUMTXNCNT"],["RC_CONFIRM","ST_STATUS"],["RC_DEPGAP","VL_AXSETTPAY"],["RC_DEPMATCH","VL_AXSETTPAY"],["RC_DUPCHK","CM_LOG"],["RC_ESCALATE","CM_NOTI_HIST"],["RC_EXCEPTION","CM_LOG"],["RC_EXCNOTIFY","CM_NOTI_SEND"],["RC_FEEDIFF","VL_FEE"],["RC_FEERECON","VL_SUMFEECHK"],["RC_FIXFEE","ST_MERCHRATE"],["RC_FIXFX","CM_FX_CONV"],["RC_FIXROUND","CM_AMT_ROUND"],["RC_FXDIFF","VL_FXCHK"],["RC_FXRECON","CM_FX_CONV"],["RC_HOLDCLR","ST_UNLOCK"],["RC_HOLDSET","ST_HOLDAMT"],["RC_LEDGERBAL","LG_BALCHK"],["RC_LEDGERLINK","LG_POST"],["RC_LIMITCHK","LIMIT_CHK"],["RC_MANUAL","LG_POST"],["RC_NOTIFY","CM_NOTI_SEND"],["RC_ORPHAN","VL_PURNOAPPR"],["RC_OVERAMT","VL_AMOUNT"],["RC_PAYLEDGER","LG_POST"],["RC_PAYMATCH","VL_RIPAY"],["RC_PROGRESS","CM_STATUS"],["RC_RECORR","LG_ADJUST"],["RC_REDIFF","VL_AMOUNT"],["RC_REFULL","VL_SUMRECON"],["RC_RELEASE","ST_PAYSTATUS"],["RC_REMATCH","VL_DUPPURCH"],["RC_REPROC","VL_STATUS_CHK"],["RC_RERUN","VL_BATCH_CHK"],["RC_ROUNDDIFF","CM_AMT_ROUND"],["RC_SNAPSHOT","LG_JOURNAL"],["RC_STATUS","CM_STATUS"],["RC_SUMCHK","VL_SUMGROSS"],["RC_TOLERANCE","VL_AMOUNT"],["RC_UNDERAMT","VL_AMOUNT"],["RC_UNMATCH","CM_LOG"],["RECONCILE","SETTLE"],["SETTLE","ST_MDR"],["ST_ADJREVERSE","LG_REVERSE"],["ST_ADJUST","LG_POST"],["ST_APPROVE","PAY_FILEGEN"],["ST_APPROVEALL","PAY_FILEGEN"],["ST_CANCEL","LG_REVERSE"],["ST_CAPCHECK","VL_SETTLE"],["ST_CHARGEBACK","LG_REVERSE"],["ST_CONFIRM","PAY_FILEGEN"],["ST_CXLRECALC","ST_MDR"],["ST_DAILYCLOSE","LG_POST"],["ST_DIFFCHK","VL_SETTLE"],["ST_GRPSETTLE","LG_POST"],["ST_HOLD","LG_POST"],["ST_INSTANTPAY","PAY_FILEGEN"],["ST_LEDGERLINK","LG_POST"],["ST_LIMITCHK","VL_SETTLE"],["ST_MDR","LG_SETTLEPOST"],["ST_NETTING","LG_POST"],["ST_NEXTPAYDT","CM_BIZDAY"],["ST_OFFSET","LG_POST"],["ST_PAYDATE","CM_BIZDAY"],["ST_PRECONFIRM","VL_SETTLE"],["ST_RATEAPPLY","ST_MDR"],["ST_RECALC","ST_MDR"],["ST_REFUNDCALC","LG_REVERSE"],["ST_RELEASE","LG_POST"],["ST_RERUN","ST_MDR"],["ST_TAXINVCHK","VL_SETTLE"],["ST_VAT","ST_ADJUST"],["ST_VATADJUST","LG_POST"],["ST_VOIDRECALC","LG_REVERSE"],["ST_WHT","ST_ADJUST"],["ST_XFERLINK","LG_POST"],["VL_AMOUNT","CM_LOG"],["VL_ANOMALY","FRAUD_DETECT"],["VL_APPRAMT","CM_LOG"],["VL_APPRNOPUR","AUTH_HISTORY"],["VL_APPR_ACQ","CM_LOG"],["VL_AXPURAPPR","CM_LOG"],["VL_AXSETTPAY","CM_LOG"],["VL_BALANCE","LG_BALCHK"],["VL_BATCH_CHK","CM_LOG"],["VL_BIN","CM_LUHN"],["VL_BIN","BIN_ROUTE_INQ"],["VL_CARD","CM_LUHN"],["VL_CROSSCHK","AUTH_STATUS"],["VL_CROSSCHK","ST_STATUS"],["VL_CROSSCHK","LG_STATUS"],["VL_DAYLIMIT","LIMIT_CHK"],["VL_DUP","RC_DUPCHK"],["VL_DUPAPPR","AUTH_SUMMARY"],["VL_DUPAUTH","RC_UNMATCH"],["VL_DUPLEDGR","LG_DUPSCAN"],["VL_DUPPAY","RC_DUPCHK"],["VL_DUPPURCH","CM_LOG"],["VL_DUPSETTLE","RC_UNMATCH"],["VL_EXPIRY","CM_LUHN"],["VL_EXPIRY","CARD_EXPIRE_CHK"],["VL_FEE","CM_LOG"],["VL_FEERECALC","CM_AMT_ROUND"],["VL_FORMAT","CM_LUHN"],["VL_FXCHK","CM_FX_VALID"],["VL_LEDGBAL","LG_BALCHK"],["VL_LEDGENTRY","LG_INQUIRY"],["VL_LEDGER","CM_LOG"],["VL_LIMIT","LIMIT_CHK"],["VL_MDRRATE","ST_RATECARD"],["VL_NEGBAL","RC_EXCEPTION"],["VL_NEGFEE","RC_EXCEPTION"],["VL_NEGNET","RC_EXCEPTION"],["VL_NIGHTTXN","FRAUD_RULE_NIGHT"],["VL_OUTLIER","FRAUD_DETECT"],["VL_OVERLIMIT","LIMIT_CHK"],["VL_PURNOAPPR","AUTH_HISTORY"],["VL_REFINTEG","LG_INQUIRY"],["VL_RIAPPR","AUTH_STATUS"],["VL_RICANCEL","CANCEL_STATUS"],["VL_RIFX","CM_FX_CONV"],["VL_RIINSTALL","PREAUTH_INQ"],["VL_RILEDGER","LG_STATUS"],["VL_RIMERCH","CM_CODE"],["VL_RIPAY","LG_INQUIRY"],["VL_RIPURCH","AUTH_HISTORY"],["VL_RISETTLE","ST_STATUS"],["VL_RITAXINV","ST_VATDETAIL"],["VL_SALES","RC_EXCEPTION"],["VL_SETTLE","RC_EXCEPTION"],["VL_SPIKEAMT","FRAUD_RULE_AMT"],["VL_STATUS_CHK","CM_STATUS"],["VL_SUMFEECHK","CM_LOG"],["VL_SUMGROSS","CM_LOG"],["VL_SUMRECON","CM_LOG"],["VL_SUMTXNCNT","CM_LOG"],["VL_SUSPACT","RISK_SCORE_INQ"],["VL_SUSPESCAL","RC_ESCALATE"],["VL_THRESHOLD","FRAUD_DETECT"],["VL_VELOCITY","VELOCITY_DAY"],["VL_ZERONET","RC_EXCEPTION"]],"CHAINS":[["ACQUIRE","RECONCILE","SETTLE","ST_MDR","LG_SETTLEPOST","LG_BALCHK"],["ACQ_SETTLELINK","ST_MDR","LG_SETTLEPOST","LG_BALCHK"],["MG_RECV","MG_PARSE","AUTH","FRAUD_DETECT","MG_LOG"],["CL_DAILY","VL_SALES","RC_EXCEPTION","CM_LOG"],["PAY_APPROVE","PAY_FILEGEN","PAY_ACCTCHK","LG_POST","LG_BALCHK"]],"STAT":{"nodes":552,"edges":494,"callees":168,"modxedge":41,"maxdepth":6}}; +window.CALLGRAPH = {"MODULES":[{"id":"ac","nm":"매입","svc":136,"in":2,"out":57},{"id":"au","nm":"승인/한도","svc":133,"in":30,"out":17},{"id":"cl","nm":"마감","svc":133,"in":1,"out":50},{"id":"cm","nm":"공통","svc":133,"in":73,"out":0},{"id":"lg","nm":"원장","svc":133,"in":71,"out":7},{"id":"mg","nm":"전문게이트웨이","svc":133,"in":16,"out":7},{"id":"mm","nm":"마스터","svc":133,"in":1,"out":28},{"id":"py","nm":"지급","svc":133,"in":9,"out":24},{"id":"rc","nm":"대사","svc":133,"in":16,"out":54},{"id":"st","nm":"정산/수수료","svc":136,"in":36,"out":27},{"id":"vl","nm":"정합성검증","svc":133,"in":81,"out":65}],"MODEDGES":[{"f":"ac","t":"rc","c":5},{"f":"ac","t":"vl","c":7},{"f":"ac","t":"au","c":6},{"f":"ac","t":"lg","c":10},{"f":"ac","t":"st","c":15},{"f":"ac","t":"mg","c":4},{"f":"ac","t":"py","c":5},{"f":"ac","t":"cm","c":4},{"f":"ac","t":"mm","c":1},{"f":"au","t":"ac","c":2},{"f":"au","t":"cm","c":7},{"f":"au","t":"mg","c":8},{"f":"cl","t":"vl","c":30},{"f":"cl","t":"lg","c":18},{"f":"cl","t":"st","c":2},{"f":"lg","t":"vl","c":6},{"f":"lg","t":"cl","c":1},{"f":"mg","t":"cm","c":6},{"f":"mg","t":"au","c":1},{"f":"mm","t":"cm","c":16},{"f":"mm","t":"vl","c":8},{"f":"mm","t":"au","c":2},{"f":"mm","t":"st","c":2},{"f":"py","t":"lg","c":11},{"f":"py","t":"st","c":6},{"f":"py","t":"mg","c":4},{"f":"py","t":"cm","c":3},{"f":"rc","t":"vl","c":25},{"f":"rc","t":"lg","c":8},{"f":"rc","t":"cm","c":13},{"f":"rc","t":"st","c":7},{"f":"rc","t":"au","c":1},{"f":"st","t":"lg","c":16},{"f":"st","t":"py","c":4},{"f":"st","t":"vl","c":5},{"f":"st","t":"cm","c":2},{"f":"vl","t":"cm","c":22},{"f":"vl","t":"au","c":20},{"f":"vl","t":"lg","c":8},{"f":"vl","t":"st","c":4},{"f":"vl","t":"rc","c":11}],"NODES":[{"id":"ACQUIRE","m":"ac","x":773.4,"y":130.8,"d":1},{"id":"ACQ_ALERTDUP","m":"ac","x":592.8,"y":203.7,"d":1},{"id":"ACQ_AMTFIX","m":"ac","x":947.0,"y":361.0,"d":1},{"id":"ACQ_APPRGAP","m":"ac","x":934.1,"y":850.2,"d":1},{"id":"ACQ_APPRLINK","m":"ac","x":940.0,"y":612.8,"d":1},{"id":"ACQ_APPRMAP","m":"ac","x":944.9,"y":347.6,"d":1},{"id":"ACQ_CANCEL","m":"ac","x":773.9,"y":443.1,"d":3},{"id":"ACQ_CB_OPEN","m":"ac","x":945.8,"y":349.9,"d":1},{"id":"ACQ_CB_REVERSE","m":"ac","x":904.8,"y":219.3,"d":1},{"id":"ACQ_CLAIMREG","m":"ac","x":882.8,"y":203.4,"d":1},{"id":"ACQ_CORRAPPR","m":"ac","x":947.0,"y":767.0,"d":1},{"id":"ACQ_CORRECT","m":"ac","x":731.7,"y":735.6,"d":1},{"id":"ACQ_DDC","m":"ac","x":710.8,"y":799.0,"d":1},{"id":"ACQ_DUPCHK","m":"ac","x":516.9,"y":305.5,"d":1},{"id":"ACQ_EDC","m":"ac","x":879.2,"y":773.7,"d":1},{"id":"ACQ_EDI","m":"ac","x":698.1,"y":674.6,"d":1},{"id":"ACQ_EDIRESEND","m":"ac","x":783.1,"y":259.1,"d":1},{"id":"ACQ_ESCROW","m":"ac","x":946.0,"y":242.5,"d":1},{"id":"ACQ_ESCROWREL","m":"ac","x":676.5,"y":372.6,"d":1},{"id":"ACQ_EXCHANGE","m":"ac","x":804.5,"y":831.6,"d":1},{"id":"ACQ_FEEADJ","m":"ac","x":367.9,"y":557.3,"d":1},{"id":"ACQ_FEERECALC","m":"ac","x":937.1,"y":461.5,"d":1},{"id":"ACQ_FOREIGN","m":"ac","x":469.8,"y":587.6,"d":1},{"id":"ACQ_FXCONVERT","m":"ac","x":434.6,"y":744.5,"d":1},{"id":"ACQ_FXRATE","m":"ac","x":519.0,"y":759.2,"d":1},{"id":"ACQ_GUARANTEE","m":"ac","x":283.6,"y":170.1,"d":1},{"id":"ACQ_HOLD","m":"ac","x":950.0,"y":166.4,"d":1},{"id":"ACQ_INSTALL","m":"ac","x":946.5,"y":357.3,"d":1},{"id":"ACQ_INSTCXL","m":"ac","x":947.2,"y":344.2,"d":1},{"id":"ACQ_LIMITCHK","m":"ac","x":943.2,"y":494.7,"d":1},{"id":"ACQ_LIMITEXC","m":"ac","x":945.1,"y":670.3,"d":1},{"id":"ACQ_MERCHSUM","m":"ac","x":516.7,"y":183.7,"d":1},{"id":"ACQ_NETCALC","m":"ac","x":668.2,"y":905.6,"d":1},{"id":"ACQ_PARTCXL","m":"ac","x":609.0,"y":649.2,"d":2},{"id":"ACQ_PARTRFND","m":"ac","x":942.6,"y":498.4,"d":1},{"id":"ACQ_PROMO","m":"ac","x":949.8,"y":117.6,"d":1},{"id":"ACQ_REFUND","m":"ac","x":776.8,"y":518.3,"d":2},{"id":"ACQ_RELEASE","m":"ac","x":777.3,"y":471.7,"d":1},{"id":"ACQ_REMATCH","m":"ac","x":943.7,"y":526.4,"d":1},{"id":"ACQ_REPROC","m":"ac","x":643.9,"y":437.4,"d":1},{"id":"ACQ_RESERVE","m":"ac","x":942.7,"y":508.5,"d":1},{"id":"ACQ_RESERVECXL","m":"ac","x":949.9,"y":656.1,"d":1},{"id":"ACQ_RETURN","m":"ac","x":897.8,"y":297.3,"d":1},{"id":"ACQ_SETTLELINK","m":"ac","x":564.7,"y":464.2,"d":2},{"id":"ACQ_SPLITPAY","m":"ac","x":118.1,"y":149.7,"d":1},{"id":"ACQ_TAXCXL","m":"ac","x":789.0,"y":138.4,"d":1},{"id":"ACQ_TAXINV","m":"ac","x":920.4,"y":470.1,"d":1},{"id":"ACQ_TAXREVERSE","m":"ac","x":776.3,"y":394.7,"d":1},{"id":"ACQ_UNMATCH","m":"ac","x":939.6,"y":648.0,"d":1},{"id":"ACQ_VELOCITY","m":"ac","x":947.6,"y":914.9,"d":1},{"id":"ACQ_VOID","m":"ac","x":946.0,"y":236.6,"d":1},{"id":"ACQ_WHT","m":"ac","x":719.9,"y":243.0,"d":2},{"id":"ACQ_XFERLINK","m":"ac","x":632.0,"y":224.3,"d":1},{"id":"AUTH","m":"au","x":626.4,"y":773.8,"d":3},{"id":"AUTH_AMT_ADJUST","m":"au","x":945.3,"y":931.3,"d":1},{"id":"AUTH_APPROVE","m":"au","x":901.7,"y":934.0,"d":1},{"id":"AUTH_CANCEL","m":"au","x":937.2,"y":641.7,"d":2},{"id":"AUTH_CAPTURE","m":"au","x":853.8,"y":939.2,"d":1},{"id":"AUTH_DECLINE","m":"au","x":780.3,"y":671.2,"d":1},{"id":"AUTH_DUP_CHK","m":"au","x":931.7,"y":856.5,"d":1},{"id":"AUTH_EXPIRE_CHK","m":"au","x":937.0,"y":790.9,"d":1},{"id":"AUTH_HISTORY","m":"au","x":918.4,"y":345.8,"d":3},{"id":"AUTH_HOLD","m":"au","x":942.7,"y":521.2,"d":1},{"id":"AUTH_PARTAPPR","m":"au","x":949.4,"y":882.4,"d":1},{"id":"AUTH_PARTCXL","m":"au","x":914.7,"y":937.2,"d":1},{"id":"AUTH_RELEASE","m":"au","x":937.8,"y":638.1,"d":1},{"id":"AUTH_RESEND","m":"au","x":723.5,"y":805.4,"d":1},{"id":"AUTH_RETRY","m":"au","x":696.6,"y":613.9,"d":1},{"id":"AUTH_REVERSE","m":"au","x":947.2,"y":828.4,"d":1},{"id":"AUTH_STATUS","m":"au","x":788.1,"y":208.8,"d":2},{"id":"AUTH_SUMMARY","m":"au","x":941.1,"y":686.9,"d":1},{"id":"AUTH_VOID","m":"au","x":946.7,"y":921.7,"d":1},{"id":"BIN_ROUTE_INQ","m":"au","x":878.2,"y":596.8,"d":1},{"id":"BLACKLIST_CHK","m":"au","x":942.0,"y":903.4,"d":1},{"id":"CANCEL_STATUS","m":"au","x":941.3,"y":546.0,"d":1},{"id":"CARD_EXPIRE_CHK","m":"au","x":765.2,"y":902.3,"d":1},{"id":"CARD_LOST_REG","m":"au","x":732.0,"y":755.3,"d":1},{"id":"CARD_STOLEN_REG","m":"au","x":656.3,"y":619.2,"d":1},{"id":"CARD_VALIDATE","m":"au","x":942.0,"y":701.6,"d":1},{"id":"CL_AMTXCHECK","m":"cl","x":889.7,"y":295.7,"d":1},{"id":"CL_APPRDELEG","m":"cl","x":803.8,"y":937.3,"d":1},{"id":"CL_APPRFINAL","m":"cl","x":789.4,"y":942.2,"d":1},{"id":"CL_APPRL1","m":"cl","x":381.5,"y":924.3,"d":1},{"id":"CL_APPRL2","m":"cl","x":607.8,"y":940.1,"d":4},{"id":"CL_APPROVE","m":"cl","x":580.0,"y":934.8,"d":1},{"id":"CL_APPRREJECT","m":"cl","x":550.0,"y":945.0,"d":1},{"id":"CL_APPRREQ","m":"cl","x":685.9,"y":944.2,"d":1},{"id":"CL_APPRSTAT","m":"cl","x":603.0,"y":940.2,"d":1},{"id":"CL_BALVERIFY","m":"cl","x":574.8,"y":815.1,"d":1},{"id":"CL_CANCEL","m":"cl","x":639.6,"y":448.2,"d":1},{"id":"CL_CHKALL","m":"cl","x":580.5,"y":661.2,"d":1},{"id":"CL_CHKPENDING","m":"cl","x":732.6,"y":512.6,"d":1},{"id":"CL_CHKUNMATCH","m":"cl","x":859.4,"y":536.0,"d":1},{"id":"CL_CHKVOID","m":"cl","x":663.9,"y":683.0,"d":1},{"id":"CL_CHNVERIFY","m":"cl","x":890.9,"y":690.3,"d":1},{"id":"CL_CNTVERIFY","m":"cl","x":848.4,"y":717.7,"d":1},{"id":"CL_CNTXCHECK","m":"cl","x":630.5,"y":727.8,"d":1},{"id":"CL_CORPCLOSE","m":"cl","x":706.3,"y":944.6,"d":1},{"id":"CL_CORPVERIFY","m":"cl","x":800.1,"y":324.7,"d":1},{"id":"CL_DAILY","m":"cl","x":527.1,"y":948.2,"d":2},{"id":"CL_DAYVERIFY","m":"cl","x":534.7,"y":944.9,"d":1},{"id":"CL_DIFFCHK","m":"cl","x":661.7,"y":257.3,"d":1},{"id":"CL_DIVCLOSE","m":"cl","x":427.7,"y":937.7,"d":1},{"id":"CL_DUPCHK","m":"cl","x":482.6,"y":408.4,"d":1},{"id":"CL_ESCALATE","m":"cl","x":826.0,"y":945.1,"d":1},{"id":"CL_FEECROSS","m":"cl","x":584.8,"y":713.3,"d":1},{"id":"CL_FEEVERIFY","m":"cl","x":505.0,"y":569.3,"d":1},{"id":"CL_FORCECLOSE","m":"cl","x":670.5,"y":949.9,"d":1},{"id":"CL_HALFCLOSE","m":"cl","x":556.8,"y":944.3,"d":1},{"id":"CL_HYVERIFY","m":"cl","x":842.7,"y":616.3,"d":1},{"id":"CL_LOCK","m":"cl","x":498.7,"y":945.2,"d":1},{"id":"CL_MAINCLOSE","m":"cl","x":655.4,"y":944.5,"d":1},{"id":"CL_MERCLOSE","m":"cl","x":420.7,"y":929.1,"d":1},{"id":"CL_MERXCHECK","m":"cl","x":701.9,"y":945.2,"d":1},{"id":"CL_MIDCLOSE","m":"cl","x":794.6,"y":941.6,"d":1},{"id":"CL_MONTHLY","m":"cl","x":166.2,"y":927.8,"d":1},{"id":"CL_MONVERIFY","m":"cl","x":792.8,"y":595.7,"d":1},{"id":"CL_NETCROSS","m":"cl","x":865.4,"y":235.8,"d":1},{"id":"CL_NETVERIFY","m":"cl","x":700.9,"y":528.3,"d":1},{"id":"CL_POSTTRIG","m":"cl","x":416.7,"y":694.2,"d":1},{"id":"CL_PRECHECK","m":"cl","x":773.1,"y":941.5,"d":1},{"id":"CL_QTRVERIFY","m":"cl","x":819.0,"y":938.2,"d":1},{"id":"CL_QUARTER","m":"cl","x":611.9,"y":940.1,"d":1},{"id":"CL_RECLOSE","m":"cl","x":637.8,"y":397.0,"d":1},{"id":"CL_RECON","m":"cl","x":712.1,"y":824.1,"d":1},{"id":"CL_ROLLBACK","m":"cl","x":679.7,"y":621.5,"d":1},{"id":"CL_SEGVERIFY","m":"cl","x":925.1,"y":558.5,"d":1},{"id":"CL_SEMIMONTH","m":"cl","x":319.5,"y":950.0,"d":1},{"id":"CL_SNAPSHOT","m":"cl","x":361.7,"y":929.3,"d":1},{"id":"CL_SNAPXCHECK","m":"cl","x":785.9,"y":943.0,"d":1},{"id":"CL_STCROSS","m":"cl","x":815.6,"y":593.4,"d":1},{"id":"CL_TENDAY","m":"cl","x":463.1,"y":936.7,"d":1},{"id":"CL_TRIGSETTLE","m":"cl","x":665.9,"y":582.9,"d":1},{"id":"CL_VERIFY","m":"cl","x":838.4,"y":906.7,"d":1},{"id":"CL_WEEKLY","m":"cl","x":173.1,"y":930.6,"d":1},{"id":"CL_WEEKVERIFY","m":"cl","x":409.6,"y":617.5,"d":1},{"id":"CL_YEAREND","m":"cl","x":618.7,"y":947.6,"d":1},{"id":"CL_YEARVERIFY","m":"cl","x":154.1,"y":266.8,"d":1},{"id":"CM_ADDDAYS","m":"cm","x":553.1,"y":944.7,"d":1},{"id":"CM_AMT_ROUND","m":"cm","x":494.5,"y":389.9,"d":3},{"id":"CM_BATDEP_CHK","m":"cm","x":330.0,"y":939.8,"d":1},{"id":"CM_BATDEP_SET","m":"cm","x":407.0,"y":940.9,"d":1},{"id":"CM_BATHIST_CNT","m":"cm","x":193.2,"y":948.7,"d":1},{"id":"CM_BATLAST","m":"cm","x":326.3,"y":907.9,"d":4},{"id":"CM_BATRERUN_REQ","m":"cm","x":414.1,"y":941.7,"d":1},{"id":"CM_BATSCHD_DEL","m":"cm","x":504.7,"y":698.2,"d":1},{"id":"CM_BATSCHD_REG","m":"cm","x":338.1,"y":607.1,"d":1},{"id":"CM_BIZDAY","m":"cm","x":243.4,"y":476.7,"d":8},{"id":"CM_BIZDAY_ADD","m":"cm","x":392.6,"y":938.7,"d":1},{"id":"CM_BIZDAY_CNT","m":"cm","x":614.3,"y":948.4,"d":1},{"id":"CM_CACHE_INV","m":"cm","x":285.5,"y":942.0,"d":1},{"id":"CM_CACHE_LOAD","m":"cm","x":278.6,"y":943.0,"d":1},{"id":"CM_CHECKDIGIT","m":"cm","x":290.1,"y":804.7,"d":1},{"id":"CM_CODE","m":"cm","x":601.4,"y":949.0,"d":2},{"id":"CM_CODEGRP_REG","m":"cm","x":364.4,"y":946.3,"d":1},{"id":"CM_CRC","m":"cm","x":116.9,"y":752.5,"d":2},{"id":"CM_ERRMSG","m":"cm","x":379.0,"y":637.7,"d":1},{"id":"CM_FX","m":"cm","x":327.1,"y":852.8,"d":6},{"id":"CM_FX_CONV","m":"cm","x":453.5,"y":533.2,"d":5},{"id":"CM_FX_CROSS","m":"cm","x":581.7,"y":949.2,"d":2},{"id":"CM_FX_INVERT","m":"cm","x":112.4,"y":946.9,"d":1},{"id":"CM_FX_MARGIN","m":"cm","x":166.3,"y":946.4,"d":1},{"id":"CM_FX_PUBLISH","m":"cm","x":543.0,"y":927.2,"d":1},{"id":"CM_FX_TRIANGLE","m":"cm","x":255.1,"y":949.4,"d":1},{"id":"CM_FX_VALID","m":"cm","x":516.4,"y":640.8,"d":2},{"id":"CM_HASH_DJB2","m":"cm","x":292.8,"y":939.8,"d":1},{"id":"CM_HASH_FNV","m":"cm","x":128.0,"y":532.1,"d":1},{"id":"CM_HASH_SUM","m":"cm","x":95.6,"y":933.8,"d":2},{"id":"CM_HOLIDAY_CHK","m":"cm","x":508.8,"y":948.0,"d":3},{"id":"CM_LOG","m":"cm","x":430.1,"y":524.3,"d":44},{"id":"CM_LUHN","m":"cm","x":739.4,"y":465.9,"d":8},{"id":"CM_MONTHEND","m":"cm","x":351.8,"y":689.7,"d":1},{"id":"CM_MSG_RENDER","m":"cm","x":386.5,"y":881.8,"d":1},{"id":"CM_NEXTBIZ","m":"cm","x":201.8,"y":656.9,"d":1},{"id":"CM_NOTI_HIST","m":"cm","x":404.4,"y":942.4,"d":1},{"id":"CM_NOTI_QUOTA","m":"cm","x":298.0,"y":789.8,"d":1},{"id":"CM_NOTI_RETRY","m":"cm","x":321.3,"y":568.3,"d":1},{"id":"CM_NOTI_SEND","m":"cm","x":231.4,"y":171.1,"d":4},{"id":"CM_NOTI_TMPL","m":"cm","x":384.8,"y":704.9,"d":1},{"id":"CM_PARAM","m":"cm","x":432.1,"y":943.4,"d":4},{"id":"CM_PREVBIZ","m":"cm","x":238.6,"y":759.1,"d":1},{"id":"CM_SEQ","m":"cm","x":133.1,"y":394.1,"d":7},{"id":"CM_SEQ_ALLOC","m":"cm","x":461.4,"y":872.1,"d":1},{"id":"CM_SEQ_DAILY","m":"cm","x":443.1,"y":940.6,"d":1},{"id":"CM_SEQ_MULTI","m":"cm","x":585.5,"y":834.8,"d":1},{"id":"CM_SEQ_RESET","m":"cm","x":405.7,"y":838.0,"d":1},{"id":"CM_SEQ_STAMP","m":"cm","x":418.1,"y":800.7,"d":1},{"id":"CM_SEQ_TYPED","m":"cm","x":365.2,"y":590.4,"d":1},{"id":"CM_STATUS","m":"cm","x":203.3,"y":419.2,"d":3},{"id":"FRAUD_DETECT","m":"au","x":857.2,"y":721.6,"d":8},{"id":"FRAUD_RULE_AMT","m":"au","x":930.5,"y":286.0,"d":1},{"id":"FRAUD_RULE_NIGHT","m":"au","x":941.5,"y":616.6,"d":1},{"id":"INSTALL_AUTH","m":"au","x":939.4,"y":824.4,"d":1},{"id":"LG_ACCRUEREV","m":"lg","x":247.1,"y":636.0,"d":1},{"id":"LG_ACCTSUM","m":"lg","x":140.1,"y":875.2,"d":3},{"id":"LG_ACQPOST","m":"lg","x":59.6,"y":663.4,"d":1},{"id":"LG_ADJUST","m":"lg","x":333.6,"y":508.1,"d":3},{"id":"LG_ALLOWANCE","m":"lg","x":296.8,"y":676.5,"d":1},{"id":"LG_ALLOWRECALC","m":"lg","x":67.2,"y":927.3,"d":1},{"id":"LG_BADDEBT","m":"lg","x":225.9,"y":576.6,"d":1},{"id":"LG_BADDEBTRCV","m":"lg","x":225.5,"y":459.5,"d":1},{"id":"LG_BALCERT","m":"lg","x":65.6,"y":940.4,"d":1},{"id":"LG_BALCHK","m":"lg","x":276.7,"y":671.8,"d":22},{"id":"LG_BALPROOF","m":"lg","x":290.0,"y":941.7,"d":1},{"id":"LG_BLACKENTRY","m":"lg","x":148.8,"y":776.7,"d":1},{"id":"LG_BSSUMMARY","m":"lg","x":59.3,"y":893.7,"d":1},{"id":"LG_CLOSE_LINK","m":"lg","x":592.4,"y":896.6,"d":4},{"id":"LG_CORPSUM","m":"lg","x":442.4,"y":866.3,"d":3},{"id":"LG_CORRECT","m":"lg","x":496.0,"y":744.8,"d":2},{"id":"LG_DEPTSUM","m":"lg","x":388.6,"y":867.4,"d":3},{"id":"LG_DOUBLE","m":"lg","x":179.1,"y":779.5,"d":1},{"id":"LG_DUPSCAN","m":"lg","x":264.3,"y":942.4,"d":1},{"id":"LG_FEEACCRUE","m":"lg","x":68.5,"y":726.0,"d":1},{"id":"LG_FEEPOST","m":"lg","x":92.5,"y":659.9,"d":2},{"id":"LG_HALFCLOSE","m":"lg","x":60.1,"y":932.9,"d":1},{"id":"LG_INQUIRY","m":"lg","x":799.3,"y":268.1,"d":3},{"id":"LG_JOURNAL","m":"lg","x":78.9,"y":945.3,"d":1},{"id":"LG_MERCHBAL","m":"lg","x":534.2,"y":802.3,"d":2},{"id":"LG_MERCHPROOF","m":"lg","x":238.0,"y":943.3,"d":2},{"id":"LG_MONTHCLOSE","m":"lg","x":122.3,"y":939.8,"d":1},{"id":"LG_MONTHLYSUM","m":"lg","x":59.6,"y":937.6,"d":2},{"id":"LG_NETPOS","m":"lg","x":235.6,"y":936.8,"d":1},{"id":"LG_PARTREVERSE","m":"lg","x":425.7,"y":501.9,"d":2},{"id":"LG_PERIODTB","m":"lg","x":370.4,"y":870.3,"d":2},{"id":"LG_PLSUMMARY","m":"lg","x":61.0,"y":836.2,"d":1},{"id":"LG_POST","m":"lg","x":352.6,"y":317.3,"d":28},{"id":"LG_PREPAIDAMORT","m":"lg","x":113.9,"y":917.0,"d":1},{"id":"LG_PREPAIDPOST","m":"lg","x":221.4,"y":893.4,"d":2},{"id":"LG_QTRCLOSE","m":"lg","x":62.1,"y":857.6,"d":1},{"id":"LG_RECALC","m":"lg","x":286.6,"y":878.3,"d":6},{"id":"LG_REDADJUST","m":"lg","x":271.3,"y":619.3,"d":1},{"id":"LG_REDBLACKNET","m":"lg","x":211.3,"y":847.1,"d":1},{"id":"LG_REDENTRY","m":"lg","x":204.3,"y":741.5,"d":2},{"id":"LG_REPOST","m":"lg","x":261.9,"y":705.9,"d":1},{"id":"LG_REVERSE","m":"lg","x":612.6,"y":273.5,"d":19},{"id":"LG_ROLLTB","m":"lg","x":311.3,"y":914.4,"d":2},{"id":"LG_SETTLEPOST","m":"lg","x":385.8,"y":456.8,"d":2},{"id":"LG_SPANTB","m":"lg","x":248.2,"y":941.3,"d":2},{"id":"LG_STATUS","m":"lg","x":597.5,"y":396.0,"d":2},{"id":"LG_SUSPENSE","m":"lg","x":105.6,"y":834.7,"d":1},{"id":"LG_THREEWAY","m":"lg","x":334.1,"y":178.8,"d":1},{"id":"LG_TRANSFER","m":"lg","x":199.7,"y":872.5,"d":1},{"id":"LG_TRIALBAL","m":"lg","x":155.8,"y":881.6,"d":7},{"id":"LG_UNEARNPOST","m":"lg","x":118.1,"y":870.1,"d":2},{"id":"LG_UNEARNRECOG","m":"lg","x":71.7,"y":936.6,"d":1},{"id":"LG_VOIDVOUCHER","m":"lg","x":731.3,"y":423.7,"d":1},{"id":"LG_VOUCHER","m":"lg","x":149.0,"y":650.0,"d":1},{"id":"LG_WEEKCLOSE","m":"lg","x":250.7,"y":940.5,"d":1},{"id":"LG_WRITEOFF","m":"lg","x":209.8,"y":473.2,"d":1},{"id":"LG_XFERPOST","m":"lg","x":171.8,"y":713.3,"d":1},{"id":"LG_YEARCLOSE","m":"lg","x":68.6,"y":720.1,"d":1},{"id":"LIMIT_CHK","m":"au","x":679.8,"y":470.6,"d":10},{"id":"LIMIT_DEC","m":"au","x":886.6,"y":824.1,"d":10},{"id":"LIMIT_EXHAUST_LST","m":"au","x":768.4,"y":641.6,"d":1},{"id":"LIMIT_FREEZE","m":"au","x":639.8,"y":566.9,"d":1},{"id":"LIMIT_OVER_ALERT","m":"au","x":444.2,"y":604.8,"d":1},{"id":"LIMIT_RST","m":"au","x":856.0,"y":729.8,"d":13},{"id":"MG_ACK","m":"mg","x":51.7,"y":682.5,"d":1},{"id":"MG_BITMAP","m":"mg","x":63.4,"y":511.6,"d":1},{"id":"MG_BMPPARSE","m":"mg","x":61.0,"y":735.4,"d":1},{"id":"MG_CHANFAILOVER","m":"mg","x":57.1,"y":493.8,"d":1},{"id":"MG_CHANHEALTH","m":"mg","x":52.6,"y":762.7,"d":1},{"id":"MG_CHANOPEN","m":"mg","x":52.9,"y":728.0,"d":1},{"id":"MG_CHANPING","m":"mg","x":58.7,"y":565.6,"d":2},{"id":"MG_CHANSTAT","m":"mg","x":64.6,"y":818.4,"d":1},{"id":"MG_CHANSWITCH","m":"mg","x":58.4,"y":652.9,"d":1},{"id":"MG_DECODE","m":"mg","x":59.4,"y":554.7,"d":1},{"id":"MG_ENCODE","m":"mg","x":52.6,"y":710.4,"d":1},{"id":"MG_ERRREQUEUE","m":"mg","x":58.5,"y":601.9,"d":1},{"id":"MG_ERRRETRY","m":"mg","x":106.0,"y":541.2,"d":1},{"id":"MG_FROMISO","m":"mg","x":50.0,"y":757.4,"d":1},{"id":"MG_ISO8583","m":"mg","x":64.9,"y":544.9,"d":1},{"id":"MG_KEYCHECK","m":"mg","x":56.2,"y":866.9,"d":1},{"id":"MG_KEYLOAD","m":"mg","x":56.5,"y":510.9,"d":1},{"id":"MG_LOADBAL","m":"mg","x":60.4,"y":592.3,"d":1},{"id":"MG_LOG","m":"mg","x":681.0,"y":778.5,"d":6},{"id":"MG_MAC","m":"mg","x":57.7,"y":871.5,"d":1},{"id":"MG_MACGEN","m":"mg","x":54.1,"y":708.0,"d":1},{"id":"MG_MACSESSION","m":"mg","x":55.4,"y":912.6,"d":1},{"id":"MG_MACVERIFY","m":"mg","x":57.1,"y":571.0,"d":1},{"id":"MG_NACK","m":"mg","x":58.5,"y":624.5,"d":1},{"id":"MG_PACK","m":"mg","x":58.3,"y":612.4,"d":1},{"id":"MG_PARSE","m":"mg","x":115.7,"y":705.3,"d":9},{"id":"MG_REASM","m":"mg","x":55.8,"y":917.5,"d":1},{"id":"MG_RECV","m":"mg","x":52.2,"y":805.9,"d":1},{"id":"MG_RESEND","m":"mg","x":466.6,"y":384.4,"d":2},{"id":"MG_RESNDONE","m":"mg","x":50.2,"y":781.9,"d":1},{"id":"MG_ROUTE","m":"mg","x":55.3,"y":743.4,"d":4},{"id":"MG_SEND","m":"mg","x":272.2,"y":574.9,"d":19},{"id":"MG_SEQFILL","m":"mg","x":54.5,"y":777.1,"d":1},{"id":"MG_SEQNEXT","m":"mg","x":54.8,"y":877.9,"d":1},{"id":"MG_STAN","m":"mg","x":96.0,"y":675.8,"d":3},{"id":"MG_TOISO","m":"mg","x":58.2,"y":583.6,"d":1},{"id":"MG_UNPACK","m":"mg","x":55.6,"y":739.1,"d":1},{"id":"MM_ACCT_REG","m":"mm","x":419.5,"y":424.8,"d":1},{"id":"MM_ACCT_VERIFY","m":"mm","x":439.0,"y":405.4,"d":1},{"id":"MM_APPLY_APPROVE","m":"mm","x":52.0,"y":327.7,"d":1},{"id":"MM_APPLY_REG","m":"mm","x":51.5,"y":313.6,"d":1},{"id":"MM_BIN_REG","m":"mm","x":488.6,"y":284.6,"d":1},{"id":"MM_BIZNO_CHECK","m":"mm","x":50.2,"y":678.0,"d":1},{"id":"MM_CHK_LIMIT","m":"mm","x":272.6,"y":409.4,"d":1},{"id":"MM_CODE_REG","m":"mm","x":168.0,"y":237.3,"d":1},{"id":"MM_CONTRACT_AMEND","m":"mm","x":56.6,"y":240.2,"d":1},{"id":"MM_CONTRACT_NEW","m":"mm","x":53.3,"y":290.2,"d":1},{"id":"MM_CONTRACT_RENEW","m":"mm","x":58.5,"y":573.3,"d":1},{"id":"MM_FEERATE_SET","m":"mm","x":333.2,"y":258.3,"d":1},{"id":"MM_GRADE_ADJUST","m":"mm","x":57.5,"y":245.0,"d":1},{"id":"MM_ISSUER_REG","m":"mm","x":265.6,"y":304.2,"d":1},{"id":"MM_LIMIT_SET","m":"mm","x":373.7,"y":414.5,"d":1},{"id":"MM_MCC_REG","m":"mm","x":335.4,"y":156.3,"d":1},{"id":"MM_MCC_UPD","m":"mm","x":318.6,"y":224.0,"d":1},{"id":"MM_MERCH_CLOSE","m":"mm","x":180.5,"y":513.0,"d":1},{"id":"MM_MERCH_DORMANT","m":"mm","x":54.0,"y":236.4,"d":1},{"id":"MM_MERCH_GRADE","m":"mm","x":59.6,"y":405.5,"d":1},{"id":"MM_MERCH_INQ","m":"mm","x":316.6,"y":188.3,"d":1},{"id":"MM_MERCH_PAUSE","m":"mm","x":85.9,"y":219.5,"d":1},{"id":"MM_MERCH_REG","m":"mm","x":60.1,"y":370.1,"d":1},{"id":"MM_MERCH_RESUME","m":"mm","x":200.7,"y":484.9,"d":1},{"id":"MM_MERCH_STATUS","m":"mm","x":65.1,"y":298.3,"d":1},{"id":"MM_MERCH_UPD","m":"mm","x":59.3,"y":356.7,"d":1},{"id":"MM_RATE_APPROVE","m":"mm","x":232.9,"y":78.2,"d":1},{"id":"MM_RATE_REQ","m":"mm","x":278.1,"y":508.2,"d":1},{"id":"MM_RISK_SCORE","m":"mm","x":179.2,"y":419.0,"d":1},{"id":"MM_RISK_SET","m":"mm","x":59.3,"y":163.9,"d":1},{"id":"MM_TERMINAL_REG","m":"mm","x":57.1,"y":388.3,"d":1},{"id":"MM_TERM_INSTALL","m":"mm","x":60.5,"y":447.7,"d":1},{"id":"MM_VALIDATE","m":"mm","x":112.4,"y":369.0,"d":5},{"id":"NOAUTH_CAPTURE","m":"au","x":934.9,"y":885.0,"d":1},{"id":"PAY_ACCTCHK","m":"py","x":137.6,"y":111.7,"d":11},{"id":"PAY_ACCTVERIFY","m":"py","x":65.3,"y":190.9,"d":1},{"id":"PAY_ADJUST","m":"py","x":434.6,"y":99.2,"d":1},{"id":"PAY_APPRBULK","m":"py","x":302.5,"y":60.5,"d":1},{"id":"PAY_APPROVE","m":"py","x":232.4,"y":57.6,"d":1},{"id":"PAY_BANKFILE","m":"py","x":175.4,"y":303.5,"d":1},{"id":"PAY_BANKVERIFY","m":"py","x":67.3,"y":62.7,"d":1},{"id":"PAY_CANCEL","m":"py","x":316.3,"y":132.9,"d":2},{"id":"PAY_CHARGEBACK","m":"py","x":432.2,"y":89.6,"d":1},{"id":"PAY_CLOSE","m":"py","x":192.8,"y":137.4,"d":1},{"id":"PAY_COMBINE","m":"py","x":74.0,"y":54.6,"d":1},{"id":"PAY_CONFIRM","m":"py","x":179.8,"y":217.7,"d":1},{"id":"PAY_FAILRSN","m":"py","x":71.6,"y":102.5,"d":3},{"id":"PAY_FILEGEN","m":"py","x":467.5,"y":87.4,"d":7},{"id":"PAY_FILEREBUILD","m":"py","x":59.9,"y":249.1,"d":1},{"id":"PAY_HOLD","m":"py","x":720.3,"y":290.0,"d":3},{"id":"PAY_MERGE","m":"py","x":60.4,"y":65.1,"d":1},{"id":"PAY_NETOFF","m":"py","x":200.1,"y":167.0,"d":1},{"id":"PAY_RECLAIM","m":"py","x":389.7,"y":111.7,"d":2},{"id":"PAY_REFUND","m":"py","x":296.5,"y":60.9,"d":1},{"id":"PAY_RELEASE","m":"py","x":517.0,"y":437.6,"d":3},{"id":"PAY_REMIT","m":"py","x":64.9,"y":133.4,"d":1},{"id":"PAY_REPROC","m":"py","x":66.5,"y":57.1,"d":1},{"id":"PAY_REQUEUE","m":"py","x":76.3,"y":455.6,"d":1},{"id":"PAY_RESULT","m":"py","x":139.7,"y":203.7,"d":1},{"id":"PAY_RESVMODIFY","m":"py","x":98.5,"y":370.6,"d":1},{"id":"PAY_RETRY","m":"py","x":66.4,"y":142.0,"d":1},{"id":"PAY_RETRYONE","m":"py","x":100.8,"y":57.7,"d":1},{"id":"PAY_REVERSE","m":"py","x":410.8,"y":83.9,"d":2},{"id":"PAY_ROLLFWD","m":"py","x":84.4,"y":442.5,"d":1},{"id":"PAY_SCHEDULE","m":"py","x":60.5,"y":348.5,"d":1},{"id":"PAY_SPLIT","m":"py","x":65.8,"y":135.7,"d":1},{"id":"PAY_SPLITEVEN","m":"py","x":56.0,"y":66.3,"d":1},{"id":"PAY_SPLITRATIO","m":"py","x":236.2,"y":57.1,"d":1},{"id":"PAY_URGENT","m":"py","x":95.5,"y":51.5,"d":1},{"id":"PAY_VOIDONE","m":"py","x":383.4,"y":134.7,"d":1},{"id":"PAY_XFERLINK","m":"py","x":355.5,"y":359.0,"d":2},{"id":"PREAUTH","m":"au","x":942.1,"y":896.3,"d":1},{"id":"PREAUTH_CANCEL","m":"au","x":654.1,"y":864.8,"d":1},{"id":"PREAUTH_COMPLETE","m":"au","x":928.2,"y":932.0,"d":1},{"id":"PREAUTH_EXTEND","m":"au","x":870.3,"y":552.0,"d":1},{"id":"PREAUTH_INQ","m":"au","x":940.3,"y":620.8,"d":1},{"id":"PREAUTH_PARTUSE","m":"au","x":941.2,"y":933.6,"d":1},{"id":"RC_3WAY","m":"rc","x":450.1,"y":134.6,"d":2},{"id":"RC_4WAY","m":"rc","x":207.1,"y":50.7,"d":1},{"id":"RC_ACQMATCH","m":"rc","x":606.5,"y":53.7,"d":1},{"id":"RC_ACQ_DEP","m":"rc","x":156.3,"y":361.5,"d":1},{"id":"RC_ALERT","m":"rc","x":210.7,"y":50.2,"d":1},{"id":"RC_AMTDIFF","m":"rc","x":479.5,"y":57.2,"d":1},{"id":"RC_APPRGAP","m":"rc","x":762.5,"y":53.1,"d":1},{"id":"RC_APPRMATCH","m":"rc","x":602.4,"y":55.4,"d":1},{"id":"RC_APPR_ACQ","m":"rc","x":404.1,"y":57.8,"d":1},{"id":"RC_AUTOFIX","m":"rc","x":515.0,"y":52.8,"d":1},{"id":"RC_CLOSEDAY","m":"rc","x":569.9,"y":57.6,"d":1},{"id":"RC_CNTDIFF","m":"rc","x":318.2,"y":151.9,"d":1},{"id":"RC_CONFIRM","m":"rc","x":499.1,"y":52.5,"d":1},{"id":"RC_DEPGAP","m":"rc","x":134.7,"y":100.0,"d":1},{"id":"RC_DEPMATCH","m":"rc","x":382.7,"y":229.6,"d":1},{"id":"RC_DUPCHK","m":"rc","x":634.5,"y":331.0,"d":3},{"id":"RC_ESCALATE","m":"rc","x":650.4,"y":663.8,"d":2},{"id":"RC_EXCEPTION","m":"rc","x":711.5,"y":322.7,"d":7},{"id":"RC_EXCNOTIFY","m":"rc","x":91.6,"y":119.1,"d":1},{"id":"RC_FEEDIFF","m":"rc","x":457.1,"y":307.4,"d":1},{"id":"RC_FEERECON","m":"rc","x":473.1,"y":195.5,"d":1},{"id":"RC_FIXFEE","m":"rc","x":337.5,"y":52.0,"d":1},{"id":"RC_FIXFX","m":"rc","x":328.8,"y":535.9,"d":1},{"id":"RC_FIXROUND","m":"rc","x":444.1,"y":340.6,"d":1},{"id":"RC_FXDIFF","m":"rc","x":575.4,"y":116.9,"d":1},{"id":"RC_FXRECON","m":"rc","x":709.1,"y":50.3,"d":1},{"id":"RC_HOLDCLR","m":"rc","x":495.5,"y":52.5,"d":1},{"id":"RC_HOLDSET","m":"rc","x":409.4,"y":50.0,"d":1},{"id":"RC_LEDGERBAL","m":"rc","x":212.5,"y":354.5,"d":1},{"id":"RC_LEDGERLINK","m":"rc","x":396.7,"y":64.5,"d":1},{"id":"RC_LIMITCHK","m":"rc","x":493.5,"y":100.0,"d":1},{"id":"RC_MANUAL","m":"rc","x":411.9,"y":58.6,"d":1},{"id":"RC_NOTIFY","m":"rc","x":314.8,"y":61.7,"d":1},{"id":"RC_ORPHAN","m":"rc","x":635.1,"y":190.0,"d":1},{"id":"RC_OVERAMT","m":"rc","x":546.0,"y":56.7,"d":1},{"id":"RC_PAYLEDGER","m":"rc","x":168.4,"y":62.6,"d":1},{"id":"RC_PAYMATCH","m":"rc","x":310.8,"y":61.3,"d":1},{"id":"RC_PROGRESS","m":"rc","x":97.4,"y":435.6,"d":1},{"id":"RC_RECORR","m":"rc","x":398.9,"y":342.0,"d":1},{"id":"RC_REDIFF","m":"rc","x":615.5,"y":55.6,"d":1},{"id":"RC_REFULL","m":"rc","x":688.3,"y":261.8,"d":1},{"id":"RC_REFUNDREC","m":"rc","x":723.7,"y":72.5,"d":1},{"id":"RC_RELEASE","m":"rc","x":397.0,"y":57.7,"d":1},{"id":"RC_REMATCH","m":"rc","x":719.0,"y":287.1,"d":2},{"id":"RC_REPROC","m":"rc","x":496.3,"y":449.7,"d":2},{"id":"RC_RERUN","m":"rc","x":508.4,"y":55.0,"d":1},{"id":"RC_ROUNDDIFF","m":"rc","x":473.6,"y":213.1,"d":1},{"id":"RC_SNAPSHOT","m":"rc","x":166.6,"y":660.9,"d":1},{"id":"RC_STATUS","m":"rc","x":300.7,"y":165.0,"d":1},{"id":"RC_SUMCHK","m":"rc","x":501.8,"y":53.1,"d":1},{"id":"RC_TOLERANCE","m":"rc","x":625.3,"y":50.2,"d":1},{"id":"RC_UNDERAMT","m":"rc","x":651.4,"y":50.3,"d":1},{"id":"RC_UNMATCH","m":"rc","x":755.6,"y":408.0,"d":4},{"id":"RECONCILE","m":"rc","x":657.7,"y":91.9,"d":2},{"id":"RISK_SCORE_INQ","m":"au","x":772.5,"y":162.6,"d":1},{"id":"SETTLE","m":"st","x":644.4,"y":290.3,"d":3},{"id":"STANDIN","m":"au","x":701.9,"y":698.7,"d":2},{"id":"STANDIN_SETTLE","m":"au","x":930.7,"y":876.2,"d":1},{"id":"ST_ADJREVERSE","m":"st","x":725.5,"y":53.1,"d":1},{"id":"ST_ADJUST","m":"st","x":585.4,"y":166.0,"d":10},{"id":"ST_APPROVE","m":"st","x":849.9,"y":55.4,"d":1},{"id":"ST_APPROVEALL","m":"st","x":656.0,"y":51.0,"d":1},{"id":"ST_CANCEL","m":"st","x":747.5,"y":327.6,"d":2},{"id":"ST_CAPCHECK","m":"st","x":721.6,"y":54.4,"d":1},{"id":"ST_CHARGEBACK","m":"st","x":858.4,"y":216.2,"d":2},{"id":"ST_COLLATERAL","m":"st","x":200.8,"y":84.7,"d":1},{"id":"ST_CONFIRM","m":"st","x":425.9,"y":64.1,"d":1},{"id":"ST_CXLRECALC","m":"st","x":804.4,"y":50.6,"d":1},{"id":"ST_DAILYCLOSE","m":"st","x":357.4,"y":523.1,"d":2},{"id":"ST_DIFFCHK","m":"st","x":690.7,"y":58.0,"d":1},{"id":"ST_DISPUTE","m":"st","x":647.7,"y":50.9,"d":1},{"id":"ST_GRPSETTLE","m":"st","x":503.3,"y":162.4,"d":1},{"id":"ST_HOLD","m":"st","x":672.6,"y":361.7,"d":3},{"id":"ST_HOLDAMT","m":"st","x":729.0,"y":54.9,"d":1},{"id":"ST_INSTANTPAY","m":"st","x":712.1,"y":59.4,"d":1},{"id":"ST_LEDGERLINK","m":"st","x":732.3,"y":51.4,"d":1},{"id":"ST_LIMITCHK","m":"st","x":781.5,"y":56.7,"d":1},{"id":"ST_LOCKBATCH","m":"st","x":556.0,"y":59.8,"d":1},{"id":"ST_MDR","m":"st","x":592.0,"y":216.7,"d":9},{"id":"ST_MERCHRATE","m":"st","x":433.6,"y":65.2,"d":1},{"id":"ST_NETTING","m":"st","x":519.6,"y":175.1,"d":1},{"id":"ST_NEXTPAYDT","m":"st","x":413.6,"y":437.5,"d":1},{"id":"ST_OFFSET","m":"st","x":772.6,"y":101.5,"d":1},{"id":"ST_PAYDATE","m":"st","x":543.2,"y":121.2,"d":1},{"id":"ST_PAYSTATUS","m":"st","x":764.6,"y":52.9,"d":1},{"id":"ST_PRECONFIRM","m":"st","x":831.3,"y":52.2,"d":1},{"id":"ST_PROMOAPPLY","m":"st","x":709.7,"y":59.7,"d":1},{"id":"ST_RATEAPPLY","m":"st","x":795.3,"y":57.4,"d":1},{"id":"ST_RATECARD","m":"st","x":815.5,"y":56.9,"d":1},{"id":"ST_RECALC","m":"st","x":846.7,"y":284.5,"d":2},{"id":"ST_REFUNDCALC","m":"st","x":878.2,"y":245.8,"d":2},{"id":"ST_RELEASE","m":"st","x":604.7,"y":492.9,"d":3},{"id":"ST_RERUN","m":"st","x":786.6,"y":55.8,"d":1},{"id":"ST_SPLIT","m":"st","x":203.2,"y":66.1,"d":1},{"id":"ST_STATUS","m":"st","x":654.0,"y":189.8,"d":3},{"id":"ST_TAXINVCHK","m":"st","x":679.9,"y":59.0,"d":1},{"id":"ST_UNLOCK","m":"st","x":841.9,"y":52.7,"d":1},{"id":"ST_VAT","m":"st","x":835.9,"y":53.2,"d":1},{"id":"ST_VATADJUST","m":"st","x":208.4,"y":200.8,"d":1},{"id":"ST_VATDETAIL","m":"st","x":704.4,"y":61.1,"d":1},{"id":"ST_VOIDRECALC","m":"st","x":820.0,"y":98.9,"d":1},{"id":"ST_WHT","m":"st","x":709.9,"y":147.4,"d":2},{"id":"ST_XFERLINK","m":"st","x":232.8,"y":298.6,"d":1},{"id":"TOKEN_VERIFY","m":"au","x":866.3,"y":668.2,"d":1},{"id":"VELOCITY_CHK","m":"au","x":941.3,"y":937.2,"d":1},{"id":"VELOCITY_DAY","m":"au","x":780.4,"y":940.1,"d":1},{"id":"VL_AMOUNT","m":"vl","x":618.9,"y":165.8,"d":8},{"id":"VL_ANOMALY","m":"vl","x":852.5,"y":549.9,"d":1},{"id":"VL_APPRAMT","m":"vl","x":406.7,"y":271.2,"d":2},{"id":"VL_APPRNOPUR","m":"vl","x":943.1,"y":246.8,"d":2},{"id":"VL_APPR_ACQ","m":"vl","x":622.6,"y":274.2,"d":2},{"id":"VL_AXLEDGDC","m":"vl","x":851.8,"y":761.5,"d":1},{"id":"VL_AXPURAPPR","m":"vl","x":713.3,"y":227.4,"d":2},{"id":"VL_AXPURSETT","m":"vl","x":945.2,"y":129.3,"d":1},{"id":"VL_AXSETTPAY","m":"vl","x":370.3,"y":379.1,"d":4},{"id":"VL_BALANCE","m":"vl","x":739.8,"y":612.2,"d":2},{"id":"VL_BATCH_CHK","m":"vl","x":421.5,"y":249.9,"d":2},{"id":"VL_BIN","m":"vl","x":593.5,"y":417.8,"d":4},{"id":"VL_CANCELMIS","m":"vl","x":720.1,"y":569.4,"d":1},{"id":"VL_CARD","m":"vl","x":931.6,"y":114.7,"d":1},{"id":"VL_CHANSPLIT","m":"vl","x":918.0,"y":617.7,"d":1},{"id":"VL_CODEVAL","m":"vl","x":389.0,"y":191.7,"d":3},{"id":"VL_CROSSCHK","m":"vl","x":565.0,"y":294.3,"d":5},{"id":"VL_DAYLIMIT","m":"vl","x":887.7,"y":474.2,"d":1},{"id":"VL_DUP","m":"vl","x":542.3,"y":343.2,"d":3},{"id":"VL_DUPAPPR","m":"vl","x":939.3,"y":431.1,"d":1},{"id":"VL_DUPAUTH","m":"vl","x":629.8,"y":375.1,"d":1},{"id":"VL_DUPLEDGR","m":"vl","x":298.4,"y":737.5,"d":1},{"id":"VL_DUPPAY","m":"vl","x":894.6,"y":160.3,"d":1},{"id":"VL_DUPPURCH","m":"vl","x":564.9,"y":317.7,"d":3},{"id":"VL_DUPSETTLE","m":"vl","x":945.5,"y":112.9,"d":1},{"id":"VL_EXPIRY","m":"vl","x":727.2,"y":735.8,"d":2},{"id":"VL_FEE","m":"vl","x":459.5,"y":474.8,"d":3},{"id":"VL_FEERECALC","m":"vl","x":543.9,"y":500.3,"d":1},{"id":"VL_FORMAT","m":"vl","x":943.6,"y":228.3,"d":1},{"id":"VL_FXCHK","m":"vl","x":529.2,"y":368.4,"d":2},{"id":"VL_INSTCHK","m":"vl","x":940.5,"y":434.1,"d":1},{"id":"VL_LEDGBAL","m":"vl","x":440.1,"y":686.1,"d":2},{"id":"VL_LEDGENTRY","m":"vl","x":935.3,"y":174.9,"d":1},{"id":"VL_LEDGER","m":"vl","x":214.3,"y":772.3,"d":8},{"id":"VL_LIMIT","m":"vl","x":869.3,"y":497.8,"d":2},{"id":"VL_LONGOPEN","m":"vl","x":833.6,"y":485.7,"d":1},{"id":"VL_MDRRATE","m":"vl","x":925.6,"y":57.6,"d":1},{"id":"VL_MERCH","m":"vl","x":107.1,"y":249.4,"d":3},{"id":"VL_NEGBAL","m":"vl","x":705.4,"y":161.6,"d":1},{"id":"VL_NEGFEE","m":"vl","x":802.4,"y":192.2,"d":1},{"id":"VL_NEGNET","m":"vl","x":721.0,"y":414.3,"d":2},{"id":"VL_NIGHTTXN","m":"vl","x":874.1,"y":603.5,"d":1},{"id":"VL_OUTLIER","m":"vl","x":793.1,"y":592.4,"d":1},{"id":"VL_OVERLIMIT","m":"vl","x":943.2,"y":478.5,"d":2},{"id":"VL_PURNOAPPR","m":"vl","x":935.1,"y":418.5,"d":3},{"id":"VL_REFINTEG","m":"vl","x":943.3,"y":486.6,"d":1},{"id":"VL_REPORT","m":"vl","x":848.5,"y":302.4,"d":1},{"id":"VL_REQUIRED","m":"vl","x":905.8,"y":840.6,"d":1},{"id":"VL_RIAPPR","m":"vl","x":842.8,"y":92.8,"d":2},{"id":"VL_RICANCEL","m":"vl","x":940.2,"y":413.1,"d":1},{"id":"VL_RIFX","m":"vl","x":410.5,"y":600.9,"d":1},{"id":"VL_RIINSTALL","m":"vl","x":939.1,"y":405.7,"d":1},{"id":"VL_RILEDGER","m":"vl","x":853.4,"y":384.3,"d":1},{"id":"VL_RIMERCH","m":"vl","x":704.3,"y":877.6,"d":2},{"id":"VL_RIPAY","m":"vl","x":510.5,"y":130.7,"d":2},{"id":"VL_RIPURCH","m":"vl","x":817.1,"y":372.3,"d":1},{"id":"VL_RISETTLE","m":"vl","x":810.7,"y":359.8,"d":2},{"id":"VL_RITAXINV","m":"vl","x":942.3,"y":62.3,"d":1},{"id":"VL_RULECOUNT","m":"vl","x":936.3,"y":439.9,"d":1},{"id":"VL_SALES","m":"vl","x":589.5,"y":769.8,"d":3},{"id":"VL_SETTLE","m":"vl","x":767.6,"y":108.5,"d":7},{"id":"VL_SPIKEAMT","m":"vl","x":944.8,"y":146.6,"d":1},{"id":"VL_STATUS_CHK","m":"vl","x":301.9,"y":424.3,"d":2},{"id":"VL_SUMFEE","m":"vl","x":937.1,"y":458.2,"d":1},{"id":"VL_SUMFEECHK","m":"vl","x":505.0,"y":495.8,"d":3},{"id":"VL_SUMGROSS","m":"vl","x":326.5,"y":275.2,"d":3},{"id":"VL_SUMMARY","m":"vl","x":939.5,"y":334.9,"d":1},{"id":"VL_SUMNETCHK","m":"vl","x":935.5,"y":450.8,"d":1},{"id":"VL_SUMRECON","m":"vl","x":669.7,"y":653.8,"d":4},{"id":"VL_SUMTXNCNT","m":"vl","x":364.0,"y":430.6,"d":3},{"id":"VL_SUSPACT","m":"vl","x":911.1,"y":66.4,"d":1},{"id":"VL_SUSPESCAL","m":"vl","x":944.1,"y":484.1,"d":1},{"id":"VL_THRESHOLD","m":"vl","x":936.4,"y":374.9,"d":1},{"id":"VL_VELOCITY","m":"vl","x":845.5,"y":828.7,"d":2},{"id":"VL_ZERONET","m":"vl","x":905.4,"y":110.1,"d":1}],"EDGES":[["ACQUIRE","RECONCILE"],["ACQ_ALERTDUP","VL_DUPPURCH"],["ACQ_AMTFIX","VL_AMOUNT"],["ACQ_APPRLINK","LIMIT_DEC"],["ACQ_APPRMAP","AUTH_CANCEL"],["ACQ_CANCEL","LIMIT_RST"],["ACQ_CANCEL","LG_REVERSE"],["ACQ_CANCEL","ST_CANCEL"],["ACQ_CB_OPEN","ST_CHARGEBACK"],["ACQ_CB_REVERSE","LG_REVERSE"],["ACQ_CLAIMREG","ST_DISPUTE"],["ACQ_CORRECT","LG_CORRECT"],["ACQ_DDC","MG_LOG"],["ACQ_DUPCHK","VL_DUP"],["ACQ_EDC","MG_LOG"],["ACQ_EDI","MG_SEND"],["ACQ_EDIRESEND","MG_RESEND"],["ACQ_ESCROW","PAY_HOLD"],["ACQ_ESCROWREL","PAY_RELEASE"],["ACQ_EXCHANGE","CM_FX_CROSS"],["ACQ_FEEADJ","LG_ADJUST"],["ACQ_FEERECALC","ST_RECALC"],["ACQ_FOREIGN","CM_FX_CONV"],["ACQ_FXCONVERT","CM_FX"],["ACQ_FXRATE","CM_FX_VALID"],["ACQ_GUARANTEE","ST_COLLATERAL"],["ACQ_HOLD","PAY_HOLD"],["ACQ_INSTALL","VL_INSTCHK"],["ACQ_INSTCXL","LIMIT_RST"],["ACQ_LIMITCHK","VL_LIMIT"],["ACQ_LIMITEXC","VL_OVERLIMIT"],["ACQ_MERCHSUM","MM_MERCH_INQ"],["ACQ_NETCALC","LG_NETPOS"],["ACQ_PARTCXL","LIMIT_RST"],["ACQ_PARTCXL","LG_PARTREVERSE"],["ACQ_PARTRFND","ST_REFUNDCALC"],["ACQ_PROMO","ST_PROMOAPPLY"],["ACQ_REFUND","LIMIT_RST"],["ACQ_REFUND","LG_REVERSE"],["ACQ_RELEASE","PAY_RELEASE"],["ACQ_REMATCH","RC_REMATCH"],["ACQ_REPROC","RC_REPROC"],["ACQ_RESERVE","ST_HOLD"],["ACQ_RESERVECXL","ST_RELEASE"],["ACQ_RETURN","RC_REFUNDREC"],["ACQ_SETTLELINK","ST_MDR"],["ACQ_SETTLELINK","LG_BALCHK"],["ACQ_SPLITPAY","ST_SPLIT"],["ACQ_TAXCXL","ST_ADJUST"],["ACQ_TAXINV","ST_ADJUST"],["ACQ_TAXREVERSE","LG_REVERSE"],["ACQ_UNMATCH","RC_UNMATCH"],["ACQ_VELOCITY","VL_VELOCITY"],["ACQ_VOID","LG_VOIDVOUCHER"],["ACQ_WHT","ST_WHT"],["ACQ_WHT","ST_ADJUST"],["ACQ_XFERLINK","PAY_XFERLINK"],["AUTH","LIMIT_DEC"],["AUTH","FRAUD_DETECT"],["AUTH_AMT_ADJUST","LIMIT_DEC"],["AUTH_APPROVE","LIMIT_DEC"],["AUTH_CANCEL","LIMIT_RST"],["AUTH_CAPTURE","ACQ_APPRGAP"],["AUTH_DECLINE","CM_LOG"],["AUTH_DUP_CHK","FRAUD_DETECT"],["AUTH_EXPIRE_CHK","LIMIT_RST"],["AUTH_HOLD","LIMIT_CHK"],["AUTH_PARTAPPR","LIMIT_DEC"],["AUTH_PARTCXL","LIMIT_RST"],["AUTH_RELEASE","LIMIT_RST"],["AUTH_RESEND","MG_SEND"],["AUTH_RETRY","MG_SEND"],["AUTH_REVERSE","LIMIT_RST"],["AUTH_VOID","LIMIT_RST"],["BLACKLIST_CHK","FRAUD_DETECT"],["CARD_LOST_REG","MG_SEND"],["CARD_STOLEN_REG","MG_SEND"],["CARD_VALIDATE","CM_LUHN"],["FRAUD_DETECT","MG_LOG"],["INSTALL_AUTH","LIMIT_DEC"],["LIMIT_CHK","CM_LOG"],["LIMIT_DEC","MG_LOG"],["LIMIT_EXHAUST_LST","CM_LOG"],["LIMIT_FREEZE","CM_LOG"],["LIMIT_OVER_ALERT","CM_LOG"],["LIMIT_RST","MG_LOG"],["NOAUTH_CAPTURE","ACQ_CORRAPPR"],["PREAUTH","LIMIT_DEC"],["PREAUTH_CANCEL","LIMIT_RST"],["PREAUTH_COMPLETE","LIMIT_DEC"],["PREAUTH_EXTEND","LIMIT_CHK"],["PREAUTH_PARTUSE","LIMIT_RST"],["STANDIN","LIMIT_CHK"],["STANDIN","MG_LOG"],["STANDIN_SETTLE","LIMIT_DEC"],["TOKEN_VERIFY","CM_LUHN"],["VELOCITY_CHK","FRAUD_DETECT"],["CL_AMTXCHECK","VL_AXPURSETT"],["CL_APPRDELEG","CL_APPRSTAT"],["CL_APPRL1","CL_APPRL2"],["CL_APPRL2","CL_APPRFINAL"],["CL_APPROVE","CL_APPRL2"],["CL_APPRREJECT","CL_ESCALATE"],["CL_APPRREQ","CL_APPRL2"],["CL_BALVERIFY","VL_LEDGBAL"],["CL_CANCEL","LG_REVERSE"],["CL_CHKALL","VL_CROSSCHK"],["CL_CHKPENDING","VL_LONGOPEN"],["CL_CHKUNMATCH","VL_PURNOAPPR"],["CL_CHKVOID","VL_CANCELMIS"],["CL_CHNVERIFY","VL_CHANSPLIT"],["CL_CNTVERIFY","VL_RULECOUNT"],["CL_CNTXCHECK","VL_AXSETTPAY"],["CL_CORPCLOSE","LG_CORPSUM"],["CL_CORPVERIFY","VL_REPORT"],["CL_DAILY","VL_SALES"],["CL_DAILY","LG_CLOSE_LINK"],["CL_DAYVERIFY","VL_SALES"],["CL_DIFFCHK","VL_AMOUNT"],["CL_DIVCLOSE","LG_DEPTSUM"],["CL_DUPCHK","VL_DUP"],["CL_FEECROSS","VL_SUMFEECHK"],["CL_FEEVERIFY","VL_FEE"],["CL_FORCECLOSE","LG_CLOSE_LINK"],["CL_HALFCLOSE","LG_ROLLTB"],["CL_HYVERIFY","VL_SUMFEE"],["CL_MAINCLOSE","LG_CLOSE_LINK"],["CL_MERCLOSE","LG_MERCHPROOF"],["CL_MERXCHECK","VL_RIMERCH"],["CL_MIDCLOSE","LG_MERCHBAL"],["CL_MONTHLY","LG_MONTHLYSUM"],["CL_MONVERIFY","VL_SUMMARY"],["CL_NETCROSS","VL_SETTLE"],["CL_NETVERIFY","VL_NEGNET"],["CL_POSTTRIG","ST_DAILYCLOSE"],["CL_PRECHECK","VL_REQUIRED"],["CL_QTRVERIFY","VL_SUMRECON"],["CL_QUARTER","LG_PERIODTB"],["CL_RECLOSE","LG_REVERSE"],["CL_RECON","VL_SUMRECON"],["CL_ROLLBACK","LG_REVERSE"],["CL_SEGVERIFY","VL_SUMNETCHK"],["CL_SEMIMONTH","LG_CORPSUM"],["CL_SNAPSHOT","LG_TRIALBAL"],["CL_SNAPXCHECK","VL_AXLEDGDC"],["CL_STCROSS","VL_RISETTLE"],["CL_TENDAY","LG_DEPTSUM"],["CL_TRIGSETTLE","SETTLE"],["CL_VERIFY","VL_BALANCE"],["CL_WEEKLY","LG_ACCTSUM"],["CL_WEEKVERIFY","VL_SUMTXNCNT"],["CL_YEAREND","LG_SPANTB"],["CL_YEARVERIFY","VL_SUMGROSS"],["CM_ADDDAYS","CM_HOLIDAY_CHK"],["CM_BATDEP_CHK","CM_BATLAST"],["CM_BATDEP_SET","CM_BATLAST"],["CM_BATHIST_CNT","CM_BATLAST"],["CM_BATRERUN_REQ","CM_BATLAST"],["CM_BATSCHD_DEL","CM_LOG"],["CM_BATSCHD_REG","CM_LOG"],["CM_BIZDAY_ADD","CM_HOLIDAY_CHK"],["CM_BIZDAY_CNT","CM_HOLIDAY_CHK"],["CM_CACHE_INV","CM_PARAM"],["CM_CACHE_LOAD","CM_PARAM"],["CM_CODE","CM_PARAM"],["CM_CODEGRP_REG","CM_PARAM"],["CM_ERRMSG","CM_LOG"],["CM_FX_CONV","CM_FX"],["CM_FX_CROSS","CM_FX"],["CM_FX_INVERT","CM_FX"],["CM_FX_MARGIN","CM_FX"],["CM_FX_PUBLISH","CM_LOG"],["CM_FX_TRIANGLE","CM_FX"],["CM_MONTHEND","CM_BIZDAY"],["CM_MSG_RENDER","CM_LOG"],["CM_NEXTBIZ","CM_BIZDAY"],["CM_NOTI_QUOTA","CM_LOG"],["CM_NOTI_RETRY","CM_LOG"],["CM_NOTI_SEND","CM_LOG"],["CM_NOTI_TMPL","CM_LOG"],["CM_PREVBIZ","CM_BIZDAY"],["CM_SEQ","CM_LOG"],["CM_SEQ_ALLOC","CM_LOG"],["CM_SEQ_DAILY","CM_LOG"],["CM_SEQ_MULTI","CM_LOG"],["CM_SEQ_RESET","CM_LOG"],["CM_SEQ_STAMP","CM_LOG"],["CM_SEQ_TYPED","CM_LOG"],["LG_ACCRUEREV","LG_POST"],["LG_ACCTSUM","LG_RECALC"],["LG_ACQPOST","LG_BALCHK"],["LG_ADJUST","LG_BALCHK"],["LG_ALLOWANCE","LG_POST"],["LG_ALLOWRECALC","LG_ACCTSUM"],["LG_BADDEBT","LG_POST"],["LG_BADDEBTRCV","LG_POST"],["LG_BALCERT","LG_BALCHK"],["LG_BALPROOF","LG_BALCHK"],["LG_BLACKENTRY","LG_BALCHK"],["LG_BSSUMMARY","VL_LEDGER"],["LG_CLOSE_LINK","CL_LOCK"],["LG_CORPSUM","LG_RECALC"],["LG_CORRECT","LG_BALCHK"],["LG_DEPTSUM","LG_RECALC"],["LG_DOUBLE","LG_BALCHK"],["LG_FEEACCRUE","LG_FEEPOST"],["LG_FEEPOST","LG_BALCHK"],["LG_HALFCLOSE","LG_TRIALBAL"],["LG_MERCHBAL","LG_RECALC"],["LG_MERCHPROOF","LG_RECALC"],["LG_MONTHCLOSE","LG_TRIALBAL"],["LG_MONTHLYSUM","LG_RECALC"],["LG_PARTREVERSE","LG_POST"],["LG_PERIODTB","VL_LEDGER"],["LG_PLSUMMARY","VL_LEDGER"],["LG_POST","LG_BALCHK"],["LG_PREPAIDAMORT","LG_PREPAIDPOST"],["LG_PREPAIDPOST","LG_BALCHK"],["LG_QTRCLOSE","LG_TRIALBAL"],["LG_REDADJUST","LG_POST"],["LG_REDBLACKNET","LG_REDENTRY"],["LG_REDENTRY","LG_BALCHK"],["LG_REPOST","LG_POST"],["LG_REVERSE","LG_BALCHK"],["LG_ROLLTB","VL_LEDGER"],["LG_SETTLEPOST","LG_BALCHK"],["LG_SPANTB","VL_LEDGER"],["LG_SUSPENSE","LG_BALCHK"],["LG_TRANSFER","LG_BALCHK"],["LG_TRIALBAL","VL_LEDGER"],["LG_UNEARNPOST","LG_BALCHK"],["LG_UNEARNRECOG","LG_UNEARNPOST"],["LG_VOUCHER","LG_BALCHK"],["LG_WEEKCLOSE","LG_TRIALBAL"],["LG_WRITEOFF","LG_POST"],["LG_XFERPOST","LG_BALCHK"],["LG_YEARCLOSE","LG_TRIALBAL"],["MG_ACK","MG_SEND"],["MG_BITMAP","MG_PARSE"],["MG_BMPPARSE","MG_PARSE"],["MG_CHANFAILOVER","MG_ROUTE"],["MG_CHANHEALTH","MG_CHANPING"],["MG_CHANOPEN","MG_ROUTE"],["MG_CHANSWITCH","MG_ROUTE"],["MG_DECODE","MG_PARSE"],["MG_ENCODE","MG_SEND"],["MG_ERRREQUEUE","MG_SEND"],["MG_ERRRETRY","MG_SEND"],["MG_FROMISO","MG_PARSE"],["MG_ISO8583","MG_PARSE"],["MG_KEYCHECK","CM_HASH_DJB2"],["MG_KEYLOAD","CM_HASH_FNV"],["MG_LOADBAL","MG_CHANPING"],["MG_MAC","CM_CRC"],["MG_MACGEN","CM_HASH_SUM"],["MG_MACSESSION","CM_HASH_SUM"],["MG_MACVERIFY","CM_CRC"],["MG_NACK","MG_SEND"],["MG_PACK","MG_SEND"],["MG_PARSE","AUTH"],["MG_REASM","MG_PARSE"],["MG_RECV","MG_PARSE"],["MG_RESEND","MG_SEND"],["MG_RESNDONE","MG_SEND"],["MG_ROUTE","MG_CHANSTAT"],["MG_SEND","MG_STAN"],["MG_SEQFILL","MG_STAN"],["MG_SEQNEXT","MG_STAN"],["MG_TOISO","MG_SEND"],["MG_UNPACK","MG_PARSE"],["MM_ACCT_REG","CM_LUHN"],["MM_ACCT_VERIFY","CM_LUHN"],["MM_APPLY_APPROVE","MM_VALIDATE"],["MM_APPLY_REG","CM_SEQ"],["MM_BIN_REG","VL_BIN"],["MM_BIZNO_CHECK","CM_CHECKDIGIT"],["MM_CHK_LIMIT","LIMIT_CHK"],["MM_CODE_REG","VL_CODEVAL"],["MM_CONTRACT_AMEND","CM_SEQ"],["MM_CONTRACT_NEW","CM_SEQ"],["MM_CONTRACT_RENEW","CM_SEQ"],["MM_FEERATE_SET","ST_MDR"],["MM_GRADE_ADJUST","VL_MERCH"],["MM_ISSUER_REG","VL_BIN"],["MM_LIMIT_SET","LIMIT_CHK"],["MM_MCC_REG","VL_CODEVAL"],["MM_MCC_UPD","VL_CODEVAL"],["MM_MERCH_CLOSE","CM_LOG"],["MM_MERCH_DORMANT","CM_LOG"],["MM_MERCH_GRADE","VL_MERCH"],["MM_MERCH_PAUSE","CM_LOG"],["MM_MERCH_REG","MM_VALIDATE"],["MM_MERCH_RESUME","CM_LOG"],["MM_MERCH_STATUS","MM_VALIDATE"],["MM_MERCH_UPD","MM_VALIDATE"],["MM_RATE_APPROVE","ST_MDR"],["MM_RATE_REQ","CM_LOG"],["MM_RISK_SCORE","CM_LOG"],["MM_RISK_SET","VL_MERCH"],["MM_TERMINAL_REG","CM_SEQ"],["MM_TERM_INSTALL","CM_SEQ"],["MM_VALIDATE","CM_LOG"],["PAY_ACCTCHK","LG_POST"],["PAY_ACCTVERIFY","PAY_ACCTCHK"],["PAY_ADJUST","ST_ADJUST"],["PAY_APPRBULK","PAY_FILEGEN"],["PAY_APPROVE","PAY_FILEGEN"],["PAY_BANKFILE","MG_SEND"],["PAY_BANKVERIFY","PAY_ACCTCHK"],["PAY_CANCEL","LG_REVERSE"],["PAY_CANCEL","ST_ADJUST"],["PAY_CHARGEBACK","LG_REVERSE"],["PAY_CLOSE","LG_POST"],["PAY_COMBINE","PAY_ACCTCHK"],["PAY_CONFIRM","LG_POST"],["PAY_FILEGEN","PAY_ACCTCHK"],["PAY_FILEREBUILD","PAY_ACCTCHK"],["PAY_HOLD","ST_HOLD"],["PAY_MERGE","PAY_ACCTCHK"],["PAY_NETOFF","LG_POST"],["PAY_RECLAIM","LG_REVERSE"],["PAY_RECLAIM","ST_ADJUST"],["PAY_REFUND","LG_REVERSE"],["PAY_RELEASE","ST_RELEASE"],["PAY_REMIT","MG_SEND"],["PAY_REPROC","PAY_FAILRSN"],["PAY_REQUEUE","MG_SEND"],["PAY_RESULT","LG_POST"],["PAY_RESVMODIFY","CM_BIZDAY"],["PAY_RETRY","PAY_FAILRSN"],["PAY_RETRYONE","PAY_FAILRSN"],["PAY_REVERSE","LG_REVERSE"],["PAY_REVERSE","ST_ADJUST"],["PAY_ROLLFWD","CM_BIZDAY"],["PAY_SCHEDULE","CM_BIZDAY"],["PAY_SPLIT","PAY_ACCTCHK"],["PAY_SPLITEVEN","PAY_ACCTCHK"],["PAY_SPLITRATIO","PAY_ACCTCHK"],["PAY_URGENT","PAY_ACCTCHK"],["PAY_VOIDONE","LG_REVERSE"],["PAY_XFERLINK","MG_SEND"],["RC_3WAY","VL_APPR_ACQ"],["RC_3WAY","LG_THREEWAY"],["RC_4WAY","VL_CROSSCHK"],["RC_ACQMATCH","VL_AXPURAPPR"],["RC_ACQ_DEP","VL_LEDGER"],["RC_ALERT","CM_NOTI_SEND"],["RC_AMTDIFF","VL_AMOUNT"],["RC_APPRGAP","VL_APPRNOPUR"],["RC_APPRMATCH","VL_RIAPPR"],["RC_APPR_ACQ","VL_APPRAMT"],["RC_AUTOFIX","LG_POST"],["RC_CLOSEDAY","ST_LOCKBATCH"],["RC_CNTDIFF","VL_SUMTXNCNT"],["RC_CONFIRM","ST_STATUS"],["RC_DEPGAP","VL_AXSETTPAY"],["RC_DEPMATCH","VL_AXSETTPAY"],["RC_DUPCHK","CM_LOG"],["RC_ESCALATE","CM_NOTI_HIST"],["RC_EXCEPTION","CM_LOG"],["RC_EXCNOTIFY","CM_NOTI_SEND"],["RC_FEEDIFF","VL_FEE"],["RC_FEERECON","VL_SUMFEECHK"],["RC_FIXFEE","ST_MERCHRATE"],["RC_FIXFX","CM_FX_CONV"],["RC_FIXROUND","CM_AMT_ROUND"],["RC_FXDIFF","VL_FXCHK"],["RC_FXRECON","CM_FX_CONV"],["RC_HOLDCLR","ST_UNLOCK"],["RC_HOLDSET","ST_HOLDAMT"],["RC_LEDGERBAL","LG_BALCHK"],["RC_LEDGERLINK","LG_POST"],["RC_LIMITCHK","LIMIT_CHK"],["RC_MANUAL","LG_POST"],["RC_NOTIFY","CM_NOTI_SEND"],["RC_ORPHAN","VL_PURNOAPPR"],["RC_OVERAMT","VL_AMOUNT"],["RC_PAYLEDGER","LG_POST"],["RC_PAYMATCH","VL_RIPAY"],["RC_PROGRESS","CM_STATUS"],["RC_RECORR","LG_ADJUST"],["RC_REDIFF","VL_AMOUNT"],["RC_REFULL","VL_SUMRECON"],["RC_RELEASE","ST_PAYSTATUS"],["RC_REMATCH","VL_DUPPURCH"],["RC_REPROC","VL_STATUS_CHK"],["RC_RERUN","VL_BATCH_CHK"],["RC_ROUNDDIFF","CM_AMT_ROUND"],["RC_SNAPSHOT","LG_JOURNAL"],["RC_STATUS","CM_STATUS"],["RC_SUMCHK","VL_SUMGROSS"],["RC_TOLERANCE","VL_AMOUNT"],["RC_UNDERAMT","VL_AMOUNT"],["RC_UNMATCH","CM_LOG"],["RECONCILE","SETTLE"],["SETTLE","ST_MDR"],["ST_ADJREVERSE","LG_REVERSE"],["ST_ADJUST","LG_POST"],["ST_APPROVE","PAY_FILEGEN"],["ST_APPROVEALL","PAY_FILEGEN"],["ST_CANCEL","LG_REVERSE"],["ST_CAPCHECK","VL_SETTLE"],["ST_CHARGEBACK","LG_REVERSE"],["ST_CONFIRM","PAY_FILEGEN"],["ST_CXLRECALC","ST_MDR"],["ST_DAILYCLOSE","LG_POST"],["ST_DIFFCHK","VL_SETTLE"],["ST_GRPSETTLE","LG_POST"],["ST_HOLD","LG_POST"],["ST_INSTANTPAY","PAY_FILEGEN"],["ST_LEDGERLINK","LG_POST"],["ST_LIMITCHK","VL_SETTLE"],["ST_MDR","LG_SETTLEPOST"],["ST_NETTING","LG_POST"],["ST_NEXTPAYDT","CM_BIZDAY"],["ST_OFFSET","LG_POST"],["ST_PAYDATE","CM_BIZDAY"],["ST_PRECONFIRM","VL_SETTLE"],["ST_RATEAPPLY","ST_MDR"],["ST_RECALC","ST_MDR"],["ST_REFUNDCALC","LG_REVERSE"],["ST_RELEASE","LG_POST"],["ST_RERUN","ST_MDR"],["ST_TAXINVCHK","VL_SETTLE"],["ST_VAT","ST_ADJUST"],["ST_VATADJUST","LG_POST"],["ST_VOIDRECALC","LG_REVERSE"],["ST_WHT","ST_ADJUST"],["ST_XFERLINK","LG_POST"],["VL_AMOUNT","CM_LOG"],["VL_ANOMALY","FRAUD_DETECT"],["VL_APPRAMT","CM_LOG"],["VL_APPRNOPUR","AUTH_HISTORY"],["VL_APPR_ACQ","CM_LOG"],["VL_AXPURAPPR","CM_LOG"],["VL_AXSETTPAY","CM_LOG"],["VL_BALANCE","LG_BALCHK"],["VL_BATCH_CHK","CM_LOG"],["VL_BIN","CM_LUHN"],["VL_BIN","BIN_ROUTE_INQ"],["VL_CARD","CM_LUHN"],["VL_CROSSCHK","AUTH_STATUS"],["VL_CROSSCHK","ST_STATUS"],["VL_CROSSCHK","LG_STATUS"],["VL_DAYLIMIT","LIMIT_CHK"],["VL_DUP","RC_DUPCHK"],["VL_DUPAPPR","AUTH_SUMMARY"],["VL_DUPAUTH","RC_UNMATCH"],["VL_DUPLEDGR","LG_DUPSCAN"],["VL_DUPPAY","RC_DUPCHK"],["VL_DUPPURCH","CM_LOG"],["VL_DUPSETTLE","RC_UNMATCH"],["VL_EXPIRY","CM_LUHN"],["VL_EXPIRY","CARD_EXPIRE_CHK"],["VL_FEE","CM_LOG"],["VL_FEERECALC","CM_AMT_ROUND"],["VL_FORMAT","CM_LUHN"],["VL_FXCHK","CM_FX_VALID"],["VL_LEDGBAL","LG_BALCHK"],["VL_LEDGENTRY","LG_INQUIRY"],["VL_LEDGER","CM_LOG"],["VL_LIMIT","LIMIT_CHK"],["VL_MDRRATE","ST_RATECARD"],["VL_NEGBAL","RC_EXCEPTION"],["VL_NEGFEE","RC_EXCEPTION"],["VL_NEGNET","RC_EXCEPTION"],["VL_NIGHTTXN","FRAUD_RULE_NIGHT"],["VL_OUTLIER","FRAUD_DETECT"],["VL_OVERLIMIT","LIMIT_CHK"],["VL_PURNOAPPR","AUTH_HISTORY"],["VL_REFINTEG","LG_INQUIRY"],["VL_RIAPPR","AUTH_STATUS"],["VL_RICANCEL","CANCEL_STATUS"],["VL_RIFX","CM_FX_CONV"],["VL_RIINSTALL","PREAUTH_INQ"],["VL_RILEDGER","LG_STATUS"],["VL_RIMERCH","CM_CODE"],["VL_RIPAY","LG_INQUIRY"],["VL_RIPURCH","AUTH_HISTORY"],["VL_RISETTLE","ST_STATUS"],["VL_RITAXINV","ST_VATDETAIL"],["VL_SALES","RC_EXCEPTION"],["VL_SETTLE","RC_EXCEPTION"],["VL_SPIKEAMT","FRAUD_RULE_AMT"],["VL_STATUS_CHK","CM_STATUS"],["VL_SUMFEECHK","CM_LOG"],["VL_SUMGROSS","CM_LOG"],["VL_SUMRECON","CM_LOG"],["VL_SUMTXNCNT","CM_LOG"],["VL_SUSPACT","RISK_SCORE_INQ"],["VL_SUSPESCAL","RC_ESCALATE"],["VL_THRESHOLD","FRAUD_DETECT"],["VL_VELOCITY","VELOCITY_DAY"],["VL_ZERONET","RC_EXCEPTION"]],"CHAINS":[["ACQUIRE","RECONCILE","SETTLE","ST_MDR","LG_SETTLEPOST","LG_BALCHK"],["ACQ_SETTLELINK","ST_MDR","LG_SETTLEPOST","LG_BALCHK"],["MG_RECV","MG_PARSE","AUTH","FRAUD_DETECT","MG_LOG"],["CL_DAILY","VL_SALES","RC_EXCEPTION","CM_LOG"],["PAY_APPROVE","PAY_FILEGEN","PAY_ACCTCHK","LG_POST","LG_BALCHK"]],"STAT":{"nodes":552,"edges":494,"callees":168,"modxedge":41,"maxdepth":6}}; diff --git a/app/ui/index.html b/app/ui/index.html index 365148b..9e0abca 100644 --- a/app/ui/index.html +++ b/app/ui/index.html @@ -123,10 +123,10 @@
상세
diff --git a/app/ui/metrics.js b/app/ui/metrics.js index 3dcf328..bb966a1 100644 --- a/app/ui/metrics.js +++ b/app/ui/metrics.js @@ -1,2 +1,2 @@ /* 자동생성: tools/gen_metrics.py — 소스 실측 마이그레이션 난이도 지표. 손대지 말 것. */ -window.METRICS={"SCALE":[{"k":"소스 파일 (.pgc/.c/.h)","v":4626,"u":"개"},{"k":"총 코드 라인","v":330642,"u":"LOC"},{"k":"온라인 서비스","v":1463,"u":"본"},{"k":"배치 잡","v":506,"u":"본"},{"k":"임베디드 SQL(EXEC SQL)","v":23742,"u":"블록"},{"k":"Tuxedo tpcall 호출","v":989,"u":"곳"},{"k":"전역 트랜잭션 tpbegin","v":1234,"u":"곳"},{"k":"UBF 버퍼 필드접근","v":46904,"u":"곳"},{"k":"DB 테이블","v":75,"u":"개"},{"k":"카피북 헤더(.h)","v":2207,"u":"개"}],"HAZARDS":[{"t":"Tuxedo ATMI (tpcall/tpservice/tpreturn)","n":989,"u":"호출","why":"Java·Spring에 1:1 대응 API가 없다. 서비스 호출 모델 자체를 REST/메시지로 재설계해야 하며, 문법 치환으로는 불가능."},{"t":"XA 2PC 전역 트랜잭션 (최대 6단 중첩)","n":1234,"u":"tpbegin","why":"형제 XA 브랜치 격리·2단계 커밋 의미론이 Spring @Transactional 경계와 다르다. 잘못 옮기면 교착·이중전기가 그대로 재현된다."},{"t":"ECPG 임베디드 SQL (호스트변수·커서·sqlca)","n":23742,"u":"블록","why":"EXEC SQL 블록마다 호스트변수 바인딩·sqlcode 분기·커서 수명을 JPA/MyBatis 의미로 옮겨야 한다. 자동 변환기가 가장 많이 깨지는 지점."},{"t":"UBF(FML32) 타입리스 버퍼","n":46904,"u":"필드접근","why":"필드ID 기반 동적 버퍼라 타입·필수여부가 컴파일타임에 없다. Java DTO로 옮기려면 47,000여 접근점의 계약을 사람이 복원해야 한다."},{"t":"카피북 공유(#include) 팬아웃","n":6892,"u":"참조","why":"한 카피북을 수십 프로그램이 공유해 구조체 변경이 전방위로 파급된다. 경계 없는 결합이라 모듈 단위 절단이 어렵다."},{"t":"전처리 매크로(#define)","n":2247,"u":"정의","why":"매크로가 코드 생성·분기를 숨겨 정적 분석을 방해한다. 전개 후에야 실제 로직이 드러난다."}],"TRACE":[{"root":"ACQUIRE","tree":{"svc":"ACQUIRE","mod":"ac","wr":["cm_log"],"children":[{"svc":"RECONCILE","mod":"rc","wr":["cm_log","ledger"],"children":[{"svc":"SETTLE","mod":"st","wr":["ledger","settlement"],"children":[{"svc":"ST_MDR","mod":"st","wr":["ledger"],"children":[{"svc":"LG_SETTLEPOST","mod":"lg","wr":["cm_log"],"children":[{"svc":"LG_BALCHK","mod":"lg","wr":["cm_log"],"children":[]}]}]}]}]}]},"stat":{"programs":6,"tables":3,"xa_branches":6,"tablelist":["cm_log","ledger","settlement"]}},{"root":"PAY_APPROVE","tree":{"svc":"PAY_APPROVE","mod":"py","wr":["cm_log","py_payout"],"children":[{"svc":"PAY_FILEGEN","mod":"py","wr":["cm_log","py_file","py_payout"],"children":[{"svc":"PAY_ACCTCHK","mod":"py","wr":["cm_log"],"children":[{"svc":"LG_POST","mod":"lg","wr":["cm_log"],"children":[{"svc":"LG_BALCHK","mod":"lg","wr":["cm_log"],"children":[]}]}]}]}]},"stat":{"programs":5,"tables":3,"xa_branches":5,"tablelist":["cm_log","py_file","py_payout"]}},{"root":"CL_DAILY","tree":{"svc":"CL_DAILY","mod":"cl","wr":["cm_log"],"children":[{"svc":"VL_SALES","mod":"vl","wr":[],"children":[{"svc":"RC_EXCEPTION","mod":"rc","wr":["cm_log"],"children":[{"svc":"CM_LOG","mod":"cm","wr":[],"children":[]}]}]},{"svc":"LG_CLOSE_LINK","mod":"lg","wr":["cm_log","lg_ledger_line"],"children":[{"svc":"CL_LOCK","mod":"cl","wr":["SET","cl_close_log","cl_period_lock","cm_log"],"children":[]}]}]},"stat":{"programs":6,"tables":5,"xa_branches":6,"tablelist":["SET","cl_close_log","cl_period_lock","cm_log","lg_ledger_line"]}}],"LEGACY":{"copybook_total":2207,"copybook_shared_max":139,"copybook_shared_name":"acq_common.h","macro_defs":2247,"goto":64,"userlog":17122,"sqlca_checks":18719,"embedded_sql_density":9.8}}; +window.METRICS={"SCALE":[{"k":"소스 파일 (.pgc/.c/.h)","v":4638,"u":"개"},{"k":"총 코드 라인","v":331721,"u":"LOC"},{"k":"온라인 서비스","v":1469,"u":"본"},{"k":"배치 잡","v":506,"u":"본"},{"k":"임베디드 SQL(EXEC SQL)","v":23810,"u":"블록"},{"k":"Tuxedo tpcall 호출","v":989,"u":"곳"},{"k":"전역 트랜잭션 tpbegin","v":1234,"u":"곳"},{"k":"UBF 버퍼 필드접근","v":47113,"u":"곳"},{"k":"DB 테이블","v":84,"u":"개"},{"k":"카피북 헤더(.h)","v":2213,"u":"개"}],"HAZARDS":[{"t":"Tuxedo ATMI (tpcall/tpservice/tpreturn)","n":989,"u":"호출","why":"Java·Spring에 1:1 대응 API가 없다. 서비스 호출 모델 자체를 REST/메시지로 재설계해야 하며, 문법 치환으로는 불가능."},{"t":"XA 2PC 전역 트랜잭션 (최대 6단 중첩)","n":1234,"u":"tpbegin","why":"형제 XA 브랜치 격리·2단계 커밋 의미론이 Spring @Transactional 경계와 다르다. 잘못 옮기면 교착·이중전기가 그대로 재현된다."},{"t":"ECPG 임베디드 SQL (호스트변수·커서·sqlca)","n":23810,"u":"블록","why":"EXEC SQL 블록마다 호스트변수 바인딩·sqlcode 분기·커서 수명을 JPA/MyBatis 의미로 옮겨야 한다. 자동 변환기가 가장 많이 깨지는 지점."},{"t":"UBF(FML32) 타입리스 버퍼","n":47113,"u":"필드접근","why":"필드ID 기반 동적 버퍼라 타입·필수여부가 컴파일타임에 없다. Java DTO로 옮기려면 47,000여 접근점의 계약을 사람이 복원해야 한다."},{"t":"카피북 공유(#include) 팬아웃","n":6904,"u":"참조","why":"한 카피북을 수십 프로그램이 공유해 구조체 변경이 전방위로 파급된다. 경계 없는 결합이라 모듈 단위 절단이 어렵다."},{"t":"전처리 매크로(#define)","n":2253,"u":"정의","why":"매크로가 코드 생성·분기를 숨겨 정적 분석을 방해한다. 전개 후에야 실제 로직이 드러난다."}],"TRACE":[{"root":"ACQUIRE","tree":{"svc":"ACQUIRE","mod":"ac","wr":["cm_log"],"children":[{"svc":"RECONCILE","mod":"rc","wr":["cm_log","ledger"],"children":[{"svc":"SETTLE","mod":"st","wr":["ledger","settlement"],"children":[{"svc":"ST_MDR","mod":"st","wr":["ledger"],"children":[{"svc":"LG_SETTLEPOST","mod":"lg","wr":["cm_log"],"children":[{"svc":"LG_BALCHK","mod":"lg","wr":["cm_log"],"children":[]}]}]}]}]}]},"stat":{"programs":6,"tables":3,"xa_branches":6,"tablelist":["cm_log","ledger","settlement"]}},{"root":"PAY_APPROVE","tree":{"svc":"PAY_APPROVE","mod":"py","wr":["cm_log","py_payout"],"children":[{"svc":"PAY_FILEGEN","mod":"py","wr":["cm_log","py_file","py_payout"],"children":[{"svc":"PAY_ACCTCHK","mod":"py","wr":["cm_log"],"children":[{"svc":"LG_POST","mod":"lg","wr":["cm_log"],"children":[{"svc":"LG_BALCHK","mod":"lg","wr":["cm_log"],"children":[]}]}]}]}]},"stat":{"programs":5,"tables":3,"xa_branches":5,"tablelist":["cm_log","py_file","py_payout"]}},{"root":"CL_DAILY","tree":{"svc":"CL_DAILY","mod":"cl","wr":["cm_log"],"children":[{"svc":"VL_SALES","mod":"vl","wr":[],"children":[{"svc":"RC_EXCEPTION","mod":"rc","wr":["cm_log"],"children":[{"svc":"CM_LOG","mod":"cm","wr":[],"children":[]}]}]},{"svc":"LG_CLOSE_LINK","mod":"lg","wr":["cm_log","lg_ledger_line"],"children":[{"svc":"CL_LOCK","mod":"cl","wr":["SET","cl_close_log","cl_period_lock","cm_log"],"children":[]}]}]},"stat":{"programs":6,"tables":5,"xa_branches":6,"tablelist":["SET","cl_close_log","cl_period_lock","cm_log","lg_ledger_line"]}}],"LEGACY":{"copybook_total":2213,"copybook_shared_max":139,"copybook_shared_name":"acq_common.h","macro_defs":2253,"goto":64,"userlog":17179,"sqlca_checks":18788,"embedded_sql_density":9.8}}; diff --git a/db/schema.d/70-econ.sql b/db/schema.d/70-econ.sql new file mode 100644 index 0000000..41425fe --- /dev/null +++ b/db/schema.d/70-econ.sql @@ -0,0 +1,148 @@ +-- =========================================================================== +-- 70-econ.sql : 실제 매입사 경제모델 (딥리서치 갭분석 고도화) +-- 수수료 3층 분해(interchange+scheme fee+acquirer markup), +-- 클리어링/프레젠트먼트(정산과 분리), 발급사↔매입사 순액정산(BIN/ICA·회원사), +-- 정산 항등식(총매출−환불−채그백−수수료−리저브=입금), 채그백/분쟁 라이프사이클. +-- 기존 flat MDR 은 markup 으로 재해석하여 하위호환. +-- =========================================================================== + +-- --------------------------------------------------------------------------- +-- 1. Interchange 요율표 (발급사 귀속분). 카드종류×MCC×채널×거래유형 차등. +-- 실제 매입사에서 요율이 갈리는 축을 그대로 반영(interchange qualification). +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS st_interchange_rate ( + card_type TEXT NOT NULL, -- CREDIT/CHECK/PREPAID + mcc TEXT NOT NULL DEFAULT 'DEFAULT',-- 업종(가맹점 category 매핑) + channel TEXT NOT NULL DEFAULT 'DEFAULT',-- POS/EDC/EDI/FOREIGN + txn_type TEXT NOT NULL DEFAULT 'SALE', -- SALE/CASH/REFUND + rate_bps BIGINT NOT NULL DEFAULT 0, -- basis points (1bp=0.01%) + fixed_fee BIGINT NOT NULL DEFAULT 0, -- 건당 고정수수료(원) + eff_date DATE NOT NULL DEFAULT current_date, + PRIMARY KEY (card_type, mcc, channel, txn_type) +); + +-- --------------------------------------------------------------------------- +-- 2. Scheme fee (카드망 assessment). 스킴×거래유형. +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS st_scheme_fee ( + scheme TEXT NOT NULL, -- BC/VISA/MASTER/LOCAL + txn_type TEXT NOT NULL DEFAULT 'SALE', + rate_bps BIGINT NOT NULL DEFAULT 0, + fixed_fee BIGINT NOT NULL DEFAULT 0, + PRIMARY KEY (scheme, txn_type) +); + +-- --------------------------------------------------------------------------- +-- 3. 거래별 수수료 분해 (MDR = interchange + scheme_fee + markup). +-- 매입사 손익: markup 만 매입사 수익, interchange 는 발급사, scheme_fee 는 카드망. +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS st_fee_component ( + purchase_id BIGINT PRIMARY KEY, + amount BIGINT NOT NULL, + interchange BIGINT NOT NULL DEFAULT 0, -- 발급사 귀속 + scheme_fee BIGINT NOT NULL DEFAULT 0, -- 카드망 귀속 + markup BIGINT NOT NULL DEFAULT 0, -- 매입사 수익(협상대상) + mdr_total BIGINT NOT NULL DEFAULT 0, -- = interchange+scheme_fee+markup + card_type TEXT NOT NULL DEFAULT 'CREDIT', + scheme TEXT NOT NULL DEFAULT 'BC', + computed_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +-- --------------------------------------------------------------------------- +-- 4. 프레젠트먼트(클리어링). 승인·정산과 분리된 단계. +-- 클리어링=데이터 교환(발급사↔매입사 채무 확정). 정산=자금이동. +-- --------------------------------------------------------------------------- +CREATE SEQUENCE IF NOT EXISTS cl_present_seq START 700000; +CREATE TABLE IF NOT EXISTS cl_presentment ( + presentment_id BIGINT PRIMARY KEY, + purchase_id BIGINT NOT NULL, + scheme TEXT NOT NULL DEFAULT 'BC', + msg_class TEXT NOT NULL DEFAULT 'FIRST_PRESENT', -- FIRST_PRESENT/REPRESENT/CHARGEBACK + clearing_amt BIGINT NOT NULL, -- 클리어링 대상 금액(net of interchange) + present_date DATE NOT NULL, + cycle TEXT NOT NULL DEFAULT 'T+1', -- 정산주기 + status TEXT NOT NULL DEFAULT 'CLEARED', -- CLEARED/REJECTED/PENDING + created_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +-- --------------------------------------------------------------------------- +-- 5. 회원사(정산 참가 은행/발급사) — 한국 BC카드형 다자간 순액정산. +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS st_member_bank ( + bank_code TEXT PRIMARY KEY, -- BC/KB/SHINHAN/... + bank_name TEXT NOT NULL, + bin TEXT NOT NULL, -- 스킴 회원식별자(Visa BIN / MC ICA 대응) + role TEXT NOT NULL DEFAULT 'BOTH' -- ISSUER/ACQUIRER/BOTH +); + +-- --------------------------------------------------------------------------- +-- 6. 순액정산 배치 (발급사↔매입사). BIN/ICA 기준 차대변 합산 → 단일 순액. +-- --------------------------------------------------------------------------- +CREATE SEQUENCE IF NOT EXISTS st_netset_seq START 800000; +CREATE TABLE IF NOT EXISTS st_net_settlement ( + net_id BIGINT PRIMARY KEY, + scheme TEXT NOT NULL DEFAULT 'BC', + member_bin TEXT NOT NULL, -- 상대 회원사 BIN/ICA + biz_date DATE NOT NULL, + txn_count BIGINT NOT NULL DEFAULT 0, + gross_amt BIGINT NOT NULL DEFAULT 0, + interchange_amt BIGINT NOT NULL DEFAULT 0, + scheme_fee_amt BIGINT NOT NULL DEFAULT 0, + net_amt BIGINT NOT NULL DEFAULT 0, -- 실제 이체 순액(부호=방향) + direction TEXT NOT NULL DEFAULT 'RECEIVE', -- RECEIVE(수취)/PAY(지급) + status TEXT NOT NULL DEFAULT 'SETTLED', + settled_at TIMESTAMPTZ NOT NULL DEFAULT now(), + UNIQUE (scheme, member_bin, biz_date) +); + +-- --------------------------------------------------------------------------- +-- 7. 롤링 리저브(유보금). +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS st_reserve ( + merchant_id TEXT NOT NULL, + biz_date DATE NOT NULL, + reserve_bps BIGINT NOT NULL DEFAULT 0, -- 유보율 + reserve_amt BIGINT NOT NULL DEFAULT 0, -- 이번 회차 유보액 + release_date DATE, -- 유보 해제 예정일(롤링) + released BOOLEAN NOT NULL DEFAULT false, + PRIMARY KEY (merchant_id, biz_date) +); + +-- --------------------------------------------------------------------------- +-- 8. 가맹점 펀딩 항등식: 총매출 − 환불 − 채그백 − 수수료 − 리저브 = 입금. +-- --------------------------------------------------------------------------- +CREATE SEQUENCE IF NOT EXISTS st_funding_seq START 900000; +CREATE TABLE IF NOT EXISTS st_merchant_funding ( + funding_id BIGINT PRIMARY KEY, + merchant_id TEXT NOT NULL, + biz_date DATE NOT NULL, + gross_sales BIGINT NOT NULL DEFAULT 0, + refunds BIGINT NOT NULL DEFAULT 0, + chargebacks BIGINT NOT NULL DEFAULT 0, + fees BIGINT NOT NULL DEFAULT 0, -- MDR 합계 + reserve BIGINT NOT NULL DEFAULT 0, + deposit BIGINT NOT NULL DEFAULT 0, -- 실제 입금액 + funding_model TEXT NOT NULL DEFAULT 'NET_DAILY', -- NET_DAILY/MONTHLY_DISCOUNT + status TEXT NOT NULL DEFAULT 'FUNDED', + funded_at TIMESTAMPTZ NOT NULL DEFAULT now(), + UNIQUE (merchant_id, biz_date) +); + +-- --------------------------------------------------------------------------- +-- 9. 채그백/분쟁 라이프사이클: 1차CB → representment → pre-arb → arbitration. +-- --------------------------------------------------------------------------- +CREATE SEQUENCE IF NOT EXISTS ac_dispute_seq START 600000; +CREATE TABLE IF NOT EXISTS ac_dispute ( + dispute_id BIGINT PRIMARY KEY, + purchase_id BIGINT NOT NULL, + merchant_id TEXT NOT NULL, + reason_code TEXT NOT NULL, -- 10.4(사기) / 13.1(상품미수취) / 12.6(중복) ... + amount BIGINT NOT NULL, + stage TEXT NOT NULL DEFAULT 'FIRST_CB', -- FIRST_CB/REPRESENT/PRE_ARB/ARBITRATION + status TEXT NOT NULL DEFAULT 'OPEN', -- OPEN/WON/LOST/ACCEPTED + opened_at TIMESTAMPTZ NOT NULL DEFAULT now(), + resolved_at TIMESTAMPTZ, + memo TEXT +); +CREATE INDEX IF NOT EXISTS ix_dispute_pid ON ac_dispute(purchase_id); +CREATE INDEX IF NOT EXISTS ix_present_pid ON cl_presentment(purchase_id); diff --git a/db/schema.d/96-econ-seed.sql b/db/schema.d/96-econ-seed.sql new file mode 100644 index 0000000..d999013 --- /dev/null +++ b/db/schema.d/96-econ-seed.sql @@ -0,0 +1,161 @@ +-- =========================================================================== +-- 96-econ-seed.sql : 매입사 경제모델 시드 (70-econ.sql DDL 이후, 실측풍) +-- 요율표(interchange/scheme) + 회원사 은행 + 기존 정산건 소급 분해/클리어링/ +-- 순액정산/펀딩. 규제 관행 반영: interchange 가 MDR 의 대부분(70~90%), +-- scheme fee 소액, markup 이 매입사 협상마진. +-- =========================================================================== + +-- --------------------------------------------------------------------------- +-- 1. Interchange 요율표 — 카드종류×채널 차등 (interchange qualification) +-- 실제 규제 관행: 체크카드 < 신용카드, 대면(POS) < 비대면(EDI)/해외(FOREIGN). +-- --------------------------------------------------------------------------- +INSERT INTO st_interchange_rate (card_type, mcc, channel, txn_type, rate_bps, fixed_fee) VALUES + ('CREDIT','DEFAULT','POS','SALE', 130, 0), + ('CREDIT','DEFAULT','EDC','SALE', 140, 0), + ('CREDIT','DEFAULT','EDI','SALE', 160, 0), -- 비대면 가산 + ('CREDIT','DEFAULT','FOREIGN','SALE', 180, 0), -- 해외 가산 + ('CHECK','DEFAULT','POS','SALE', 70, 0), -- 체크카드 저율 + ('CHECK','DEFAULT','EDC','SALE', 80, 0), + ('CHECK','DEFAULT','EDI','SALE', 95, 0), + ('CHECK','DEFAULT','FOREIGN','SALE', 110, 0), + ('PREPAID','DEFAULT','POS','SALE', 60, 0), + ('CREDIT','DEFAULT','DEFAULT','REFUND', 0, 0), -- 환불은 interchange 역방향(발급사→매입사), 여기선 0 처리 + ('CREDIT','DEFAULT','DEFAULT','CASH', 100, 0) +ON CONFLICT (card_type, mcc, channel, txn_type) DO NOTHING; + +-- --------------------------------------------------------------------------- +-- 2. Scheme fee — 스킴 assessment (소액). BC=국내 표준. +-- --------------------------------------------------------------------------- +INSERT INTO st_scheme_fee (scheme, txn_type, rate_bps, fixed_fee) VALUES + ('BC','SALE', 11, 0), + ('VISA','SALE', 14, 0), + ('MASTER','SALE',13, 0), + ('LOCAL','SALE', 9, 0), + ('BC','REFUND', 0, 0), + ('BC','CASH', 8, 0) +ON CONFLICT (scheme, txn_type) DO NOTHING; + +-- --------------------------------------------------------------------------- +-- 3. 회원사 은행 — 발급사↔매입사 다자 순액정산 참가자 (BC카드 컨소시엄형). +-- --------------------------------------------------------------------------- +INSERT INTO st_member_bank (bank_code, bank_name, bin, role) VALUES + ('BC', 'BC카드(매입)', '940020','ACQUIRER'), + ('KB', 'KB국민카드', '940021','ISSUER'), + ('SHINHAN','신한카드', '940022','ISSUER'), + ('HYUNDAI','현대카드', '940023','ISSUER'), + ('SAMSUNG','삼성카드', '940024','ISSUER'), + ('LOTTE', '롯데카드', '940025','ISSUER'), + ('NH', 'NH농협카드', '940026','ISSUER'), + ('HANA', '하나카드', '940027','ISSUER') +ON CONFLICT (bank_code) DO NOTHING; + +-- --------------------------------------------------------------------------- +-- 4. 기존 정산완료 매입건 → 수수료 3층 분해 (소급). +-- 카드종류는 issuer 로 근사(BC=CHECK 30%, 그 외 CREDIT), 채널=purchase.channel. +-- interchange = amount×ic_bps, scheme = amount×scheme_bps, +-- markup = 기존 flat fee − interchange − scheme (음수면 0 clamp), +-- mdr_total = interchange+scheme+markup (기존 fee 와 근사 일치). +-- --------------------------------------------------------------------------- +INSERT INTO st_fee_component (purchase_id, amount, interchange, scheme_fee, markup, mdr_total, card_type, scheme) +SELECT p.purchase_id, p.amount, + (p.amount * ic.rate_bps / 10000) AS interchange, + (p.amount * sf.rate_bps / 10000) AS scheme_fee, + GREATEST(p.fee - (p.amount*ic.rate_bps/10000) - (p.amount*sf.rate_bps/10000), p.amount*8/10000) AS markup, + (p.amount*ic.rate_bps/10000) + (p.amount*sf.rate_bps/10000) + + GREATEST(p.fee - (p.amount*ic.rate_bps/10000) - (p.amount*sf.rate_bps/10000), p.amount*8/10000) AS mdr_total, + ct.card_type, + CASE WHEN p.issuer IN ('BC') THEN 'BC' ELSE 'BC' END AS scheme +FROM purchase p +CROSS JOIN LATERAL (SELECT CASE WHEN (p.purchase_id % 10) < 3 THEN 'CHECK' ELSE 'CREDIT' END AS card_type) ct +JOIN st_interchange_rate ic + ON ic.card_type = ct.card_type AND ic.channel = p.channel AND ic.txn_type = 'SALE' +JOIN st_scheme_fee sf ON sf.scheme = 'BC' AND sf.txn_type = 'SALE' +WHERE p.status = 'S' +ON CONFLICT (purchase_id) DO NOTHING; + +-- --------------------------------------------------------------------------- +-- 5. 프레젠트먼트(클리어링) — 정산완료건마다 1차 프레젠트먼트 기록. +-- clearing_amt = amount − interchange (발급사 귀속분 차감 후 매입사 클리어링액). +-- --------------------------------------------------------------------------- +INSERT INTO cl_presentment (presentment_id, purchase_id, scheme, msg_class, clearing_amt, present_date, cycle, status) +SELECT nextval('cl_present_seq'), fc.purchase_id, fc.scheme, 'FIRST_PRESENT', + fc.amount - fc.interchange, p.biz_date, 'T+1', 'CLEARED' +FROM st_fee_component fc JOIN purchase p ON p.purchase_id = fc.purchase_id +WHERE NOT EXISTS (SELECT 1 FROM cl_presentment c + WHERE c.purchase_id = fc.purchase_id AND c.msg_class = 'FIRST_PRESENT'); + +-- --------------------------------------------------------------------------- +-- 6. 순액정산 배치 — 발급사(회원 BIN)×영업일 기준 차대변 합산 → 단일 순액. +-- 매입사(BC)가 각 발급사로부터 (매출−interchange−scheme) 순액을 수취. +-- --------------------------------------------------------------------------- +INSERT INTO st_net_settlement (net_id, scheme, member_bin, biz_date, txn_count, + gross_amt, interchange_amt, scheme_fee_amt, net_amt, direction, status) +SELECT nextval('st_netset_seq'), 'BC', mb.bin, p.biz_date, count(*), + sum(fc.amount), sum(fc.interchange), sum(fc.scheme_fee), + sum(fc.amount - fc.interchange - fc.scheme_fee), 'RECEIVE', 'SETTLED' +FROM st_fee_component fc +JOIN purchase p ON p.purchase_id = fc.purchase_id +JOIN st_member_bank mb ON mb.bank_code = p.issuer +GROUP BY mb.bin, p.biz_date +ON CONFLICT (scheme, member_bin, biz_date) DO NOTHING; + +-- --------------------------------------------------------------------------- +-- 7. 롤링 리저브 — 위험업종(HOLD/PENDING 상태였던 가맹점 등) 8% 유보, 그 외 0. +-- 여기선 전 가맹점 일괄 저율(총매출의 0.5%) 유보 예시 + T+30 해제. +-- --------------------------------------------------------------------------- +INSERT INTO st_reserve (merchant_id, biz_date, reserve_bps, reserve_amt, release_date, released) +SELECT p.merchant_id, p.biz_date, 50, sum(p.amount)*50/10000, + p.biz_date + 30, (p.biz_date + 30 < current_date) +FROM purchase p WHERE p.status='S' +GROUP BY p.merchant_id, p.biz_date +ON CONFLICT (merchant_id, biz_date) DO NOTHING; + +-- --------------------------------------------------------------------------- +-- 8. 가맹점 펀딩 항등식: 총매출 − 환불 − 채그백 − 수수료 − 리저브 = 입금. +-- 환불=취소(C)건 금액, 채그백=아래 8단계 시드분, 수수료=MDR합계. +-- --------------------------------------------------------------------------- +INSERT INTO st_merchant_funding (funding_id, merchant_id, biz_date, gross_sales, refunds, + chargebacks, fees, reserve, deposit, funding_model, status) +SELECT nextval('st_funding_seq'), s.merchant_id, s.biz_date, + s.gross, s.refunds, s.cb, s.fees, coalesce(rv.reserve_amt,0), + s.gross - s.refunds - s.cb - s.fees - coalesce(rv.reserve_amt,0), + 'NET_DAILY', 'FUNDED' +FROM ( + SELECT p.merchant_id, p.biz_date, + sum(CASE WHEN p.status='S' THEN p.amount ELSE 0 END) AS gross, + sum(CASE WHEN p.status='C' THEN p.amount ELSE 0 END) AS refunds, + 0::bigint AS cb, + coalesce(sum(fc.mdr_total),0) AS fees + FROM purchase p LEFT JOIN st_fee_component fc ON fc.purchase_id=p.purchase_id + GROUP BY p.merchant_id, p.biz_date +) s +LEFT JOIN st_reserve rv ON rv.merchant_id=s.merchant_id AND rv.biz_date=s.biz_date +WHERE s.gross > 0 +ON CONFLICT (merchant_id, biz_date) DO NOTHING; + +-- --------------------------------------------------------------------------- +-- 9. 채그백/분쟁 케이스 — 취소·보류였던 매입 일부를 분쟁으로 (reason code 체계). +-- 라이프사이클 단계 혼재: FIRST_CB / REPRESENT / PRE_ARB / ARBITRATION. +-- --------------------------------------------------------------------------- +INSERT INTO ac_dispute (dispute_id, purchase_id, merchant_id, reason_code, amount, stage, status, opened_at, resolved_at, memo) +SELECT nextval('ac_dispute_seq'), p.purchase_id, p.merchant_id, + (ARRAY['10.4','13.1','12.6','13.7','4853'])[1 + (p.purchase_id % 5)], + p.amount, + (ARRAY['FIRST_CB','REPRESENT','PRE_ARB','ARBITRATION'])[1 + (p.purchase_id % 4)], + (ARRAY['OPEN','WON','LOST','ACCEPTED'])[1 + (p.purchase_id % 4)], + p.biz_date::timestamptz + interval '2 days', + CASE WHEN (p.purchase_id % 4) IN (1,2,3) THEN p.biz_date::timestamptz + interval '20 days' ELSE NULL END, + '분쟁 시드: reason ' || (ARRAY['사기','상품미수취','중복청구','품질불량','거래취소'])[1 + (p.purchase_id % 5)] +FROM purchase p +WHERE p.status IN ('C','H') AND (p.purchase_id % 3) = 0 + AND NOT EXISTS (SELECT 1 FROM ac_dispute d WHERE d.purchase_id = p.purchase_id); + +-- 펀딩의 chargebacks 컬럼을 실제 분쟁(LOST 확정분)으로 보정. +-- 채그백은 원매입의 영업일(biz_date)에 귀속시켜 가맹점×일자 단위로만 차감한다 +-- (가맹점 전체 합을 매일 중복 차감하면 입금액이 일수만큼 붕괴한다). +UPDATE st_merchant_funding f SET chargebacks = d.cb, + deposit = f.gross_sales - f.refunds - d.cb - f.fees - f.reserve +FROM (SELECT p.merchant_id, p.biz_date, sum(dp.amount) cb + FROM ac_dispute dp JOIN purchase p ON p.purchase_id = dp.purchase_id + WHERE dp.status = 'LOST' GROUP BY p.merchant_id, p.biz_date) d +WHERE f.merchant_id = d.merchant_id AND f.biz_date = d.biz_date; diff --git a/docs/GAP_ANALYSIS.md b/docs/GAP_ANALYSIS.md new file mode 100644 index 0000000..3451e0c --- /dev/null +++ b/docs/GAP_ANALYSIS.md @@ -0,0 +1,45 @@ +# 실제 매입시스템 vs acquire-core-x — 갭 분석 + +> 딥리서치(1차 규제·표준 출처 기반, 검증된 9개 finding)로 확인한 **실제 카드 매입사 +> 아키텍처**를 우리 구현과 대조한다. 목적: 리얼리티 갭을 찾아 고도화 우선순위를 정한다. +> 출처: OCC Merchant Processing Handbook, Fed Philadelphia clearing&settlement paper, +> Berlin Group ISO 8583, Marqeta/Checkout/Stripe, BC Card. + +## 핵심 대조 (검증된 실제 메커니즘 → 우리 현황) + +| # | 실제 매입시스템 메커니즘 (검증됨) | 우리 현황 | 갭 | +|---|---|---|---| +| 1 | **Clearing ≠ Settlement.** 승인은 권한/홀드일 뿐 돈이 안 움직인다. 클리어링=상세 거래데이터 교환(발급사↔매입사 채무 확정), 정산=그 채무를 실제 자금이동으로 해소. | 승인(au)·정산(st)은 있으나 **클리어링(프레젠트먼트) 단계가 통째로 없음**. 정산이 곧 자금이동으로 뭉뚱그려짐. | 🔴 **대** | +| 2 | **이중메시지 vs 단일메시지.** 신용/서명체크=승인과 클리어링 분리(EDC 배치 캡처 후 일 1회+ 제출, 프레젠트먼트 윈도우). PIN/ATM=승인+클리어링 1회 통합. | 채널(POS/EDC/EDI/FOREIGN)은 있으나 **이중/단일 구분·프레젠트먼트 윈도우 없음**. | 🟠 중 | +| 3 | **ISO 8583 클리어링 메시지 클래스.** presentment / chargeback / fee-collection / reconciliation / file-rejection 이 별도 기능. | mg 모듈에 채널·라우팅·큐는 있으나 **클리어링 메시지 클래스 모델 없음**. MTI 언급은 있음. | 🟠 중 | +| 4 | **BIN/ICA 기준 순액정산.** 정산은 매입사 스킴 회원식별자(Visa=BIN, MC=ICA)로 라우팅, 은행별 차대변 합산 후 **단일 순액**을 정산은행 통해 이체. | 정산이 **가맹점 단위**로만 계산됨. **발급사↔매입사 순액정산(net settlement) 계층 없음**. | 🔴 **대** | +| 5 | **수수료 3층 분해.** MDR = interchange(발급사, 최대·일단위 순정산시 징수) + scheme fee(카드망) + acquirer markup(매입사 마진, 유일한 협상대상, 월청구). 요율은 카드종류·MCC·거래유형·채널·사기율에 따라 변동. | **flat MDR 하나**(`fee = amount × mdr_bps`). interchange·scheme fee·markup 분해 **전무**. | 🔴 **대(최우선)** | +| 6 | **Interchange qualification.** 데이터 품질/채널/카드종류로 interchange 등급(tier)이 갈림. | mm_fee_rate 가 merchant×card_type 단일요율. **MCC·채널·등급 차등 없음**. | 🟠 중 | +| 7 | **정산·펀딩 항등식.** 총매출 − 환불 − 채그백 − 처리수수료 − 롤링리저브 = 예상 입금액. | 정산은 net 만. **환불·채그백·리저브를 반영한 펀딩 계산 없음**. | 🔴 **대** | +| 8 | **채그백/분쟁 라이프사이클.** 1차 채그백 → representment(재청구) → pre-arbitration → arbitration, reason code 체계. | chargeback/dispute 언급 일부(테이블 없음), **representment·중재 단계 없음**. | 🟠 중 | +| 9 | **한국 BC카드형 다자간 순액정산.** 회원은행 간(카드소지자 은행↔가맹점 은행) 다자간 순액정산 = 공유 클리어링/정산망(밴사/VAN). | 발급사(issuer) 값은 있으나 **회원사간 다자정산 계층 없음**. | 🟠 중 | + +## 고도화 우선순위 (리얼리티 임팩트 순) + +**🔴 1순위 — 수수료 3층 분해 + 정산 항등식 (매입사 경제모델의 핵심)** +- interchange(발급사 귀속) / scheme fee(카드망) / acquirer markup(매입사 마진) 분리 +- 요율표: 카드종류 × MCC × 채널 × 거래유형 차등 (interchange qualification) +- 정산 항등식: 총매출 − 환불 − 채그백 − 수수료 − 리저브 = 가맹점 입금 +- 이게 있어야 "이 시스템이 실제로 돈을 어떻게 나누는지" 설명됨 + +**🔴 2순위 — 클리어링 ≠ 정산 분리 + 순액정산** +- 승인 → 캡처 → **프레젠트먼트(클리어링)** → **순액정산** → 가맹점 펀딩 을 별도 단계로 +- 발급사↔매입사 순액정산(net settlement), BIN/ICA 라우팅 +- 한국형: 회원사간 다자 순액정산(밴사/VAN) + +**🟠 3순위 — 채그백/분쟁 라이프사이클 + ISO 8583 클리어링 메시지** +- dispute 상태기계: 1차CB → representment → pre-arb → arbitration + reason code +- mg에 클리어링 메시지 클래스(presentment/chargeback/fee-collection/recon/reject) + +## 설계 방침 + +- **기존 구조를 깨지 않는다.** 신규 테이블·서비스를 추가하고, 기존 flat MDR 는 markup 으로 + 재해석해 하위호환. 6단 XA 체인·477 tpcall 체인은 유지. +- **오너-라이츠·XA 브랜치 격리 규율** 그대로 적용 (Wave F 교훈). +- **실측 데이터로 시드**: interchange 요율표(카드종류×MCC×채널), 프레젠트먼트/클리어링 이력, + 채그백 케이스, 순액정산 배치 결과.