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

# WebView 테스트 모드

> 라이브 환경에서 WebView 연동을 검증하는 테스트 모드 사용법

캠페인 오픈 전에 WebView 연동이 정상 동작하는지 **라이브 환경에서** 검증할 수 있습니다. 테스트 모드에서는 실제 DB에 데이터를 기록하지 않으면서, 웹훅은 실제로 발송되어 게임 서버의 수신 로직까지 검증 가능합니다.

<Warning>
  테스트 모드는 **쿠폰에는 적용되지 않습니다**. 테스트 모드에서도 쿠폰을 사용하면 실제 쿠폰이 소진됩니다.
</Warning>

## 동작 원칙

| 항목           | 테스트 모드 동작                                           |
| ------------ | --------------------------------------------------- |
| 크리에이터        | Mock 데이터 반환 (TEST1, TEST2, TEST3)                   |
| 부스트 등록/변경/해제 | Mock 응답 + **실제 웹훅 발송** (DB 미기록)                     |
| 부스트 상태 조회    | 세션에 저장 — 등록 후 조회 시 유지됨                              |
| 캠페인 목록       | **실제 DB 조회** — `COMPLETED`, `CANCELLED` 제외 전체 상태 포함 |
| 캠페인 상세       | **실제 DB 조회**                                        |
| 쿠폰           | **미적용** — 실제 쿠폰이 소진됩니다                              |
| WebView UI   | 상단에 보라색 "TEST MODE" 배너 표시                           |

## 전체 흐름

```mermaid theme={null}
sequenceDiagram
    participant S as 게임 서버
    participant P as PlayCamp SDK API
    participant W as WebView

    S->>P: OTT 발급 (isTest: true)
    P-->>S: OTT 반환
    S-->>W: OTT 전달 → WebView 열기
    Note over W: 보라색 TEST MODE 배너 표시
    W->>P: 크리에이터 검색 → Mock 데이터 반환
    W->>P: 부스트 등록
    P-->>S: 웹훅 발송 (_isTestData: true)
    Note over S: DB 기록 없이 웹훅만 수신
```

## Step 1: OTT 발급 시 `isTest: true` 추가

게임 서버에서 OTT를 발급할 때 `isTest: true`를 추가하면 해당 세션 전체가 테스트 모드로 동작합니다.

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://sdk-api.playcamp.io/v1/server/webview/ott" \
      -H "Authorization: Bearer {SERVER_KEY}" \
      -H "Content-Type: application/json" \
      -d '{
        "userId": "user-123",
        "campaignId": "camp-abc",
        "isTest": true
      }'
    ```
  </Tab>

  <Tab title="Node SDK">
    ```typescript theme={null}
    const { ott } = await server.webview.createOtt({
      userId: 'user-123',
      campaignId: 'camp-abc',
      isTest: true,
    });
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    result, err := server.Webview.CreateOTT(ctx, playcamp.WebviewOttParams{
        UserID:     "user-123",
        CampaignID: "camp-abc",
        IsTest:     true,
    })
    ```
  </Tab>
</Tabs>

<Note>
  `isTest`는 OTT → 세션으로 전파되어 세션 수명 동안 유지됩니다. WebView URL이나 클라이언트에서 별도로 설정할 수 없으며, 반드시 OTT 발급 시 Server API Key로 설정해야 합니다.
</Note>

## Step 2: WebView에서 테스트 진행

테스트 모드 WebView에 진입하면 상단에 보라색 **TEST MODE** 배너가 표시됩니다.

### 캠페인 목록

일반 모드에서는 `IN_PROGRESS`, `COMPLETED` 상태의 캠페인만 표시되지만, 테스트 모드에서는 **작성 중/심사 단계 캠페인**까지 표시됩니다:

| 모드  | 허용                                                                                  | 차단                       |
| --- | ----------------------------------------------------------------------------------- | ------------------------ |
| 일반  | `IN_PROGRESS`, `COMPLETED`                                                          | 그 외 전체                   |
| 테스트 | `DRAFT`, `PENDING_REVIEW`, `REJECTED`, `PENDING_EXPOSURE`, `EXPOSED`, `IN_PROGRESS` | `COMPLETED`, `CANCELLED` |

캠페인 작성 단계(`DRAFT`)부터 오픈 전(`EXPOSED`, `PENDING_EXPOSURE`)까지 WebView QA가 가능합니다.

### 크리에이터

테스트 모드에서는 고정된 Mock 크리에이터가 반환됩니다:

| creatorKey | creatorName     | status |
| ---------- | --------------- | ------ |
| `TEST1`    | \[Mock] Alpha   | TEST   |
| `TEST2`    | \[Mock] Bravo   | TEST   |
| `TEST3`    | \[Mock] Charlie | TEST   |

### 부스트

부스트 등록/변경/해제 시:

* **DB 기록**: 없음
* **응답**: Mock 데이터
* **웹훅**: **실제 발송** (`_isTestData: true` 포함)
* **세션 상태**: Redis 세션에 저장되어 새로고침 후에도 유지

## Step 3: 웹훅 수신 및 `_isTestData` 처리

테스트 모드에서 발생한 웹훅에는 `_isTestData: true` 필드가 포함됩니다:

```json theme={null}
{
  "events": [
    {
      "event": "sponsor.created",
      "data": {
        "userId": "user-123",
        "campaignId": "camp-abc",
        "creatorKey": "TEST1",
        "_isTestData": true
      },
      "timestamp": "2026-04-16T05:00:00.000Z",
      "callbackId": "..."
    }
  ]
}
```

게임 서버의 웹훅 핸들러에서 `_isTestData`를 확인하여 테스트 웹훅과 실제 웹훅을 구분하세요:

<Tabs>
  <Tab title="Node.js">
    ```typescript theme={null}
    app.post('/webhooks/playcamp', (req, res) => {
      for (const { event, data } of req.body.events) {
        if (data._isTestData) {
          console.log(`[TEST] ${event}`, data);
          continue;
        }

        // 실제 처리 로직
      }

      res.json({ received: true });
    });
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    for _, evt := range payload.Events {
        if evt.Data.IsTestData {
            log.Printf("[TEST] %s: %+v", evt.Event, evt.Data)
            continue
        }

        // 실제 처리 로직
    }
    ```
  </Tab>
</Tabs>

적용 대상 이벤트: `sponsor.created`, `sponsor.changed`, `sponsor.ended`

<Warning>
  OTT 발급 시 `campaignId`를 지정하지 않으면 웹훅 payload의 `campaignId`가 `'TEST_CAMPAIGN'`(리터럴)으로 설정됩니다. 게임 서버에서 이 값으로 캠페인 조회를 시도하면 404가 반환되므로, `_isTestData: true`인 웹훅에서는 `campaignId` 조회를 건너뛰도록 처리하세요.
</Warning>

## 주의사항

* **쿠폰은 테스트 모드 미적용**: 테스트 모드에서도 쿠폰 사용 시 실제 쿠폰이 소진됩니다
* **Sandbox vs Live**: 테스트 모드는 Live 환경에서도 안전하게 사용할 수 있습니다. Sandbox 환경과 병행하여 사용 가능합니다
* **연동 검증 인정**: `isTest: true`로 호출해도 [연동 완료 조건](/ko/guides/developers/game-integration/test-mode#연동-완료-조건)에 포함됩니다

## 관련 문서

* [WebView + 웹훅 연동](/ko/guides/developers/game-integration/cases/webview-webhook) — WebView 연동 전체 흐름
* [WebView 연동](/ko/guides/developers/game-integration/webview) — OTT 발급, URL 구성, 보안 상세
* [웹훅 이벤트](/ko/guides/developers/game-integration/webhook) — 웹훅 수신 및 서명 검증
* [테스트 모드](/ko/guides/developers/game-integration/test-mode) — Server/Client API의 isTest 사용법
