Wave E/F: 업무흐름 tpcall 오케스트레이션 + 크로스브랜치 교착 제거
477개 서비스를 tpcall 체인으로 연결하고(2 → 477), 그 과정에서 드러난
런타임 결함들을 실행 검증으로 잡아냈다.
체인 오케스트레이션 (Wave E)
- 매입/승인/정산/지급/대사/원장/마감/마스터/전문 흐름을 모듈 간 tpcall 로 연결
- 호출그래프 553노드 494엣지, 순환 0, SELFCALL 0
- 핵심 경로: ACQUIRE→RECONCILE→SETTLE→ST_MDR→LG_SETTLEPOST (6단, XA 2PC)
런타임 결함 수정 (Wave F) — 정적 게이트로는 잡히지 않던 것들
1. 모듈내 체인 자기교착: 모듈 서버 카피가 1이면 SETTLE→ST_MDR 처럼 같은
서버로 되돌아오는 호출이 자기 요청을 못 꺼내 TPETIME. 카피 4로 상향.
2. 크로스브랜치 핫로우 교착: 한 글로벌 트랜잭션의 형제 XA 브랜치가 같은 행을
UPDATE 하면 같은 트랜잭션이라 락이 안 풀려 타임아웃까지 블록된다.
- mg_channel: 비소유자 96개 서비스의 UPDATE 제거, STAN 은 시퀀스 채번으로
(실제 전문 스위치 방식). 생애주기 소유자 7개만 UPDATE 유지.
- lg_merch_bal: ACQ_SETTLELINK 의 LG_SETTLEPOST 다이아몬드 호출 제거.
교착일 뿐 아니라 같은 정산건이 원장에 이중 전기되는 회계 오류였다.
- cl_close_log / py_payout / lg_account_bal: CHAIN 마커로 쓰기 소유자 일원화.
py_payout 건은 피호출자가 호출자의 미커밋 승인을 볼 수 없어 기능적으로도
동작 불능이었다.
3. cm_log PK 충돌: st 131개 파일이 max(log_id)+1 로 채번해 nextval 을 쓰는
피호출자와 동일 PK 를 INSERT, 미커밋 인덱스 엔트리에 걸려 블록. 전부
nextval('cm_log_seq') 로 전환.
4. strncpy 스택 파괴: cmdb_get_param 이 strncpy(out, h_val, 127) 로 항상 128
바이트를 써서, bizdate[16] 을 넘기는 호출부 133곳이 매번 호출자 스택 112
바이트를 훼손했다. 인접 ecpg 호스트 변수가 오염돼 서버 카피가 세그폴트.
DB 락 대기가 0인데 60초 블록되는 증상의 원인. cm_code/py_payout_reject 동일.
5. ACQ_CANCEL→LIMIT_RST 입력계약 불일치: 카드번호를 안 실어 보내 항상 거절.
승인원장에서 카드를 끌어오고, 무승인 매입은 한도원복을 생략하도록 수정.
6. mgdb_channel_bump_stan: 활동 채널 전체를 한 번에 잠그는 다중행 UPDATE
(호출자 0인 잠복 지뢰). 시퀀스 채번 + 집계 조회로 교체.
화면
- 기본값을 실존 시드 키로 부팅 시 조회해 덮어쓴다. 기존 플레이스홀더
(card_limit 에 없는 카드, 8자리 영업일)로는 처리성 화면이 전부 거절당했다.
- 게이트웨이가 단일 스레드 직렬 루프라 기본값 조회도 순차로 수행.
검증 (실측)
- 통합 빌드: modules=11 servers=11 batches=506, error 0
- 도메인: 45 프로세스, 1,466 서비스 AVAIL
- 체인 전수 스모크 477/477 응답, TPETIME/TPEABORT 0건, 최대 530ms
- AUTH: 수정 전 60초 블록→TPEABORT, 수정 후 0.215초 ok:true
- 6단 매입 체인 COMMIT OK, 미결 2PC 0
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4cede852a0
commit
074d244bba
654 changed files with 36008 additions and 2805 deletions
|
|
@ -143,6 +143,39 @@ void ACQ_ALERTDUP(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 중복 경보 -> 매입 중복 검증(VL_DUPPURCH) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_ALERTDUP", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 경보로 잡힌 후보를 검증계 매입중복 규칙으로 확정한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
if (tpcall("VL_DUPPURCH", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(VL_DUPPURCH) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "매입 중복 검증 실패", 0L); setl(b, T_RC, 491);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: VL_DUPPURCH 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부: 결과 필드 채움 */
|
||||
setl(b, T_COUNT, h_a);
|
||||
setl(b, T_ARG1, h_b);
|
||||
|
|
|
|||
|
|
@ -140,6 +140,39 @@ void ACQ_AMTFIX(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 금액 보정 -> 금액 검증(VL_AMOUNT) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_AMTFIX", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 보정 후 금액이 허용 오차 안인지 검증계에서 확인한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_DELTA, h_delta);
|
||||
if (tpcall("VL_AMOUNT", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(VL_AMOUNT) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "보정 금액 검증 실패", 0L); setl(b, T_RC, 531);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: VL_AMOUNT 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
setl(b, T_DELTA, h_delta);
|
||||
|
|
|
|||
|
|
@ -148,6 +148,39 @@ void ACQ_APPRLINK(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 승인 연계 -> 한도 차감(LIMIT_DEC) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_APPRLINK", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 매입에 연결된 승인건만큼 한도를 확정 차감한다 */
|
||||
Bchg(b, T_ISSUER, 0, h_issuer, 0L);
|
||||
setl(b, T_ARG3, h_id);
|
||||
if (tpcall("LIMIT_DEC", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LIMIT_DEC) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "승인 한도 차감 실패", 0L); setl(b, T_RC, 341);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LIMIT_DEC 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_COUNT, h_b);
|
||||
setl(b, T_ID1, h_id);
|
||||
|
|
|
|||
|
|
@ -134,6 +134,40 @@ void ACQ_APPRMAP(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 승인 매핑 -> 미매핑 승인 취소(AUTH_CANCEL) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_APPRMAP", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 매입에 붙지 못한 승인건을 승인계에서 정리한다 */
|
||||
Bchg(b, T_ISSUER, 0, h_issuer, 0L);
|
||||
setl(b, T_ARG3, h_id);
|
||||
Bchg(b, T_REASON, 0, "ACQ_UNMAPPED", 0L);
|
||||
if (tpcall("AUTH_CANCEL", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(AUTH_CANCEL) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "승인 취소 연동 실패", 0L); setl(b, T_RC, 351);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: AUTH_CANCEL 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부: 결과 필드 채움 */
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_ARG1, h_a);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ void ACQ_CANCEL(TPSVCINFO *p)
|
|||
long h_id, h_pid, h_amt;
|
||||
long h_orig = 0, h_fee = 0, h_prior = 0, h_cnt = 0, h_sum = 0, h_logid = 0;
|
||||
char h_bizdate[16], h_reason[128], h_prev[8], h_merch[64], h_logmsg[256];
|
||||
char h_cardno[32];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
userlog("%s 진입: 매입 전액 취소 요청", SVC);
|
||||
|
|
@ -105,6 +106,76 @@ void ACQ_CANCEL(TPSVCINFO *p)
|
|||
VALUES (:h_logid, 'ACQ_CANCEL', 'I', :h_logmsg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); }
|
||||
|
||||
/* --- 업무 체인: 매입취소 -> 한도원복(LIMIT_RST) -> 원장역분개(LG_REVERSE) -> 정산취소(ST_CANCEL) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_CANCEL", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
setl(b, T_CANCEL_ID, h_id);
|
||||
|
||||
/* 1단계: 취소금액만큼 가맹점/카드 한도를 되돌린다.
|
||||
* LIMIT_RST 는 카드번호(T_KEY1)를 필수로 요구하지만 매입원장에는 카드가 없다.
|
||||
* 승인원장(au_authorization.auth_id = purchase_id)에서 카드를 끌어와 전문에 싣는다.
|
||||
* 승인 없이 접수된 매입(무승인 매입 등)은 원복할 카드 컨텍스트 자체가 없으므로
|
||||
* 한도원복 단계를 건너뛴다 — 실패가 아니라 해당 없음이다. */
|
||||
h_cardno[0] = 0;
|
||||
EXEC SQL SELECT card_no INTO :h_cardno FROM au_authorization WHERE auth_id = :h_pid;
|
||||
if (sqlca.sqlcode < 0) {
|
||||
userlog("%s: 승인원장 카드 조회 실패 [%d]", SVC, sqlca.sqlcode);
|
||||
setl(b, T_RC, 90); FAIL(b);
|
||||
}
|
||||
if (h_cardno[0] != 0) {
|
||||
Bchg(b, T_KEY1, 0, h_cardno, 0L);
|
||||
setl(b, T_ARG3, h_orig);
|
||||
Bchg(b, T_REASON, 0, h_reason, 0L);
|
||||
if (tpcall("LIMIT_RST", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LIMIT_RST) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "한도 원복 실패", 0L); setl(b, T_RC, 141);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LIMIT_RST 응답 rc=%ld card=%s", SVC, chain_rc, h_cardno);
|
||||
} else {
|
||||
userlog("%s 체인: pid=%ld 승인원장 카드 없음 — 한도원복 생략", SVC, h_pid);
|
||||
}
|
||||
|
||||
/* 2단계: 원 매입 전표를 역분개해 회계 잔액을 맞춘다 */
|
||||
setl(b, T_ARG4, h_id);
|
||||
setl(b, T_ARG5, ratio);
|
||||
if (tpcall("LG_REVERSE", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LG_REVERSE) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "원장 역분개 실패", 0L); setl(b, T_RC, 142);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LG_REVERSE 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 3단계: 정산 예정분을 취소해 지급 대상에서 제외한다 */
|
||||
setl(b, T_ARG6, h_fee);
|
||||
if (tpcall("ST_CANCEL", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_CANCEL) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "정산 취소 실패", 0L); setl(b, T_RC, 143);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_CANCEL 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 (계약 보존: T_CANCEL_ID / T_STATUS='C') */
|
||||
setl(b, T_CANCEL_ID, h_id);
|
||||
Bchg(b, T_STATUS, 0, "C", 0L);
|
||||
|
|
|
|||
|
|
@ -156,6 +156,39 @@ void ACQ_CB_OPEN(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 차지백 접수 -> 정산 차지백 반영(ST_CHARGEBACK) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_CB_OPEN", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 접수된 차지백 금액을 정산 지급에서 차감 예약한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
Bchg(b, T_REASON, 0, h_reason, 0L);
|
||||
if (tpcall("ST_CHARGEBACK", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_CHARGEBACK) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "차지백 정산 반영 실패", 0L); setl(b, T_RC, 561);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_CHARGEBACK 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_CANCEL_ID, h_canid);
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
|
|
|
|||
|
|
@ -165,6 +165,39 @@ void ACQ_CB_REVERSE(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 차지백 역전 -> 원장 역분개(LG_REVERSE) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_CB_REVERSE", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 가맹점 승소로 되돌아온 차지백을 원장에서 역분개한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_ARG3, h_val);
|
||||
if (tpcall("LG_REVERSE", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LG_REVERSE) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "차지백 역전 원장 반영 실패", 0L); setl(b, T_RC, 571);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LG_REVERSE 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_ARG1, h_rem);
|
||||
|
|
|
|||
|
|
@ -156,6 +156,39 @@ void ACQ_CLAIMREG(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 클레임 등록 -> 분쟁 등록(ST_DISPUTE) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_CLAIMREG", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 접수된 클레임을 정산 분쟁건으로 등록해 지급을 묶는다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
Bchg(b, T_REASON, 0, h_reason, 0L);
|
||||
if (tpcall("ST_DISPUTE", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_DISPUTE) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "정산 분쟁 등록 실패", 0L); setl(b, T_RC, 581);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_DISPUTE 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ID1, h_id);
|
||||
setl(b, T_ARG1, h_val);
|
||||
|
|
|
|||
|
|
@ -144,6 +144,39 @@ void ACQ_CORRECT(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 매입정정 -> 원장 정정분개(LG_CORRECT) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_CORRECT", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 정정 전/후 금액 차액을 원장에 정정분개로 반영한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_DELTA, h_amt - h_gross);
|
||||
if (tpcall("LG_CORRECT", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LG_CORRECT) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "원장 정정 분개 실패", 0L); setl(b, T_RC, 191);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LG_CORRECT 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ADJ, h_adjid);
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
|
|
|
|||
|
|
@ -156,6 +156,40 @@ void ACQ_DDC(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: DDC 매입 -> 전문 로깅(MG_LOG) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_DDC", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: DDC 수신 전문을 게이트웨이 로그에 남겨 추적 가능하게 한다 */
|
||||
Bchg(b, T_CHANNEL, 0, h_chan, 0L);
|
||||
Bchg(b, T_KEY1, 0, "DDC", 0L);
|
||||
setl(b, T_AMT1, h_gross);
|
||||
if (tpcall("MG_LOG", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(MG_LOG) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "DDC 전문 로깅 실패", 0L); setl(b, T_RC, 401);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: MG_LOG 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ID1, h_id);
|
||||
setl(b, T_AMOUNT, h_krw);
|
||||
|
|
|
|||
|
|
@ -152,6 +152,39 @@ void ACQ_DUPCHK(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 중복 매입 점검 -> 중복 검증(VL_DUP) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_DUPCHK", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 검증계 중복 규칙으로 동일 매입 재접수를 걸러낸다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
if (tpcall("VL_DUP", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(VL_DUP) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "중복 검증 실패", 0L); setl(b, T_RC, 481);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: VL_DUP 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부: 결과 필드 채움 */
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_ARG1, h_c);
|
||||
|
|
|
|||
|
|
@ -146,6 +146,40 @@ void ACQ_EDC(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: EDC 매입 -> 전문 로깅(MG_LOG) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_EDC", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: EDC 단말 매입 전문을 게이트웨이 로그로 적재한다 */
|
||||
Bchg(b, T_CHANNEL, 0, h_chan, 0L);
|
||||
Bchg(b, T_KEY1, 0, "EDC", 0L);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
if (tpcall("MG_LOG", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(MG_LOG) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "EDC 전문 로깅 실패", 0L); setl(b, T_RC, 411);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: MG_LOG 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_PURCHASE_ID, h_new);
|
||||
setl(b, T_FEE, h_fee);
|
||||
|
|
|
|||
|
|
@ -154,6 +154,40 @@ void ACQ_EDI(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: EDI 매입 -> 전문 송신(MG_SEND) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_EDI", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 확정된 EDI 매입 전문을 상대 기관으로 송신한다 */
|
||||
Bchg(b, T_CHANNEL, 0, h_chan, 0L);
|
||||
Bchg(b, T_KEY1, 0, "EDI", 0L);
|
||||
setl(b, T_AMT1, h_gross);
|
||||
if (tpcall("MG_SEND", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(MG_SEND) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "EDI 전문 송신 실패", 0L); setl(b, T_RC, 421);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: MG_SEND 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_PURCHASE_ID, h_new);
|
||||
setl(b, T_ID1, h_id);
|
||||
|
|
|
|||
|
|
@ -158,6 +158,40 @@ void ACQ_EDIRESEND(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: EDI 재전송 -> 전문 재송신(MG_RESEND) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_EDIRESEND", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 미응답 EDI 전문을 게이트웨이에서 재송신시킨다 */
|
||||
Bchg(b, T_CHANNEL, 0, h_chan, 0L);
|
||||
setl(b, T_ARG3, h_n);
|
||||
Bchg(b, T_KEY1, 0, "EDI_RESEND", 0L);
|
||||
if (tpcall("MG_RESEND", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(MG_RESEND) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "EDI 전문 재송신 실패", 0L); setl(b, T_RC, 431);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: MG_RESEND 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ID1, h_id);
|
||||
Bchg(b, T_DOCNO, 0, h_str1, 0L);
|
||||
|
|
|
|||
|
|
@ -148,6 +148,39 @@ void ACQ_ESCROW(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 에스크로 예치 -> 지급보류(PAY_HOLD) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_ESCROW", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 예치 기간 동안 지급이 나가지 않도록 잠근다 */
|
||||
setl(b, T_AMT1, h_net);
|
||||
Bchg(b, T_KEY1, 0, "ESCROW", 0L);
|
||||
if (tpcall("PAY_HOLD", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(PAY_HOLD) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "에스크로 지급보류 실패", 0L); setl(b, T_RC, 221);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: PAY_HOLD 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ID1, h_ledid);
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
|
|
|
|||
|
|
@ -149,6 +149,39 @@ void ACQ_ESCROWREL(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 에스크로 해지 -> 지급보류해제(PAY_RELEASE) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_ESCROWREL", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 예치 해지 후 지급 가능 상태로 되돌린다 */
|
||||
setl(b, T_AMT1, h_net);
|
||||
Bchg(b, T_KEY1, 0, "ESCROW_REL", 0L);
|
||||
if (tpcall("PAY_RELEASE", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(PAY_RELEASE) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "에스크로 해지 지급 재개 실패", 0L); setl(b, T_RC, 231);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: PAY_RELEASE 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ID1, h_ledid);
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
|
|
|
|||
|
|
@ -165,6 +165,39 @@ void ACQ_EXCHANGE(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 환전 매입 -> 교차환율 조회(CM_FX_CROSS) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_EXCHANGE", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 원통화-정산통화 간 교차환율을 공통계에서 구한다 */
|
||||
Bchg(b, T_CCY, 0, h_ccy, 0L);
|
||||
setl(b, T_FX_AMT, h_fx);
|
||||
if (tpcall("CM_FX_CROSS", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(CM_FX_CROSS) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "교차환율 조회 실패", 0L); setl(b, T_RC, 471);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: CM_FX_CROSS 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_CANCEL_ID, h_canid);
|
||||
setl(b, T_DELTA, h_delta);
|
||||
|
|
|
|||
|
|
@ -143,6 +143,39 @@ void ACQ_FEEADJ(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 수수료 조정 -> 원장 조정분개(LG_ADJUST) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_FEEADJ", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 조정된 수수료 증감분을 원장 조정분개로 남긴다 */
|
||||
setl(b, T_DELTA, h_delta);
|
||||
setl(b, T_AMT1, h_fee);
|
||||
if (tpcall("LG_ADJUST", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LG_ADJUST) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "수수료 조정 원장 반영 실패", 0L); setl(b, T_RC, 281);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LG_ADJUST 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ADJ, h_adjid);
|
||||
setl(b, T_DELTA, h_delta);
|
||||
|
|
|
|||
|
|
@ -138,6 +138,39 @@ void ACQ_FEERECALC(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 수수료 재산출 -> 정산 재계산(ST_RECALC) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_FEERECALC", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 재산출된 요율로 정산 지급액을 다시 만든다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_ARG3, h_rate);
|
||||
if (tpcall("ST_RECALC", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_RECALC) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "정산 재계산 실패", 0L); setl(b, T_RC, 291);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_RECALC 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ADJ, h_adjid);
|
||||
setl(b, T_FEE, h_fee);
|
||||
|
|
|
|||
|
|
@ -158,6 +158,40 @@ void ACQ_FOREIGN(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 해외 매입 -> 환산(CM_FX_CONV) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_FOREIGN", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 원통화 금액을 공통 환율로 원화 환산한다 */
|
||||
Bchg(b, T_CCY, 0, h_ccy, 0L);
|
||||
setl(b, T_FX_AMT, h_fx);
|
||||
setl(b, T_AMT1, h_krw);
|
||||
if (tpcall("CM_FX_CONV", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(CM_FX_CONV) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "해외매입 환산 실패", 0L); setl(b, T_RC, 441);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: CM_FX_CONV 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_PURCHASE_ID, h_new);
|
||||
setl(b, T_AMOUNT, h_krw);
|
||||
|
|
|
|||
|
|
@ -162,6 +162,39 @@ void ACQ_FXCONVERT(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 통화 환산 -> 환율 조회(CM_FX) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_FXCONVERT", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 영업일 기준 고시환율을 공통계에서 받아온다 */
|
||||
Bchg(b, T_CCY, 0, h_ccy, 0L);
|
||||
setl(b, T_FX_AMT, h_fx);
|
||||
if (tpcall("CM_FX", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(CM_FX) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "환율 조회 실패", 0L); setl(b, T_RC, 451);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: CM_FX 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ID1, h_id);
|
||||
setl(b, T_AMOUNT, h_krw);
|
||||
|
|
|
|||
|
|
@ -145,6 +145,39 @@ void ACQ_FXRATE(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 환율 적용 -> 환율 유효성 검증(CM_FX_VALID) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_FXRATE", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 적용하려는 환율이 고시 범위 안인지 확인한다 */
|
||||
Bchg(b, T_CCY, 0, h_ccy, 0L);
|
||||
setl(b, T_ARG3, h_rate);
|
||||
if (tpcall("CM_FX_VALID", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(CM_FX_VALID) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "환율 유효성 검증 실패", 0L); setl(b, T_RC, 461);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: CM_FX_VALID 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부: 결과 필드 채움 */
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_ARG1, h_rate);
|
||||
|
|
|
|||
|
|
@ -149,6 +149,39 @@ void ACQ_GUARANTEE(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 매입 보증 -> 정산 담보 확인(ST_COLLATERAL) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_GUARANTEE", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 보증 한도가 담보 범위 안인지 정산계에서 확인한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_AMT2, h_net);
|
||||
if (tpcall("ST_COLLATERAL", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_COLLATERAL) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "정산 담보 확인 실패", 0L); setl(b, T_RC, 631);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_COLLATERAL 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ID1, h_ledid);
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
|
|
|
|||
|
|
@ -122,6 +122,39 @@ void ACQ_HOLD(TPSVCINFO *p)
|
|||
if (h_ctx > 1000)
|
||||
userlog("%s 경보: 당일 보류 처리 %ld 회로 과다", SVC, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 매입보류 -> 지급보류(PAY_HOLD) 연동 ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_HOLD", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 보류된 매입의 정산 지급을 지급계에서 함께 잠근다 */
|
||||
Bchg(b, T_REASON, 0, h_reason, 0L);
|
||||
setl(b, T_ARG3, h_id);
|
||||
if (tpcall("PAY_HOLD", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(PAY_HOLD) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "지급 보류 연동 실패", 0L); setl(b, T_RC, 201);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: PAY_HOLD 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 (계약 보존: 반영 시 T_STATUS='H', T_RC 는 0/1) */
|
||||
if (h_aff > 0) Bchg(b, T_STATUS, 0, "H", 0L);
|
||||
else Bchg(b, T_STATUS, 0, h_prev, 0L);
|
||||
|
|
|
|||
|
|
@ -158,6 +158,39 @@ void ACQ_INSTALL(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 할부 등록 -> 할부 조건 검증(VL_INSTCHK) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_INSTALL", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 개월수/금액 하한 등 할부 규칙을 검증계에서 확인한다 */
|
||||
setl(b, T_INSTALL_N, h_months);
|
||||
setl(b, T_AMT1, h_gross);
|
||||
if (tpcall("VL_INSTCHK", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(VL_INSTCHK) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "할부 조건 검증 실패", 0L); setl(b, T_RC, 321);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: VL_INSTCHK 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_COUNT, h_months);
|
||||
setl(b, T_INSTALL_N, h_months);
|
||||
|
|
|
|||
|
|
@ -160,6 +160,39 @@ void ACQ_INSTCXL(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 할부 취소 -> 한도원복(LIMIT_RST) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_INSTCXL", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 할부 잔여 회차분의 점유 한도를 되돌린다 */
|
||||
setl(b, T_INSTALL_N, h_months);
|
||||
setl(b, T_AMT1, h_gross);
|
||||
if (tpcall("LIMIT_RST", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LIMIT_RST) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "할부취소 한도 원복 실패", 0L); setl(b, T_RC, 331);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LIMIT_RST 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_COUNT, h_rem);
|
||||
setl(b, T_INSTALL_N, h_months);
|
||||
|
|
|
|||
|
|
@ -152,6 +152,39 @@ void ACQ_LIMITCHK(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 매입 한도 점검 -> 한도 검증(VL_LIMIT) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_LIMITCHK", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 가맹점 한도 소진 여부를 검증계 규칙으로 재확인한다 */
|
||||
setl(b, T_AMT1, h_lim);
|
||||
setl(b, T_AMT2, h_sum);
|
||||
if (tpcall("VL_LIMIT", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(VL_LIMIT) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "한도 검증 실패", 0L); setl(b, T_RC, 501);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: VL_LIMIT 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부: 결과 필드 채움 */
|
||||
setl(b, T_GROSS, h_b);
|
||||
setl(b, T_ARG1, h_lim);
|
||||
|
|
|
|||
|
|
@ -156,6 +156,39 @@ void ACQ_LIMITEXC(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 한도 초과 처리 -> 한도초과 검증(VL_OVERLIMIT) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_LIMITEXC", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 초과분이 예외 승인 범위인지 검증계에서 판정한다 */
|
||||
setl(b, T_AMT1, h_lim);
|
||||
setl(b, T_AMT2, h_sum);
|
||||
if (tpcall("VL_OVERLIMIT", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(VL_OVERLIMIT) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "한도초과 검증 실패", 0L); setl(b, T_RC, 511);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: VL_OVERLIMIT 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_GROSS, h_sum);
|
||||
setl(b, T_ARG1, h_lim);
|
||||
|
|
|
|||
|
|
@ -103,6 +103,37 @@ void ACQ_MERCHSUM(TPSVCINFO *p)
|
|||
VALUES (:h_logid, 'ACQ_MERCHSUM', 'I', :h_logmsg, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); }
|
||||
|
||||
/* --- 업무 체인: 가맹점 실적 요약 -> 가맹점 마스터 조회(MM_MERCH_INQ) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_MERCHSUM", 0L);
|
||||
Bchg(b, T_MERCHANT, 0, h_merch, 0L);
|
||||
Bchg(b, T_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 요약에 붙일 가맹점 등급/상태를 마스터계에서 받아온다 */
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_AMT1, h_gross);
|
||||
if (tpcall("MM_MERCH_INQ", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(MM_MERCH_INQ) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "가맹점 마스터 조회 실패", 0L); setl(b, T_RC, 621);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: MM_MERCH_INQ 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 (계약 보존: T_COUNT / T_GROSS) */
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_GROSS, h_gross);
|
||||
|
|
|
|||
|
|
@ -146,6 +146,39 @@ void ACQ_NETCALC(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 순액 산출 -> 원장 순포지션 확인(LG_NETPOS) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_NETCALC", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 산출한 순액이 원장 순포지션과 맞는지 대조한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_AMT2, h_fee);
|
||||
if (tpcall("LG_NETPOS", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LG_NETPOS) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "원장 순포지션 조회 실패", 0L); setl(b, T_RC, 611);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LG_NETPOS 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_NET, computed);
|
||||
setl(b, T_DELTA, h_delta);
|
||||
|
|
|
|||
|
|
@ -163,6 +163,50 @@ void ACQ_PARTCXL(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 부분취소 -> 한도원복(LIMIT_RST) -> 부분역분개(LG_PARTREVERSE) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_PARTCXL", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 부분취소 금액만큼만 한도를 되돌린다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_ARG3, h_val);
|
||||
if (tpcall("LIMIT_RST", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LIMIT_RST) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "부분취소 한도 원복 실패", 0L); setl(b, T_RC, 161);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LIMIT_RST 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 2단계: 원 전표를 남긴 채 취소분만 부분 역분개한다 */
|
||||
setl(b, T_AMT2, h_fee);
|
||||
setl(b, T_AMT3, h_net);
|
||||
if (tpcall("LG_PARTREVERSE", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LG_PARTREVERSE) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "부분 역분개 실패", 0L); setl(b, T_RC, 162);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LG_PARTREVERSE 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_CANCEL_ID, h_canid);
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
|
|
|
|||
|
|
@ -168,6 +168,39 @@ void ACQ_PARTRFND(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 부분환불 -> 정산 환불액 재산출(ST_REFUNDCALC) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_PARTRFND", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 부분환불 후 남는 정산 지급액을 정산계에서 재산출한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_AMT2, h_fee);
|
||||
if (tpcall("ST_REFUNDCALC", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_REFUNDCALC) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "환불 정산액 산출 실패", 0L); setl(b, T_RC, 171);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_REFUNDCALC 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_CANCEL_ID, h_canid);
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
|
|
|
|||
|
|
@ -149,6 +149,39 @@ void ACQ_PROMO(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 프로모션 적용 -> 정산 프로모 반영(ST_PROMOAPPLY) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_PROMO", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 프로모션 우대요율을 정산 수수료에 반영한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
Bchg(b, T_KEY1, 0, h_str1, 0L);
|
||||
if (tpcall("ST_PROMOAPPLY", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_PROMOAPPLY) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "프로모션 정산 반영 실패", 0L); setl(b, T_RC, 311);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_PROMOAPPLY 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_PURCHASE_ID, h_new);
|
||||
setl(b, T_FEE, h_fee);
|
||||
|
|
|
|||
|
|
@ -165,6 +165,50 @@ void ACQ_REFUND(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 매입환불 -> 한도원복(LIMIT_RST) -> 원장역분개(LG_REVERSE) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_REFUND", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 환불액만큼 소진한도를 복구한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
Bchg(b, T_ISSUER, 0, h_issuer, 0L);
|
||||
if (tpcall("LIMIT_RST", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LIMIT_RST) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "환불 한도 원복 실패", 0L); setl(b, T_RC, 151);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LIMIT_RST 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 2단계: 환불분에 해당하는 매입 전표를 역분개한다 */
|
||||
setl(b, T_AMT2, h_fee);
|
||||
setl(b, T_ARG5, h_rem);
|
||||
if (tpcall("LG_REVERSE", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LG_REVERSE) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "환불 원장 역분개 실패", 0L); setl(b, T_RC, 152);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LG_REVERSE 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_CANCEL_ID, h_canid);
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
|
|
|
|||
|
|
@ -153,6 +153,39 @@ void ACQ_RELEASE(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 보류해제 -> 지급보류해제(PAY_RELEASE) 연동 ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_RELEASE", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 매입 보류 해제와 동시에 지급 잠금도 해제한다 */
|
||||
setl(b, T_AMT1, h_net);
|
||||
Bchg(b, T_REASON, 0, h_reason, 0L);
|
||||
if (tpcall("PAY_RELEASE", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(PAY_RELEASE) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "지급 보류 해제 실패", 0L); setl(b, T_RC, 211);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: PAY_RELEASE 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
Bchg(b, T_STR1, 0, h_prev, 0L);
|
||||
setl(b, T_ARG1, h_val);
|
||||
|
|
|
|||
|
|
@ -159,6 +159,39 @@ void ACQ_REMATCH(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 재매칭 -> 대사 재매칭(RC_REMATCH) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_REMATCH", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 보정된 키로 대사계에 재매칭을 요청한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
if (tpcall("RC_REMATCH", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(RC_REMATCH) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "대사 재매칭 실패", 0L); setl(b, T_RC, 551);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: RC_REMATCH 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_ARG1, h_a);
|
||||
|
|
|
|||
|
|
@ -150,6 +150,39 @@ void ACQ_REPROC(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 매입 재처리 -> 대사 재처리(RC_REPROC) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_REPROC", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 재처리된 매입을 대사계에서 다시 태운다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
if (tpcall("RC_REPROC", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(RC_REPROC) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "대사 재처리 실패", 0L); setl(b, T_RC, 601);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: RC_REPROC 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_ARG1, h_val);
|
||||
|
|
|
|||
|
|
@ -148,6 +148,39 @@ void ACQ_RESERVE(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 유보금 설정 -> 정산 보류(ST_HOLD) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_RESERVE", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 유보율만큼 정산 지급을 정산계에서 붙잡아 둔다 */
|
||||
setl(b, T_AMT1, h_net);
|
||||
setl(b, T_ARG3, h_rate);
|
||||
if (tpcall("ST_HOLD", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_HOLD) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "정산 유보 설정 실패", 0L); setl(b, T_RC, 241);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_HOLD 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_PURCHASE_ID, h_new);
|
||||
Bchg(b, T_BIZDATE, 0, h_d1, 0L);
|
||||
|
|
|
|||
|
|
@ -157,6 +157,39 @@ void ACQ_RESERVECXL(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 유보금 해제 -> 정산 보류해제(ST_RELEASE) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_RESERVECXL", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 해제된 유보금을 다음 정산 회차에 태운다 */
|
||||
setl(b, T_AMT1, h_net);
|
||||
setl(b, T_ARG3, h_val);
|
||||
if (tpcall("ST_RELEASE", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_RELEASE) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "정산 유보 해제 실패", 0L); setl(b, T_RC, 251);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_RELEASE 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
setl(b, T_ARG1, h_rem);
|
||||
|
|
|
|||
|
|
@ -153,6 +153,39 @@ void ACQ_RETURN(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 반품 매입 -> 대사 환불건 등록(RC_REFUNDREC) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_RETURN", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 반품으로 발생한 환불건을 대사계에 등록한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
Bchg(b, T_REASON, 0, h_reason, 0L);
|
||||
if (tpcall("RC_REFUNDREC", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(RC_REFUNDREC) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "대사 환불건 등록 실패", 0L); setl(b, T_RC, 591);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: RC_REFUNDREC 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_CANCEL_ID, h_canid);
|
||||
setl(b, T_AMOUNT, h_gross);
|
||||
|
|
|
|||
|
|
@ -151,6 +151,95 @@ void ACQ_SETTLELINK(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 정산연계 -> 수수료 산출/원장반영(ST_MDR) -> 대차검증(LG_BALCHK) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다.
|
||||
*
|
||||
* XA 핫로우 규율: 원장 전기(LG_SETTLEPOST)는 ST_MDR 브랜치가 이미 수행한다
|
||||
* (ST_MDR -> LG_SETTLEPOST). 여기서 LG_SETTLEPOST 를 다시 직접 호출하면
|
||||
* 같은 글로벌 트랜잭션의 '형제 브랜치'가 lg_merch_bal 의 동일행
|
||||
* (merchant_id, biz_date) 을 ON CONFLICT DO UPDATE 로 두 번 잠가
|
||||
* 서로의 미커밋 락을 기다리며 트랜잭션 타임아웃까지 교착된다. 게다가
|
||||
* 같은 정산건이 원장에 두 번 전기되어 잔액이 이중계상되는 회계 오류도 된다.
|
||||
* 따라서 원장 쓰기 소유자는 ST_MDR 브랜치 하나로 일원화하고, 이 브랜치는
|
||||
* 전기 결과를 읽기전용 서비스 LG_BALCHK 로 대차검증만 한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
long chain_fee = 0, bal_dr = 0, bal_cr = 0, bal_diff = 0, bal_cnt = 0;
|
||||
long keep_amt2 = 0, keep_amt3 = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_SETTLELINK", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 정산계 요율표로 MDR 수수료를 확정한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_ARG3, h_rate);
|
||||
Bchg(b, T_CATEGORY, 0, h_category, 0L);
|
||||
if (tpcall("ST_MDR", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_MDR) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "정산 수수료 산출 실패", 0L); setl(b, T_RC, 271);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
chain_fee = getl(b, T_ARG1);
|
||||
if (chain_fee > 0) setl(b, T_AMT2, chain_fee); /* 하위 산출 수수료를 다음 단계로 */
|
||||
userlog("%s 체인: ST_MDR 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 2단계: ST_MDR 브랜치가 전기한 정산 원장의 대차일치를 검증한다.
|
||||
* LG_BALCHK 는 조회 전용(원장/잔액에 쓰기 없음)이라 형제 브랜치와
|
||||
* 같은 행을 잠그지 않는다. 따라서 이 체인은 핫로우 교착을 만들지 않는다. */
|
||||
keep_amt2 = getl(b, T_AMT2); /* 하위가 덮어쓰기 전 수수료 보존 */
|
||||
keep_amt3 = getl(b, T_AMT3);
|
||||
setl(b, T_AMT3, h_net);
|
||||
setl(b, T_AMOUNT, (h_net < 0 ? 0 : h_net));
|
||||
setl(b, T_ID1, h_setid);
|
||||
setl(b, T_DELTA, 0L);
|
||||
Bchg(b, T_MERCHANT, 0, h_merch, 0L);
|
||||
Bchg(b, T_BIZDATE, 0, h_bizdate, 0L);
|
||||
Bchg(b, T_REASON, 0, "정산전기-대차검증", 0L);
|
||||
if (tpcall("LG_BALCHK", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LG_BALCHK) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "정산 원장 대차검증 실패", 0L); setl(b, T_RC, 272);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
bal_dr = getl(b, T_ARG7);
|
||||
bal_cr = getl(b, T_ARG8);
|
||||
bal_cnt = getl(b, T_ARG5);
|
||||
bal_diff = getl(b, T_ARG6);
|
||||
if (bal_diff < 0) bal_diff = -bal_diff;
|
||||
userlog("%s 체인: LG_BALCHK 응답 rc=%ld 차변=%ld 대변=%ld 건수=%ld 차이=%ld",
|
||||
SVC, chain_rc, bal_dr, bal_cr, bal_cnt, bal_diff);
|
||||
|
||||
/* 대차 불일치는 정산 연계를 되돌릴 사유는 아니지만(원장 전기 자체는
|
||||
* ST_MDR 브랜치에서 성공), 감사 추적이 남도록 사유/경보를 기록한다. */
|
||||
if (chain_rc != 0 || bal_diff != 0) {
|
||||
snprintf(h_logmsg, sizeof(h_logmsg),
|
||||
"%s 정산원장 대차불일치 merch=%s biz=%s 차변=%ld 대변=%ld 차이=%ld",
|
||||
SVC, h_merch, h_bizdate, bal_dr, bal_cr, bal_diff);
|
||||
userlog("%s 경보: %s", SVC, h_logmsg);
|
||||
Bchg(b, T_MSG, 0, "정산 원장 대차 불일치(감사대상)", 0L);
|
||||
} else {
|
||||
userlog("%s 체인: 정산원장 대차일치 확인 merch=%s biz=%s 계상=%ld",
|
||||
SVC, h_merch, h_bizdate, bal_dr);
|
||||
}
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태/금액 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
if (keep_amt2 > 0) setl(b, T_AMT2, keep_amt2);
|
||||
if (keep_amt3 > 0) setl(b, T_AMT3, keep_amt3);
|
||||
setl(b, T_AMOUNT, h_amt);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_SETTLE_ID, h_setid);
|
||||
setl(b, T_NET, h_net);
|
||||
|
|
|
|||
|
|
@ -161,6 +161,39 @@ void ACQ_SPLITPAY(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 분할지급 -> 정산 분할(ST_SPLIT) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_SPLITPAY", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 분할 회차 수만큼 정산 지급 계획을 쪼갠다 */
|
||||
setl(b, T_AMT1, h_net);
|
||||
setl(b, T_ARG3, h_n);
|
||||
if (tpcall("ST_SPLIT", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_SPLIT) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "정산 분할 처리 실패", 0L); setl(b, T_RC, 301);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_SPLIT 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_COUNT, h_n);
|
||||
setl(b, T_AMT1, h_mamt);
|
||||
|
|
|
|||
|
|
@ -155,6 +155,39 @@ void ACQ_TAXCXL(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 세금계산서 취소 -> 정산 조정 반영(ST_ADJUST) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_TAXCXL", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 취소된 세액을 정산 조정에서 되돌린다 */
|
||||
setl(b, T_TAX, -h_vat);
|
||||
Bchg(b, T_DOCNO, 0, h_docno, 0L);
|
||||
if (tpcall("ST_ADJUST", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_ADJUST) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "세금계산서 취소 정산 반영 실패", 0L); setl(b, T_RC, 371);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_ADJUST 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ID1, h_invid);
|
||||
setl(b, T_GROSS, h_delta);
|
||||
|
|
|
|||
|
|
@ -142,6 +142,40 @@ void ACQ_TAXINV(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 세금계산서 발행 -> 정산 조정 반영(ST_ADJUST) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_TAXINV", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 발행된 세액/공급가액을 정산 조정으로 넘긴다 */
|
||||
setl(b, T_TAX, h_vat);
|
||||
setl(b, T_AMT1, h_supply);
|
||||
Bchg(b, T_DOCNO, 0, h_docno, 0L);
|
||||
if (tpcall("ST_ADJUST", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_ADJUST) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "세금계산서 정산 조정 실패", 0L); setl(b, T_RC, 361);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_ADJUST 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ID1, h_invid);
|
||||
setl(b, T_TAX, h_vat);
|
||||
|
|
|
|||
|
|
@ -160,6 +160,39 @@ void ACQ_TAXREVERSE(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 세금계산서 역발행 -> 원장 역분개(LG_REVERSE) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_TAXREVERSE", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 역발행분의 부가세 전표를 원장에서 역분개한다 */
|
||||
setl(b, T_TAX, h_vat);
|
||||
Bchg(b, T_DOCNO, 0, h_docno, 0L);
|
||||
if (tpcall("LG_REVERSE", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LG_REVERSE) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "세무 원장 역분개 실패", 0L); setl(b, T_RC, 381);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LG_REVERSE 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ID1, h_invid);
|
||||
setl(b, T_ID2, h_id);
|
||||
|
|
|
|||
|
|
@ -160,6 +160,39 @@ void ACQ_UNMATCH(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 미매칭 매입 -> 대사 미매칭 등록(RC_UNMATCH) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_UNMATCH", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 매입측에서 잡은 미매칭 건을 대사계 원장에 올린다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
if (tpcall("RC_UNMATCH", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(RC_UNMATCH) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "대사 미매칭 등록 실패", 0L); setl(b, T_RC, 541);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: RC_UNMATCH 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ID1, h_id);
|
||||
setl(b, T_COUNT, h_cnt + 1);
|
||||
|
|
|
|||
|
|
@ -157,6 +157,39 @@ void ACQ_VELOCITY(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 속도 점검 -> 속도 검증(VL_VELOCITY) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_VELOCITY", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 단위시간 건수/금액이 임계치를 넘는지 검증계에 묻는다 */
|
||||
setl(b, T_COUNT, h_cnt);
|
||||
setl(b, T_AMT1, h_gross);
|
||||
if (tpcall("VL_VELOCITY", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(VL_VELOCITY) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "속도 검증 실패", 0L); setl(b, T_RC, 521);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: VL_VELOCITY 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부: 결과 필드 채움 */
|
||||
setl(b, T_COUNT, h_a);
|
||||
setl(b, T_ARG2, h_b);
|
||||
|
|
|
|||
|
|
@ -154,6 +154,39 @@ void ACQ_VOID(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 매입무효 -> 전표무효(LG_VOIDVOUCHER) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_VOID", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 무효 처리된 매입의 회계 전표를 무효화한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
Bchg(b, T_REASON, 0, h_reason, 0L);
|
||||
if (tpcall("LG_VOIDVOUCHER", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(LG_VOIDVOUCHER) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "전표 무효화 실패", 0L); setl(b, T_RC, 181);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: LG_VOIDVOUCHER 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_AMOUNT, h_gross);
|
||||
setl(b, T_DELTA, h_delta);
|
||||
|
|
|
|||
|
|
@ -155,6 +155,52 @@ void ACQ_WHT(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 원천징수 -> 원천세 산출(ST_WHT) -> 정산 조정 반영(ST_ADJUST) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
long chain_wht = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_WHT", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 정산계 원천징수 요율로 원천세를 산출한다 */
|
||||
setl(b, T_AMT1, h_gross);
|
||||
setl(b, T_ARG3, h_rate);
|
||||
if (tpcall("ST_WHT", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_WHT) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "원천세 산출 실패", 0L); setl(b, T_RC, 391);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
chain_wht = getl(b, T_TAX);
|
||||
if (chain_wht > 0) setl(b, T_AMT2, chain_wht); /* 산출 원천세를 조정단계로 전달 */
|
||||
userlog("%s 체인: ST_WHT 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 2단계: 원천세 차감분을 정산 지급액에 조정 반영한다 */
|
||||
setl(b, T_AMT3, h_net);
|
||||
if (tpcall("ST_ADJUST", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(ST_ADJUST) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "원천세 정산 조정 실패", 0L); setl(b, T_RC, 392);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: ST_ADJUST 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_TAX, h_tax);
|
||||
setl(b, T_ID1, h_id);
|
||||
|
|
|
|||
|
|
@ -153,6 +153,39 @@ void ACQ_XFERLINK(TPSVCINFO *p)
|
|||
userlog("%s 경보: 당일 호출 %ld 회로 과다", SVC, h_ctx);
|
||||
setl(b, T_ARG6, h_ctx);
|
||||
|
||||
/* --- 업무 체인: 이체 연계 -> 지급 이체건 연결(PAY_XFERLINK) ---
|
||||
* 하위 서비스는 별도 XA 브랜치라 이 서비스가 방금 INSERT/UPDATE 한
|
||||
* 미커밋 행을 볼 수 없다. 판정에 필요한 값은 전부 UBF 전문으로 실어 보낸다.
|
||||
* 하위 실패 시 같은 글로벌 트랜잭션이므로 FAIL 로 전체 롤백한다(보상 불필요).
|
||||
* 자기 응답 계약은 이 블록 뒤 응답부에서 다시 확정한다. */
|
||||
{
|
||||
long rlen = 0, chain_rc = 0;
|
||||
char keep_status[16];
|
||||
|
||||
keep_status[0] = 0;
|
||||
gets_(b, T_STATUS, keep_status, sizeof(keep_status));
|
||||
Bchg(b, T_SVCNAME, 0, "ACQ_XFERLINK", 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_BIZDATE, 0, h_bizdate, 0L);
|
||||
|
||||
/* 1단계: 매입건과 실제 이체건을 지급계에서 짝지어 둔다 */
|
||||
setl(b, T_AMT1, h_net);
|
||||
Bchg(b, T_CHANNEL, 0, h_chan, 0L);
|
||||
if (tpcall("PAY_XFERLINK", (char *)b, 0L, (char **)&b, &rlen, 0L) < 0) {
|
||||
userlog("%s: tpcall(PAY_XFERLINK) 실패: %s", SVC, tpstrerror(tperrno));
|
||||
Bchg(b, T_MSG, 0, "지급 이체 연계 실패", 0L); setl(b, T_RC, 261);
|
||||
FAIL(b);
|
||||
}
|
||||
chain_rc = getl(b, T_RC);
|
||||
userlog("%s 체인: PAY_XFERLINK 응답 rc=%ld", SVC, chain_rc);
|
||||
|
||||
/* 하위가 덮어쓴 자기 상태 계약값 복원 */
|
||||
if (keep_status[0] != 0) Bchg(b, T_STATUS, 0, keep_status, 0L);
|
||||
setl(b, T_RC, 0);
|
||||
}
|
||||
|
||||
/* 8) 응답부 */
|
||||
setl(b, T_ID1, h_ledid);
|
||||
setl(b, T_NET, h_net);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue