İçeriğe geç
ReinoAds

EntegrasyonSDK Beta

Ödül Doğrulama (S2S)

Ödüllü reklamlarda ödülü imzalı sunucudan sunucuya bildirimle doğrulayın.

Ödüllü birimde S2S callback adresi tanımlarsanız, kullanıcı videoyu tamamladığında ReinoAds sunucunuza imzalı bir POST isteği gönderir. Değerli ödülleri istemcideki onReward yerine bu bildirime göre verin.

Kurulum

  • Panelde ödüllü birimi düzenleyip https ile başlayan callback adresini girin.
  • Birimin gizli anahtarını aynı ekrandan kopyalayın ve sunucunuzda saklayın. Anahtar istenildiğinde yenilenebilir; yenilendiğinde eski anahtar geçersiz olur.
  • SDK'da kullanıcı kimliğini verin; bildirimde userId ve customData olarak döner.
<ReinoAdsProvider
  appKey={APP_KEYS}
  options={{ user: { id: "player-42", customData: "level=7" } }}
>
  <Root />
</ReinoAdsProvider>

ReinoAds.setUser({ id: "player-42", customData: "level=8" });

userId en fazla 128, customData en fazla 512 karakter olabilir.

İstek

POST /reinoads/reward HTTP/1.1
Content-Type: application/json
User-Agent: ReinoAds-Callbacks/1.0
X-Reino-Timestamp: 1793260800
X-Reino-Signature: sha256=5f2b...c41e

{
  "transactionId": "9b4921e9111c7778897003c4ed39696e",
  "adUnitId": "rau_...",
  "rewardName": "coin",
  "rewardAmount": 10,
  "userId": "player-42",
  "customData": "level=7",
  "timestamp": 1793260795
}
AlanAçıklama
transactionIdGösterime özgü kimlik. Aynı ödülü iki kez vermemek için saklayın.
adUnitIdÖdüllü birimin kimliği.
rewardName, rewardAmountPanelde birim için tanımlanan ödül.
userId, customDataSDK'da verilen kullanıcı bilgisi; verilmediyse boş.
timestampÖdül olayının zamanı (Unix saniye).

İmzayı doğrulama

X-Reino-Signature, birim gizli anahtarıyla hesaplanan HMAC-SHA256 değeridir: sha256=hex(HMAC(secret, X-Reino-Timestamp + "." + ham gövde)). Gövdeyi JSON olarak yeniden üretmeyin, gelen ham baytlar üzerinden hesaplayın.

import { createHmac, timingSafeEqual } from "node:crypto";
import express from "express";

const app = express();

app.post("/reinoads/reward", express.raw({ type: "application/json" }), async (req, res) => {
  const timestamp = req.header("X-Reino-Timestamp") ?? "";
  const signature = req.header("X-Reino-Signature") ?? "";
  const body = req.body.toString("utf8");

  const expected = "sha256=" + createHmac("sha256", process.env.REINOADS_UNIT_SECRET!)
    .update(`${timestamp}.${body}`)
    .digest("hex");
  const valid = signature.length === expected.length
    && timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
  const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) < 300;
  if (!valid || !fresh) {
    return res.status(401).end();
  }

  const event = JSON.parse(body);
  await grantRewardOnce(event.transactionId, event.userId, event.rewardName, event.rewardAmount);
  res.status(200).end();
});

Yanıt ve tekrar deneme

  • 2xx yanıt başarılı sayılır.
  • 408 ve 429 dışındaki 4xx yanıtlar kalıcı ret sayılır, tekrar denenmez.
  • Diğer hatalar ve zaman aşımı (5 sn) üstel beklemeyle toplam 6 kez denenir. Bu yüzden transactionId ile tekrarları ayıklayın.
  • Test modundaki gösterimler için bildirim gönderilmez.