# 보상형 광고 플러스 연동

## 1. 유저 식별값(USN) 입력

보상형 광고 플러스 기능을 활성화 및 활용하기 위해서는 반드시 유저의 식별값이 지정되어야 합니다.

유저 식별값은 리워드 지급 조건이 달성되었을 때 **완료 유저를 식별하기 위해 사용되는 고유한 값**입니다.

{% hint style="danger" %}
**주의 사항**

1. 1명의 유저는 반드시 1개의 고유한 유저 식별값(USN)을 가져야 하며, 앱 실행 시점이나 세션마다 변경되는 가변적인 값은 사용할 수 없습니다.
2. 개인정보(이메일, 이름, 전화번호, 식별 가능한 유저 아이디 등)이 포함되어서는 안됩니다.
3. USN으로 사용하기에 적합하지 않은 값의 예시는 다음과 같습니다.&#x20;
   1. 디바이스 ID(Android ID, Advertising ID, IDFA 등)&#x20;
   2. 앱 재설치, 기기 변경, 초기화 등에 따라 변경될 수 있는 값
4. 한글, 특수 문자, 공백 등이 포함된 경우에는 반드시 URL 인코딩 처리를 하여 사용하여야 합니다.
5. USN은 비디오 광고 로딩 이전에 반드시 설정되어 있어야 합니다.
6. <mark style="color:red;">**개발 서버에서 사용한 특정 USN값을 라이브 서버에서 유저가 할당받지 않도록 예외 처리를 하거나, 개발 서버에서 사용하는 USN은 별도 구분값을 설정해주셔야 합니다.**</mark>
   {% endhint %}

위 주의사항에 유의하여 유저 식별값을 입력합니다.

```csharp
AdPopcornSSPPlugin.setUserId("userId");
```

## 2. 보상형 광고 플러스 세팅 페이지 연동

유저의 CS 문의 및 현재 리워드 참여 횟수 확인을 위해서는 세팅 페이지 연동이 반드시 필요합니다.

유저의 보상형 광고 플러스 정보는 아래 API를 통해 확인 가능합니다.&#x20;

```csharp
AdPopcornSSPPlugin.openRewardAdPlusPage(string version);
```

현재 지원하는 버전은 아래와 같습니다. 아래의 버전 정보를 입력해야 합니다.

* v1.5 = "1.5"

<figure><img src="/files/jYn6DnfPnQ8nxFUrhNxi" alt="" width="360"><figcaption><p>v1.5 보상형 광고 플러스 설정 페이지 예시</p></figcaption></figure>

## 3. 보상형 광고 플러스 델리게이트 지원

보상형 광고 플러스에서 발생되는 아래 이벤트들에 대해선 이벤트 리스너로 이벤트를 전달해 줍니다.

* OnClosedRewardAdPlusPage : 보상형 광고 세팅 페이지 닫기
* OnEventResult : 1차 광고 참여 완료 후 포인트 박스 지급 성공 or 실패에 대한 이벤트

```csharp
AdPopcornSSPPlugin.setRewardAdPlusEventListener(this);
```

```csharp
public class AdPopcornSSPSampleScene : MonoBehaviour, 
                    IRewardAdPlusEventCallbackListener
{
    void Start (){
        AdPopcornSSPPlugin.setRewardAdPlusEventListener(this);
    }
	
    void IRewardAdPlusEventCallbackListener.OnClosedRewardAdPlusPage()
    {
    }

    void IRewardAdPlusEventCallbackListener.OnEventResult(int resultCode, string resultMessage)
    {
        
    }
}
```

## 4. 보상형 광고 플러스 사용자 정보 조회

현재 유저의 사용 정보를 직접 조회하고자 할 땐, 아래의 API를 활용 가능합니다.

4.1 유저의 매체 전체 지면에 대한정보 조회

```csharp
AdPopcornSSPPlugin.getRewardPlusUserSetting(string placementId, IRewardAdPlusUserStatusEventCallbackListener listener);
```

* 전체 조회하고자 할 경우에는 placementId에 null 이 들어가면 됩니다.

4.2 유저의 지면별 정보 조회

```csharp
AdPopcornSSPPlugin.getRewardPlusUserSetting(string placementId, IRewardAdPlusUserStatusEventCallbackListener listener);
```

* 조회하고자 하는 지면키를 placementId 파라미터로 넘겨주세요.

```csharp
public class AdPopcornSSPSampleScene : MonoBehaviour, 
		IRewardAdPlusUserStatusEventCallbackListener
{
    [System.Serializable]
    public class RewardAdPlacementStatusModel
    {
        public string placementId;        
        public int dailyUserLimit;
        public int dailyUserCount;        
    }

    [System.Serializable]
    public class RewardAdPlacementStatusListWrapper
    {
        public List<RewardAdPlacementStatusModel> placements;
    }
    
    void Start (){	
        AdPopcornSSPPlugin.getRewardPlusUserSetting(null, this);
    }
	
    // RewardPlus Setting Event Callback
    void IRewardAdPlusUserStatusEventCallbackListener.OnRewardAdPlusUserMediaStatus(bool result, int totalBoxCount, string placementStatusListJson)
    {
        Debug.Log("AdPopcornSSP.OnRewardAdPlusUserMediaStatus : " + result + ", totalBoxCount : " + totalBoxCount + ", placementStatusListJson : " + placementStatusListJson);
        string wrappedJsonString = "{\"placements\":" + placementStatusListJson + "}";

        // Wrapper 클래스를 사용하여 파싱하여 직접 파싱해야 합니다.
        RewardAdPlacementStatusListWrapper wrapper = JsonUtility.FromJson<RewardAdPlacementStatusListWrapper>(wrappedJsonString);
        List<RewardAdPlacementStatusModel> placementStatusList = wrapper.placements;

        if (placementStatusList != null)
        {
            Debug.Log($"Unity: Parsed {placementStatusList.Count} placement statuses.");
            foreach (var status in placementStatusList)
            {
                Debug.Log($"  Placement ID: {status.placementId}, Limit: {status.dailyUserLimit}, Count: {status.dailyUserCount}");
            }
        }
        else
        {
            Debug.LogWarning("Unity: placementStatusList is null after parsing.");
        } 
    }

    void IRewardAdPlusUserStatusEventCallbackListener.OnRewardAdPlusUserPlacementStatus(bool result, string placementId, int dailyUserLimit, int dailyUserCount)
    {
        Debug.Log("AdPopcornSSP.OnRewardAdPlusUserPlacementStatus. " + placementId + ", dailyUserLimit : " + dailyUserLimit + ", dailyUserCount : " + dailyUserCount);
    }

}
```

* OnRewardAdPlusUserMediaStatus  : 매체에 활성화된 전체 리워드 애드 플러스 지면에 대한 정보.
  * result : 조회 성공 여부
  * totalBoxCount : 전체 받은 포인트 박스
  * placementStatusListJson
    * placementId : 조회 한 지면 키
    * dailyUserLimit : 일별 유저 한도
    * dailyUserCount : 일별 유저 참여 횟수
  * Native -> Unity 메시지 전달 방식에 따라 Json 데이터를 직접 파싱하여 정보를 받아야 합니다. Unity내 기본 Json 라이브러리 사용시에는 위 샘플과 같이 처리하면 됩니다.
* OnRewardAdPlusUserPlacementStatus : 특정 지면에 대한 정보를 제공
  * result : 조회 성공 여부
  * placementId : 조회 한 지면 키
  * dailyUserLimit : 일별 유저 한도
  * dailyUserCount : 일별 유저 참여 횟수


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://adpopcornssp.gitbook.io/ssp-sdk/sdk/unity/unity-android/undefined-2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
