오퍼 검증 API
개요
플레이어가 오퍼 메시지를 열람하고 구매 버튼을 클릭하는 등 오퍼를 수락하면 다음 단계로 진행하기 전에 REST API를 이용해 오퍼를 검증해야 합니다. 이 검증 API를 사용하면 해당 오퍼가 텐투플레이 서버에서 온 것으로 신뢰성과 무결성, 그리고 보안 면에서 문제가 없다는 것을 확인할 수 있습니다. 오퍼 검증은 개인화 오퍼와 AI 인게임 상점 모두 적용 가능하며 응답 메시지만 차이가 납니다.
오퍼 검증하기
검증 API 사용 전에 텐투플레이에 아래의 키 정보를 요청하여 받으십시오.
|
API키 보안 프론트엔드 앱에 API키가 노출되지 않도록 요청 결과를 가져올 때에 백엔드 서버를 통해 결과가 프론트엔드에 전달되도록 하십시오. |
API 메소드
오퍼 검증
플레이어가 받은 오퍼 id에 대한 검증 요청
요청 Body
-
Content type: application/json
이름 | 설명 | 자료형 | 필수여부 | 기본값 |
---|---|---|---|---|
|
플레이어의 고유 id |
string |
필수 |
없음 |
|
오퍼 id |
integer |
필수 |
없음 |
Body 예시
{
"player_uuid": "string",
"offer_id": 10
}
응답
인증 성공
HTTP/1.1 200 OK
Content-Type:application/json
{
"success": true, //boolean
"result": "(string encoded in base64)"
}
응답 데이터는 AES-256-CTR 알고리즘으로 암호화되어있습니다. 결과 문자열은 임시값(nonce)과 암호화된 데이터가 결합되어 있으며 헥사로 인코딩되어 있습니다. 디코딩된 데이터의 앞 12바이트가 임시값입니다.
디코딩 후 데이터 파트는 payload 키를 이용하여 복호화해야 합니다. 가령 다음 예시 코드는 Python으로 쓰여진 복호화 코드입니다.
result = response.data['result']
byte_data = binascii.unhexlify(result.encode('utf-8'))
nonce = byte_data[:8]
encrypted_bytes = byte_data[8:]
cipher = AES.new(payload_key.encode('utf-8'), AES.MODE_CTR, nonce=nonce)
decrypted_bytes = cipher.decrypt(encrypted_bytes)
raw_data = decrypted_bytes.decode('utf-8')
복호화에 성공하면 응답 메시지의 JSON body를 다음 예시와 같이 볼 수 있습니다. 응답 메시지는 오퍼의 종류에 따라 다릅니다.
복호화된 데이터 예시
- 수동 오퍼 (개인화 오퍼)
-
{ "player_uuid": "", "offer": { "price": 99.99, "message": { "en": { "url": "https://", "image": "https://", "title": "" } }, "product_id": "", "product_name": "", "discount_rate": 10, "discount_price": 89.99, "message_layout": "h" }, "is_opened": true, "expire_at": "YYYY-MM-DD hh:mm:ss" // 값이 없으면 기간에 제한이 없음을 의미 }
- AI 오퍼 (AI 인게임 상점)
-
{ "player_uuid": "", "offer": { "offer_type": "ai", "recommendations": [ { "store": "google", "product_list": [ { "purchasable_slug": "diamond_500", "product_index": "", "purchase_link": "", "start_datetime": "YYYY-MM-DD hh:mm:ss", "end_datetime": "YYYY-MM-DD hh:mm:ss" } ] } ], "display_parameters": { "en": { "title": "", "message": "", "background_url": "https://", "toggle_message": "don't see me again today" } }, { "player_uuid": "", "offer": { "offer_type": "ai", "recommendations": [ { "store": "google", "product_list": [ { "purchasable_slug": "diamond_500", "product_index": "", "purchase_link": "", "start_datetime": "YYYY-MM-DD hh:mm:ss", "end_datetime": "YYYY-MM-DD hh:mm:ss" } ] } ], "display_parameters": { "en": { "title": "", "message": "", "background_url": "https://", "toggle_message": "don't see me again today" } }, "message_parameters": { "<parameter_in_message>": { "entity": "<purchasable|characterarchetype|item|...>", "slug": "" } } }, "is_opened": true, "expire_at": "YYYY-MM-DD hh:mm:ss" // 값이 없으면 기간에 제한이 없음을 의미 }