UA ๋ชจ์•„๋ณด๊ธฐ(SIS) ์—ฐ๋™ ๊ฐ€์ด๋“œ

UA ๋ชจ์•„๋ณด๊ธฐ(SIS) ์—ฐ๋™ ๊ฐ€์ด๋“œ

Index

1. ๊ฐœ์š”

๋ฒ„์ฆˆ๋นŒ SIS ๊ด‘๊ณ  ์ œํ’ˆ์„ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ€์ด๋“œ์ž…๋‹ˆ๋‹ค. ํ•„์ˆ˜ ์ •๋ณด๋ฅผ pquery ํ˜•ํƒœ๋กœ ๋„˜๊ฒจ์ฃผ์…”์•ผ ๊ด‘๊ณ  ํ• ๋‹น์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

2. ๊ธฐ๋ณธ URL ๊ตฌ์กฐ

https://ad.buzzvil.com/action/api/ads/uahub/buzzad?pquery=[์ธ์ฝ”๋”ฉ๋œ_ํŒŒ๋ผ๋ฏธํ„ฐ]&custom=[์ปค์Šคํ…€_ํŒŒ๋ผ๋ฏธํ„ฐ]&custom2=[์ปค์Šคํ…€2_ํŒŒ๋ผ๋ฏธํ„ฐ]

2025.07.02 pquery ํ‚ค ๋Œ€์‹  p๋กœ๋„ ์ง„์ž… ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

3. ํŒŒ๋ผ๋ฏธํ„ฐ (pquery)

pquery ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋‹ค์Œ ์ •๋ณด๋ฅผ ํฌํ•จํ•œ JSON ๊ฐ์ฒด๋ฅผ URI ์ธ์ฝ”๋”ฉ ํ›„ Base64๋กœ ์ธ์ฝ”๋”ฉํ•˜์—ฌ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

3.1 ํ•„์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ

ํŒŒ๋ผ๋ฏธํ„ฐ

์„ค๋ช…

์˜ˆ์‹œ

ํŒŒ๋ผ๋ฏธํ„ฐ

์„ค๋ช…

์˜ˆ์‹œ

unit_id

๋ฒ„์ฆˆ๋นŒ์—์„œ ๋ฐœ๊ธ‰๋“œ๋ฆฐ ๊ณ ์œ  ์‹๋ณ„์ž

1234567

puid

๋งค์ฒด์‚ฌ ์•”ํ˜ธํ™” ์œ ์ € ID

"user123"

ifa

๊ด‘๊ณ  ID

"a31752d2-5d7e-4f41-a45c-af4d39d2fb2d"

client_ip

์‚ฌ์šฉ์ž์˜ IP ์ฃผ์†Œ

"192.168.1.1"

platform

์šด์˜ ์ฒด์ œ ์ •๋ณด

"A" (Android) ๋˜๋Š” "I" (iOS)

3.2 ์„ ํƒ์  ํŒŒ๋ผ๋ฏธํ„ฐ

ํŒŒ๋ผ๋ฏธํ„ฐ

์„ค๋ช…

์˜ˆ์‹œ

ํŒŒ๋ผ๋ฏธํ„ฐ

์„ค๋ช…

์˜ˆ์‹œ

birthday

์ƒ๋…„์›”์ผ (์šฐ์„ ์ˆœ์œ„ ๋†’์Œ)

"1990-01-01"

year_of_birth

์ถœ์ƒ๋…„๋„

"1990"

sex

์„ฑ๋ณ„

"M" ๋˜๋Š” "F"

region

์ง€์—ญ

"์„œ์šธํŠน๋ณ„์‹œ ๊ฐ•๋‚จ๊ตฌ"

device_name

๋‹จ๋ง๊ธฐ๊ธฐ ์ •๋ณด

"SHV-E250S"

carrier

ํ†ต์‹ ์‚ฌ

"kt", "skt", "lgt" ๋˜๋Š” null

currency_unit

์žฌํ™” ๋‹จ์œ„

โ€œPโ€, โ€œ์บ์‹œโ€, โ€œ์›โ€, โ€œMโ€

won_to_currency_rate

์›ํ™” ๊ธฐ์ค€ ํ™˜์‚ฐ์œจ

1

3.3 ์˜ต์…”๋„ ํŒŒ๋ผ๋ฏธํ„ฐ(์ธ์ฝ”๋”ฉ ์ ์šฉ ์•ˆํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ)

ํŒŒ๋ผ๋ฏธํ„ฐ

์„ค๋ช…

์˜ˆ์‹œ

ํŒŒ๋ผ๋ฏธํ„ฐ

์„ค๋ช…

์˜ˆ์‹œ

custom

๋งค์ฒด์‚ฌ๋ณ„ custom data ํ•„๋“œ

json ํ•„๋“œ

custom2

๋งค์ฒด์‚ฌ๋ณ„ custom data ํ•„๋“œ

json ํ•„๋“œ

ย 

4. ํŒŒ๋ผ๋ฏธํ„ฐ ์ธ์ฝ”๋”ฉ ๊ณผ์ •

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ธฐ์ค€์˜ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

  1. JSON ๊ฐ์ฒด ์ƒ์„ฑ

  2. URI ์ธ์ฝ”๋”ฉ (JavaScript์˜ encodeURIComponent() ํ•จ์ˆ˜ ์‚ฌ์šฉ)

  3. Base64 ์ธ์ฝ”๋”ฉ (JavaScript์˜ btoa() ํ•จ์ˆ˜ ์‚ฌ์šฉ)

ย 

์˜ˆ์‹œ JSON

{ "puid": "์•”ํ˜ธํ™”๋œ ์œ ์ € ID", "ifa": "a31752d2-5d7e-4f41-a45c-af4d39d2fb2d", "birthday": "1990-01-01", "year_of_birth": "1989", "sex": "M", "platform": "A", "carrier": "kt", "device_name": "SHV-E250S", "region": "์„œ์šธํŠน๋ณ„์‹œ ๊ฐ•๋‚จ๊ตฌ" }
'{"puid":"์•”ํ˜ธํ™”๋œ ์œ ์ € ID","ifa":"a31752d2-5d7e-4f41-a45c-af4d39d2fb2d","birthday":"1990-01-01","year_of_birth":"1989","sex":"M","platform":"A","carrier":"kt","device_name":"SHV-E250S","region":"์„œ์šธํŠน๋ณ„์‹œ ๊ฐ•๋‚จ๊ตฌ"}'

URI ์ธ์ฝ”๋”ฉ

let jsonString = '{"puid":"์•”ํ˜ธํ™”๋œ ์œ ์ € ID","ifa":"a31752d2-5d7e-4f41-a45c-af4d39d2fb2d","birthday":"1990-01-01","year_of_birth":"1989","sex":"M","platform":"A","carrier":"kt","device_name":"SHV-E250S","region":"์„œ์šธํŠน๋ณ„์‹œ ๊ฐ•๋‚จ๊ตฌ"}'; let uriEncodedString = encodeURIComponent(jsonString);

Base64 ์ธ์ฝ”๋”ฉ

let base64EncodedString = btoa(uriEncodedString);

์ตœ์ข… p๊ฐ’ ์ƒ์„ฑ

์œ„์—์„œ ์–ป์€ Base64 ์ธ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์—ด์ด ์ตœ์ข…์ ์œผ๋กœ p ์ฟผ๋ฆฌ ๊ฐ’์ด ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ’์„ URL์˜ ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ฒจ์ฃผ์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.

https://ad.buzzvil.com/action/api/ads/uahub/buzzad?pquery=JTdCJTIyaWZhJTIyJTNBJTIyRVRFR0RHUkVHLTExQUFBLUJCQjIyMzQ1JTIyJTJDJTIyYWdlJTIyJTNBMzAlMkMlMjJzZXglMjIlM0ElMjJNJTIyJTJDJTIycGxhdGZvcm0lMjIlM0ElMjJBJTIyJTJDJTIyY2FycmllciUyMiUzQSUyMmt0JTIyJTJDJTIyZGV2aWNlX25hbWUlMjIlM0ElMjJTSFYtRTI1MFMlMjIlMkMlMjJyZWdpb24lMjIlM0ElMjIlRUMlODQlOUMlRUMlOUElQjglRUQlOEElQjklRUIlQjMlODQlRUMlOEIlOUMlMjAlRUElQjAlOTUlRUIlODIlQTglRUElQjUlQUMlMjIlN0Q=

2025.07.02 ๋˜๋Š”,

https://ad.buzzvil.com/action/api/ads/uahub/buzzad?p=JTdCJTIyaWZhJTIyJTNBJTIyRVRFR0RHUkVHLTExQUFBLUJCQjIyMzQ1JTIyJTJDJTIyYWdlJTIyJTNBMzAlMkMlMjJzZXglMjIlM0ElMjJNJTIyJTJDJTIycGxhdGZvcm0lMjIlM0ElMjJBJTIyJTJDJTIyY2FycmllciUyMiUzQSUyMmt0JTIyJTJDJTIyZGV2aWNlX25hbWUlMjIlM0ElMjJTSFYtRTI1MFMlMjIlMkMlMjJyZWdpb24lMjIlM0ElMjIlRUMlODQlOUMlRUMlOUElQjglRUQlOEElQjklRUIlQjMlODQlRUMlOEIlOUMlMjAlRUElQjAlOTUlRUIlODIlQTglRUElQjUlQUMlMjIlN0Q=

5. ์ฃผ์˜์‚ฌํ•ญ

  • birthday์™€ year_of_birth ์ค‘ birthday๊ฐ€ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์Šต๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ ๋‚˜์ด ๊ณ„์‚ฐ์„ ์œ„ํ•ด ๊ฐ€๋Šฅํ•œ birthday๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

  • ๋ชจ๋“  ์„ ํƒ์  ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๊ฐ€๋Šฅํ•œ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์„ ํƒ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ํ• ๋‹น ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๊ด‘๊ณ  ๋ฌผ๋Ÿ‰์— ์ œํ•œ์ด ์ƒ๊น๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์„ฑ๋ณ„ ์ •๋ณด๋ฅผ ๋ณด๋‚ด์ฃผ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์„ฑ๋ณ„ ํƒ€๊ฒŸํŒ…๋œ ๊ด‘๊ณ ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

ย 

6. ์ ๋ฆฝ ํฌ์ŠคํŠธ๋ฐฑ ์—ฐ๋™

์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ƒ์„ ์ง€๊ธ‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ ํฌ์ŠคํŠธ๋ฐฑ(Postback) ์—ฐ๋™์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํฌ์ŠคํŠธ๋ฐฑ ์š”์ฒญ์€ ๋ณด์•ˆ์„ ์œ„ํ•ด ์„œ๋ฒ„ ๊ฐ„ ํ†ต์‹ (Server-to-Server) ํ˜•ํƒœ๋กœ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

์ ˆ์ฐจ ์š”์•ฝ

  1. ๋ฒ„์ฆˆ๋นŒ์˜ ํฌ์ธํŠธ ์ ๋ฆฝ ์š”์ฒญ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์„œ๋ฒ„ endpoint ๊ตฌ์ถ• (ํ•ด๋‹น endpoint ์˜ URL์„ postback url๋กœ ์ง€์นญ)

  2. ๋ณธ ๊ฐ€์ด๋“œ์— ๋”ฐ๋ผ Server-to-Server ์—ฐ๋™

  3. ๋ฒ„์ฆˆ๋นŒ ๊ธฐ์ˆ ์ง€์› ๋งค๋‹ˆ์ €์—๊ฒŒ postback url ์ „๋‹ฌ

ย 

Introduction

๋ฒ„์ฆˆ๋นŒ์„ ํ†ตํ•ด ์œ ์ €๊ฐ€ ํฌ์ธํŠธ๋ฅผ ์ง€๊ธ‰๋ฐ›์€ ๊ฒฝ์šฐ, ๋งค์ฒด์‚ฌ์—๊ฒŒ ์ด ์‚ฌ์‹ค์„ ์ „๋‹ฌํ•˜์—ฌ ์ ๋ฆฝ ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•œ API์ž…๋‹ˆ๋‹ค.

ํ•ญ๋ชฉ

๋‚ด์šฉ

ํ•ญ๋ชฉ

๋‚ด์šฉ

1

์š”์ฒญ ๋ฐฉํ–ฅ

๋ฒ„์ฆˆ๋นŒ โ†’ ๋งค์ฒด์‚ฌ

2

HTTP Request method

POST - application/x-www-form-urlencoded

3

HTTP Request URL

๋งค์ฒด์‚ฌ ์„œ๋ฒ„์˜ endpoint

4

HTTP Request Parameters

์•„๋ž˜ Http Request Parameters ํ…Œ์ด๋ธ”์„ ์ฐธ๊ณ ํ•ฉ๋‹ˆ๋‹ค.

5

HTTP Response Code

๋ฒ„์ฆˆ๋นŒ ์„œ๋ฒ„๋Š” ๋งค์ฒด์‚ฌ ์„œ๋ฒ„๋กœ ๋ถ€ํ„ฐ ์ „๋‹ฌ๋ฐ›์€ ์‘๋‹ต ์ฝ”๋“œ(Response Code)๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ ๋ฆฝ ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค.

  • 200 (OK), 204 (No Content), 409 (Conflicted Request) : ์„ฑ๊ณต ์ฒ˜๋ฆฌ

    • ๋งค์ฒด ์„œ๋ฒ„์—์„œ ์œ ์ €์—๊ฒŒ ํฌ์ธํŠธ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์ ๋ฆฝํ•ด์ค€ ๊ฒฝ์šฐ ์˜ ์‘๋‹ต ์ฝ”๋“œ

  • 200, 204, 409 ์ด์™ธ์˜ ์‘๋‹ต ์ฝ”๋“œ: ์ตœ๋Œ€ 5ํšŒ๊นŒ์ง€ ํ•ด๋‹น Postback ์š”์ฒญ์„ ์žฌ์‹œ๋„

    • 1๋ถ„, 10๋ถ„, 1์‹œ๊ฐ„, 3์‹œ๊ฐ„, 24์‹œ๊ฐ„์˜ ๊ฐ„๊ฒฉ์„ ๋‘๊ณ  ์žฌ์ ๋ฆฝ ์‹œ๋„ ์ˆ˜ํ–‰

    • 200 ์ด์™ธ์˜ ์‘๋‹ต ์ฝ”๋“œ๋Š” ํ‘œ์ค€ HTTP ์‘๋‹ต ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•ฉ๋‹ˆ๋‹ค.

body์— ์˜ค๋ฅ˜ ๋‚ด์šฉ์„ ๋‹ด๋”๋ผ๋„ ์‘๋‹ต ์ฝ”๋“œ๊ฐ€ 200์ธ ๊ฒฝ์šฐ ์žฌ์‹œ๋„ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ฃผ์˜ํ•ด ์ฃผ์„ธ์š”.

HTTP Request Parameters

๊ธฐ๋Šฅ์— ๋”ฐ๋ผ์„œ ๋‘ ์ข…๋ฅ˜์˜ ํฌ์ŠคํŠธ๋ฐฑ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ํƒ€์ž…์— ๊ด€ํ•œ ํฌ์ŠคํŠธ๋ฐฑ ํŒŒ๋ผ๋ฏธํ„ฐ ์ •๋ณด๋Š” ์•„๋ž˜์˜ ํ‘œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

String ํƒ€์ž…์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ํ•„๋“œ ๊ฐ’์ด ํ•œ๊ตญ์–ด์ผ ๊ฒฝ์šฐ์—๋Š” ์œ ๋‹ˆ์ฝ”๋“œ๋กœ ์ธ์ฝ”๋”ฉ๋˜์–ด ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

ํŒŒ๋ผ๋ฏธํ„ฐ ํ•„๋“œ(Field)

ํƒ€์ž…
(Type)

์„ค๋ช…

ํŒŒ๋ผ๋ฏธํ„ฐ ํ•„๋“œ(Field)

ํƒ€์ž…
(Type)

์„ค๋ช…

user_id

REQUIRED

Stringย 
(max 65)

๋งค์ฒด์‚ฌ์—์„œ ์ •์˜ํ•œ ์œ ์ €์˜ ์‹๋ณ„๊ฐ’

์ตœ๋Œ€ 65์ž๊นŒ์ง€๋งŒ ์ „๋‹ฌ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

transaction_id

REQUIRED

Stringย 
(max 32)

๋ณด์ƒ์— ๋ฐœ๊ธ‰๋˜๋Š” ID. ๊ฐ ๋ณด์ƒ์„ ์‹๋ณ„ํ•˜๊ณ  ํฌ์ธํŠธ ์ค‘๋ณต ์ง€๊ธ‰์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

  • ์ตœ๋Œ€ 32์ž๊นŒ์ง€ ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์—ฐ๋™ ์‹œ ํ™•์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์žฌ์ ๋ฆฝ ์‹œ๋„ ์‹œ ๋™์ผํ•œ transaction_id๋กœ ํฌ์ŠคํŠธ๋ฐฑ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

๊ฐ™์€ transaction_id๋กœ ์š”์ฒญ์ด ์˜จ ๊ฒฝ์šฐ์— ํฌ์ธํŠธ๊ฐ€ ์ค‘๋ณต ์ ๋ฆฝ๋˜์ง€๋Š” ์•Š๋Š”์ง€ ํ•„์ˆ˜์ ์œผ๋กœ ์œ ์˜ํ•ด์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

point

REQUIRED

Integer

์œ ์ €์—๊ฒŒ ์ง€๊ธ‰ํ•ด์•ผํ•˜๋Š” ํฌ์ธํŠธ

unit_id

REQUIRED

Long

๊ด‘๊ณ ๊ฐ€ ๋…ธ์ถœ๋œ ์ง€๋ฉด์˜ ID ๊ฐ’

ํ˜„์žฌ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ’์€ 15์ž๋ฆฌ์˜ ์ˆซ์ž์ž…๋‹ˆ๋‹ค.

title

REQUIRED

String
(max 255)

ํฌ์ธํŠธ๊ฐ€ ์ง€๊ธ‰๋œ ๋ฐฉ์‹์— ์„ค์ •๋œ ์ด๋ฆ„

  • ๊ด‘๊ณ  (์ฐธ์—ฌํ•œ ๊ด‘๊ณ ์˜ ์ด๋ฆ„)

    • e.g ์ถœ์‹œ ์ž„๋ฐ•! ํ•ด๋‹น CPS ์ƒํ’ˆ์„ ๋จผ์ € ๋งŒ๋‚˜๋ณด์„ธ์š”! ๐Ÿ˜ #Buzzvil #ํ™˜์ƒ์ 

  • ๊ทธ ์™ธ๋Š” ๋ชจ๋‘ ๋นˆ๊ฐ’

    • ex. ๋ฃฐ๋ ›/๋งŒ๋ณด๊ธฐ/๋ฝ€๋˜

์ตœ๋Œ€ ํ•œ๊ธ€ 255์ž๊นŒ์ง€ ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์—ฐ๋™ ์‹œ DB๋ณ„ String ์‚ฌ์ด์ฆˆ๋ฅผ ์ฐธ์กฐํ•ด ์ฃผ์„ธ์š”.

event_at

REQUIRED

Long (timestamp)

ํฌ์ธํŠธ ์ง€๊ธ‰ ์‹œ์  (UNIX Timestamp ์ดˆ๋‹จ์œ„)

๋Œ€๋ถ€๋ถ„ API ํ˜ธ์ถœ์‹œ์ ๊ณผ ๋™์ผํ•˜์ง€๋งŒ API ํ˜ธ์ถœ์ด ์žฌ์‹œ๋„์ธ ๊ฒฝ์šฐ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

action_type

OPTIONAL

String
(max 32)

ํฌ์ธํŠธ๋ฅผ ์ง€๊ธ‰ ๋ฐ›๊ธฐ ์œ„ํ•ด ์œ ์ €๊ฐ€ ์ทจํ•œ ์•ก์…˜ ํƒ€์ž…

  • opened: Feed ์ง€๋ฉด ์ง„์ž… (์ง€๋ฉด์„ ๋ฐฉ๋ฌธํ•˜๊ธฐ๋งŒ ํ•ด๋„ ๊ธฐ๋ณธ ๋ฆฌ์›Œ๋“œ ์ ๋ฆฝ)

  • u: ์ž ๊ธˆ ํ•ด์ œ

  • l: ๋žœ๋”ฉ

  • a: ์•ก์…˜ (ํ•ด๋‹น ๊ด‘๊ณ ์˜ ์š”๊ตฌ ์•ก์…˜์„ ์™„๋ฃŒํ–ˆ์„ ๋•Œ)

  • p: ์ปจํ…์ธ  ์ฐธ์—ฌ

  • won: Potto์—์„œ ๋‹น์ฒจ๋ฒˆํ˜ธ์— ๋‹น์ฒจ๋˜์—ˆ์„ ์‹œ ํฌ์ธํŠธ ์ ๋ฆฝ์„ ์š”์ฒญ

  • manual: ๋‹ด๋‹น์ž ์ˆ˜๊ธฐ ์ ๋ฆฝ ์š”์ฒญ

  • spinned : ๋ฃฐ๋ › ๋ฏธ์…˜ ์ฐธ์—ฌ ์‹œ ์ง€๊ธ‰๋˜๋Š” ํฌ์ธํŠธ

  • daily : Feed ์ถœ์„์ฒดํฌ(๋ฐ์ผ๋ฆฌ ๋ฆฌ์›Œ๋“œ ์ด๋ฒคํŠธ) ์ฐธ์—ฌ ๋ณด์ƒ

  • benefit_luckybox : ๋Ÿญํ‚ค๋ฐ•์Šค ์ฐธ์—ฌ ๋ณด์ƒ

  • benefit_missionpack: ๋ฏธ์…˜ํŒฉ ํŠน๋ณ„ ๋ณด์ƒ

  • benefit_missionpack_task: ๋ฏธ์…˜ํŒฉ ๋ฏธ์…˜๋ณ„ ๋ณด์ƒ

  • booster_attended : ๋ฒ„์ฆˆ๋ถ€์Šคํ„ฐ ์ถœ์„์ฒดํฌ ๋ณด์ƒ

  • booster_hiddendone : ๋ฒ„์ฆˆ๋ถ€์Šคํ„ฐ ๋น„๋…ธ์ถœ ์บ ํŽ˜์ธ ๋ณด์ƒ

  • booster_optedin : ๋ฒ„์ฆˆ๋ถ€์Šคํ„ฐ ๋งˆ์ผ€ํŒ… ์ˆ˜์‹ ๋™์˜ ์บ ํŽ˜์ธ ๋ณด์ƒ

  • booster_spinned : ๋ฒ„์ฆˆ๋ถ€์Šคํ„ฐ ๋ฃฐ๋ › ์บ ํŽ˜์ธ ๋ณด์ƒ

  • booster_scratched : ๋ฒ„์ฆˆ๋ถ€์Šคํ„ฐ ๊ธ๋Š” ๋ณต๊ถŒ ์บ ํŽ˜์ธ ๋ณด์ƒ

  • booster_stamped : ๋ฒ„์ฆˆ๋ถ€์Šคํ„ฐ ์Šคํ…œํ”„ ์บ ํŽ˜์ธ ๋ณด์ƒ

  • booster_inviting : ์นœ๊ตฌ ์ดˆ๋Œ€ ์บ ํŽ˜์ธ ๋ณด์ƒ (์ดˆ๋Œ€ ํ•œ ์‚ฌ๋žŒ)

  • booster_invited : ์นœ๊ตฌ ์ดˆ๋Œ€ ์บ ํŽ˜์ธ ๋ณด์ƒ (์ดˆ๋Œ€ ๋ฐ›์€ ์‚ฌ๋žŒ)

์ถ”ํ›„ ๋‹ค์–‘ํ•œ action_type์ด ํƒ€์ž…์ด ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํฌ์ŠคํŠธ๋ฐฑ ์š”์ฒญ์„ ๋ฐ›์„ ๋•Œ ์ •์˜๋œ ๊ฐ’๋งŒ ๋ฐ›๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ๊ฐ’์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๊ณ  ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์œ ์˜ ๋ฐ”๋ž๋‹ˆ๋‹ค.

revenue_type

OPTIONAL

String
(max 32)

์œ ์ €๊ฐ€ ์ฐธ์—ฌํ•œ ๊ด‘๊ณ ์˜ ๊ด‘๊ณ  ์œ ํ˜•

  • cpc: ํด๋ฆญํ˜• ์ƒํ’ˆ

  • cpm: ๋…ธ์ถœํ˜• ์ƒํ’ˆ

  • cpa: ์ผ๋ฐ˜ ์ฐธ์—ฌํ˜• ์ƒํ’ˆ

  • cpk: ์นด์นด์˜คํ†ก ์ฑ„๋„ ์ถ”๊ฐ€ ์ƒํ’ˆ

  • cpq: ํ€ด์ฆˆ ์ƒํ’ˆ

  • cpqlite: ํ€ด์ฆˆ ์ƒํ’ˆ

  • cpl: ํŽ˜์ด์Šค๋ถ ์ข‹์•„์š” ์ƒํ’ˆ

  • cpyoutube: ์œ ํŠœ๋ธŒ ๊ตฌ๋… ์ƒํ’ˆ

  • cps: ์‡ผํ•‘ํ˜• ์ƒํ’ˆ

  • cptiktok: ํ‹ฑํ†ก ํŒ”๋กœ์šฐ ์ƒํ’ˆ

  • cpnstore: ๋„ค์ด๋ฒ„ ์Šคํ† ์–ด ์•Œ๋ฆผ์„ค์ • ์ƒํ’ˆ

  • cpi: ์•ฑ ์„ค์น˜ ์ƒํ’ˆ

  • cpe: ์•ฑ๋‚ด ์ด๋ฒคํŠธ ์ฐธ์—ฌ ์ƒํ’ˆ

  • cpylike: ์œ ํŠœ๋ธŒ ๊ตฌ๋…+์ข‹์•„์š” ์ƒํ’ˆ

  • cpinsta: ์ธ์Šคํƒ€๊ทธ๋žจ ํŒ”๋กœ์šฐ ์ƒํ’ˆ

  • cpcquiz : ํ€ด์ฆˆ ์ ๋ฆฝ ์ปจํ…์ธ 

์ถ”ํ›„ ๋‹ค์–‘ํ•œ ํƒ€์ž…์ด ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

extra

OPTIONAL

String
(max 1024)

ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผํ•  ๊ฒฝ์šฐ, ํ•ด๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ(JSON serialize ๋œ ๋ฌธ์ž์—ด ๊ฐ’)๋ฅผ ํ™œ์šฉ

ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์œผ์‹œ๋‹ค๋ฉด help@buzzvil.com์œผ๋กœ ๋ฌธ์˜ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

campaign_id

OPTIONAL

Long

์œ ์ €๊ฐ€ ์ฐธ์—ฌํ•œ ์บ ํŽ˜์ธ(๊ด‘๊ณ , ์ปจํ…์ธ , ํ”„๋กœ๋ชจ์…˜) ์˜ ID์ž…๋‹ˆ๋‹ค.

data

OPTIONAL

String

HTTP request parameter๋ฅผ ์•”ํ˜ธํ™” ํ•ด์„œ ์ „์†กํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ๋˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ

์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ HTTP Request Parameter Encryption/Decryption์„ ์ฐธ์กฐํ•˜์„ธ์š”.

c

OPTIONAL

String

HTTP request parameter์— Checksum์„ ์ „์†กํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ๋˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ

์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ Add Checksum Parameter๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

custom2

OPTIONAL

String
(max 255)

ํผ๋ธ”๋ฆฌ์…” ์‹ค์‹œ๊ฐ„ S2S API ์ œํ’ˆ ์—ฐ๋™ ๋งค์ฒด์‚ฌ์—์„œ ์ง€์ •ํ•˜๋Š” ์ปค์Šคํ…€ ํŒŒ๋ผ๋ฏธํ„ฐ

  • ๋ฒ„์ฆˆ๋นŒ์—์„œ ๋งค์ฒด์‚ฌ๋กœ ํฌ์ŠคํŠธ๋ฐฑ request ์‹œ ์ „๋‹ฌ ๋˜๋Š” ๊ฐ’

  • custom2~4๊นŒ์ง€ ์ „๋‹ฌ ๊ฐ€๋Šฅ

custom3

OPTIONAL

String
(max 255)

ํผ๋ธ”๋ฆฌ์…” ์‹ค์‹œ๊ฐ„ S2S API ์ œํ’ˆ ์—ฐ๋™ ๋งค์ฒด์‚ฌ์—์„œ ์ง€์ •ํ•˜๋Š” ์ปค์Šคํ…€ ํŒŒ๋ผ๋ฏธํ„ฐ

  • ๋ฒ„์ฆˆ๋นŒ์—์„œ ๋งค์ฒด์‚ฌ ๋กœ ํฌ์ŠคํŠธ๋ฐฑ request ์‹œ ์ „๋‹ฌ ๋˜๋Š” ๊ฐ’

  • custom2~4๊นŒ์ง€ ์ „๋‹ฌ ๊ฐ€๋Šฅ

custom4

OPTIONAL

String
(max 255)

ํผ๋ธ”๋ฆฌ์…” ์‹ค์‹œ๊ฐ„ S2S API ์ œํ’ˆ ์—ฐ๋™ ๋งค์ฒด์‚ฌ์—์„œ ์ง€์ •ํ•˜๋Š” ์ปค์Šคํ…€ ํŒŒ๋ผ๋ฏธํ„ฐ

  • ๋ฒ„์ฆˆ๋นŒ์—์„œ ๋งค์ฒด์‚ฌ๋กœ ํฌ์ŠคํŠธ๋ฐฑ request ์‹œ ์ „๋‹ฌ ๋˜๋Š” ๊ฐ’

  • custom2~4๊นŒ์ง€ ์ „๋‹ฌ ๊ฐ€๋Šฅ

ย 

HTTP Request Parameter ํฌ์ŠคํŠธ๋ฐฑ ์˜ˆ์ œ

๋‹ค์Œ์€ HTTP Request Parameter์˜ ํฌ์ŠคํŠธ๋ฐฑ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

{ "user_id": "12345", "point": 1, "transaction_id": "126905422_10000001", "event_at": 1641452397, "unit_id": 5539189976900000, "action_type": "l", "title": "ํƒ€์ดํ‹€", "extra": "{}" }

ย 

IP Whitelist ์ถ”๊ฐ€

๋ฒ„์ฆˆ๋นŒ ์„œ๋ฒ„์—์„œ ๋ณด๋‚ด๋Š” ํฌ์ธํŠธ ์ ๋ฆฝ ์š”์ฒญ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ์•„๋ž˜ IP์— ๋Œ€ํ•œ inbound ๋ฐฉํ™”๋ฒฝ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ๋ถ€ํƒ ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

  • 13.231.21.93

  • 18.179.158.39

  • 52.68.114.43

์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฒ€์ฆย OPTIONAL

๋ฒ„์ฆˆ๋นŒ ์„œ๋ฒ„์—์„œ ์ „๋‹ฌ๋˜๋Š” ํฌ์ธํŠธ ์ ๋ฆฝ ์š”์ฒญ(ํฌ์ŠคํŠธ๋ฐฑ)์„ ์•”ํ˜ธํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์€ ํ•„์ˆ˜ ์ ์šฉ ํ•ญ๋ชฉ์€ ์•„๋‹ˆ๋ฉฐ, ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์•„๋ž˜์˜ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

1. HTTP Request Parameter Encryption/Decryption

๋ฒ„์ฆˆ๋นŒ ์„œ๋ฒ„์—์„œ ๋งค์ฒด์‚ฌ๋กœ ๋ณด๋‚ด๋Š” HTTP Request parameter๋ฅผ ์•”ํ˜ธํ™” ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ณตํ•˜๋Š” ์•”ํ˜ธํ™” ๋ฐฉ์‹์€ ๊ณ ๊ธ‰ ์•”ํ˜ธํ™” ํ‘œ์ค€, AES(Advanded Encryption Standard)์ž…๋‹ˆ๋‹ค. ์ œ๊ณต๋˜๋Š” ๋ธ”๋ก ์•”ํ˜ธํ™”๋Š” AES-256 ์ด๊ณ , ์‚ฌ์šฉํ•˜๋Š” ๋ธ”๋ก ์•”ํ˜ธํ™” ๋ชจ๋“œ(Block Cipher)๋Š” CBC(Cipher Block Chaning) Mode์™€ PKCS7์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ค€๋น„๋ฌผ

  • ๋ฒ„์ฆˆ๋นŒ ๋งค๋‹ˆ์ € ํ†ตํ•ด AES-256 ์•”ํ˜ธํ™”์— ํ•„์š”ํ•œ ์•„๋ž˜ ๊ฐ’ ๋ฐœ๊ธ‰:

    • AES Key (๊ธธ์ด 32)

    • AES IV (๊ธธ์ด 16)

  • ๋ฒ„์ฆˆ๋นŒ โ†’ ๋งค์ฒด์‚ฌ๋กœ AES Key, IV ๊ฐ’์„ ์ „๋‹ฌํ•˜๊ธฐ ์ „, ๋งค์ฒด์‚ฌ์—์„œ RSA-1024๋กœ private key์™€ public key๋ฅผ ๋ฐœ๊ธ‰ํ•˜๊ณ  public key๋ฅผ ๋ฒ„์ฆˆ๋นŒ ๋งค๋‹ˆ์ €์—๊ฒŒ ์ „๋‹ฌ

    • ์ดํ›„ public key๋กœ ์•”ํ˜ธํ™”๋œ AES Key, IV๋ฅผ ๋งค์ฒด์‚ฌ์— ์ „๋‹ฌ

์ง„ํ–‰ ์ ˆ์ฐจ

  1. ๋ฒ„์ฆˆ๋นŒ ์„œ๋ฒ„์—์„œ HTTP Request parameter๋ฅผ ์•”ํ˜ธํ™”

    1. JSON serialized parameters(string)์— ํ•ด๋‹น string์„ UTF-8 ์ธ์ฝ”๋”ฉ ์ ์šฉ

    2. ํ•ด๋‹น string์— PKCS7 ํŒจ๋”ฉ ์ ์šฉ ๋ฐ AES ์•”ํ˜ธํ™” ์ง„ํ–‰

    3. ์•”ํ˜ธํ™”๋œ ๊ฐ’์„ base64 encoding์„ ์ง„ํ–‰

  2. ์•”ํ˜ธํ™” ๋œ ๋ฐ์ดํ„ฐ๋ฅผ HTTP POST request์— ํŒŒ๋ผ๋ฏธํ„ฐ data๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ถ”๊ฐ€ํ•˜์—ฌ ์ „์†ก

    1. e.g

      { "data": "cg087LiIp30jCWpc3MVLfxPL4F05OFGGCkQwwpS6pRVMZhkumzfTFxc8iBoZ8unI15uk0cmY+CbSeOaLHsd7PaxsbyKISiJ31WJJ1OwfaYttoMwFysKNfL7pSz2HB9ULWZicG8MSPxCPKr9RDqgOXpuEoVm9YR3I4yNE5M0LNltpCTdXRBjTrOcjp+RtEZ1VENtHqTICK18nDqO+91BUt3AJsf4VmzogJ8UpA0izEbY=" }
  3. ์ˆ˜์‹  ์ธก (๋งค์ฒด์‚ฌ) ์—์„œ๋Š” HTTP POST request์—์„œ data ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ์•„๋ž˜์™€ ๊ฐ™์€ ์ˆœ์„œ๋กœ ๋ณตํ˜ธํ™”

    1. ์•”ํ˜ธํ™”๋œ ๊ฐ’์„ base64 decoding ์ง„ํ–‰

    2. ํ•ด๋‹น decoding๋œ string์„ ๋ณตํ˜ธํ™” ์ง„ํ–‰ ์ดํ›„ PKCS7 ํŒจ๋”ฉ ์ œ๊ฑฐ

    3. ํ•ด๋‹น string์„ UTF-8 ๋””์ฝ”๋”ฉ

ย 

์˜ˆ์ œ

  • ์˜ˆ์ œ์—์„œ๋Š” AES key, IV ๊ฐ’์œผ๋กœ ๋ชจ๋‘ buzzvil123456789๋ฅผ ์‚ฌ์šฉ

{ "unit_id":"12345", "transaction_id":"10000000_1", "user_id":"buzzvil", "point": 1, "action_type":"won", "event_at": 1599622182, "title":"title", "extra": "{}" }
  • ์•”ํ˜ธํ™” ๊ฒฐ๊ณผ

    • JSON (UTF-8encoding) โ†’ AES encryption โ†’ base64 encoding ์ˆœ์„œ๋กœ ์ง„ํ–‰

      cg087LiIp30jCWpc3MVLfxPL4F05OFGGCkQwwpS6pRVMZhkumzfTFxc8iBoZ8unI15uk0cmY+CbSeOaLHsd7PaxsbyKISiJ31WJJ1OwfaYttoMwFysKNfL7pSz2HB9ULWZicG8MSPxCPKr9RDqgOXpuEoVm9YR3I4yNE5M0LNltpCTdXRBjTrOcjp+RtEZ1VENtHqTICK18nDqO+91BUt3AJsf4VmzogJ8UpA0izEbY=

ย 

  • ์œ„์˜ ์•”ํ˜ธํ™”๋œ ๋ฌธ์žฅ์„ ๋ณตํ˜ธํ™”์‹œ, ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    • base64 decoding

      r\r<\xec\xb8\x88\xa7}#\tj\\\xdc\xc5K\x7f\x13\xcb\xe0]98Q\x86\nD0\xc2\x94\xba\xa5\x15Lf\x19.\x9b7\xd3\x17\x17<\x88\x1a\x19\xf2\xe9\xc8\xd7\x9b\xa4\xd1\xc9\x98\xf8&\xd2x\xe6\x8b\x1e\xc7{=\xaclo"\x88J"w\xd5bI\xd4\xec\x1fi\x8bm\xa0\xcc\x05\xca\xc2\x8d|\xbe\xe9K=\x87\x07\xd5\x0bY\x98\x9c\x1b\xc3\x12?\x10\x8f*\xbfQ\x0e\xa8\x0e^\x9b\x84\xa1Y\xbda\x1d\xc8\xe3#D\xe4\xcd\x0b6[i\t7WD\x18\xd3\xac\xe7#\xa7\xe4m\x11\x9dU\x10\xdbG\xa92\x02+_\'\x0e\xa3\xbe\xf7PT\xb7p\t\xb1\xfe\x15\x9b: \'\xc5)\x03H\xb3\x11\xb6

      ย 

    • AES decryption) Key, IV: buzzvil123456789

      {"unit_id": "12345", "transaction_id": "10000000_1", "user_id": "buzzvil", "point": 1, "action_type": "won", "event_at": 1599622182, "title": "title", "extra": "{}"}

      ย 

    • UTF-8 decoding

      {"unit_id": "12345", "transaction_id": "10000000_1", "user_id": "buzzvil", "point": 1, "action_type": "won", "event_at": 1599622182, "title": "title", "extra": "{}"}

      (memo) ์œ„์˜ ์˜ˆ์ œ์— ํ•œ๊ธ€์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— UTF-8 decoding ์„ ๊ฑฐ์น˜์ง€ ์•Š์•„๋„ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.๋กœ ์ œ๊ณต๋˜๋Š” ์˜ˆ์‹œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

import java.lang.RuntimeException; import java.nio.charset.StandardCharsets; import java.util.Base64; import javax.crypto.Cipher; import javax.crypto.spec.*; import javax.crypto.spec.SecretKeySpec; public class Main { public static void main(String[] args) { String aesKey = "BuzzvilAESKeyTest123456789101112"; String aesIV = "0000000000000000"; // Check to make sure encryption is compatible with Buzzvil String toBuzzvilMessage = "{\"success\": 1, \"reason\": \"์ค‘๋ณต ์ ๋ฆฝ ์š”์ฒญ\"}"; String encrypted = encrypt(toBuzzvilMessage, aesKey, aesIV); System.out.println("----encrypted----\n"+encrypted); System.out.println("buzzvil encryption compatible? YES"); // Check to make sure values coming from Buzzvil is decryptable String fromBuzzvilEncrypted = "IGCdundUBkXf3s7VXl0pqIKDSC/KGc2j8n1DBLKLZAHqkYlG+aWW+G5hGLvoNeUjlI42FtJLpwGUYbFlhy0QXLQv1Z+P7iUOyJrhujmFWX1FdJ5ZBefA5aceGiOlN119NPAX3JOuUAf45HkWG52NcdaHOzWu8rTnghSeLPo9QK0t6l/2gSFvGtOfZolnAHNZAeGEmcqAkhPmUoFtRAW+Zh6TNQY68FrSUI/XYc87Ky0ndaug1Kf7Ogbf8zLK+tJ4LdTCn9A+wcWxEpdkX45f1r/8jTIUK/s1PqBirXFuruq5/XhkhFmdq/I0qBAJ0uxBnk+29GaEQVMtYTzB+eJWTgrQzKhN6Nww2XEPEOl27yH+K0F+sj8QpZ0jkPETadP0gpwKMKv3zlA6xyndIYWrpw=="; String fromBuzzvilDecrypted = "{\"point\": 1, \"user_id\": \"buzzvil_test\", \"transaction_id\": \"100004_100000000\", \"event_at\": 1588936508, \"campaign_name\": \"๋ฒ„์ฆˆ๋นŒ ํ…Œ์ŠคํŠธ campaign_name\", \"extra\": \"{}\", \"action_type\": \"l\", \"base_point\": 1, \"campaign_id\": 202010160022, \"is_media\": 1, \"unit_id\": 452613281179508, \"revenue_type\": \"cpm\"}"; String decrypted = decrypt(fromBuzzvilEncrypted, aesKey, aesIV); System.out.println("----decrypted-----\n"+decrypted); System.out.println("buzzvil decryption compatible? "+fromBuzzvilDecrypted.equals(decrypted)); } static String encrypt(String message, String key, String iv) { try { // 1. encode in utf-8 byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8); // 2. encrypt message through AES CBC with PKCS7 byte[] encrypted = aes(messageBytes, key, iv, Cipher.ENCRYPT_MODE); // 3. encode in base64 return Base64.getEncoder().encodeToString(encrypted); } catch (Exception e) { System.out.println(e.getMessage()); throw new RuntimeException(e); } } static String decrypt(String message, String key, String iv) { try { // 1. decode base64 message byte[] base64DecodedBytes = Base64.getDecoder().decode(message); // 2. decrypt message through AES CBC with PKCS7 byte[] decrypted = aes(base64DecodedBytes, key, iv, Cipher.DECRYPT_MODE); // 3. decode in utf-8 return new String(decrypted, StandardCharsets.UTF_8); } catch (Exception e) { System.out.println(e.getMessage()); throw new RuntimeException(e); } } static byte[] aes(byte[] messageBytes, String key, String iv, int cipherMode) { try { byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); byte[] ivBytes = iv.getBytes(StandardCharsets.UTF_8); SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(cipherMode, keySpec, ivSpec); return cipher.doFinal(messageBytes); } catch (Exception e) { System.out.println(e.getMessage()); throw new RuntimeException(e); } } }
<?php function encrypt($str, $mode, $key, $iv) { $encrypted = openssl_encrypt($str, $mode, $key, OPENSSL_RAW_DATA, $iv); return base64_encode($encrypted); } function decrypt($str, $mode, $key, $iv) { $text = base64_decode($str); return openssl_decrypt($text, $mode, $key, OPENSSL_RAW_DATA, $iv); } $mode = "AES-256-CBC"; $key = "BuzzvilAESKeyTest123456789101112"; $iv = "0000000000000000"; $plaintext = '{"success": 1, "reason": "์ค‘๋ณต ์ ๋ฆฝ ์š”์ฒญ"}'; $encrypted = encrypt($plaintext, $mode, $key, $iv); print ("ENCRYPTED: ".$encrypted."\n"); // +VEmHrt+jwI6Dg2zImdGtI+iIQEqV8v5btpS1a3cdEQBzIc72V9aKju5m6+ELTBixbITMBoHIYjj8jJbsKbIgg== $fromBuzzvil = "IGCdundUBkXf3s7VXl0pqIKDSC/KGc2j8n1DBLKLZAHqkYlG+aWW+G5hGLvoNeUjlI42FtJLpwGUYbFlhy0QXLQv1Z+P7iUOyJrhujmFWX1FdJ5ZBefA5aceGiOlN119NPAX3JOuUAf45HkWG52NcdaHOzWu8rTnghSeLPo9QK0t6l/2gSFvGtOfZolnAHNZAeGEmcqAkhPmUoFtRAW+Zh6TNQY68FrSUI/XYc87Ky0ndaug1Kf7Ogbf8zLK+tJ4LdTCn9A+wcWxEpdkX45f1r/8jTIUK/s1PqBirXFuruq5/XhkhFmdq/I0qBAJ0uxBnk+29GaEQVMtYTzB+eJWTgrQzKhN6Nww2XEPEOl27yH+K0F+sj8QpZ0jkPETadP0gpwKMKv3zlA6xyndIYWrpw=="; $decrypted = decrypt($fromBuzzvil, $mode, $key, $iv); print("DECRYPTED: ".$decrypted); /* {"point": 1, "user_id": "buzzvil_test", "transaction_id": "100004_100000000", "event_at": 1588936508, "campaign_name": "๋ฒ„์ฆˆ๋นŒ ํ…Œ์ŠคํŠธ campaign_name", "extra": "{}", "action_type": "l", "base_point": 1, "campaign_id": 202010160022, "is_media": 1, "unit_id": 452613281179508, "revenue_type": "cpm"} */ ?>

Python 2.7+

# -*- coding:utf-8 -*- import base64 # https://pypi.python.org/pypi/pycryptodome/3.9.9 from Crypto.Cipher import AES # https://pypi.python.org/pypi/pkcs7/0.1.2 from pkcs7 import PKCS7Encoder def encrypt(message, key, iv): message_plaintext_padded = PKCS7Encoder().encode(message) cipher = AES.new(key, AES.MODE_CBC, iv) message_encrypted_raw = cipher.encrypt(message_plaintext_padded) return base64.b64encode(message_encrypted_raw) def decrypt(message, key, iv): message_decoded = base64.b64decode(message) cipher = AES.new(key, AES.MODE_CBC, iv) messaged_decrypted_padded = cipher.decrypt(message_decoded) message_plaintext_decoded = PKCS7Encoder().decode(messaged_decrypted_padded) return message_plaintext_decoded iv = '0000000000000000' key = 'BuzzvilAESKeyTest123456789101112' plaintext = '{"success": 1, "reason": "์ค‘๋ณต ์ ๋ฆฝ ์š”์ฒญ"}' encrypted = encrypt(plaintext, key, iv) print "ENCRYPTED: {}".format(encrypted) # +VEmHrt+jwI6Dg2zImdGtI+iIQEqV8v5btpS1a3cdEQBzIc72V9aKju5m6+ELTBixbITMBoHIYjj8jJbsKbIgg== from_buzzvil = "IGCdundUBkXf3s7VXl0pqIKDSC/KGc2j8n1DBLKLZAHqkYlG+aWW+G5hGLvoNeUjlI42FtJLpwGUYbFlhy0QXLQv1Z+P7iUOyJrhujmFWX1FdJ5ZBefA5aceGiOlN119NPAX3JOuUAf45HkWG52NcdaHOzWu8rTnghSeLPo9QK0t6l/2gSFvGtOfZolnAHNZAeGEmcqAkhPmUoFtRAW+Zh6TNQY68FrSUI/XYc87Ky0ndaug1Kf7Ogbf8zLK+tJ4LdTCn9A+wcWxEpdkX45f1r/8jTIUK/s1PqBirXFuruq5/XhkhFmdq/I0qBAJ0uxBnk+29GaEQVMtYTzB+eJWTgrQzKhN6Nww2XEPEOl27yH+K0F+sj8QpZ0jkPETadP0gpwKMKv3zlA6xyndIYWrpw==" decrypted = decrypt(from_buzzvil, key, iv) print "DECRYPTED: {}".format(decrypted) #{"point": 1, "user_id": "buzzvil_test", "transaction_id": "100004_100000000", "event_at": 1588936508, "campaign_name": "๋ฒ„์ฆˆ๋นŒ ํ…Œ์ŠคํŠธ campaign_name", "extra": "{}", "action_type": "l", "base_point": 1, "campaign_id": 202010160022, "is_media": 1, "unit_id": 452613281179508, "revenue_type": "cpm"}

ย 

Python 3.6+

# -*- coding:utf-8 -*- import base64 # https://pypi.python.org/pypi/pycryptodome/3.9.9 from Crypto.Cipher import AES from binascii import unhexlify BLOCK_SIZE = 16 def encrypt(message, key, iv): message_plaintext_padded = pad(message).encode('utf-8') cipher = AES.new(key, AES.MODE_CBC, iv) message_encrypted_raw = cipher.encrypt(message_plaintext_padded) return base64.b64encode(message_encrypted_raw) def decrypt(message, key, iv): message_decoded = base64.b64decode(message) cipher = AES.new(key, AES.MODE_CBC, iv) messaged_decrypted_padded = unpad(cipher.decrypt(message_decoded)) return messaged_decrypted_padded.decode('utf-8') def pad(s): return s + (BLOCK_SIZE - len(s.encode('utf-8')) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s.encode('utf-8')) % BLOCK_SIZE) def unpad(s): return s[:-ord(s[len(s)-1:])] iv = '0000000000000000'.encode('utf-8') key = 'BuzzvilAESKeyTest123456789101112'.encode('utf-8') plaintext = '{"success": 1, "reason": "์ค‘๋ณต ์ ๋ฆฝ ์š”์ฒญ"}' encrypted = encrypt(plaintext, key, iv) print ("ENCRYPTED: {}".format(encrypted)) # +VEmHrt+jwI6Dg2zImdGtI+iIQEqV8v5btpS1a3cdEQBzIc72V9aKju5m6+ELTBixbITMBoHIYjj8jJbsKbIgg== from_buzzvil = "IGCdundUBkXf3s7VXl0pqIKDSC/KGc2j8n1DBLKLZAHqkYlG+aWW+G5hGLvoNeUjlI42FtJLpwGUYbFlhy0QXLQv1Z+P7iUOyJrhujmFWX1FdJ5ZBefA5aceGiOlN119NPAX3JOuUAf45HkWG52NcdaHOzWu8rTnghSeLPo9QK0t6l/2gSFvGtOfZolnAHNZAeGEmcqAkhPmUoFtRAW+Zh6TNQY68FrSUI/XYc87Ky0ndaug1Kf7Ogbf8zLK+tJ4LdTCn9A+wcWxEpdkX45f1r/8jTIUK/s1PqBirXFuruq5/XhkhFmdq/I0qBAJ0uxBnk+29GaEQVMtYTzB+eJWTgrQzKhN6Nww2XEPEOl27yH+K0F+sj8QpZ0jkPETadP0gpwKMKv3zlA6xyndIYWrpw==" decrypted = decrypt(from_buzzvil, key, iv) print ("DECRYPTED: {}".format(decrypted)) #{"point": 1, "user_id": "buzzvil_test", "transaction_id": "100004_100000000", "event_at": 1588936508, "campaign_name": "๋ฒ„์ฆˆ๋นŒ ํ…Œ์ŠคํŠธ campaign_name", "extra": "{}", "action_type": "l", "base_point": 1, "campaign_id": 202010160022, "is_media": 1, "unit_id": 452613281179508, "revenue_type": "cpm"}

ย 

2. Add Checksum Parameter

ํฌ์ŠคํŠธ๋ฐฑ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ์„ ์œ„ํ•ด Request Parameter์— Checksum parameter๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ณตํ•˜๋Š” ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ ๋ฐฉ์‹์€ HMAC ์ธ์ฆ์ด๊ณ , SHA-256 ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ค€๋น„๋ฌผ

  • ๋ฒ„์ฆˆ๋นŒ ๋งค๋‹ˆ์ € ํ†ตํ•ด HMAC ์ธ์ฆ์— ํ•„์š”ํ•œ ์•„๋ž˜ ๊ฐ’๋“ค ๋ฐœ๊ธ‰:

    • HMAC KEY (์ตœ๋Œ€ ๊ธธ์ด 64)

์ง„ํ–‰ ์ ˆ์ฐจ

  1. ์ „๋‹ฌ๋ฐ›์€ ํฌ์ŠคํŠธ๋ฐฑ ํŒŒ๋ผ๋ฏธํ„ฐ ์ค‘ transaction_id, user_id, point, event_at ๊ฐ’์œผ๋กœ ์•„๋ž˜ ํ˜•์‹๋Œ€๋กœ String์„ ์ƒ์„ฑ (์ดํ•˜ "msg")

    1. ์ฃผ์˜์‚ฌํ•ญ : msg ๊ฐ’์€ ์ธ์ฝ”๋”ฉ๋˜์–ด์•ผ ํ•˜๋ฉฐ, ๊ฐ ํŒŒ๋ผ๋ฏธํ„ฐ string ๊ณผ colon ์‚ฌ์ด์—๋Š” ๋„์–ด์“ฐ๊ธฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

      msg=u'{0}:{1}:{2}:{3}'.format( params['transaction_id'], params['user_id'], params['point'], params['event_at'], ).encode('utf-8')

      ย 

  2. HMAC SHA-256 ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ msg ๊ฐ’์„ ์•”ํ˜ธํ™”

    • key: 1๋ฒˆ์—์„œ ๋ฐœ๊ธ‰๋ฐ›์€ hmac_key

    • data: 2๋ฒˆ์—์„œ ์ƒ์„ฑํ•œ msg

  3. ์ „๋‹ฌ๋ฐ›์€ ํฌ์ŠคํŠธ๋ฐฑ ํŒŒ๋ผ๋ฏธํ„ฐ ์ค‘ c ํ•„๋“œ์˜ ๊ฐ’๊ณผ ๋น„๊ต, ์ผ์น˜ ์—ฌ๋ถ€๋ฅผ ํ™•์ธ

    • ๊ฒฐ๊ณผ๊ฐ’ ๊ธธ์ด: 64์ž

์˜ˆ์ œ

  • hmac_key = 12345678abcdefgh12345678abcdefgh12345678abcdefgh12345678abcdefgh

    { "transaction_id": 429482977, "user_id": "testuserid76301", "point": 2, "event_at": 1849274, "c": "43ad5b2639e3363d81879e0ac441a14a369993a0cc6a1f21921f8344cb2612eb" }

    ย 

  • msg = 429482977:testuserid76301:2:1849274

๋งค์ฒด์‚ฌ ํฌ์ธํŠธ ์ ๋ฆฝ ํฌ์ŠคํŠธ๋ฐฑ API ์—ฐ๋™

ย 

7. ์ง€์› ๋ฐ ๋ฌธ์˜

์—ฐ๋™ ๊ณผ์ •์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ, Buzzvil ๊ธฐ์ˆ  ์ง€์›ํŒ€์— ๋ฌธ์˜ํ•ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

csm@buzzvil.com