// 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한 번의 수집 요청. 비동기로 실행되며 완료까지 분 단위로 걸립니다.

전체 흐름

  1. STEP 1. 자격증명 등록: 파트너 서버가 POST /api/v1/registration-sessions 로 1회용 세션을 발급받고, 고객에게 managed SDK 등록 화면을 제공합니다. 고객이 직접 인증서/로그인을 입력하면 파트너 서버가 connectionId 를 받아 자기 사용자와 매핑해 저장합니다.
  2. STEP 2. 입출금내역 수집: 파트너 서버가 connectionId 와 고객 BRN으로 POST /api/v1/data-jobs 를 호출하고, kind 가 종료 상태(Succeeded/Failed)가 될 때까지 폴링한 뒤 결과를 받습니다.

사전 준비

  • 파트너 API Key: h6s_live_... 형식의 키를 발급받아 모든 요청에 Authorization: Bearer h6s_live_... 로 함께 보내 주세요. 키는 안전한 채널로 받아 서버에만 보관해 주세요.
  • 고객 BRN: 수집 대상 고객의 사업자등록번호(숫자 10자리). 등록과 수집 요청 모두 X-H6S-Business 헤더에 이 값을 넣어 주세요.

STEP 1. 고객 자격증명 등록

고객이 자격증명을 직접 입력하도록 1회용 등록 세션을 발급하고, 그 화면을 고객에게 managed SDK로 제공해 주세요.

등록 세션 발급 (파트너 서버)

terminal curl
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 동반).
originAllowlistmanaged SDK iframe을 띄울 부모 페이지 origin.
clientReferenceId파트너의 안정적인 고객 식별자. 같은 고객 재등록에도 같은 값을 보내며, 비밀값이나 개인정보는 넣지 않습니다.
response
{
  "sessionId": "0193...",
  "sessionToken": "reg_AbCdEf...",   // 응답에만 1회 노출
  "expiresAt": "2026-06-21T08:30:00Z",
  "status": "PENDING"
}
  • sessionToken 은 1회용이며 만료 시간이 짧습니다. 고객이 등록 화면에 막 진입하는 시점에 발급해 바로 전달해 주세요.
  • clientReferenceId 는 Connection을 유지할 고객 식별자입니다. 재등록에도 같은 값을 보내고, 새 고객마다 다른 값을 사용해 주세요.
  • 공동인증서 등록 시, 인증서 안 사업자번호가 요청 BRN과 다르면 CERT_BIZNO_MISMATCH 로 거부됩니다.

등록 화면 제공

방식설명connectionId 수령
managed SDKmanaged 등록 UI를 전체화면 iframe으로 빠르게 띄우고 싶을 때.onSuccess

자격증명 입력은 managed iframe 안에서 처리되고, 파트너 서버는 자격증명 원문을 거치지 않습니다.

managed SDK

설치 패키지: @h6s-ai/web(바닐라 JS), @h6s-ai/react(React). 자세한 옵션과 컴포넌트는 SDK 문서를 참고해 주세요. CDN으로는 <script src="https://js.h6s.ai/sdk/v1/h6s.js"></script> 로도 사용할 수 있습니다.

vanilla - managed
import { openRegistration } from "@h6s-ai/web/managed";

openRegistration({
  sessionToken, // 파트너 서버가 발급한 값
  onSuccess: (event) => {
    // event.connectionId 를 파트너 사용자와 매핑해 저장
    saveConnection({ connectionId: event.connectionId, userId });
  },
  onExit: (event) => {
    if (event.reason === "expired") {
      // 새 sessionToken 을 발급받아 다시 띄웁니다
    }
  },
});
react - 버튼
import { RegistrationButton } from "@h6s-ai/react/managed";

<RegistrationButton
  sessionToken={sessionToken}
  onSuccess={(event) => saveConnection(event.connectionId)}
>
  자격증명 등록 시작
</RegistrationButton>

PC 공동인증서 등록은 managed iframe 진입 시 자동으로 진행됩니다. 등록에 사용할 도메인은 사전에 화이트리스트로 등록해야 하며, 와일드카드(예: *.example.com) 없이 정확히 일치해야 합니다. 새로 연동할 도메인이 있으면 미리 알려 주세요.

CSP를 운용한다면 다음 항목을 허용해 주세요.

항목
frame-srchttps://connect.h6s.ai
script-srchttps://js.h6s.ai (CDN 사용 시)

onSuccess 반환 정보는 connectionId, sessionId, registrationKind, providerCode, clientReferenceId 를 담습니다. onExitreason 별 대응은 아래와 같습니다.

reason의미권장 대응
closed사용자가 닫기·overlay·ESC로 종료다시 시도 안내 또는 재시도 버튼 노출
expired세션 토큰 만료새 토큰을 발급받아 다시 엽니다
consumed이미 등록이 끝난 세션 재진입등록 완료 안내 후 자격증명 목록으로 이동
cancelled발급자(파트너 백엔드)가 취소처리됨 안내
max_attempts_exceeded입력 실패 횟수 초과잠시 후 새 토큰으로 재시도 안내
error서버·검증 오류 (message 동반)message 노출 후 재시도 옵션 제공

세션 상태 폴링

managed SDK 콜백을 받은 뒤에도 파트너 서버가 세션 상태를 폴링해 서버 기준 결과를 확정할 수 있습니다.

terminal curl
curl https://api.h6s.ai/api/v1/registration-sessions/{sessionId} \
  -H "Authorization: Bearer h6s_live_..." \
  -H "X-H6S-Business: 1234567890"
response
{
  "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를 호출할 필요는 없습니다.

  • 같은 파트너, BRN, clientReferenceId 로 재등록하면 같은 인증서는 기존credentialId 를 재사용하고, 새 인증서는 새 credentialId 로 교체됩니다. 어느 경우든 기존 connectionId 는 유지됩니다.
  • clientReferenceId 를 생략했거나 Connection을 detach한 뒤 다시 연결하면 새connectionId 가 발급될 수 있습니다. 파트너 수집에는 credentialId대신 저장한 connectionId 만 사용해 주세요.

Connection 이벤트 복구

웹훅 처리 시 idempotencyKey 로 중복을 제거하고, 마지막으로 처리한 cursor를 저장해 주세요. 장애나 재시작 뒤에는 해당 cursor 이후 이벤트를 재생해 Connection 상태를 맞춥니다.

terminal curl
curl "https://api.h6s.ai/api/v1/connections/events?after=120" \
  -H "Authorization: Bearer h6s_live_..." \
  -H "X-H6S-Business: 1234567890"

STEP 2. 입출금내역 수집

수집 요청

terminal curl
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수집 대상 금융기관 코드.
schemabank.transactions.cb.v1 (기업뱅킹 입출금내역).
connectionIdSTEP 1 에서 받은 값. 필수입니다.
params.dateRangeStart / dateRangeEnd조회 기간(YYYY-MM-DD). 한 번에 최대 365일.
params.accountNumber(선택) 특정 계좌만 조회. 문자열 또는 문자열 배열(^[0-9]{6,20}$). 생략 시 전 계좌 자동 조회.

특정 계좌만 조회하려면 params.accountNumber 에 계좌 배열을 넣습니다.

특정 계좌 요청 body
{
  "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" 가 즉시 포함됩니다.

폴링

terminal curl
curl https://api.h6s.ai/api/v1/data-jobs/{id} \
  -H "Authorization: Bearer h6s_live_..." \
  -H "X-H6S-Business: 1234567890"
kind의미
InProgress진행 중. phasePENDING(대기) 또는 RUNNING(수집 중).
Succeeded완료. recordCount 가 0 이면 자격증명/입력은 유효하나 조회 가능한 데이터가 없는 경우입니다.
Failed영구 실패. error.code / error.category 로 사유를 분기합니다.

폴링 간격과 한도는 응답의 suggestedPollIntervalMs, maxWaitSeconds 를 그대로 사용합니다. 자세한 패턴은 폴링 가이드를 참고해 주세요.

결과 조회

GET /api/v1/data-jobs/{id}/results 로 결과를 조회합니다. CSV가 필요하면 .../results.csv 를 사용합니다.

response
{
  "jobId": "...",
  "schema": "bank.transactions.cb.v1",
  "totalCount": 2,
  "data": [
    {
      "identifier": "bank_txn_v1_a1_2b5f0d6c8a91e3f4472c1a9d0e6b8f31",
      "transactionAt": "2026-05-29T14:23:00+09:00",
      "accountNumber": "1234567890",
      "accountNumberFormatted": "123-456-7890",
      "accountType": "CHECKING",
      "currencyCode": "KRW",
      "amount": "2000000",
      "description": "㈜에이클라이언트",
      "balance": "15234567"
    },
    {
      "identifier": "bank_txn_v1_a1_8c4d7e1a9b3056f2d0c1a2b3e4f56789",
      "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)

모든 계좌 유형에서 거래 식별자를 포함한 동일한 9개 필드로 제공됩니다. 전체 필드 메타는 스키마 카탈로그에서 확인할 수 있습니다.

필드타입설명
identifierstring동일 계좌의 같은 거래를 재식별하기 위한 불투명 문자열.
transactionAtISO8601 offset datetime거래 시각(예: 2026-05-29T14:23:00+09:00). 시간 정보가 없으면 00:00:00.
accountNumberstring계좌번호(하이픈/공백 없는 연속 숫자).
accountNumberFormattedstring (nullable)금융기관 표시 포맷(예: 123-456-7890). 미제공이면 null.
accountTypeenumCHECKING / FOREIGN / FUND / LOAN.
currencyCodestringISO 4217 통화 코드(예: KRW).
amountdecimal (부호값)해당 계좌 잔고 증감 기준 부호값(아래 규약 참조).
descriptionstring (nullable)거래 설명(이체 상대방/적요 등). 비어 있으면 null.
balancedecimal (nullable)거래 후 잔액. 일부 유형/기관은 미제공으로 null.

amount 부호 규약

accountType부호 의미
CHECKING / FOREIGN / FUND입금/매수 +, 출금/매도 -.
LOAN상환 -, 차입 +.

LOAN 의 amount > 0 은 대출 잔액 증가(차입)를 뜻합니다. 회계 관점과 반대일 수 있으므로 해석에 유의해 주세요. 기업뱅킹 전 기관에서 입출금(CHECKING) 거래를 지원합니다.

자격증명 검증

별도의 검증 전용 엔드포인트는 없습니다. 자격증명 유효성을 확인하려면 가장 작은 범위로 data-job 을 한 번 실행하고 결과로 판정합니다.

  • Succeeded 이면 자격증명은 유효합니다(recordCount=0 도 유효 케이스).
  • Failed 이고 error.category == "CREDENTIAL" 이면 자격증명 문제입니다. 고객에게 새 등록 세션으로 재등록을 안내해 주세요.

에러 핸들링

요청 거부 (형식/스코프)

코드HTTP의미
PARTNER_BUSINESS_SELECTOR_REQUIRED400X-H6S-Business 헤더 누락 또는 형식 오류(숫자 10자리 아님).
CONNECTION_REQUIRED_FOR_PARTNER400수집 요청에 connectionId 누락.
CREDENTIAL_ID_NOT_ALLOWED400credentialId 를 보냄. 파트너 경로는 connectionId 만 사용합니다.
PARTNER_CREDENTIAL_API_UNSUPPORTED410파트너의 /credentials 호출. 등록 세션과 connectionId 흐름으로 전환합니다.
CONNECTION_NOT_FOUND404현재 사업자등록번호 스코프에 없는 connectionId.
CERT_BIZNO_MISMATCH422인증서 사업자번호와 요청 BRN 불일치.
DATA_JOB_NOT_FOUND404다른 고객의 job id 접근 포함(존재 여부 비노출).
(인증 실패)401API Key 누락 또는 무효.

수집 실패 분류

Failed 응답의 error.category 로 후처리를 분기하고, error.retryable 로 재시도 여부를 판단합니다.

categoryretryable대응
CREDENTIALfalse자격증명 재등록 안내.
CREDENTIAL_MISSINGfalse해당 기관 자격증명을 먼저 등록.
USER_ENVIRONMENTfalse고객 환경/기관 점검 안내.
INVALID_INPUTfalse요청 파라미터(기간/계좌 등) 점검.
TRANSIENTtrue잠시 후 재시도.
OTHERfalse반복되면 문의.

세부 코드 목록과 설명은 에러 가이드를 참고해 주세요.

다음 단계