메인 콘텐츠로 건너뛰기

개요

리워드 광고의 서버 사이드 검증(SSV, Server-Side Verification) 을 사용하면, 사용자가 광고 시청을 완료했을 때 Adrop 서버가 지정된 서버 URL로 콜백을 전송합니다. 서버에서 보상 지급을 직접 검증하여 어뷰징을 방지할 수 있어요. 콜백 페이로드는 API 키로 암호화되므로, URL이 외부에 노출되더라도 API 키를 가진 주체만 내용을 복호화할 수 있습니다.

설정하기

1

API 키 준비

SSV 콜백 페이로드 복호화에 사용할 API 키를 먼저 발급하세요. 프로젝트에 활성 API 키가 1개 이상 있어야 SSV를 등록할 수 있어요.발급 방법은 연동 & API 키 문서를 참고하세요.
2

SSV 등록

콘솔 [관리] > [연동] > 리워드 광고 SSV 섹션에서 [+ 리워드 광고 SSV 등록] 버튼을 누릅니다.
항목설명
URL보상 완료 시 호출할 서버 URL. https://로 시작해야 합니다.
연결할 API 키콜백 페이로드 복호화에 사용할 API 키. 기본값은 가장 최근에 만든 활성 키.
3

SDK에서 userId / customData 전달

SDK에서 setServerSideVerificationOptions()userIdcustomData를 설정하면, 해당 값이 콜백 페이로드에 포함되어 서버로 전달됩니다.각 플랫폼별 설정 방법은 아래 문서를 참고하세요.
등록/수정 시 HTTPS URL만 허용되며, 사설 IP(localhost, 10.x, 172.16~31.x, 192.168.x, 169.254.x)는 차단됩니다.

요청 사양

Adrop 서버는 다음과 같이 콜백을 전송합니다.
항목
MethodPOST
Content-Typeapplication/json
재시도최대 3회 (0ms / 1s / 2s 간격)
타임아웃요청당 5초
성공 조건HTTP 200 응답
요청 바디는 AES-256-GCM으로 암호화되어 전달됩니다.
{
  "encrypted": "<ivHex>:<tagHex>:<ciphertextHex>"
}
각 구간은 콜론(:)으로 구분된 hex 문자열입니다. 복호화 후 얻어지는 평문 JSON 스펙은 다음과 같습니다.
필드타입설명
projectstringAdrop 프로젝트 ID
appstringAdrop 앱 ID
unitstringAdrop 광고 유닛 ID
adNetworkstring광고 네트워크 식별자
adUnitstring광고 네트워크 내 유닛 식별자
userIdstring?SDK에서 설정한 사용자 식별자
customDatastring?SDK에서 설정한 커스텀 데이터
rewardItemstring보상 아이템명
rewardAmountnumber보상 수량
transactionIdstring트랜잭션 ID (중복 방지용 고유값)
timestampnumber콜백 발생 시각 (Unix ms)
transactionId는 고유값입니다. 서버에서 이미 처리한 transactionId를 다시 수신하면 중복 보상을 지급하지 않도록 멱등(idempotent) 처리하는 것을 권장합니다.

페이로드 복호화

AES-256-GCM 키는 API 키 원문을 SHA-256 해시한 32바이트입니다.

Node.js

import { createDecipheriv, createHash } from 'node:crypto'
import express from 'express'

function decryptSsvPayload(encrypted, apiKey) {
  const [ivHex, tagHex, ciphertextHex] = encrypted.split(':')
  const key = createHash('sha256').update(apiKey).digest() // 32바이트

  const decipher = createDecipheriv('aes-256-gcm', key, Buffer.from(ivHex, 'hex'))
  decipher.setAuthTag(Buffer.from(tagHex, 'hex'))

  const plaintext = Buffer.concat([
    decipher.update(Buffer.from(ciphertextHex, 'hex')),
    decipher.final()
  ]).toString('utf8')

  return JSON.parse(plaintext)
}

const app = express()

app.post('/ssv-callback', express.json(), (req, res) => {
  const payload = decryptSsvPayload(req.body.encrypted, process.env.ADROP_API_KEY)
  // payload.userId, payload.customData, payload.rewardAmount 등으로 보상 지급 처리
  res.sendStatus(200)
})

Python

import hashlib
import json
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

def decrypt_ssv_payload(encrypted: str, api_key: str) -> dict:
    iv_hex, tag_hex, ciphertext_hex = encrypted.split(':')
    key = hashlib.sha256(api_key.encode()).digest()  # 32바이트

    aesgcm = AESGCM(key)
    # AESGCM은 ciphertext + tag가 이어진 형태를 기대
    plaintext = aesgcm.decrypt(
        bytes.fromhex(iv_hex),
        bytes.fromhex(ciphertext_hex) + bytes.fromhex(tag_hex),
        None
    )
    return json.loads(plaintext)
SSV 콜백은 URL이 외부로 노출되더라도 Adrop API 키를 가진 주체만 복호화할 수 있도록 설계돼 있습니다. SSV에 연결된 API 키가 노출되면 서버에서 즉시 폐기하고, 연동 메뉴에서 새 API 키로 교체하세요.

수정 및 삭제

등록된 SSV는 리워드 광고 SSV 섹션 우측 메뉴에서 수정 또는 삭제할 수 있어요.
  • 수정: URL 또는 연결된 API 키를 변경합니다.
  • 삭제: 콜백이 더 이상 호출되지 않습니다. 삭제 후에도 SDK의 userId / customData는 Adrop 내부 SSV 로그에 저장됩니다.

관련 문서

연동 & API 키

API 키 발급, 관리, 폐기 방법

리포트 API

캠페인 성과 및 백필 수익 데이터를 API로 조회하는 방법