> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# 인증 상태: 세션 수명 주기 및 상태 코드

> Didit 세션의 모든 상태를 설명합니다: 승인됨, 거부됨, 검토 중, 만료됨, 재제출됨, 중단됨, KYC 만료됨. 결정, 재시도, webhook 처리 방법을 확인하세요.

모든 검증 세션은 일련의 상태를 거칩니다. 이 상태를 이해하면 사용자 진행 상황을 모니터링하고, 규정 준수 결정을 자동화하고, 전환율을 최적화하는 데 도움이 됩니다.

이 열거형은 `GET /v3/session/<id>/decision/`과 모든 Didit webhook이 반환하는 문자열에 대한 유일한 기준입니다.

***

## 모든 상태 값

> [!NOTE]
>
> 모든 상태는 Didit API와 webhook이 반환하는 **정확한 문자열**입니다. 코드에서는 항상 엄격한 문자열 비교를 사용하십시오(예: `=== "In Review"`). 이 값은 대소문자를 구분하며 공백을 포함합니다. `Kyc Expired` 값도 `KYC`가 아니라 `K`를 대문자로 한 번만 씁니다.

| 상태 | 문자열 값 | 설명 |
| - | - | - |
| 시작되지 않음 | `"Not Started"` | 세션이 생성되었지만 사용자가 링크를 열지 않았습니다 |
| 진행 중 | `"In Progress"` | 사용자가 인증을 진행하고 있습니다 |
| 승인됨 | `"Approved"` | 모든 검사를 통과했습니다. 신원이 확인되었습니다 |
| 거부됨 | `"Declined"` | 하나 이상의 검사에 실패했습니다 |
| 검토 중 | `"In Review"` | 수동 규정 준수 검토 대상으로 표시되었습니다 |
| 사용자 대기 중 | `"Awaiting User"` | 하나 이상의 당사자가 인증을 완료하기를 기다리는 중입니다(KYB) |
| 재제출됨 | `"Resubmitted"` | 사용자가 특정 단계를 다시 수행하도록 요청했습니다 |
| 만료됨 | `"Expired"` | 사용자가 링크를 열기 전에 세션 시간이 초과되었습니다 |
| 중단됨 | `"Abandoned"` | 사용자가 시작했지만 제한 시간 내에 완료하지 않았습니다 |
| KYC 만료됨 | `"Kyc Expired"` | 이전에 승인된 세션으로, 확인된 문서의 만료일이 지났습니다 |

***

## 세션 상태

> [accordion] 시작 전 ("Not Started")
>
> **API 값:** `"Not Started"`
>
> 세션은 API를 통해 생성되었지만 사용자가 **아직 인증 링크를 열지 않은** 상태입니다.
>
> * **할 일:** 사용자가 시작할 때까지 기다리거나, 시간이 많이 지났다면 리마인더를 보내십시오.
> * **전환 대상:** `"In Progress"`, `"Expired"`

> [accordion] 진행 중 ("In Progress")
>
> **API 값:** `"In Progress"`
>
> 사용자가 링크를 열고 인증 단계(문서 촬영, 라이브니스 등)를 **적극적으로 진행하고 있는** 상태입니다.
>
> * **할 일:** 별도의 조치가 필요하지 않습니다. 사용자가 흐름을 따라 진행하고 있습니다.
> * **전환 대상:** `"Approved"`, `"Declined"`, `"In Review"`, `"Abandoned"`

> [accordion] 승인됨 ("Approved")
>
> **API 값:** `"Approved"`
>
> 모든 검증 항목을 **성공적으로 통과한** 상태입니다. 사용자의 신원이 확인되었습니다.
>
> * **할 일:** 사용자에게 접근 권한을 부여하고, 프로필을 업데이트하며, 결정 데이터를 저장하십시오.
> * **webhook 포함 항목:** 모든 기능 결과가 포함된 전체 `decision` 객체.
> * **전환 대상:** `"Kyc Expired"`(검증된 문서의 만료일이 지나면 적용됩니다. 해당 국가 및 문서 유형의 **Expiration mode**가 **Allow expired**인 경우를 제외하고는 기본 동작입니다). 검토자 또는 update-status endpoint로 `"Declined"` 또는 `"Resubmitted"`로도 설정할 수 있습니다.

> [accordion] 거부됨 ("Declined")
>
> **API 값:** `"Declined"`
>
> 하나 이상의 검증 항목이 **실패한** 상태입니다. 사용자가 인증을 통과하지 못했습니다.
>
> * **할 일:** 사용자에게 알리십시오. 문제를 해결할 수 있다면 선택적으로 재제출을 요청할 수 있습니다.
> * **webhook 포함 항목:** 실패 원인을 설명하는 경고가 포함된 전체 `decision` 객체.
> * **전환 대상:** `"Resubmitted"`(검토자가 요청한 경우). 검토자 또는 update-status endpoint로 `"Approved"`로도 설정할 수 있습니다.

> [accordion] 검토 중 ("In Review")
>
> **API 값:** `"In Review"`
>
> 자동 검사에서 **사람의 검토가 필요한 경고**가 표시된 상태입니다. 최종 결정은 컴플라이언스 검토자가 내려야 합니다.
>
> * **할 일:** 검토자는 Console에서 세션을 열고 승인, 거부 또는 재제출 요청을 하십시오.
> * **webhook 포함 항목:** 경고가 포함된 전체 `decision` 객체.
> * **전환 대상:** `"Approved"`, `"Declined"`, `"Resubmitted"`

> [accordion] 사용자 대기 중 ("Awaiting User")
>
> **API 값:** `"Awaiting User"`
>
> 주요 인물 단계에서 당사자 목록이 제출되어 하위 KYC / KYB 세션이 생성된 **기업 확인(KYB) 세션**에서 사용됩니다. 상위 세션은 **필수 당사자 모두가 개별 인증을 완료할 때까지** 대기합니다.
>
> * **할 일:** 하위 KYC 세션의 상태를 모니터링하십시오. 필수 당사자가 모두 완료되면(승인, 거부 또는 만료) 상위 세션은 최종 상태로 자동 재집계됩니다.
> * **webhook 포함 항목:** 현재 당사자 목록과 각 하위 세션의 상태.
> * **전환 대상:** `"Approved"`, `"Declined"`, `"In Review"`(모든 하위 세션이 종료 상태가 된 후)
> * **전환 이전 상태:** `"In Progress"`(주요 인물 단계가 제출된 후)
> * **참고:** 하위 KYC 세션이 재제출되면 재제출된 세션이 완료될 때까지 상위 세션은 `"Awaiting User"`로 돌아갑니다. `"Declined"` KYB 레지스트리 확인은 `"Awaiting User"`보다 우선합니다.

> [accordion] 재제출됨 ("Resubmitted")
>
> **API 값:** `"Resubmitted"`
>
> 검토자가 사용자에게 **특정 검증 단계를 다시 진행하도록** 요청한 상태입니다(예: 흐릿한 문서 사진을 다시 촬영).
>
> * **할 일:** 사용자가 다시 진행하도록 요청된 단계를 완료할 때까지 기다리십시오. 시스템이 자동으로 다시 평가합니다.
> * **webhook 포함 항목:** 다시 진행할 기능 목록과 사유가 담긴 `resubmit_info` 객체.
> * **전환 대상:** `"Approved"`, `"Declined"`, `"In Review"`, 또는 세션 기간이 끝날 때까지 사용자가 단계를 다시 진행하지 않으면 `"Abandoned"`.

> [accordion] 만료됨 ("Expired")
>
> **API 값:** `"Expired"`
>
> 사용자가 인증 링크를 열기 전에 세션 시간이 **초과된** 상태입니다.
>
> * **할 일:** 새 세션을 만들고 사용자에게 새 링크를 보내십시오.
> * **최종 상태**이므로 이후 전환은 없습니다.

> [accordion] 중단됨 ("Abandoned")
>
> **API 값:** `"Abandoned"`
>
> 사용자가 허용된 시간 안에 인증을 **시작했지만 완료하지 않은** 상태입니다.
>
> * **할 일:** 리마인더를 보내거나 새 세션을 만드십시오.
> * **자동 전환 없음.** 검토자 또는 `PATCH /v3/session/{sessionId}/update-status/`로 `"Approved"`, `"Declined"` 또는 `"Resubmitted"`로 설정할 수 있습니다.

> [accordion] KYC 만료됨 ("Kyc Expired")
>
> **API 값:** `"Kyc Expired"`
>
> 세션 중 검증된 문서가 **자체 만료일을 지난** 상태입니다. 전환의 트리거는 승인 시점부터 측정한 기간이 아니라 그 만료일이며, 사전 경고는 발송되지 않습니다.
>
> * **할 일:** 새 세션으로 재인증을 요청하십시오. `status.updated`로 전환이 전달되며, 신분증 인증 결과에는 `DOCUMENT_EXPIRED` 경고가 포함됩니다.
> * **제어 설정:** *ID verification → Additional settings by country & document type*에서 해당 국가 및 문서 유형의 **Expiration mode**로 제어됩니다. **Reject expired**(기본값)이면 문서를 모니터링하고, **Allow expired**이면 세션이 이 상태로 전환되지 않습니다.
> * **자동 전환 없음.** 검토자 또는 `PATCH /v3/session/{sessionId}/update-status/`로 `"Approved"`, `"Declined"` 또는 `"Resubmitted"`로 설정할 수 있습니다.

***

## 상태 전환

| 이전 상태 | 다음 상태 | 트리거 |
| - | - | - |
| `"Not Started"` | `"In Progress"` | 사용자가 인증 링크를 엽니다 |
| `"Not Started"` | `"Expired"` | 사용자가 링크를 열기 전에 세션 TTL이 경과합니다 |
| `"In Progress"` | `"Approved"` | 모든 자동 검사를 통과합니다 |
| `"In Progress"` | `"Declined"` | 하나 이상의 검사에 실패합니다 |
| `"In Progress"` | `"In Review"` | 검사에서 사람의 검토가 필요한 경고가 표시됩니다 |
| `"In Progress"` | `"Awaiting User"` | KYB 주요 인물 단계가 제출되었고, 상위 세션이 하위 KYC 당사자를 기다립니다 |
| `"In Progress"` | `"Abandoned"` | 사용자가 정해진 기간 안에 완료하지 않습니다 |
| `"Awaiting User"` | `"Approved"` | 필수 KYB 당사자가 모두 완료되고 종합 검사를 통과합니다 |
| `"Awaiting User"` | `"Declined"` | 필수 당사자가 거부되거나 KYB 등기부 검사에 실패합니다 |
| `"Awaiting User"` | `"In Review"` | 종합 KYB 결과에 수동 검토가 필요합니다 |
| `"In Review"` | `"Approved"` | 검토자가 수동으로 승인합니다 |
| `"In Review"` | `"Declined"` | 검토자가 수동으로 거부합니다 |
| `"In Review"` | `"Resubmitted"` | 검토자가 특정 단계를 다시 진행하도록 요청합니다 |
| `"Declined"` | `"Resubmitted"` | 검토자가 특정 단계를 다시 진행하도록 요청합니다 |
| `"Approved"` | `"Resubmitted"` | 검토자가 특정 단계를 다시 진행하도록 요청합니다 |
| `"Approved"` | `"Declined"` | 검토자 또는 API가 다른 결정을 설정합니다 |
| `"Declined"` | `"Approved"` | 검토자 또는 API가 다른 결정을 설정합니다 |
| `"Abandoned"`, `"Kyc Expired"` | `"Approved"`, `"Declined"`, `"Resubmitted"` | 결정 없이 종료된 세션에 대해 검토자 또는 API가 결정합니다 |
| `"Resubmitted"` | `"Abandoned"` | 사용자가 단계를 다시 진행하기 전에 세션 기간이 종료됩니다 |
| `"Resubmitted"` | `"Approved"` | 재제출된 단계가 모든 검사를 통과합니다 |
| `"Resubmitted"` | `"Declined"` | 재제출된 단계가 실패합니다 |
| `"Resubmitted"` | `"In Review"` | 재제출된 단계에서 새로운 경고가 표시됩니다 |
| `"Resubmitted"` (KYB 하위) | `"Awaiting User"` (KYB 상위) | 하위 세션이 완료될 때까지 상위 세션이 대기 상태로 돌아갑니다 |
| `"Approved"` | `"Kyc Expired"` | 인증된 문서의 만료일이 지납니다 (만료 모드는 **Reject expired**입니다) |

### 수명 주기 다이어그램

```mermaid theme={null}
flowchart LR
    NS["Not Started"] --> IP["In Progress"]
    NS --> EX["Expired"]
    IP --> AP["Approved"]
    IP --> DC["Declined"]
    IP --> IR["In Review"]
    IP --> AU["Awaiting User<br/>(KYB only)"]
    IP --> AB["Abandoned"]
    AU --> AP
    AU --> DC
    AU --> IR
    IR --> AP
    IR --> DC
    IR --> RS["Resubmitted"]
    DC --> RS
    AP --> RS
    AP <--> DC
    AB --> AP
    AB --> DC
    AB --> RS
    KE --> AP
    KE --> DC
    KE --> RS
    RS --> AB
    RS --> AP
    RS --> DC
    RS --> IR
    AP --> KE["Kyc Expired"]
```

***

## 최종 상태와 비최종 상태

| 분류 | 상태 | 의미 |
| - | - | - |
| **확정** | `"Approved"`, `"Declined"`, `"Kyc Expired"` | 검사로 결정이 내려졌으며, 스스로 바뀌지는 않습니다. 단, 인증된 문서의 만료일이 지나면 `"Approved"`가 `"Kyc Expired"`로 바뀝니다. 검토자 또는 상태 업데이트 endpoint는 여전히 결정을 변경할 수 있습니다. |
| **비최종** | `"Not Started"`, `"In Progress"`, `"Resubmitted"`, `"Awaiting User"` | 아직 진행 중입니다. 사용자 조치, 하위 세션 또는 처리를 기다리는 상태입니다. |
| **실행 가능** | `"In Review"` | 팀의 수동 조치가 필요합니다. |
| **비활성** | `"Expired"`, `"Abandoned"` | 인증 결정 없이 종료되었습니다. `"Expired"`는 변경되지 않습니다. 검토자는 여전히 `"Abandoned"` 세션에 결정을 내릴 수 있습니다. |

***

## 코드에서 상태 처리하기

webhook 또는 [세션 조회 API](https://docs.didit.me/ko/sessions-api/retrieve-session.md)를 사용하여 상태 변경에 대응하세요.

> [!WARNING]
>
> 상태는 **공백을 포함한 정확한 문자열이며, 대소문자를 구분합니다**. 예를 들어 `"In Review"`이며, `"in_review"`나 `"IN_REVIEW"`는 아닙니다. 비교할 때는 항상 엄격한 동등 비교(`===`)를 사용하세요.

```javascript theme={null}
// All ten possible status string values (StatusChoices, source of truth):
// "Not Started"  | "In Progress" | "Approved"     | "Declined" |
// "In Review"    | "Resubmitted" | "Awaiting User"|
// "Expired"      | "Abandoned"   | "Kyc Expired"

async function handleWebhook(webhook) {
  const { status, vendor_data: vendorData } = webhook;

  switch (status) {
    case "Not Started":
      // Session created but user hasn't opened the link yet
      break;

    case "In Progress":
      // User is actively completing verification steps
      break;

    case "Approved":
      // All checks passed — grant access
      await db.users.update(vendorData, {
        verified: true,
        verifiedAt: new Date(),
        decision: webhook.decision,
      });
      break;

    case "Declined":
      // Verification failed — notify user
      await db.users.update(vendorData, {
        verificationStatus: "declined",
        declineReasons: webhook.decision?.warnings,
      });
      break;

    case "In Review":
      // Needs manual review by compliance team
      await db.users.update(vendorData, {
        verificationStatus: "pending_review",
      });
      break;

    case "Awaiting User":
      // KYB parent waiting for all child KYC parties to finish
      await db.users.update(vendorData, {
        verificationStatus: "awaiting_kyb_parties",
      });
      break;

    case "Resubmitted":
      // User will redo specific steps
      await db.users.update(vendorData, {
        verificationStatus: "resubmission_pending",
        resubmitInfo: webhook.resubmit_info,
      });
      break;

    case "Abandoned":
      // User started but didn't finish — send reminder
      await sendReminderEmail(vendorData);
      break;

    case "Expired":
    case "Kyc Expired":
      // Session expired — create a new one
      await createNewSession(vendorData);
      break;
  }
}
```

***

## 재제출

**재제출됨** 상태를 사용하면 새 세션을 만들지 않고도 컴플라이언스 팀이 사용자에게 두 번째 기회를 줄 수 있습니다.

**1. 검토자가 재제출을 시작합니다**

Console에서 `In Review` 또는 `Declined` 세션을 열고 **재제출 요청**을 클릭합니다. 다시 진행해야 하는 단계를 선택합니다.

**2. 이전 데이터가 보관됩니다**

시스템이 선택된 기능을 초기화하고, 이전 데이터를 `previous_attempt`로 표시하여 전체 감사 추적을 유지합니다.

**3. 사용자에게 알림이 전송됩니다**

이메일이 있는 경우, 사용자는 진행을 재개할 수 있는 직접 링크가 포함된 현지화된 이메일을 받습니다.

**4. 사용자가 특정 단계를 다시 진행합니다**

사용자는 플래그가 지정된 단계만 반복합니다. 전체 인증을 다시 하지 않습니다.

**5. 시스템이 다시 평가합니다**

완료되면 세션은 자동으로 `"Approved"`, `"Declined"` 또는 `"In Review"`로 전환됩니다.

### 재제출 webhook 페이로드

```json theme={null}
{
  "session_id": "uuid-of-the-session",
  "status": "Resubmitted",
  "resubmit_info": {
    "nodes_to_resubmit": [
      { "node_id": "feature_ocr", "feature": "OCR" },
      { "node_id": "feature_liveness", "feature": "LIVENESS" }
    ],
    "reasons": {
      "feature_ocr": "DOCUMENT_EXPIRED",
      "feature_liveness": "LOW_LIVENESS_SCORE"
    }
  }
}
```

`reasons`는 재제출된 각 `node_id`를 해당 단계에서 가장 관련성이 높은 로그의 경고 코드에 매핑합니다(이 코드는 [결정](https://docs.didit.me/ko/reference/data-models.md)에서 보고되는 것과 같습니다). 이를 자체 문구에 맞게 매핑할 수 있습니다. 호스팅 흐름의 재제출 화면과 재제출 이메일은 이 코드를 사용해 사용자에게 현지화된 사유를 표시합니다. 다만 스크리닝 또는 사기 신호를 드러낼 수 있는 경고(중복, AML, 차단 목록, 조직 간 검사, 위치 무결성 등)는 예외입니다. 이 경우 사용자에게는 일반적인 사유가 표시되며, webhook의 `resubmit_info.reasons`에는 항상 실제 코드가 포함됩니다. 기록된 경고가 없는 단계는 항목이 없습니다.

### 어떤 기능을 재제출할 수 있나요?

승인되지 않은 상태인 모든 기능을 재제출할 수 있습니다. 여기에는 **거부됨**, **검토 중**, **완료되지 않음**, **시작되지 않음**, **만료됨**이 포함됩니다.

> [!TIP]
>
> 같은 세션에서 재제출을 여러 번 요청할 수 있습니다. 재제출할 때마다 이전 시도 데이터가 보관되므로, 사용자의 인증 이력을 완전히 확인할 수 있습니다.

***

## 권장 사항

> [card] 검토 중 상태 모니터링
>
> Didit Console에서 알림(이메일 또는 Slack)을 설정하면 세션에 수동 검토가 필요할 때 알림을 받을 수 있습니다.

> [card] 재제출 우선
>
> 문제를 해결할 수 있는 경우(흐릿한 사진, 문서의 잘못된 면)에는 거부하는 대신 재제출을 요청하십시오. 이렇게 하면 전환율이 높아집니다.

> [card] 이탈 추적
>
> 중단됨 또는 만료됨 비율이 높다면 UX에 마찰이 있을 수 있습니다. 세션 TTL을 조정하거나 사용자 안내를 개선하는 것을 고려하십시오.

> [card] 멱등성 핸들러
>
> webhook은 재시도될 수 있습니다. `session_id`를 고유 키로 사용하면 각 상태 변경을 한 번만 처리할 수 있습니다.

> [!WARNING]
>
> payload를 처리하기 전에 항상 webhook 서명을 검증하십시오. Didit은 세 가지 방식을 제공합니다. `X-Signature`, `X-Signature-V2`(권장), 그리고 더 이상 사용되지 않는 `X-Signature-Simple`입니다. 이 방식은 엔벨로프만 인증하며 `decision` 본문은 절대 인증하지 않습니다. 자세한 내용은 [Webhooks](https://docs.didit.me/ko/integration/webhooks.md#서명-검증)를 참조하십시오.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.