# 한화생명

한화생명 API 가이드 문서

- 보험코어
- 디지털 데스크
- 융자

# 제공 서비스 리스트

한화생명 전용 API는 다음과 같은 서비스를 제공합니다.

| 서비스 그룹 | 서비스명 | API명 (`service`) | 대상 모듈 | 비고 |
| :--- | :--- | :--- | :--- | :--- |
| **핀패드 상태/설정 조회** | 핀패드 초기화 | `TSP90.Init` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 포트 오픈 및 하드웨어 초기화 |
| | 버전 정보 조회 | `TSP90.GetVersion` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 펌웨어/DLL 버전 획득 |
| | 스피커 볼륨 조회 | `TSP90.GetVolume` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 1~10 |
| | 버튼 볼륨 조회 | `TSP90.GetButtonVolume` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 1~10 |
| | 밝기 조회 | `TSP90.GetBright` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 1~10 |
| | 폰트 조회 | `TSP90.GetFont` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 설정된 폰트명 반환 |
| **핀패드 하드웨어 설정** | 스피커 볼륨 설정 | `TSP90.SetVolume` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 1~10 |
| | 버튼 볼륨 설정 | `TSP90.SetButtonVolume` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 1~10 |
| | 밝기 설정 | `TSP90.SetBright` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 1~10 |
| | 폰트 설정 | `TSP90.SetFont` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 굴림체 / 엽서체 |
| | 대기화면 설정 | `TSP90.SetWindow` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 대기 이미지/비디오 인덱스 지정 |
| **핀패드 보안 입력** | 비밀번호 입력 | `TSP90.Read` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 비밀번호(최대 4자리) 입력 |
| | 주민등록번호 입력 | `TSP90.SSNRead` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 주민번호(최대 13자리) 입력 |
| | 다이얼로그 입력 | `TSP90.ReadProcess` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 화면 다이얼로그 문구 노출 모드 |
| | 비다이얼로그 입력 | `TSP90.ReadNDProcess` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 다이얼로그 없는 입력 모드 |
| | 자동 확인/종료 | `TSP90.PINAutoConfirmed`| `TSP90Wrapper.dll`(1.0.3.3 이상) | 최소 입력 충족 시 즉시 반환 |
| | 입력 프로세스 강제종료 | `TSP90.Off` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 진행 중인 입력 즉시 취소 |
| **핀패드 디스플레이 출력** | 미디어 출력 | `TSP90.MediaOut` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 이미지/텍스트/음성 동합 출력 |
| | 핀패드 폼(그리드) 출력 | `TSP90.PinpadFormOut` | `TSP90Wrapper.dll`(1.0.3.3 이상) | 테이블 형태 Grid 데이터 출력 |
| **한화생명 MCI 통신** | MCI 서버 TCP 연결 | `mcipush.Connect` | `tcpsvc.dll` (1.0.3.2 이상) | TCP 연결 및 serviceId 발급 |
| | 종료 메시지 등록 | `mcipush.SaveDisposeMessage` | `tcpsvc.dll` (1.0.3.2 이상) | 세션 해제 시 자동 송신 메시지 |
| | MCI 서버 연결 해제 | `mcipush.Disconnect` | `tcpsvc.dll` (1.0.3.2 이상) | TCP 소켓 세션 Close |
| | 메시지 전송 | `mcipush.SendMessage` | `tcpsvc.dll` (1.0.3.2 이상) | 서버로 전문 송신 |
| | MCI Push 메시지 수신 | `mcipush.Listener` | `tcpsvc.dll` (1.0.3.2 이상) | 서버 Push 비동기 리스너 |

# TSP90 핀패드 제어 서비스

SP90 핀패드 단말기를 제어하기 위한 API 그룹입니다.

## 서비스 리스트

| No. | 서비스명 | API명 | 비고 |
| :---: | :--- | :--- | :--- |
| 1 | 핀패드 초기화 | `TSP90.Init` | 포트 오픈 및 하드웨어 초기화 |
| 2 | 버전 정보 조회 | `TSP90.GetVersion` | 펌웨어/DLL 버전 획득 |
| 3 | 스피커 볼륨 조회 | `TSP90.GetVolume` | 1~10 |
| 4 | 버튼 볼륨 조회 | `TSP90.GetButtonVolume` | 1~10 |
| 5 | 밝기 조회 | `TSP90.GetBright` | 1~10 |
| 6 | 폰트 조회 | `TSP90.GetFont` | 설정된 폰트명 반환 |
| 7 | 스피커 볼륨 설정 | `TSP90.SetVolume` | 1~10 |
| 8 | 버튼 볼륨 설정 | `TSP90.SetButtonVolume` | 1~10 |
| 9 | 밝기 설정 | `TSP90.SetBright` | 1~10 |
| 10 | 폰트 설정 | `TSP90.SetFont` | 굴림체 / 엽서체 |
| 11 | 대기화면 설정 | `TSP90.SetWindow` | 대기 이미지/비디오 인덱스 지정 |
| 12 | 비밀번호 입력 | `TSP90.Read` | 비밀번호(최대 4자리) 입력 |
| 13 | 주민등록번호 입력 | `TSP90.SSNRead` | 주민번호(최대 13자리) 입력 |
| 14 | 다이얼로그 입력 | `TSP90.ReadProcess` | 화면 다이얼로그 문구 노출 모드 |
| 15 | 비다이얼로그 입력 | `TSP90.ReadNDProcess` | 다이얼로그 없는 입력 모드 |
| 16 | 자동 확인 | `TSP90.PINAutoConfirmed` | 최소 입력 충족 시 즉시 반환 |
| 17 | 입력 프로세스 강제종료 | `TSP90.Off` | 진행 중인 입력 즉시 취소 |
| 18 | 미디어 출력 | `TSP90.MediaOut` | 이미지/텍스트/음성 통합 출력 |
| 19 | 핀패드 폼(그리드) 출력 | `TSP90.PinpadFormOut` | 테이블 형태 Grid 데이터 출력 |

## 서비스 상태 코드 리스트

 본 서비스에서 공통으로 사용되는 서비스 상태코드 리스트입니다. 응답 JSON 메시지 중 `return` 또는 `return.returnValue` 값에 해당합니다.

| 리턴코드 | 내용 | 상세 설명 |
| :---: | :--- | :--- |
| **0** | 성공 | 정상적으로 서비스를 호출했습니다. |
| **-1** | 정의되지 않은 예외 | 로그 파일 확인이 필요합니다. |
| **1** | Fail(0) 리턴 | 핀패드 제어 DLL Method 호출 결과 Fail(0)이 리턴되었습니다. |
| **2** | PINOn Fail | `PINOn()` 호출 결과 Fail(0)이 리턴되었습니다. |
| **3** | PINStart Fail | `PINStart()` 호출 결과 Fail(0)이 리턴되었습니다. |
| **4** | PINRead Fail | `PINRead()` 호출 결과 Fail(0)이 리턴되었습니다. |
| **5** | PINStartSSN Fail | `PINStartSSN()` 호출 결과 Fail(0)이 리턴되었습니다. |
| **6** | 이미지 파일 부재 | `SetDefaultWindow()`에서 핀패드에 지정된 인덱스의 이미지 파일이 존재하지 않음(-1)이 리턴되었습니다. |
| **7** | 하드웨어 에러 | `SetDefaultWindow()`에서 하드웨어 에러(0)가 리턴되었습니다. |
| **8** | 지원 범위 초과 파라미터 | 지원 범위를 벗어난 파라미터가 입력되었습니다. |
| **9** | 유효하지 않은 파라미터 | 유효하지 않은 파라미터가 입력되었습니다. |
| **10** | 사용자 취소 | `ReadProcess()` 진행 중 사용자가 취소 버튼을 클릭했습니다. |
| **11** | 유효하지 않은 데이터 | 핀패드에서 전달받은 데이터가 유효하지 않은 데이터입니다. |
| **12** | 데이터 변환 실패 | 핀패드에서 전달받은 데이터를 변환하지 못했습니다. |
| **13** | 폰트 데이터 변환 실패 | 파라미터로 전달받은 폰트 데이터 변환에 실패했습니다. |
| **14** | 다이얼로그 데이터 변환 실패 | 파라미터로 전달받은 다이얼로그 메시지 데이터 변환에 실패했습니다. |
| **15** | 이미지 리스트 변환 실패 | 파라미터로 전달받은 이미지 리스트 Array의 데이터 변환에 실패했습니다. |
| **16** | 데이터 추출 실패 | 핀패드에서 전달받은 비밀번호/주민번호 데이터 추출에 실패했습니다. |
| **17** | 작업 중복 | 이미 다른 입력 작업이 수행 중입니다. |
| **18** | 취소/타임아웃 발생 | 핀패드 Read 중 사용자에 의한 취소 또는 타임아웃에 의한 취소가 발생했습니다. |
| **19** | Off 불가 상태 | Off로 종료할 수 없는 입력 프로세스가 진행 중입니다. |
| **101~121** | Invoke 에러 | 핀패드 DLL 내부 메서드 호출 중 예외가 발생했습니다. (101: `PINInit`, 102: `GetPinpadVersion`, 103: `SetDefaultWindow`, 104: `GetVolume`, 105: `SetVolume`, 106: `GetBright`, 107: `SetBright`, 108: `GetFont`, 109: `SetFont`, 110: `PINOn`, 111: `PINStart`, 112: `PINRead`, 113: `PINOff`, 114: `PINStartSSN`, 115: `PINReadProcess`, 116: `PINReadProcessND`, 117: `PINAutoConfirmed`, 118: `MediaOut`, 119: `PinpadFormOut`, 120: `GetButtonVolume`, 121: `SetButtonVolume`) |

---

## 1. 핀패드 초기화

**API명**

- `TSP90.Init`

**정의**

- TSP90 핀패드 디바이스 통신 포트를 열고 하드웨어를 초기화합니다.

**호출 예시**

```json
{
  "service": "TSP90.Init",
  "requestKey": "REQ_PIN_INIT_01",
  "param": {}
}
```

- param
    - 전달할 파라미터 정보가 없습니다.

**응답 예시**

```json
{
  "service": "TSP90.Init",
  "requestKey": "REQ_PIN_INIT_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)

---

## 2. 버전 정보 조회

**API명**

- `TSP90.GetVersion`

**정의**

- 핀패드 장치 펌웨어 및 제어 DLL(`TSP90Wrapper.dll`)의 버전 정보를 조회합니다.

**호출 예시**

```json
{
  "service": "TSP90.GetVersion",
  "requestKey": "REQ_PIN_VER_01",
  "param": {}
}
```

- param
    - 전달할 파라미터 정보가 없습니다.

**응답 예시**

```json
{
  "service": "TSP90.GetVersion",
  "requestKey": "REQ_PIN_VER_01",
  "statusCode": "0000",
  "return": {
    "returnValue": 0,
    "version": "2.0.3.4"
  }
}
```

- returnValue
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)
- version
    - 핀패드 장치 펌웨어 및 제어 DLL 버전 문자열입니다.

---

## 3. 스피커 볼륨 조회

**API명**

- `TSP90.GetVolume`

**정의**

- 현재 핀패드 본체 스피커에 설정된 볼륨 수치를 조회합니다.

**호출 예시**

```json
{
  "service": "TSP90.GetVolume",
  "requestKey": "REQ_PIN_VOL_01",
  "param": {}
}
```

- param
    - 전달할 파라미터 정보가 없습니다.

**응답 예시**

```json
{
  "service": "TSP90.GetVolume",
  "requestKey": "REQ_PIN_VOL_01",
  "statusCode": "0000",
  "return": {
    "returnValue": 0,
    "volume": "5"
  }
}
```

- returnValue
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)
- volume
    - 현재 설정된 스피커 볼륨 수치입니다. (1 ~ 10)

---

## 4. 버튼 볼륨 조회

**API명**

- `TSP90.GetButtonVolume`

**정의**

- 핀패드 키패드 터치 시 발생하는 버튼 비프음의 볼륨 수치를 조회합니다.

**호출 예시**

```json
{
  "service": "TSP90.GetButtonVolume",
  "requestKey": "REQ_PIN_BVOL_01",
  "param": {}
}
```

- param
    - 전달할 파라미터 정보가 없습니다.

**응답 예시**

```json
{
  "service": "TSP90.GetButtonVolume",
  "requestKey": "REQ_PIN_BVOL_01",
  "statusCode": "0000",
  "return": {
    "returnValue": 0,
    "volume": "5"
  }
}
```

- returnValue
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)
- volume
    - 현재 설정된 버튼음 볼륨 수치입니다. (1 ~ 10)

---

## 5. 밝기 조회

**API명**

- `TSP90.GetBright`

**정의**

- 핀패드 LCD 화면의 밝기 수치를 조회합니다.

**호출 예시**

```json
{
  "service": "TSP90.GetBright",
  "requestKey": "REQ_PIN_BRT_01",
  "param": {}
}
```

- param
    - 전달할 파라미터 정보가 없습니다.

**응답 예시**

```json
{
  "service": "TSP90.GetBright",
  "requestKey": "REQ_PIN_BRT_01",
  "statusCode": "0000",
  "return": {
    "returnValue": 0,
    "bright": "8"
  }
}
```

- returnValue
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)
- bright
    - 현재 설정된 LCD 화면 밝기 수치입니다. (1 ~ 10)

---

## 6. 폰트 조회

**API명**

- `TSP90.GetFont`

**정의**

- 핀패드 LCD에 설정된 폰트 명칭을 조회합니다.

**호출 예시**

```json
{
  "service": "TSP90.GetFont",
  "requestKey": "REQ_PIN_FONT_01",
  "param": {}
}
```

- param
    - 전달할 파라미터 정보가 없습니다.

**응답 예시**

```json
{
  "service": "TSP90.GetFont",
  "requestKey": "REQ_PIN_FONT_01",
  "statusCode": "0000",
  "return": {
    "returnValue": 0,
    "font": "굴림체"
  }
}
```

- returnValue
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)
- font
    - 현재 설정된 폰트 명칭입니다. (예: "굴림체", "엽서체")

---

## 7. 스피커 볼륨 설정

**API명**

- `TSP90.SetVolume`

**정의**

- 핀패드 본체 스피커 볼륨 수치를 설정합니다.

**호출 예시**

```json
{
  "service": "TSP90.SetVolume",
  "requestKey": "REQ_PIN_SETVOL_01",
  "param": {
    "volume": "7"
  }
}
```

- volume
    - 설정할 스피커 볼륨 수치입니다. (1 ~ 10)

**응답 예시**

```json
{
  "service": "TSP90.SetVolume",
  "requestKey": "REQ_PIN_SETVOL_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)

---

## 8. 버튼 볼륨 설정

**API명**

- `TSP90.SetButtonVolume`

**정의**

- 핀패드 버튼 터치 시 발생하는 비프음의 볼륨 수치를 설정합니다.

**호출 예시**

```json
{
  "service": "TSP90.SetButtonVolume",
  "requestKey": "REQ_PIN_SETBVOL_01",
  "param": {
    "volume": "7"
  }
}
```

- volume
    - 설정할 버튼음 볼륨 수치입니다. (1 ~ 10)

**응답 예시**

```json
{
  "service": "TSP90.SetButtonVolume",
  "requestKey": "REQ_PIN_SETBVOL_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)

---

## 9. 밝기 설정

**API명**

- `TSP90.SetBright`

**정의**

- 핀패드 LCD 화면의 밝기 수치를 설정합니다.

**호출 예시**

```json
{
  "service": "TSP90.SetBright",
  "requestKey": "REQ_PIN_SETBRT_01",
  "param": {
    "bright": "8"
  }
}
```

- bright
    - 설정할 LCD 화면 밝기 수치입니다. (1 ~ 10)

**응답 예시**

```json
{
  "service": "TSP90.SetBright",
  "requestKey": "REQ_PIN_SETBRT_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)

---

## 10. 폰트 설정

**API명**

- `TSP90.SetFont`

**정의**

- 핀패드 LCD 화면 출력에 적용할 폰트를 설정합니다.

**호출 예시**

```json
{
  "service": "TSP90.SetFont",
  "requestKey": "REQ_PIN_SETFONT_01",
  "param": {
    "font": "굴림체"
  }
}
```

- font
    - 설정할 폰트 명칭입니다. (예: "굴림체", "엽서체")

**응답 예시**

```json
{
  "service": "TSP90.SetFont",
  "requestKey": "REQ_PIN_SETFONT_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)

---

## 11. 대기화면 설정

**API명**

- `TSP90.SetWindow`

**정의**

- 입력 대기 상태일 때 핀패드 LCD 화면에 순환 표시할 이미지 또는 동영상을 지정합니다.

**호출 예시**

```json
{
  "service": "TSP90.SetWindow",
  "requestKey": "REQ_PIN_SETWIN_01",
  "param": {
    "type": "1",
    "size": "0",
    "imageIndex": "[21,22,23]",
    "interval": "3"
  }
}
```

- type
    - 화면에 표시할 미디어 종류입니다. (1: 이미지, 2: 동영상)
- size
    - 설정할 대상 화면 영역입니다. (0: 대기화면)
- imageIndex
    - 핀패드에 내장/등록된 이미지 또는 비디오 인덱스 목록 배열 문자열입니다. (예: `"[21,22,23]"`)
- interval
    - 미디어 간 순환 전환 인터벌 주기입니다. (초 단위, 예: 3)

**응답 예시**

```json
{
  "service": "TSP90.SetWindow",
  "requestKey": "REQ_PIN_SETWIN_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)

---

## 12. 비밀번호 입력

**API명**

- `TSP90.Read`

**정의**

- 고객에게 핀패드 키패드를 통한 비밀번호(숫자) 입력을 요청하고 암호화된 입력값을 수신합니다.

**호출 예시**

```json
{
  "service": "TSP90.Read",
  "requestKey": "REQ_PIN_READ_01",
  "param": {
    "sound": "1",
    "min": "4",
    "max": "4"
  }
}
```

- sound
    - 키패드 입력 시 비프음 볼륨입니다. (1 ~ 10)
- min
    - 최소 입력 자리수입니다. (비밀번호의 경우 일반적으로 4)
- max
    - 최대 입력 자리수입니다. (비밀번호의 경우 일반적으로 4)

**응답 예시**

```json
{
  "service": "TSP90.Read",
  "requestKey": "REQ_PIN_READ_01",
  "statusCode": "0000",
  "return": {
    "returnValue": 0,
    "password": "E2F5B6A8C9D01234..."
  }
}
```

- returnValue
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)
- password
    - 핀패드 하드웨어에서 암호화되어 반환된 비밀번호 데이터 문자열입니다.

---

## 13. 주민등록번호 입력

**API명**

- `TSP90.SSNRead`

**정의**

- 핀패드를 통해 13자리 주민등록번호를 안전하게 입력받습니다.

**호출 예시**

```json
{
  "service": "TSP90.SSNRead",
  "requestKey": "REQ_PIN_SSN_01",
  "param": {
    "sound": "1",
    "min": "13",
    "max": "13"
  }
}
```

- sound
    - 키패드 입력 시 비프음 볼륨입니다. (1 ~ 10)
- min
    - 최소 입력 자리수입니다. (주민등록번호 13자리)
- max
    - 최대 입력 자리수입니다. (주민등록번호 13자리)

**응답 예시**

```json
{
  "service": "TSP90.SSNRead",
  "requestKey": "REQ_PIN_SSN_01",
  "statusCode": "0000",
  "return": {
    "returnValue": 0,
    "idNumber": "8A9B0C1D2E3F4567..."
  }
}
```

- returnValue
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)
- idNumber
    - 핀패드 하드웨어에서 암호화되어 반환된 주민등록번호 데이터 문자열입니다.

---

## 14. 다이얼로그 동반 입력

**API명**

- `TSP90.ReadProcess`

**정의**

- 브라우저 화면에 취소 가능한 다이얼로그 창을 팝업하면서 핀패드 입력을 진행합니다. 사용자가 화면 다이얼로그의 [취소] 버튼을 누르면 입력을 중단하고 상태코드 10을 반환합니다.

**호출 예시**

```json
{
  "service": "TSP90.ReadProcess",
  "requestKey": "REQ_PIN_PROC_01",
  "param": {
    "sound": "1",
    "min": "4",
    "max": "4",
    "dialogMessage": "핀패드에 비밀번호 4자리를 입력해주세요."
  }
}
```

- sound
    - 키패드 입력 시 비프음 볼륨입니다. (1 ~ 10)
- min
    - 최소 입력 자리수입니다.
- max
    - 최대 입력 자리수입니다.
- dialogMessage
    - 브라우저 화면 다이얼로그 팝업창에 표기할 안내 문구입니다.

**응답 예시**

```json
{
  "service": "TSP90.ReadProcess",
  "requestKey": "REQ_PIN_PROC_01",
  "statusCode": "0000",
  "return": {
    "returnValue": 0,
    "data": "A1B2C3D4E5F6..."
  }
}
```

- returnValue
    - 서비스 상태 코드입니다. (0: 성공, 10: 사용자 취소, 그 외: 에러 코드)
- data
    - 핀패드에서 암호화되어 전달된 입력 데이터(비밀번호 또는 주민등록번호)입니다.

---

## 15. 비다이얼로그 입력

**API명**

- `TSP90.ReadNDProcess`

**정의**

- 화면 다이얼로그 없이 동작하며, 고객이 핀패드 하드웨어 상의 [확인] 버튼을 누를 때까지 입력 세션을 대기합니다.

**호출 예시**

```json
{
  "service": "TSP90.ReadNDProcess",
  "requestKey": "REQ_PIN_ND_01",
  "param": {
    "sound": "1",
    "min": "4",
    "max": "4"
  }
}
```

- sound
    - 키패드 입력 시 비프음 볼륨입니다. (1 ~ 10)
- min
    - 최소 입력 자리수입니다.
- max
    - 최대 입력 자리수입니다.

**응답 예시**

```json
{
  "service": "TSP90.ReadNDProcess",
  "requestKey": "REQ_PIN_ND_01",
  "statusCode": "0000",
  "return": {
    "returnValue": 0,
    "data": "9876543210AB..."
  }
}
```

- returnValue
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)
- data
    - 핀패드에서 암호화되어 전달된 입력 데이터입니다.

---

## 16. 자동 확인

**API명**

- `TSP90.PINAutoConfirmed`

**정의**

- `min` 파라미터 이상의 숫자가 이미 핀패드에 입력되어 있는 경우, 확인 버튼 입력 없이도 즉시 입력 과정을 종료하고 현재까지 입력된 데이터를 반환합니다. (핀패드에 입력된 값이 없는 경우 `AutoConfirm`을 호출하면 입력을 종료합니다.)

**호출 예시**

```json
{
  "service": "TSP90.PINAutoConfirmed",
  "requestKey": "REQ_PIN_AUTOCONF_01",
  "param": {}
}
```

- param
    - 전달할 파라미터 정보가 없습니다.

**응답 예시**

```json
{
  "service": "TSP90.PINAutoConfirmed",
  "requestKey": "REQ_PIN_AUTOCONF_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)

---

## 17. 입력 프로세스 강제종료

**API명**

- `TSP90.Off`

**정의**

- 현재 진행 중인 `Read` / `SSNRead` 세션을 강제로 취소하고 장치를 대기 상태로 복귀시킵니다.

**호출 예시**

```json
{
  "service": "TSP90.Off",
  "requestKey": "REQ_PIN_OFF_01",
  "param": {}
}
```

- param
    - 전달할 파라미터 정보가 없습니다.

**응답 예시**

```json
{
  "service": "TSP90.Off",
  "requestKey": "REQ_PIN_OFF_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)

---

## 18. 미디어 복합 출력

**API명**

- `TSP90.MediaOut`

**정의**

- 핀패드 LCD 화면에 오디오, 비디오, 이미지, 텍스트를 지정한 위치 및 시간 동안 출력합니다.

**호출 예시**

```json
{
  "service": "TSP90.MediaOut",
  "requestKey": "REQ_PIN_MEDIA_01",
  "param": {
    "audio": "0",
    "video": "0",
    "image": "0",
    "text": "1",
    "startLine": "1",
    "textAlign": "3",
    "fontsize": "16",
    "textStr": "한화생명 고객 안내 메시지",
    "time": "5"
  }
}
```

- audio
    - 재생할 오디오 파일 인덱스입니다. (0: 미사용)
- video
    - 재생할 비디오 파일 인덱스입니다. (0: 미사용)
- image
    - 출력할 이미지 파일 인덱스입니다. (0: 미사용)
- text
    - 텍스트 출력 여부입니다. (0: 미출력, 1: 출력)
- startLine
    - 텍스트 출력 시작 줄 번호입니다. (1부터 시작)
- textAlign
    - 텍스트 정렬 방식입니다. (1: 좌측 정렬, 2: 우측 정렬, 3: 가운데 정렬)
- fontsize
    - 글꼴 크기입니다. (예: 16)
- textStr
    - 핀패드 화면에 출력할 텍스트 본문 문자열입니다.
- time
    - 화면 노출 유지 시간입니다. (초 단위)

**응답 예시**

```json
{
  "service": "TSP90.MediaOut",
  "requestKey": "REQ_PIN_MEDIA_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)

---

## 19. 핀패드 폼(그리드) 출력

**API명**

- `TSP90.PinpadFormOut`

**정의**

- 핀패드 LCD에 표(Grid) 형태의 다중 셀/다중 행 데이터를 정렬하여 출력합니다.

**주의사항**
1. 셀(Cell) 구분자는 `|`(파이프 기호), 행(Row) 구분자는 `\n`(줄바꿈)을 사용합니다.
2. 예시 포맷: `항목1|항목2|항목3\n내용1|내용2|내용3\n`
3. 연속된 파이프 기호(`||`) 등으로 인해 열 개수가 초과될 경우 마지막 열 데이터가 핀패드 화면에서 누락될 수 있으므로 정확한 규격을 준수하시길 바랍니다.

**호출 예시**

```json
{
  "service": "TSP90.PinpadFormOut",
  "requestKey": "REQ_PIN_FORM_01",
  "param": {
    "formType": "1",
    "textStr": "계약자|홍길동|납입금액|100,000원\n피보험자|김영희|보험상태|정상유지\n",
    "time": "60"
  }
}
```

- formType
    - 핀패드 LCD에 출력할 폼/그리드 유형 식별값입니다. (기본값: 1)
- textStr
    - 핀패드 화면에 그리드 표 형태로 출력할 데이터 문자열입니다.
    - 셀(열) 구분자는 `|`(파이프), 행 구분자는 `\n`(줄바꿈)을 사용합니다.
- time
    - 핀패드 화면에 그리드 데이터를 표시 유지할 시간입니다. (초 단위)

**응답 예시**

```json
{
  "service": "TSP90.PinpadFormOut",
  "requestKey": "REQ_PIN_FORM_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)

# MCI Server (TCP) 통신 서비스

eXDevice+ Agent를 중계 서버로 활용하여 웹 브라우저가 외부 한화생명 MCI(Message Communication Interface) 서버와 직접 TCP 소켓 통신을 수행할 수 있도록 지원하는 전용 프로토콜 서비스입니다.


```mermaid
sequenceDiagram
    autonumber
    actor User as 웹 브라우저 (JS)
    participant Agent as eXDevice+ Agent
    participant MCI as 한화생명 MCI Server

    User->>Agent: mcipush.Connect (IP, Port, Timeout, Alive Check 주기)
    Agent->>MCI: TCP Socket Connect
    MCI-->>Agent: 연결 완료
    Agent-->>User: 응답 (statusCode: 0000, serviceId 발급)

    User->>Agent: mcipush.SaveDisposeMessage (serviceId, 종료시전송메시지)
    Agent-->>User: 저장 완료

    loop Alive Check (주기적)
        Agent->>MCI: Ping ("00000003req")
        MCI-->>Agent: Pong ("00000003res")
    end

    User->>Agent: mcipush.SendMessage (serviceId, 전문내용)
    Agent->>MCI: TCP 전문 전송 ("8bytes Length" + 전문내용)

    MCI->>Agent: Async Push 메시지 수신 ("8bytes Length" + 메시지)
    Agent->>User: mcipush.Listener 이벤트 알림

    User->>Agent: mcipush.Disconnect (serviceId)
    Agent->>MCI: 사전 저장된 Dispose Message 송신 후 소켓 Close
    Agent-->>User: 연결 해제 완료
```

---

## 1. 통신 아키텍처 및 다중 소켓 접속 구조

 `tcpsvc.dll`은 하나의 웹소켓 클라이언트(브라우저)에서 다중 TCP 서버와의 소켓 연결을 지원하며, 단일 웹소켓 연결 상에서 동일한 TCP 서버에 대해 2개 이상의 다중 소켓 세션을 동시에 수립하고 독립적으로 제어할 수 있습니다.

```mermaid
flowchart TD
    subgraph Browser["웹 브라우저"]
        WSClient1["ws client 1"]
        WSClient2["ws client 2"]
    end

    subgraph Agent["eXDevice+ Agent (tcpsvc.dll)"]
        Sock1["tcpsvc socket 1"]
        Sock2["tcpsvc socket 2"]
        Sock3["tcpsvc socket 3"]
        Sock4["tcpsvc socket 4"]
    end

    subgraph Servers["한화생명 MCI 서버군"]
        Server1["TCP Server (1)"]
        Server2["TCP Server (2)"]
    end

    WSClient1 -->|"동일 Client에서 다중 TCP 소켓 연결"| Sock1
    WSClient1 -->|"동일 Client에서 다중 TCP 소켓 연결"| Sock2
    WSClient2 --> Sock3
    WSClient2 --> Sock4

    Sock1 --> Server1
    Sock2 --> Server1
    Sock3 --> Server2
    Sock4 --> Server2
```

---

## 2. TCP 패킷 통신 프로토콜 (Packet Frame Format)

 eXDevice+와 한화생명 MCI 서버 간의 TCP 데이터 송수신은 **"고정 8바이트 메시지 길이 헤더(Length)" + "가변 전송 메시지 본문(Body)"** 규격을 준수합니다.

```text
+------------------------------------+----------------------------------------------------+
|       Length (고정 8 Bytes)        |          Body (가변 길이 전송 메시지 본문)          |
+------------------------------------+----------------------------------------------------+
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 5      | T | o |   | S | e | n | d |   | M | e | s | s | a | g | e |
+------------------------------------+----------------------------------------------------+
```

- **헤더 규격:** 전송할 메시지 본문의 바이트 길이를 8자리 10진수 문자열로 포맷팅합니다. (예: 메시지 길이가 15바이트인 경우 `00000015`를 헤더로 결합하여 총 23바이트를 전송)
- **수신 검증:** TCP 서버로부터 수신한 초기 8바이트 데이터가 정수형(Integer) 값이 아닌 경우, eXDevice+는 즉시 TCP 소켓 연결을 해제하고 웹소켓 클라이언트에게 상태코드 `3`(전문 길이 포맷 오류)을 통보합니다.
- **라이프사이클 연동:** 서비스를 요청한 웹소켓 클라이언트(브라우저)와 eXDevice+ 간의 연결이 해제되면, 해당 클라이언트가 생성했던 모든 TCP 서버와의 소켓 연결도 즉시 일괄 해제됩니다.

---

## 3. Keep-Alive (Ping-Pong) 동작 메커니즘

- **Ping 전송:** eXDevice+는 `pingInterval` 주기에 맞춰 MCI 서버로 `"req"` 문자열(8바이트 헤더 포함: `"00000003req"`)을 전송합니다.
- **Pong 응답:** MCI 서버는 Ping 수신 시 `"res"` 문자열(8바이트 헤더 포함: `"00000003res"`)을 회신해야 합니다.
- **비정상 단절 처리:** `pingTimeout` 시간 내에 `"res"` 응답을 수신하지 못한 경우, eXDevice+는 소켓 연결을 즉시 강제 해제합니다. (이 경우 `DisposeMessage`는 서버로 전송하지 않습니다.)

---

## 4. 브라우저 TCP 세션 식별 키 관리

 하나의 웹소켓 연결에서 여러 TCP 소켓을 식별하고 제어하기 위해 브라우저는 다음 두 가지 키값을 관리해야 합니다.

| No. | Key 명칭 | 확인 가능 시점 | 주요 용도 및 역할 |
| :---: | :--- | :--- | :--- |
| 1 | **requestKey** | 브라우저에서 `mcipush.Connect` 호출 시 생성한 키 | 서버로부터 비동기 `mcipush.Listener` 푸시 메시지 수신 시 어떤 TCP 서버/소켓에서 온 메시지인지 식별하기 위한 식별자 |
| 2 | **serviceId** | `mcipush.Connect` 호출 성공 시 응답받은 세션 ID | 해당 TCP 소켓을 대상으로 추가 서비스(`mcipush.SendMessage`, `mcipush.SaveDisposeMessage`, `mcipush.Disconnect`)를 요청할 때 식별자로 사용 |

---

## 서비스 리스트

| No. | 서비스명 | API명 | 비고 |
| :---: | :--- | :--- | :--- |
| 1 | MCI 서버 TCP 연결 | `mcipush.Connect` | TCP 소켓 연결 및 `serviceId` 발급 |
| 2 | Disconnect 메시지 등록 | `mcipush.SaveDisposeMessage` | 소켓 해제 시 자동 송신 메시지 등록 |
| 3 | 메시지 전송 | `mcipush.SendMessage` | MCI 서버로 전문 송신 |
| 4 | MCI Push 메시지 수신 | `mcipush.Listener` | 비동기 Push 수신 이벤트 (직접 호출 불가) |
| 5 | MCI 서버 연결 해제 | `mcipush.Disconnect` | TCP 소켓 연결 종료 |

## 서비스 상태 코드 리스트

### 1. 서비스 응답 상태 코드 (`tcpsvcCode`)
 `mcipush` 서비스 API 호출 결과 객체의 `return` 또는 `return.returnValue` 값 매핑표입니다.

| 리턴코드 | 내용 | 조치 가이드 |
| :---: | :--- | :--- |
| **0** | 성공 | 정상 처리되었습니다. |
| **-1** | 정의되지 않은 예외 | eXDevice+ 로그 파일을 확인하시길 바랍니다. |
| **1** | 이미 연결됨 | MCI Server와 이미 연결되어 있습니다. 기존 연결 해제 후 재연결을 수행하시길 바랍니다. |
| **2** | 잘못된 IP 주소 | 유효하지 않은 IP 주소가 입력되었습니다. 입력한 IP 주소를 확인하시길 바랍니다. |
| **3** | 잘못된 Port 번호 | 유효하지 않은 Port 넘버가 입력되었습니다. 입력한 Port 넘버를 확인하시길 바랍니다. |
| **4** | MCI 서버 연결 불가 | MCI Server와 연결할 수 없습니다. MCI Server의 주소 또는 네트워크 연결을 확인하시길 바랍니다. |
| **5** | 연결 종료됨 | 사용자/eXDevice+에 의해 MCI Server와의 연결이 종료되었습니다. |
| **6** | 연결 타임아웃 | MCI Server와 연결 중 타임아웃이 발생했습니다. MCI Server의 주소 또는 네트워크 연결을 확인하시길 바랍니다. |
| **7** | 미연결 상태 | MCI Server에 연결되어 있지 않습니다. `serviceId` 유효성 및 사전 연결을 확인하시길 바랍니다. |
| **8** | Disconnect 실패 | MCI Server로부터 Disconnect에 실패했습니다. |
| **9** | 메시지 전송 실패 | MCI Server에 메시지 전송에 실패했습니다. |
| **10** | LogFormat 설정 오류 | 유효하지 않은 LogFormat이 입력되었습니다. `modules.json`을 확인하시길 바랍니다. |

### 2. 푸시 리스너 상태 코드 (`listenerCode`)

| 리턴코드 | 내용 | 상세 설명 |
| :---: | :--- | :--- |
| **0** | 성공 | 정상적으로 푸시 메시지를 수신했습니다. |
| **-1** | 정의되지 않은 예외 | 로그 파일을 확인하시길 바랍니다. |
| **1** | 연결 해제됨 | MCI 서버와 연결이 해제되었습니다. |
| **2** | Pong 미수신 | MCI 서버로부터 pong을 받지 못했습니다. |
| **3** | 전문 길이 포맷 오류 | MCI 서버로부터 수신한 Message length 데이터가 Integer 값이 아닙니다. |

---

## 1. MCI 서버 TCP 연결

**API명**

- `mcipush.Connect`

**정의**

- 대상 MCI 서버의 IP와 Port로 TCP 소켓을 생성하고, Keep-Alive 스레드를 가동하며 리스너를 바인딩합니다.

**호출 예시**

```json
{
  "service": "mcipush.Connect",
  "requestKey": "MCI_SOCK_01",
  "param": {
    "serverIp": "127.0.0.1",
    "serverPort": "9480",
    "socketTimeout": "3000",
    "retry": "3",
    "pingTimeout": "3000",
    "pingInterval": "600000"
  }
}
```

- serverIp
    - 대상 한화생명 MCI 서버 IP 주소입니다.
- serverPort
    - 대상 한화생명 MCI 서버 TCP Port 번호입니다.
- socketTimeout
    - TCP 소켓 연결 수립 타임아웃 시간입니다. (밀리초 단위, ms)
- retry
    - 서버 연결 시도 시 또는 Ping 전송 후 Pong 수신 대기 시의 최대 재시도 횟수입니다.
- pingTimeout
    - Alive check(Ping) 전송 후 Pong 응답 수신 대기 타임아웃 시간입니다. (밀리초 단위, ms)
- pingInterval
    - Alive check(Ping) 주기입니다. (밀리초 단위, ms, 예: 600000 = 10분)

**응답 예시**

```json
{
  "service": "mcipush.Connect",
  "requestKey": "MCI_SOCK_01",
  "statusCode": "0000",
  "return": {
    "returnValue": 0,
    "serviceId": "0c089b51-083b-4654-8261-aa2220ebf809"
  }
}
```

- returnValue
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)
- serviceId
    - 생성된 TCP 소켓 세션의 고유 식별자입니다. (이후 `SendMessage`, `SaveDisposeMessage`, `Disconnect` 호출 시 파라미터로 사용됩니다.)

---

## 2. Disconnect 메시지 등록

**API명**

- `mcipush.SaveDisposeMessage`

**정의**

- 웹브라우저와 eXDevice+ 간 웹소켓 연결이 끊어지거나, 웹브라우저에서 TCP 소켓 연결 해제(`Disconnect`)를 요청할 때 소켓 종료 직전 MCI 서버로 자동 전송할 고별(Dispose) 전문을 사전에 eXDevice+ 메모리에 등록합니다.

**호출 예시**

```json
{
  "service": "mcipush.SaveDisposeMessage",
  "requestKey": "REQ_SAVE_DISP_01",
  "param": {
    "serviceId": "0c089b51-083b-4654-8261-aa2220ebf809",
    "message": "DISCONNECT|CLIENT_SESSION_CLOSE"
  }
}
```

- serviceId
    - 대상 TCP 소켓 식별자입니다. (`mcipush.Connect` 응답으로 발급받은 값)
- message
    - 세션 종료 또는 연결 단절 시 MCI 서버로 자동 전송할 종료 전문 내용입니다.

**응답 예시**

```json
{
  "service": "mcipush.SaveDisposeMessage",
  "requestKey": "REQ_SAVE_DISP_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)

---

## 3. 메시지 전송

**API명**

- `mcipush.SendMessage`

**정의**

- 수립된 TCP 소켓을 통해 한화생명 MCI 서버로 데이터를 송신합니다. (전송 시 `8bytes 메시지 길이` 헤더가 자동으로 결합되어 송신됩니다.)

**호출 예시**

```json
{
  "service": "mcipush.SendMessage",
  "requestKey": "REQ_MCI_SEND_01",
  "param": {
    "serviceId": "0c089b51-083b-4654-8261-aa2220ebf809",
    "message": "TR001|20260901|REQ_LOAN_STATUS|CUSTOMER_001"
  }
}
```

- serviceId
    - 전송 대상 TCP 소켓 식별자입니다.
- message
    - MCI 서버로 전송할 전문 데이터 문자열입니다.

**응답 예시**

```json
{
  "service": "mcipush.SendMessage",
  "requestKey": "REQ_MCI_SEND_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)

---

## 4. MCI Push 메시지 수신

**API명**

- `mcipush.Listener`

**정의**

- MCI 서버로부터 TCP 스트림을 통해 비동기 푸시 전문이 수신되었을 때, eXDevice+가 브라우저의 WebSocket 콜백 핸들러로 전달하는 이벤트 메시지입니다. (직접 호출 불가)

**수신 메시지 예시 (브라우저 수신 형태)**

```json
{
  "service": "mcipush.Listener",
  "requestKey": "MCI_SOCK_01",
  "statusCode": "0000",
  "return": {
    "returnValue": 0,
    "message": "TR001|RES_LOAN_STATUS|SUCCESS|BALANCE:5000000"
  }
}
```

- requestKey
    - `mcipush.Connect` 호출 시 전달했던 `requestKey`가 포함되어 전달되므로, 브라우저는 이 값을 통해 어떤 TCP 소켓 연결로부터 수신된 푸시 메시지인지 식별할 수 있습니다.
- returnValue
    - 리스너 상태 코드입니다. (0: 성공, 그 외: 에러 코드)
- message
    - MCI 서버로부터 수신된 비동기 푸시 전문 데이터 본문입니다.

---

## 5. MCI 서버 연결 해제

**API명**

- `mcipush.Disconnect`

**정의**

- 지정한 `serviceId`에 매핑된 TCP 소켓 연결을 종료합니다. 등록된 `DisposeMessage`가 존재하는 경우 TCP 서버에 Dispose 메시지를 전송하고 확인 메시지를 수신한 뒤 안전하게 TCP 소켓을 Close합니다.

**호출 예시**

```json
{
  "service": "mcipush.Disconnect",
  "requestKey": "REQ_MCI_DISC_01",
  "param": {
    "serviceId": "0c089b51-083b-4654-8261-aa2220ebf809"
  }
}
```

- serviceId
    - 연결을 해제할 대상 TCP 소켓 식별자입니다.

**응답 예시**

```json
{
  "service": "mcipush.Disconnect",
  "requestKey": "REQ_MCI_DISC_01",
  "statusCode": "0000",
  "return": 0
}
```

- return
    - 서비스 상태 코드입니다. (0: 성공, 그 외: 에러 코드)