POST /api/track بيستقبل الـevents من ثيمات سلة (Angel + Neptune)، يتحقّق من HMAC، ويخزّنهم في tracking_events للـanalytics.
#الـRequest
POST /api/track HTTP/1.1
Host: afterads.com
Content-Type: application/json
X-Signature: 5e88e2d4...
X-Timestamp: 1715174400
{
"event": "product_view",
"store_id": "salla:1234567890",
"session_id": "...",
"user_id": "salla:9876543210",
"metadata": {
"product_id": "1828908128",
"category": "fashion",
"currency": "SAR",
"price": 350
}
}#أنواع الـevents
| Event | الوصف | metadata required |
|---|---|---|
store_view | زيارة عامة | referrer, page |
product_view | عرض صفحة منتج | product_id, category |
addtocart | إضافة للسلة | product_id, quantity, price |
begin_checkout | بدء الـcheckout | carttotal, itemscount |
purchase | إتمام الطلب | order_id, total, items |
signup | تسجيل عميل جديد | email_hash |
review_submit | تقييم منتج | product_id, rating |
search | بحث في الموقع | query, results_count |
#HMAC verification
الـserver بيتحقّق من X-Signature كالتالي:
import { createHmac } from 'crypto';
const expected = createHmac('sha256', SECRET_KEY)
.update(timestamp + ':' + JSON.stringify(body))
.digest('hex');
if (!constantTimeEqual(expected, providedSignature)) {
return 401;
}#مفتاح الـsigning
#مثال كامل (Salla theme)
// في ثيم سلة (server-side via httpClient أو client-side)
async function trackEvent(event, metadata) {
const ts = Math.floor(Date.now() / 1000);
const body = JSON.stringify({
event,
store_id: salla.config.store.id,
session_id: getSessionId(),
user_id: salla.user?.id,
metadata,
});
const signature = await sign(ts + ':' + body, AFTERADS_TRACKING_KEY);
await fetch('https://afterads.com/api/track', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Signature': signature,
'X-Timestamp': String(ts),
},
body,
});
}
// استخدام
trackEvent('add_to_cart', {
product_id: '1828908128',
quantity: 1,
price: 350,
});#Response
| — | "Code" | "Body" |
|---|---|---|
| 200 | { "ok": true, "event_id": "uuid" } | |
| 401 | { "error": "invalid_signature" } | |
| 401 | { "error": "stale_timestamp" } | |
| 409 | { "error": "replay" } (nonce reused) | |
| 400 | { "error": "invalideventtype" } | |
| 429 | { "error": "ratelimited", "retryafter_seconds": 60 } |
#Anti-replay
كل request له session_id + timestamp فريد. الـserver بيخزّنهم لـ5 دقائق ويرفض أي تكرار. ده بيمنع الـreplay attacks لو حصل sniffing على الـnetwork.