잔가조회 → 렌탈료계산 2단계 호출을 캡슐화한 GNA 상위 래퍼 API
GNA 견적 화면이 매칭된 하나코드 + 차량금액만 넘기면, 오케스트레이터가 하나 릴레이를
dvCd=1(잔가조회) → dvCd=2(렌탈료계산) 순으로 호출하고 GNA 최종 산출값을 반환한다.
| 항목 | 값 |
|---|---|
| 오케스트레이터 기본 URL | http://localhost:8080 |
| 요청 방식 | HTTP POST · Content-Type: application/json |
| 하위 릴레이 | http://localhost:11080/inbound (하나캐피탈 설치·운영) |
| 인증 | ccoCustNo / ccoCustSno (하나캐피탈 발급) — 서버가 자동 첨부 |
POST/api/v1/vehicle-finance/quote
잔가 + 렌탈료를 한 번에. 2단계 호출을 서버가 자동 수행한다.
| 필드 | 구분 | 설명 |
|---|---|---|
vehicle.braNo | 동적 | 브랜드코드 (매칭값 apiHanaBrand) · 필수 |
vehicle.mdlNo | 동적 | 모델코드 (apiHanaModel) · 필수 |
vehicle.linupNo | 동적 | 라인업코드 (apiHanaLineup) · 필수 |
vehicle.trimNo | 동적 | 트림코드 (apiHanaTrim) · 필수 |
contract.puryCarAmt | 동적 | 차량금액 + 옵션금액 · 필수 |
contract.cntrPrid | 동적 | 계약기간(개월) 12/24/36/48/60 · 필수 |
contract.prrpAmt | 동적 | 선납금 (기본 0) |
contract.drvrAgeDvCd | 동적 | 운전자연령 02:만21↑ 04:만26↑ (기본 04) |
options.* | 고정 | 상품·보장·부대 고정값 오버라이드(선택). 미지정 시 서버 기본값(필요값 §4) |
curl -sS -X POST \
'http://localhost:8080/api/v1/vehicle-finance/quote' \
-H 'Content-Type: application/json' \
-d '{
"vehicle": {"braNo":"111","mdlNo":"11609",
"linupNo":"115311","trimNo":"1049401"},
"contract": {"puryCarAmt":34000000,"cntrPrid":36,
"prrpAmt":0,"drvrAgeDvCd":"04"},
"options": {"reprPrdtCd":"1","custDvCd":"1",
"agrTrvgDstnCd":"20000"}
}'
{
"status": "OK",
"priceResidualRto": 61.5,
"priceResidual": 20910000,
"priceMonth": 1174910,
"rentalFeeInfo": {
"rlpnRtfe":"1174910","carRtfe":"986700",
"addRtfe":"81400","spprcAmt":"1068100",
"srtxAmt":"106810","acqCamtAmt":"31679602",
"irrPer":"5.8","jnIscoNm":"디비손해보험주식회사"
},
"residualDistanceSeg": "00000",
"resInfo": {"rspnsCd":"PS000001",
"rspnsMsg":"정상처리 되었습니다."}
}
| 필드 | 출처 | 산출 |
|---|---|---|
priceResidualRto | 1단계 | 잔가율(%) — 예 61.5 |
priceResidual | 1단계 | 적용잔가금액 = 차량금액 × 잔가율% — 예 20,910,000 |
priceMonth | 2단계 | 월 렌탈료 = rentalFeeInfo.rlpnRtfe — 예 1,174,910 |
| HTTP | status | 의미 |
|---|---|---|
| 200 | OK | 정상 견적 |
| 400 | ERROR | 필수값 누락 / 요청 JSON 파싱 실패 (missing 배열 포함) |
| 422 | RESTRICTED | 취급제한(업무거절, rspnsCd=PS000100) — 예: LPi·수동트림 |
| 502 | ERROR | 릴레이 접속 실패 / 연계 오류(Z***·1xxx~2xxx) |
POST/api/v1/vehicle-finance/residual
잔가율(%)과 적용잔가금액만 필요할 때. 요청 본문은 /quote와 동일.
응답에 priceResidualRto, priceResidual, 파싱된 mxRevalRtoCtnt 맵을 반환한다.
오케스트레이터가 내부적으로 주고받는 하나 릴레이 전문 구조. 직접 호출 시 참고.
{
"Header":{"serviceID":"UCARI00013","version":"1.0"},
"Message":{
"reqInfo":{"ccoCustNo":"6502189659",
"ccoCustSno":"0","prdtCd":"0","dvCd":"1"},
"info":{"braNo":"111","mdlNo":"11609",
"linupNo":"115311","trimNo":"1049401",
"puryCarAmt":"34000000","cntrPrid":"36",
"prrpAmt":"0","drvrAgeDvCd":"04",
"reprPrdtCd":"1","agrTrvgDstnCd":"20000",
"custDvCd":"1", ... 고정 파라미터 전체 ...}
}}
{
"Header":{"serviceID":"UCARI00013","version":"1.0"},
"Message":{
"reqInfo":{... "dvCd":"2"},
"info":{... 1단계와 동일 +
"rcstPer":"61.5", // 1단계 잔가율
"aplRcstAmt":"20910000"} // 차량금액×잔가율%
}}
Header.code(연계 결과, Z000=정상) + errorDesc,
Message.resInfo.rspnsCd(업무 결과, PS000001=정상) + rspnsMsgCtnt를 공통 포함.
성공 시 mxRvInfo(잔가) 또는 rentalFeeInfo(렌탈료)가 추가된다.
mxRevalRtoCtnt는 {계약기간={약정주행거리구간=잔가율, ...}, ...} 형태의 Java Map 문자열.
1차 키=계약기간(개월), 2차 키=주행거리구간(00000=기본), 값=최대 잔가율(%).
"mxRevalRtoCtnt":
"{12={00000=68.5, ...}, 36={00000=61.5, 15000=67.5,
20000=66.0, 25000=62.0, 30000=60.0, 50000=55.0}, 60={...}}"
→ 잔가율 = mxRevalRtoCtnt["36"]["00000"] = 61.5 (36개월/기본구간)
00000 사용(가이드 worked example). 약정주행거리
agrTrvgDstnCd 구간을 잔가 선택에 반영할지는 하나캐피탈과 확정.
현재 구현 기본값 00000, options.residualDstnCd로 변경 가능.
| 필드 | 의미 | 값(실측 예) |
|---|---|---|
rlpnRtfe | 월 렌탈료(실 납입금) ← GNA priceMonth | 1,174,910 |
evtmPyinAmt | 매월 납입금액(=rlpnRtfe) | 1,174,910 |
carRtfe | 차량 렌탈료(공급가 중 차량분) | 986,700 |
addRtfe | 부가 렌탈료(정비·보험 등) | 81,400 |
spprcAmt | 공급가액 (carRtfe + addRtfe) | 1,068,100 |
srtxAmt | 부가세액 (공급가액의 10%) | 106,810 |
prrpRtfe | 선납 렌탈료(선납금 반영분) | 0 |
acqCamtAmt | 취득원가금액 (차량 취득가 기준) | 31,679,602 |
irrPer | 내부수익률(IRR, %) | 5.8 |
fnnInerErnRto2 | 금융 내부수익률 | 5.8063 |
rmbrAplInrt | 적용 이율(%) | 7.5871 |
jnIscoNm | 가입 보험사명 | 디비손해보험 |
※ 금액은 실테스트(쏘나타 디 엣지 가솔린 1.6터보, 3,400만원/36개월/기본구간) 결과. 실제 값은 차량·조건·시점에 따라 달라진다.
코드는 4자리(또는 접두문자+숫자). 0000 / Z000 / 1200 / H000 / F000 = 정상. 그 외는 오류.
| 코드 | 내용 |
|---|---|
| Z999 | 정의되지 않은 에러 |
| ZA01 | 인증과정 중 오류(토큰 미수신) |
| ZI01 | 입력 데이터 오류(필수정보/파일 없음) |
| ZI02~04 | OpenAPI 접속/수신/데이터 오류 |
| ZI05 / ZI99 | Inbound 암호화 / 송신 전 오류 |
| Z001~003 | 입력/제휴사 접속·수신 오류 |
| Z005 / Z006 | Outbound 암호화 / 복호화 오류 |
| 코드 | 내용 |
|---|---|
| H000 | 정상 |
| H001 | 필수 입력값 처리 확인 불가 |
| H998 / H999 | 기타 / 기타 시스템 에러 |
| 코드 | 내용 |
|---|---|
| 1200 | 정상 |
| 1300 / 1301 / 1302 | Body 없음 / ENTR_CD null / 토큰 없음 |
| 1400~1404 | 잘못된 요청 / 인증·권한 / 서비스 없음 |
| 1700~1704 | 엑세스 불가(Client ID·URI·IP·ENTR_CD) |
| 1711 / 1712 | 거래제한 요일 / 시간 |
| 1714 / 1716 | 오늘 이용불가 / 공휴일 거래제한 |
| 1717 / 1800 | SQL인젝션 검증 실패 / 잘못된 토큰 |
| 1900 | 초과된 연결 횟수 |
| 2500 / 2510 / 2530 | 맵핑정보 없음 / 요청맵핑 없음 / 응답전문 오류 |
| 2600 / 2700 / 2701 | 내부 / 외부 시스템 오류 / 타임아웃 |
PS000001=정상처리, PS000100=취급제한(업무거절).
FileWAS(F***)는 파일 송수신용으로 잔가/렌탈료 조회와 무관(참고).
| 파일 | 내용 |
|---|---|
| plan.md | 연동 플랜 / 분석 |
| required-values.md | 필요한 값 전체 정리 |
| openapi.yaml | OpenAPI 3.0 스펙 |
api/app.py | 오케스트레이터 API 서버 |
api/hana_relay.py | 릴레이 클라이언트 + 잔가맵 파서 |
api/config.py | 엔드포인트·인증·고정값·에러코드표 |
api/mock_relay.py · test_quote.py · run_demo.sh | 로컬 테스트 도구 |