SNT 가상계좌 발급·입금통지(스튜디오씨에스에/glovic, V1.5 임시계좌) — 내부 전용, 중앙 토큰 인증, relay 경유. 주문당 가상계좌(임시계좌, **1원인증 없음** — 모두페이 전용 발급 스펙): 주문마다 본인인증 데이터+계좌정보+입금 허용금액을 **단일 호출**로 보내 가상계좌를 즉시 발급 → 사용자가 입금 → 입금통지 → 계좌 자동만료(SNT). ★SNT 측 강제(벤더 확정): **입금 허용금액(amount)과 일치하는 입금만 처리**. 입금 완료 시 임시계좌는 SNT 가 자동 만료 — 별도 만료 호출 불필요(미입금 주문 취소 시에만 /api/expire). 계좌 유효시간 = **발급 후 10분**. 발급 시 modooapi 가 고유 핸들 vid 를 만들어 반환 — 플랫폼은 **vid** 로 조회/만료/웹훅을 상관한다. **trackId 는 플랫폼 주문번호**(주문당 1계좌; 멀티 플랫폼: (토큰, trackId) 복합 멱등이라 다른 플랫폼의 같은 trackId 와 충돌 안 함).
## 구조: 주문당 [발급(본인인증+계좌+입금 허용금액, 단일 호출)] → 1회 입금 → 자동만료 (모두페이 전용 스펙, 임시계좌 — 1원인증 없음) **주문당 임시계좌 모델**. 주문마다 가상계좌 1개를 **한 번의 호출로 즉시 발급**(1원 인증 절차 없음) → 지정한 금액이 입금되면 통지 후 계좌 자동만료. 발급 시 **modooapi 가 vid(고유 핸들) 발급** → 플랫폼은 vid 로 조회/만료/웹훅 상관. **trackId 는 플랫폼 주문번호**(멱등 키=(토큰,trackId) 복합 — 다른 플랫폼의 같은 trackId 와 충돌 없음, 멀티 플랫폼 안전). 1) POST /api/issue {trackId(주문번호), custBankCode, custBankAccount, custName, custDob, custSex(M/W), custDomestic(Y/N), mobileNumber, mobileCi, **passKey**, **amount(입금 허용금액, 최소 10,000원)**, mobileComCode?} → **주문 전용 가상계좌 즉시 발급**. **응답 vid 를 주문 레코드에 저장**(이후 조회/만료/웹훅 키). expireDate=계좌 만료일시(발급 후 10분). ★**DI 는 보내지 마세요**(passKey 만 → 서버가 DI=가맹점ID_passKey 합성). ★본인인증 데이터에 없는 정보 처리(확정 정책): **mobileComCode=생략**(서버가 99 자동 적용 — 통신사 미보유 통일; 보유 시 SKT 01·KT 02·LG 03·알뜰 04/05/06). **custSex=본인인증 성별이 빈값이면 국적/성별 코드에서 M/W 로 파생해 전달**(필수). **custDomestic=내외국인 판별값을 Y/N 로 변환**(필수). **passKey=플랫폼이 생성해 전달하는 값(해시 등)** — 항상 동일할 필요 없음(요청마다 달라도 됨). 서버가 가맹점ID_passKey 로 DI 를 합성하며 합성 결과 ≤128자만 지키면 된다. 2) 사용자에게 가상계좌·금액·**남은 시간(10분)** 을 표시하고, **amount 와 정확히 일치하는 금액**을 **만료일시(expireDate) 내에** 입금하도록 안내. ★금액 불일치 입금은 처리되지 않는다(SNT 강제, 벤더 확정). 10분 경과 시 계좌 만료 — 플랫폼 UI 는 남은 시간을 표시하고 만료 시 새 주문번호로 재발급을 안내하라. 3) 입금 발생 → SNT 가 /notify/deposit → 우리가 등록 웹훅(/api/webhook)으로 전달(payload 에 vid 포함). **임시계좌는 입금 시 SNT 가 자동 만료** — 플랫폼이 별도 만료 호출 불필요(우리 상태도 자동 expired). 플랫폼은 GET /api/issues/**:vid** 의 deposits[] 로도 확인 가능. 4) **미입금 주문 취소** 시에만 POST /api/expire {**vid**}(추가 입금 차단). **재발급 제한은 입금 여부로만 판단** — 입금 내역이 있는 주문만 같은 trackId 재사용 불가(새 주문번호), 미입금 주문(발급됨/만료/실패)은 같은 trackId 재요청 시 계좌 교체 발급(vid 유지). 5) **동일인 1계좌 정책(자동, 재발급 판단=CI)**: 같은 사용자(CI 기준)가 발급을 요청하면 — **주문번호가 같든 다르든, 금액이 달라졌든** — 그 사용자의 **미만료(issued) 이전 가상계좌를 서버가 자동 만료한 뒤** 새 계좌를 발급한다(같은 플랫폼 범위). 플랫폼은 이전 주문의 계좌가 만료됨(추가 입금 불가)을 전제로 처리하라 — 이전 주문 상태는 GET /api/issues/:vid 로 확인 가능. ## 성공 판정(중요) - /api/issue 는 SNT 실패 시에도 HTTP 200 success:true 로 응답한다. success:true=‘요청 처리됨’일 뿐. - 실제 성공은 **data.resultCode==='0000' AND issueId 가 non-null** 로 판단. 실패면 사유 확인 후 재시도. - **재발급 — 판단은 CI(동일인)**: 같은 사용자가 재요청하면(주문/금액 달라도) 이전 활성 계좌를 만료하고 새 계좌를 발급. 같은 trackId 재요청은 **입금 내역 없는 주문만** 허용(vid 유지, account·expireDate·amount 갱신). ⚠️ 재요청마다 계좌가 교체되므로 무의미한 중복 호출 금지. 입금 내역 있는 주문·타 사용자(CI) trackId 재사용은 409. 통신오류로 결과 미확정이면 그 건은 잠겨 재발급 차단 → GET /api/issues/:vid 로 상태 확인 후 처리. ## 통지 수신(웹훅 — 플랫폼) 플랫폼이 받을 통지 웹훅을 **POST /api/webhook {url, secret}** 로 등록(토큰당 1개, 변경 즉시 전 계좌 반영). 입금 발생 시 우리가 그 URL 로 application/json POST: { "type":"deposit", "vid":"vid_ab12...", "vact_id":"V...", "issue_id":"VI...", "amount":"50000", "trx_type":"pay|rfd", "trx_day":"yyyyMMdd", "trx_time":"HHmmss", "account":"12345678901"(가상계좌), "bank_code":"034", "trx_sender":"홍*동"(마스킹), "merchant_id":"..." } - 입금자 실계좌(trx_account)·CI/DI 등 PII 는 전송 안 함(마스킹). trx_type rfd=환불. 입금통지 수신 = 해당 주문 입금완료(임시계좌 자동만료). - **헤더**: `X-Snt-Event`(deposit), `X-Snt-Event-Id`(멱등키=vact_id), secret 등록 시 `X-Snt-Timestamp`(epoch ms)·`X-Snt-Signature: sha256=<hex>`. - **서명 검증(secret 등록 시)**: HMAC-SHA256(secret, `X-Snt-Timestamp + "." + 원문 body`) 가 X-Snt-Signature 와 일치 + timestamp 신선도(예: 5분) 확인 → 위조·재전송 차단. (재전달마다 timestamp 를 새로 찍어 재서명하므로 정상 재전달은 신선도 통과. secret 미등록 시 미서명 — 운영은 secret 등록 권장.) - **플랫폼이 구현할 것**: 수신 endpoint(POST, application/json) → 서명 검증 → `X-Snt-Event-Id`(=vact_id) 기준 **1회만 처리(멱등)** → **2xx 응답**. 못 받아도 GET /api/issues/:vid 로 복구. - 통지 전달은 **등록 웹훅(/api/webhook) 한 경로**로 일원화 — 미등록이면 전달 안 함(GET /api/issues/:vid 폴링으로 복구). ## 멱등/무손실 - 발급: **(토큰, trackId=주문번호) 복합**으로 멱등 — 주문당 1계좌, 플랫폼별 분리. 같은 주문 재요청은 기존 vid/계좌 반환. failed 만 재시도 가능, expired 는 새 주문번호로. - 입금통지: **입금 건마다 고유한 vact_id(거래고유번호, 불변)** — 플랫폼은 vact_id 기준으로 정확히 1회 처리(SNT 재전송(3회)·재전달 대비 멱등, at-least-once). - 모든 통지는 우리 측에 영구 기록 후 응답 → 누락 없음. 웹훅 전달 실패는 자동 재전달(cron) + GET /api/issues 폴링으로 복구. ## 보안·로그(중계 API) - 전 구간(플랫폼↔우리, 우리↔SNT, SNT→우리 통지, 우리→플랫폼 전달) **요청/응답을 PII 마스킹 후 D1 에 기록**(소스 IP·토큰·HTTP 상태·결과코드 포함) — 보안/장애 추적용. 콘솔(/console)에서 발급내역·입금내역·정산·로그 **페이징 조회**. - 90일 보관(retention cron). 시크릿(merchant_key)·CI/DI·passKey·고객/입금자 실계좌·생년월일은 로그에 평문 미기록(마스킹). - SNT 호출은 relay 고정 IP(209.71.88.78) 경유(SNT 화이트IP). - **통지 수신**: SNT 통지 발신 IP(112.175.152.245)만 허용(+merchant_id 일치). `POST /notify/deposit`(입금), `POST /notify/settlement`(정산 — 일별 집계+정산금, 지급완료 시). result_code "0000"/HTTP 200 응답 시 재전송 중지(최대 3회). ⚠️ **통지 주소 설정 API 는 없음** — 우리 URL 을 SNT(스튜디오씨에스에)에 사전 등록(입금통지 URL 전달 완료). /notify/issue(발급통지)는 API 발급 사용 시 연동 불필요(수신·기록만). 플랫폼은 SNT 통지를 직접 받지 않고, 등록 웹훅(/api/webhook)으로 우리가 전달한다. - 미설정(가맹점ID·인증키) 시 503. 시각 KST. 연동 키 관리: https://snt.modooapi.com/console. 은행코드: GET /api/banks.
Authorization: Bearer <token>
/help
공개
/help/prompt
공개
/health
공개
/api/issue
🔒 토큰
{ "trackId":"order-1001", "custBankCode":"004", "custBankAccount":"123...", "custName":"홍길동",
"custDob":"19900101", "custSex":"M", "custDomestic":"Y",
"mobileNumber":"01012345678", "mobileCi":"<CI>", "passKey":"<passKey>", "amount":"50000" }
// trackId = 주문번호(주문당 1계좌). DI 는 전달 금지 — 서버가 가맹점ID_passKey 로 자동 생성.
// mobileComCode 는 선택 — 미입력 시 99(통신사 미보유) 자동 적용. 보유 시 SKT 01·KT 02·LG 03·알뜰 04/05/06.
// amount = 입금 허용금액(원, 정수, 최소 10,000) — 일치 입금만 처리됨.{ "success": true, "data": { "vid":"vid_ab12...", "trackId":"order-1001", "issueId":"VI...", "account":"12345678901", "bankCode":"034", "amount":"50000", "expireDate":"yyyyMMddHHmm", "resultCode":"0000" } }
// ★ vid 를 저장해 이후 조회/만료/웹훅 상관에 사용. 발급 실패 예: { ..., "vid":"vid_...", "issueId":null, "account":null, "resultCode":"<에러>" }/api/expire
🔒 토큰
{ "vid":"vid_ab12..." }{ "success": true, "data": { "vid":"vid_ab12...", "trackId":"order-1001", "issueId":"VI...", "resultCode":"0000" } }/api/issues/:vid
🔒 토큰
{ "success": true, "data": {
"vid":"vid_ab12...", "trackId":"order-1001", "status":"expired", "issueId":"VI...", "account":"12345678901", "bankCode":"034",
"amount":"50000", "expireDate":"yyyyMMddHHmm", "resultCd":"0000", "issueNotifiedAt":"...", "createdAt":"...", "expiredAt":"...",
"deposits":[ { "vactId":"V...", "trxType":"pay", "amount":"50000", "trxDay":"yyyyMMdd", "trxTime":"HHmmss",
"sender":"홍*동", "account":"12345678901", "bankCode":"034", "createdAt":"..." } ] } }/api/banks
🔒 토큰
/api/webhook
🔒 토큰
{ "url":"https://platform.example.com/snt/notify", "secret":"<공유 서명키(선택, 권장)>" }{ "success": true, "data": { "url":"https://...", "secretConfigured": true, "active": true } }/api/webhook
🔒 토큰
/notify/issue
공개
/notify/deposit
공개
/notify/settlement
공개
GET https://snt.modooapi.com/help/prompt)# modooapi-workers-snt 연동 가이드 (AI 에이전트용)
너는 modooapi 의 "modooapi-workers-snt" API 를 호출하는 통합 에이전트다. 아래 명세대로 정확히 요청을 구성하라.
- Base URL: https://snt.modooapi.com
- 인증: modooapi.com/console 에서 발급한 중앙 액세스 토큰을 모든 /api/* 요청에 `Authorization: Bearer <token>` 헤더로 전송한다.
- 공통 응답: 성공 { "success": true, "data": ... }, 실패 { "success": false, "error": "<메시지>" }.
- 개요: 주문당 가상계좌(임시계좌, **1원인증 없음** — 모두페이 전용 발급 스펙): 주문마다 본인인증 데이터+계좌정보+입금 허용금액을 **단일 호출**로 보내 가상계좌를 즉시 발급 → 사용자가 입금 → 입금통지 → 계좌 자동만료(SNT). ★SNT 측 강제(벤더 확정): **입금 허용금액(amount)과 일치하는 입금만 처리**. 입금 완료 시 임시계좌는 SNT 가 자동 만료 — 별도 만료 호출 불필요(미입금 주문 취소 시에만 /api/expire). 계좌 유효시간 = **발급 후 10분**. 발급 시 modooapi 가 고유 핸들 vid 를 만들어 반환 — 플랫폼은 **vid** 로 조회/만료/웹훅을 상관한다. **trackId 는 플랫폼 주문번호**(주문당 1계좌; 멀티 플랫폼: (토큰, trackId) 복합 멱등이라 다른 플랫폼의 같은 trackId 와 충돌 안 함).
## 연동 가이드
## 구조: 주문당 [발급(본인인증+계좌+입금 허용금액, 단일 호출)] → 1회 입금 → 자동만료 (모두페이 전용 스펙, 임시계좌 — 1원인증 없음)
**주문당 임시계좌 모델**. 주문마다 가상계좌 1개를 **한 번의 호출로 즉시 발급**(1원 인증 절차 없음) → 지정한 금액이 입금되면 통지 후 계좌 자동만료. 발급 시 **modooapi 가 vid(고유 핸들) 발급** → 플랫폼은 vid 로 조회/만료/웹훅 상관. **trackId 는 플랫폼 주문번호**(멱등 키=(토큰,trackId) 복합 — 다른 플랫폼의 같은 trackId 와 충돌 없음, 멀티 플랫폼 안전).
1) POST /api/issue {trackId(주문번호), custBankCode, custBankAccount, custName, custDob, custSex(M/W), custDomestic(Y/N), mobileNumber, mobileCi, **passKey**, **amount(입금 허용금액, 최소 10,000원)**, mobileComCode?} → **주문 전용 가상계좌 즉시 발급**. **응답 vid 를 주문 레코드에 저장**(이후 조회/만료/웹훅 키). expireDate=계좌 만료일시(발급 후 10분).
★**DI 는 보내지 마세요**(passKey 만 → 서버가 DI=가맹점ID_passKey 합성).
★본인인증 데이터에 없는 정보 처리(확정 정책): **mobileComCode=생략**(서버가 99 자동 적용 — 통신사 미보유 통일; 보유 시 SKT 01·KT 02·LG 03·알뜰 04/05/06). **custSex=본인인증 성별이 빈값이면 국적/성별 코드에서 M/W 로 파생해 전달**(필수). **custDomestic=내외국인 판별값을 Y/N 로 변환**(필수). **passKey=플랫폼이 생성해 전달하는 값(해시 등)** — 항상 동일할 필요 없음(요청마다 달라도 됨). 서버가 가맹점ID_passKey 로 DI 를 합성하며 합성 결과 ≤128자만 지키면 된다.
2) 사용자에게 가상계좌·금액·**남은 시간(10분)** 을 표시하고, **amount 와 정확히 일치하는 금액**을 **만료일시(expireDate) 내에** 입금하도록 안내. ★금액 불일치 입금은 처리되지 않는다(SNT 강제, 벤더 확정). 10분 경과 시 계좌 만료 — 플랫폼 UI 는 남은 시간을 표시하고 만료 시 새 주문번호로 재발급을 안내하라.
3) 입금 발생 → SNT 가 /notify/deposit → 우리가 등록 웹훅(/api/webhook)으로 전달(payload 에 vid 포함). **임시계좌는 입금 시 SNT 가 자동 만료** — 플랫폼이 별도 만료 호출 불필요(우리 상태도 자동 expired). 플랫폼은 GET /api/issues/**:vid** 의 deposits[] 로도 확인 가능.
4) **미입금 주문 취소** 시에만 POST /api/expire {**vid**}(추가 입금 차단). **재발급 제한은 입금 여부로만 판단** — 입금 내역이 있는 주문만 같은 trackId 재사용 불가(새 주문번호), 미입금 주문(발급됨/만료/실패)은 같은 trackId 재요청 시 계좌 교체 발급(vid 유지).
5) **동일인 1계좌 정책(자동, 재발급 판단=CI)**: 같은 사용자(CI 기준)가 발급을 요청하면 — **주문번호가 같든 다르든, 금액이 달라졌든** — 그 사용자의 **미만료(issued) 이전 가상계좌를 서버가 자동 만료한 뒤** 새 계좌를 발급한다(같은 플랫폼 범위). 플랫폼은 이전 주문의 계좌가 만료됨(추가 입금 불가)을 전제로 처리하라 — 이전 주문 상태는 GET /api/issues/:vid 로 확인 가능.
## 성공 판정(중요)
- /api/issue 는 SNT 실패 시에도 HTTP 200 success:true 로 응답한다. success:true=‘요청 처리됨’일 뿐.
- 실제 성공은 **data.resultCode==='0000' AND issueId 가 non-null** 로 판단. 실패면 사유 확인 후 재시도.
- **재발급 — 판단은 CI(동일인)**: 같은 사용자가 재요청하면(주문/금액 달라도) 이전 활성 계좌를 만료하고 새 계좌를 발급. 같은 trackId 재요청은 **입금 내역 없는 주문만** 허용(vid 유지, account·expireDate·amount 갱신). ⚠️ 재요청마다 계좌가 교체되므로 무의미한 중복 호출 금지. 입금 내역 있는 주문·타 사용자(CI) trackId 재사용은 409. 통신오류로 결과 미확정이면 그 건은 잠겨 재발급 차단 → GET /api/issues/:vid 로 상태 확인 후 처리.
## 통지 수신(웹훅 — 플랫폼)
플랫폼이 받을 통지 웹훅을 **POST /api/webhook {url, secret}** 로 등록(토큰당 1개, 변경 즉시 전 계좌 반영). 입금 발생 시 우리가 그 URL 로 application/json POST:
{ "type":"deposit", "vid":"vid_ab12...", "vact_id":"V...", "issue_id":"VI...", "amount":"50000", "trx_type":"pay|rfd",
"trx_day":"yyyyMMdd", "trx_time":"HHmmss", "account":"12345678901"(가상계좌), "bank_code":"034",
"trx_sender":"홍*동"(마스킹), "merchant_id":"..." }
- 입금자 실계좌(trx_account)·CI/DI 등 PII 는 전송 안 함(마스킹). trx_type rfd=환불. 입금통지 수신 = 해당 주문 입금완료(임시계좌 자동만료).
- **헤더**: `X-Snt-Event`(deposit), `X-Snt-Event-Id`(멱등키=vact_id), secret 등록 시 `X-Snt-Timestamp`(epoch ms)·`X-Snt-Signature: sha256=<hex>`.
- **서명 검증(secret 등록 시)**: HMAC-SHA256(secret, `X-Snt-Timestamp + "." + 원문 body`) 가 X-Snt-Signature 와 일치 + timestamp 신선도(예: 5분) 확인 → 위조·재전송 차단. (재전달마다 timestamp 를 새로 찍어 재서명하므로 정상 재전달은 신선도 통과. secret 미등록 시 미서명 — 운영은 secret 등록 권장.)
- **플랫폼이 구현할 것**: 수신 endpoint(POST, application/json) → 서명 검증 → `X-Snt-Event-Id`(=vact_id) 기준 **1회만 처리(멱등)** → **2xx 응답**. 못 받아도 GET /api/issues/:vid 로 복구.
- 통지 전달은 **등록 웹훅(/api/webhook) 한 경로**로 일원화 — 미등록이면 전달 안 함(GET /api/issues/:vid 폴링으로 복구).
## 멱등/무손실
- 발급: **(토큰, trackId=주문번호) 복합**으로 멱등 — 주문당 1계좌, 플랫폼별 분리. 같은 주문 재요청은 기존 vid/계좌 반환. failed 만 재시도 가능, expired 는 새 주문번호로.
- 입금통지: **입금 건마다 고유한 vact_id(거래고유번호, 불변)** — 플랫폼은 vact_id 기준으로 정확히 1회 처리(SNT 재전송(3회)·재전달 대비 멱등, at-least-once).
- 모든 통지는 우리 측에 영구 기록 후 응답 → 누락 없음. 웹훅 전달 실패는 자동 재전달(cron) + GET /api/issues 폴링으로 복구.
## 보안·로그(중계 API)
- 전 구간(플랫폼↔우리, 우리↔SNT, SNT→우리 통지, 우리→플랫폼 전달) **요청/응답을 PII 마스킹 후 D1 에 기록**(소스 IP·토큰·HTTP 상태·결과코드 포함) — 보안/장애 추적용. 콘솔(/console)에서 발급내역·입금내역·정산·로그 **페이징 조회**.
- 90일 보관(retention cron). 시크릿(merchant_key)·CI/DI·passKey·고객/입금자 실계좌·생년월일은 로그에 평문 미기록(마스킹).
- SNT 호출은 relay 고정 IP(209.71.88.78) 경유(SNT 화이트IP).
- **통지 수신**: SNT 통지 발신 IP(112.175.152.245)만 허용(+merchant_id 일치). `POST /notify/deposit`(입금), `POST /notify/settlement`(정산 — 일별 집계+정산금, 지급완료 시). result_code "0000"/HTTP 200 응답 시 재전송 중지(최대 3회). ⚠️ **통지 주소 설정 API 는 없음** — 우리 URL 을 SNT(스튜디오씨에스에)에 사전 등록(입금통지 URL 전달 완료). /notify/issue(발급통지)는 API 발급 사용 시 연동 불필요(수신·기록만). 플랫폼은 SNT 통지를 직접 받지 않고, 등록 웹훅(/api/webhook)으로 우리가 전달한다.
- 미설정(가맹점ID·인증키) 시 503. 시각 KST. 연동 키 관리: https://snt.modooapi.com/console. 은행코드: GET /api/banks.
## 엔드포인트
### POST https://snt.modooapi.com/api/issue [🔒 토큰]
가상계좌 발급(주문당, 단일 호출 — 1원인증 없음) — amount(입금 허용금액, 최소 10,000원) 필수 — 본인인증 데이터(실명·생년월일·성별·내외국인·휴대폰·CI) + 사용자 계좌(은행·계좌번호) + **amount(입금 허용금액, 필수 — 최소 10,000원, 1만원 미만 결제 불가)** 를 한 번에 전달해 **주문 전용 가상계좌(임시계좌)** 를 즉시 발급한다(1원인증 절차 없음). ★DI 는 보내지 않는다 — 플랫폼은 passKey 만 전달하고, 서버가 DI=가맹점ID_passKey 로 합성해 SNT 에 전송(가맹점ID 미노출). SNT 는 **amount 와 일치하는 입금만** 처리한다(벤더 확정). ★응답의 **vid 가 modooapi 핸들** — 이후 조회/만료/웹훅은 vid 로. expireDate=계좌 만료일시(yyyyMMddHHmm, **발급시간 기준 10분** — 사용자는 10분 내 입금). 멱등 키는 **(토큰, trackId=주문번호) 복합**. ★**동일인 1계좌 정책**: 같은 CI 의 미만료(issued) 이전 가상계좌가 있으면 **자동 만료 후 발급**(같은 플랫폼 범위; CI 는 해시로만 매칭·미보관). ★성공 판정: data.resultCode==='0000' AND issueId 비-null. ★**재발급 — 판단은 CI(동일인) 기준**: 같은 사용자가 다시 발급을 요청하면 **주문번호·금액이 달라도** 이전 활성 계좌를 자동 만료하고 새 계좌를 발급한다. 같은 trackId 재요청도 가능 — **입금 내역이 없는 주문만**(이전 계좌 만료 후 vid 유지, account·expireDate·amount 갱신). **입금 내역이 있는 주문은 409 — 새 주문번호 사용**. 다른 사용자(CI)가 쓰던 trackId 재사용은 409. 통신오류 미확정 시 잠금 → GET /api/issues/:vid 로 확인.
요청:
{ "trackId":"order-1001", "custBankCode":"004", "custBankAccount":"123...", "custName":"홍길동",
"custDob":"19900101", "custSex":"M", "custDomestic":"Y",
"mobileNumber":"01012345678", "mobileCi":"<CI>", "passKey":"<passKey>", "amount":"50000" }
// trackId = 주문번호(주문당 1계좌). DI 는 전달 금지 — 서버가 가맹점ID_passKey 로 자동 생성.
// mobileComCode 는 선택 — 미입력 시 99(통신사 미보유) 자동 적용. 보유 시 SKT 01·KT 02·LG 03·알뜰 04/05/06.
// amount = 입금 허용금액(원, 정수, 최소 10,000) — 일치 입금만 처리됨.
응답:
{ "success": true, "data": { "vid":"vid_ab12...", "trackId":"order-1001", "issueId":"VI...", "account":"12345678901", "bankCode":"034", "amount":"50000", "expireDate":"yyyyMMddHHmm", "resultCode":"0000" } }
// ★ vid 를 저장해 이후 조회/만료/웹훅 상관에 사용. 발급 실패 예: { ..., "vid":"vid_...", "issueId":null, "account":null, "resultCode":"<에러>" }
### POST https://snt.modooapi.com/api/expire [🔒 토큰]
가상계좌 만료(미입금 주문 취소 시) — vid 기준 — 주문의 가상계좌를 vid 로 만료(사용 정지)한다. **입금 완료 시엔 SNT 가 자동 만료하므로 호출 불필요** — 미입금 상태의 주문 취소 시에만 사용. resultCode '0000' 까지 재시도(멱등). **이미 만료된 계좌(10분 시간만료 포함)에 대한 만료 요청도 0000 으로 응답**(상태 동기화 — 0000 수신 시 재시도 중단).
요청:
{ "vid":"vid_ab12..." }
응답:
{ "success": true, "data": { "vid":"vid_ab12...", "trackId":"order-1001", "issueId":"VI...", "resultCode":"0000" } }
### GET https://snt.modooapi.com/api/issues/:vid [🔒 토큰]
발급/입금 상태 조회(vid 기준) — 통지 누락 폴백 폴링 — vid(발급 응답의 modooapi 핸들)로 조회. status: issuing·issued·failed·expired(입금완료 자동만료 포함). deposits[]=그 계좌의 입금내역(통지 못 받아도 여기서 확인). 없거나 타 토큰 vid 는 404.
응답:
{ "success": true, "data": {
"vid":"vid_ab12...", "trackId":"order-1001", "status":"expired", "issueId":"VI...", "account":"12345678901", "bankCode":"034",
"amount":"50000", "expireDate":"yyyyMMddHHmm", "resultCd":"0000", "issueNotifiedAt":"...", "createdAt":"...", "expiredAt":"...",
"deposits":[ { "vactId":"V...", "trxType":"pay", "amount":"50000", "trxDay":"yyyyMMdd", "trxTime":"HHmmss",
"sender":"홍*동", "account":"12345678901", "bankCode":"034", "createdAt":"..." } ] } }
### GET https://snt.modooapi.com/api/banks [🔒 토큰]
은행코드 목록
### POST https://snt.modooapi.com/api/webhook [🔒 토큰]
통지 웹훅 등록/변경(플랫폼당 1회) — 플랫폼이 발급/입금 통지를 받을 웹훅 URL(https)과 서명키(secret)를 등록/변경한다. 토큰당 1개(중앙토큰=플랫폼 식별). 등록 후 그 플랫폼의 모든 계좌 통지를 이 URL 로 전달(URL 변경이 전 계좌 즉시 반영). 통지 전달은 이 등록 웹훅으로 일원화(per-issue callback 없음). secret 설정 시 전달 요청에 HMAC-SHA256 서명 헤더(X-Snt-Signature: sha256=..., X-Snt-Timestamp) 부착 → 플랫폼이 위조 통지 차단. secret 빈칸이면 기존 유지(write-only).
요청:
{ "url":"https://platform.example.com/snt/notify", "secret":"<공유 서명키(선택, 권장)>" }
응답:
{ "success": true, "data": { "url":"https://...", "secretConfigured": true, "active": true } }
### GET https://snt.modooapi.com/api/webhook [🔒 토큰]
등록된 통지 웹훅 조회(url·서명키 설정여부)
### POST https://snt.modooapi.com/notify/issue [공개]
계좌 발급 통지(SNT→우리, webhook) — API 발급 사용 시 연동 불필요 — SNT 가 계좌 발급 시 전송(API 발급 미사용 업체용 — 벤더 확인). 우리는 수신·기록만 하고 0000 응답(플랫폼 전달 없음, 발급 정보는 /api/issue 응답으로 수령). 재전송 최대 3회.
### POST https://snt.modooapi.com/notify/deposit [공개]
입금 통지(SNT→우리, webhook) — 가상계좌 입금 발생 시 전송(vact_id 멱등). 임시계좌는 입금 시 SNT 자동만료 → 우리 상태도 expired 로 갱신 후 등록 웹훅으로 플랫폼 전달. result_code 0000/200 응답 시 재전송 중지(최대 3회).
### POST https://snt.modooapi.com/notify/settlement [공개]
정산 통지(SNT→우리, webhook) — 일별 정산금 지급완료 시 전송(일별 집계+정산금, stl_id 멱등 — 벤더 확인). 저장 후 콘솔 '정산' 에서 조회(merchant 단위 집계라 플랫폼 전달 없음). result_code 0000/200 응답 시 재전송 중지(최대 3회).
## 규칙
- 금액은 정수(원). 날짜/시각은 명세 포맷을 따른다.
- 토큰이 없거나 무효면 401. 권한/IP 오류는 403. 입력 오류는 400.
- 실패 시 error 메시지와 (있으면) resCode 를 사용자에게 그대로 전달하라.