// api guide / partner
파트너 연동
플랫폼에서 고객(end-user)의 은행 입출금내역을 수집하기 위한 연동 가이드입니다. 고객 자격증명 등록부터 데이터 수집까지 한 흐름으로 다룹니다. API 베이스 URL 은 https://api.h6s.ai 입니다.
개요
- 플랫폼(파트너)에는 전용 워크스페이스가 하나 배정됩니다. 여러 고객의 자격증명과 수집 요청이 이 안에 함께 담기고, 고객 구분은 매 요청 헤더
X-H6S-Business: <사업자등록번호>로 합니다. - 고객의 자격증명(공동인증서 또는 은행 ID/PW)은 암호화되어 보관되며, 파트너 서버는 자격증명 원문을 보관하지 않습니다.
- 한 고객을 등록하면 그 고객을 가리키는
connectionId를 돌려받습니다. 이후 수집 요청은 이connectionId로 합니다.
| 용어 | 뜻 |
|---|---|
| BRN | 사업자등록번호(Business Registration Number). 하이픈 없는 숫자 10자리. 고객을 식별합니다. |
| 자격증명(credential) | 고객의 은행 인증 수단(공동인증서 또는 은행 ID/PW). |
| 등록 세션(registration session) | 고객이 자격증명을 직접 입력하도록 발급하는 1회용 세션. |
connectionId | 등록을 마친 고객 연결의 공개 핸들. 수집 요청에 사용합니다. |
| data-job | 한 번의 수집 작업. 비동기로 실행되며 분 단위가 걸립니다. |
전체 흐름
- STEP 1. 자격증명 등록 — 파트너 서버가
POST /api/v1/registration-sessions로 1회용 세션을 발급받고, 고객에게 등록 화면(임베디드 SDK 또는 호스티드 링크)을 제공합니다. 고객이 직접 인증서/로그인을 입력하면connectionId를 받아 자기 사용자와 매핑해 저장합니다. - STEP 2. 입출금내역 수집 —
connectionId와 고객 BRN 으로POST /api/v1/data-jobs를 호출하고,kind가 종료될 때까지 폴링한 뒤 결과를 받습니다.
사전 준비
- 파트너 API Key —
h6s_live_...형식의 키를 발급받아 모든 요청에Authorization: Bearer h6s_live_...로 함께 보냅니다. 키는 안전한 채널로 받아 서버에만 보관합니다. - 고객 BRN — 수집 대상 고객의 사업자등록번호(숫자 10자리). 등록과 수집 요청 모두
X-H6S-Business헤더에 이 값을 넣습니다.
STEP 1. 고객 자격증명 등록
고객이 자격증명을 직접 입력하도록 1회용 등록 세션을 발급하고, 그 화면을 고객에게 제공합니다. 화면을 보여주는 방식은 임베디드 SDK 와 호스티드 페이지 중에서 고릅니다.
등록 세션 발급 (파트너 서버)
curl -X POST https://api.h6s.ai/api/v1/registration-sessions \
-H "Authorization: Bearer h6s_live_..." \
-H "X-H6S-Business: 1234567890" \
-H "Content-Type: application/json" \
-d '{
"originAllowlist": ["https://app.partner.example.com"],
"clientReferenceId": "user-42",
"registrationOptions": [
{ "kind": "CERTIFICATE" },
{ "kind": "PROVIDER_LOGIN", "providerCode": "CB_WOORI" }
]
}'| 필드 | 설명 |
|---|---|
registrationOptions | 고객이 선택할 수 있는 등록 방식. 최소 1개. CERTIFICATE(공동인증서) 또는 PROVIDER_LOGIN(은행 ID/PW, providerCode 동반). |
originAllowlist | 임베디드 SDK 를 띄울 부모 페이지 origin. 호스티드 페이지만 쓸 경우 생략 가능. |
clientReferenceId | 파트너가 자기 사용자/신청과 매칭할 짧은 참조값(선택). 비밀값이나 개인정보는 넣지 않습니다. |
{
"sessionId": "0193...",
"sessionToken": "reg_AbCdEf...", // 응답에만 1회 노출
"hostedUrl": "https://connect.h6s.ai/s/reg_AbCdEf...",
"expiresAt": "2026-06-21T08:30:00Z",
"status": "PENDING"
}sessionToken은 1회용이며 짧은 만료를 가집니다. 고객이 등록 화면에 막 진입하는 시점에 발급해 바로 전달합니다.- 공동인증서 등록 시, 인증서 안 사업자번호가 요청 BRN 과 다르면
CERT_BIZNO_MISMATCH로 거부됩니다.
등록 화면 제공 방식 선택
| 방식 | 언제 적합한가 | connectionId 수령 |
|---|---|---|
| 임베디드 SDK | 파트너 앱 안에서 끊김 없이 등록을 끝내고 싶을 때. 모달/인라인/직접 UI 선택 가능. | onSuccess |
| 호스티드 페이지 | 별도 화면 작업 없이 링크만 전달하면 될 때. CSP 가 엄격하거나 모바일 환경. | 세션 폴링 |
두 방식 모두 자격증명 입력은 headless 화면에서 처리되고, 파트너 서버는 자격증명 원문을 거치지 않습니다.
방식 A. 임베디드 SDK
설치 패키지: @h6s-ai/web(바닐라 JS), @h6s-ai/react(React). 자세한 옵션과 컴포넌트는 SDK 문서를 참고합니다. CDN 으로는 <script src="https://js.h6s.ai/sdk/v1/h6s.js"></script> 로도 사용할 수 있습니다.
import { openRegistrationModal } from "@h6s-ai/web/embedded";
openRegistrationModal({
sessionToken, // 파트너 서버가 발급한 값
onSuccess: (event) => {
// event.connectionId 를 파트너 사용자와 매핑해 저장
saveConnection({ connectionId: event.connectionId, userId });
},
onExit: (event) => {
if (event.reason === "expired") {
// 새 sessionToken 을 발급받아 다시 띄웁니다
}
},
});import { RegistrationButton } from "@h6s-ai/react/embedded";
<RegistrationButton
sessionToken={sessionToken}
onSuccess={(event) => saveConnection(event.connectionId)}
>
자격증명 등록 시작
</RegistrationButton>PC 공동인증서는 모달/인라인 진입 시 자동으로 처리되며 파트너가 별도로 호출하는 API 는 없습니다. CSP 를 운용한다면 다음을 허용합니다.
| 항목 | 값 |
|---|---|
frame-src | https://connect.h6s.ai |
script-src | https://js.h6s.ai (CDN 사용 시) |
connect-src | http://localhost:33840 (PC 공동인증서 사용 시) |
onSuccess 페이로드는 connectionId, sessionId, registrationKind, providerCode, clientReferenceId 를 담습니다. onExit 의 reason 별 대응은 아래와 같습니다.
| reason | 의미 | 권장 대응 |
|---|---|---|
| closed | 사용자가 닫기·overlay·ESC 로 종료 | 다시 시도 안내 또는 재시도 버튼 노출 |
| expired | 세션 토큰 만료 | 새 토큰을 발급받아 다시 엽니다 |
| consumed | 이미 등록이 끝난 세션 재진입 | 등록 완료 안내 후 자격증명 목록으로 이동 |
| cancelled | 발급자(파트너 백엔드)가 취소 | 처리됨 안내 |
| max_attempts_exceeded | 입력 실패 횟수 초과 | 잠시 후 새 토큰으로 재시도 안내 |
| error | 서버·검증 오류 (message 동반) | message 노출 후 재시도 옵션 제공 |
방식 B. 호스티드 페이지
세션 발급 응답의 hostedUrl 을 고객에게 그대로 전달합니다(메일/SMS/링크 등). 고객이 그 페이지에서 자격증명을 입력합니다. 파트너 서버는 세션 상태를 폴링해 결과를 확인합니다.
curl https://api.h6s.ai/api/v1/registration-sessions/{sessionId} \
-H "Authorization: Bearer h6s_live_..." \
-H "X-H6S-Business: 1234567890"{
"sessionId": "0193...",
"status": "CONSUMED", // PENDING / CONSUMED / EXPIRED / CANCELLED / ATTEMPT_LIMIT_EXCEEDED
"consumedConnectionId": "01234567-89ab-cdef-0123-456789abcdef",
"consumedAt": "2026-06-21T08:12:00Z",
"expiresAt": "2026-06-21T08:30:00Z"
}status 는 종료 상태에 따라 다음과 같이 처리합니다.
| status | 의미 | 대응 |
|---|---|---|
CONSUMED | 고객이 자격증명 입력을 완료. | consumedConnectionId 를 읽어 저장합니다. 이 값이 곧 수집 요청에 쓰는 connectionId 입니다. |
EXPIRED | 만료 시각(expiresAt) 경과. | 새 등록 세션을 발급해 다시 안내합니다. |
CANCELLED | 고객이 등록을 취소. | 새 등록 세션을 발급해 다시 안내합니다. |
ATTEMPT_LIMIT_EXCEEDED | 입력 실패가 한도를 초과. | 잠시 후 새 등록 세션으로 다시 안내합니다. |
등록 세션은 1회용이라 종료 상태에서는 이어서 쓸 수 없습니다. 실패로 끝났다면 새 세션을 발급합니다. expiresAt 가 지나도록 PENDING 이면 폴링을 멈춥니다.
connectionId 저장
수령한 connectionId 를 파트너 시스템의 사용자/사업자 항목과 매핑해 저장합니다. 이후 그 고객의 입출금내역은 이 connectionId 로 수집합니다. 등록 뒤 별도의 연결 API 를 호출할 필요는 없습니다.
STEP 2. 입출금내역 수집
수집 요청
curl -X POST https://api.h6s.ai/api/v1/data-jobs \
-H "Authorization: Bearer h6s_live_..." \
-H "X-H6S-Business: 1234567890" \
-H "Content-Type: application/json" \
-d '{
"providerCode": "CB_KB",
"schema": "bank.transactions.cb.v1",
"connectionId": "01234567-89ab-cdef-0123-456789abcdef",
"params": {
"dateRangeStart": "2026-05-01",
"dateRangeEnd": "2026-05-31"
}
}'| 필드 | 설명 |
|---|---|
providerCode | 수집 대상 금융기관 코드. |
schema | bank.transactions.cb.v1 (기업뱅킹 입출금내역). |
connectionId | STEP 1 에서 받은 값. 필수입니다. |
params.dateRangeStart / dateRangeEnd | 조회 기간(YYYY-MM-DD). 한 번에 최대 365일. |
params.accountNumber | (선택) 특정 계좌만 조회. 문자열 또는 문자열 배열(^[0-9]{6,20}$). 생략 시 전 계좌 자동 조회. |
특정 계좌만 조회하려면 params.accountNumber 에 계좌 배열을 넣습니다.
{
"providerCode": "CB_KB",
"schema": "bank.transactions.cb.v1",
"connectionId": "01234567-89ab-cdef-0123-456789abcdef",
"params": {
"accountNumber": ["1234567890", "1111111150690"],
"dateRangeStart": "2026-05-01",
"dateRangeEnd": "2026-05-31"
}
}응답으로 즉시 id(jobId)와 kind: "InProgress" 가 돌아옵니다.
폴링
curl https://api.h6s.ai/api/v1/data-jobs/{id} \
-H "Authorization: Bearer h6s_live_..." \
-H "X-H6S-Business: 1234567890"| kind | 의미 |
|---|---|
InProgress | 진행 중. phase 가 PENDING(대기) 또는 RUNNING(수집 중). |
Succeeded | 완료. recordCount 가 0 이면 자격증명/입력은 유효하나 조회 가능한 데이터가 없는 경우입니다. |
Failed | 영구 실패. error.code / error.category 로 사유를 분기합니다. |
폴링 간격과 한도는 응답의 suggestedPollIntervalMs, maxWaitSeconds 를 그대로 사용합니다. 자세한 패턴은 폴링 가이드를 참고합니다.
결과 조회
GET /api/v1/data-jobs/{id}/results 로 결과를 받습니다. CSV 가 필요하면 .../results.csv 를 사용합니다.
{
"jobId": "...",
"schema": "bank.transactions.cb.v1",
"totalCount": 2,
"data": [
{
"transactionAt": "2026-05-29T14:23:00+09:00",
"accountNumber": "1234567890",
"accountNumberFormatted": "123-456-7890",
"accountType": "CHECKING",
"currencyCode": "KRW",
"amount": "2000000",
"description": "㈜에이클라이언트",
"balance": "15234567"
},
{
"transactionAt": "2026-05-02T09:02:11+09:00",
"accountNumber": "1234567890",
"accountNumberFormatted": "123-456-7890",
"accountType": "CHECKING",
"currencyCode": "KRW",
"amount": "-450000",
"description": "자동이체",
"balance": "13234567"
}
]
}입출금내역 스키마 (bank.transactions.cb.v1)
모든 계좌 유형에서 동일한 8필드 형태로 내려옵니다. 전체 필드 메타는 스키마 카탈로그에서 확인할 수 있습니다.
| 필드 | 타입 | 설명 |
|---|---|---|
transactionAt | ISO8601 offset datetime | 거래 시각(예: 2026-05-29T14:23:00+09:00). 시간 정보가 없으면 00:00:00. |
accountNumber | string | 계좌번호(하이픈/공백 없는 연속 숫자). |
accountNumberFormatted | string (nullable) | 금융기관 표시 포맷(예: 123-456-7890). 미제공이면 null. |
accountType | enum | CHECKING / FOREIGN / FUND / LOAN. |
currencyCode | string | ISO 4217 통화 코드(예: KRW). |
amount | decimal (부호값) | 해당 계좌 잔고 증감 기준 부호값(아래 규약 참조). |
description | string (nullable) | 거래 설명(이체 상대방/적요 등). 비어 있으면 null. |
balance | decimal (nullable) | 거래 후 잔액. 일부 유형/기관은 미제공으로 null. |
amount 부호 규약
| accountType | 부호 의미 |
|---|---|
| CHECKING / FOREIGN / FUND | 입금/매수 +, 출금/매도 -. |
| LOAN | 상환 -, 차입 +. |
LOAN 의 amount > 0 은 대출 잔액 증가(차입)를 뜻합니다. 회계 관점과 반대일 수 있으므로 해석에 유의합니다. 기업뱅킹 23개 기관 중 22개에서 입출금(CHECKING) 거래를 지원합니다.
자격증명 검증
별도의 검증 전용 엔드포인트는 없습니다. 자격증명 유효성을 확인하려면 가장 작은 범위로 data-job 을 한 번 실행하고 결과로 판정합니다.
Succeeded이면 자격증명은 유효합니다(recordCount=0도 유효 케이스).Failed이고error.category == "CREDENTIAL"이면 자격증명 문제입니다. 고객에게 재등록을 안내한 뒤 새 등록 세션으로 다시 등록받습니다.
에러 핸들링
요청 거부 (형식/스코프)
| 코드 | HTTP | 의미 |
|---|---|---|
PARTNER_BUSINESS_SELECTOR_REQUIRED | 400 | X-H6S-Business 헤더 누락 또는 형식 오류(숫자 10자리 아님). |
CONNECTION_REQUIRED_FOR_PARTNER | 400 | 수집 요청에 connectionId 누락. |
CREDENTIAL_ID_NOT_ALLOWED | 400 | credentialId 를 보냄. 파트너 경로는 connectionId 만 사용합니다. |
CONNECTION_NOT_FOUND | 404 | 현재 사업자등록번호 스코프에 없는 connectionId. |
CERT_BIZNO_MISMATCH | 422 | 인증서 사업자번호와 요청 BRN 불일치. |
DATA_JOB_NOT_FOUND | 404 | 다른 고객의 job id 접근 포함(존재 여부 비노출). |
| (인증 실패) | 401 | API Key 누락 또는 무효. |
수집 실패 분류
Failed 응답의 error.category 로 후처리를 분기하고, error.retryable 로 재시도 여부를 판단합니다.
| category | retryable | 대응 |
|---|---|---|
CREDENTIAL | false | 자격증명 재등록 안내. |
CREDENTIAL_MISSING | false | 해당 기관 자격증명을 먼저 등록. |
USER_ENVIRONMENT | false | 고객 환경/기관 점검 안내. |
INVALID_INPUT | false | 요청 파라미터(기간/계좌 등) 점검. |
TRANSIENT | true | 잠시 후 재시도. |
OTHER | false | 반복되면 문의. |
세부 코드 목록과 설명은 에러 가이드를 참고합니다.