نِت اَرز · مستندات API نرخ ارز
همهٔ مستندات
تابلوی نرخ مرجع تعاملی کلید رایگان

هشدار قیمت و وبهوک

هشدار عبور از آستانه، تغییر درصدی یا هر به‌روزرسانی؛ تحویل امضاشده با HMAC، تلاش مجدد و اعتبارسنجی امضا در سرور شما.

base_url: https://netarz.ir/api/fx/v1 دلار امروز: ۲۷۳,۶۰۰ تومان به‌روزرسانی: 1405/06/27

هشدار قیمت یعنی «وقتی این اتفاق افتاد، به سرورم خبر بدهید». نِت اَرز هر دقیقه هشدارهای اپ‌های پرو را با نرخ زنده می‌سنجد و برای هر کدام که فعال شود یک POST امضاشده به آدرس شما می‌فرستد؛ اگر سرور شما جواب نداد، تا ۶ بار با فاصلهٔ افزایشی دوباره تلاش می‌کند.

انواع هشدار

typeکی فعال می‌شودپارامتر
aboveمیانگین از پایین به بالای آستانه عبور کند. بعد از فعال‌شدن «خلع سلاح» می‌شود و وقتی نرخ دوباره زیر آستانه رفت، خودکار مسلح می‌شود — پس هر عبور فقط یک بار خبر می‌دهد.threshold (تومان)
belowعبور از بالا به پایین آستانه؛ همان منطق.threshold
changeنرخ نسبت به آخرین اعلان دست‌کم percent درصد (بالا یا پایین) حرکت کرده باشد. مناسب «با هر ۱٪ تغییر خبرم کنید».percent (حداقل ۰٫۱)
updateهر بار که نرخ منتشرشده عوض شود (چند بار در ساعت در بازار فعال). برای آینه‌کردن نرخ در سیستم خودتان.—

ساخت هشدار

POST /api/fx/v1/alerts فقط طرح پرو

می‌توانید از پنل هم بسازید. secret را می‌توانید خودتان بدهید (۱۶ تا ۶۴ کاراکتر) یا بگذارید تولید شود؛ در هر دو حالت فقط یک بار در پاسخ ساخت برمی‌گردد.

cURL
curl -X POST https://netarz.ir/api/fx/v1/alerts \
  -H "Authorization: Bearer $NETARZ_FX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "دلار بالای ۱۱۰ هزار",
    "code": "USD",
    "type": "above",
    "threshold": 110000,
    "webhook_url": "https://example.com/hooks/netarz-fx"
  }'
پاسخ ۲۰۱
{
  "data": {
    "id": 42, "label": "دلار بالای ۱۱۰ هزار", "code": "USD", "type": "above", "threshold": 110000, "percent": null,
    "webhook_url": "https://example.com/hooks/netarz-fx", "is_active": true, "armed": true,
    "last_value": null, "last_triggered_at": null, "triggered_count": 0, "created_at": "2026-09-05T10:20:00+03:30",
    "secret": "whsec_R3q…"   // فقط همین یک بار
  }
}

سایر عملیات: GET /alerts فهرست، GET /alerts/{id} جزئیات + ۲۰ تحویل اخیر، PATCH /alerts/{id} با is_active / label / webhook_url، DELETE /alerts/{id}. حداکثر ۲۰ هشدار برای هر اپ.

آدرس وبهوک

  • باید https باشد و به یک آدرس عمومی اشاره کند؛ آدرس‌های شبکهٔ داخلی و loopback رد می‌شوند (invalid_webhook_url).
  • سرور شما باید ظرف ۱۰ ثانیه یک پاسخ 2xx بدهد. کارهای سنگین را به صف بسپارید و سریع ۲۰۰ برگردانید.
  • تحویل‌های تکراری ممکن است (مثلاً پاسخ شما در راه گم شود)؛ با X-NetArz-Delivery (یا id در بدنه) idempotent باشید.

درخواستی که می‌گیرید

وبهوک
POST /hooks/netarz-fx HTTP/1.1
Content-Type: application/json
User-Agent: NetArz-FX-Webhooks/1.0
X-NetArz-Event: rate.above
X-NetArz-Delivery: 7e0c4b0e-2a1d-4d4a-9a0f-1f8a1e1b2c3d
X-NetArz-Signature: t=1788600000,v1=5f1a2b…c9

{
  "id": "7e0c4b0e-2a1d-4d4a-9a0f-1f8a1e1b2c3d",
  "event": "rate.above",
  "created_at": "2026-09-05T10:20:00+03:30",
  "alert": { "id": 42, "label": "دلار بالای ۱۱۰ هزار", "type": "above", "code": "USD", "threshold": 110000, "percent": null },
  "app_id": 12,
  "reason": "mid crossed above 110000",
  "rate": { "code": "USD", "quote_currency": "IRT", "mid": 110200, "buy": 109700, "sell": 110700, "previous_mid": 109800, "as_of": "2026-09-05T10:20:00+03:30" }
}

event یکی از rate.above، rate.below، rate.change، rate.update یا test است. previous_mid مقدار مرجع قبلی است (برای change، مقدار آخرین اعلان).

اعتبارسنجی امضا

هر تحویل با X-NetArz-Signature: t=<timestamp>,v1=<hex> می‌آید که v1 برابر HMAC-SHA256 رشتهٔ "<t>.<بدنهٔ خام>" با secret هشدار است. همیشه با بدنهٔ خام (قبل از parse) محاسبه کنید و برای مقایسه از تابع constant-time استفاده کنید. در هر تلاش مجدد امضا با timestamp تازه ساخته می‌شود.

Node.js
import crypto from "node:crypto";
import express from "express";

const app = express();
app.post("/hooks/netarz-fx", express.raw({ type: "application/json" }), (req, res) => {
  const header = req.get("X-NetArz-Signature") || "";
  const t = header.match(/t=(\d+)/)?.[1];
  const v1 = header.match(/v1=([a-f0-9]+)/)?.[1];
  if (!t || !v1) return res.status(400).end();

  // ۱) پنجرهٔ زمانی ۵ دقیقه‌ای در برابر replay
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return res.status(400).end();

  // ۲) HMAC-SHA256 روی "<t>.<body خام>"
  const expected = crypto.createHmac("sha256", process.env.NETARZ_FX_WEBHOOK_SECRET)
    .update(`${t}.${req.body.toString("utf8")}`).digest("hex");
  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1))) return res.status(401).end();

  const event = JSON.parse(req.body);
  console.log(event.event, event.rate.code, event.rate.mid);
  res.status(200).end();   // هر 2xx = تحویل شد
});
PHP / Laravel
<?php
// Laravel — routes/api.php (بدون CSRF)
Route::post('/hooks/netarz-fx', function (\Illuminate\Http\Request $request) {
    $header = (string) $request->header('X-NetArz-Signature');
    preg_match('/t=(\d+)/', $header, $t);
    preg_match('/v1=([a-f0-9]+)/', $header, $v1);

    abort_unless($t && $v1, 400);
    abort_if(abs(time() - (int) $t[1]) > 300, 400);

    $expected = hash_hmac('sha256', $t[1].'.'.$request->getContent(), config('services.netarz.webhook_secret'));
    abort_unless(hash_equals($expected, $v1[1]), 401);

    $event = $request->json()->all();
    // … کاری که می‌خواهید: ذخیره، پیام تلگرام، تغییر قیمت محصولات
    return response()->noContent();
});
Python
import hmac, hashlib, time, json
from flask import Flask, request, abort

app = Flask(__name__)
SECRET = b"whsec_..."

@app.post("/hooks/netarz-fx")
def hook():
    sig = request.headers.get("X-NetArz-Signature", "")
    parts = dict(p.split("=", 1) for p in sig.split(","))
    if abs(time.time() - int(parts["t"])) > 300:
        abort(400)
    expected = hmac.new(SECRET, f'{parts["t"]}.'.encode() + request.get_data(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, parts["v1"]):
        abort(401)
    event = json.loads(request.get_data())
    print(event["event"], event["rate"]["mid"])
    return "", 200

تلاش مجدد

پاسخ غیر 2xx یا timeout = تلاش مجدد با فاصله‌های فوری، ۱ دقیقه، ۵ دقیقه، ۱۵ دقیقه، ۱ ساعت، ۳ ساعت. بعد از ۶ تلاش، تحویل «ناموفق» علامت می‌خورد و در پنل و GET /alerts/{id} با کد پاسخ و بدنهٔ خطا دیده می‌شود.

تست

POST /api/fx/v1/alerts/{id}/test فقط طرح پرو
cURL
curl -X POST https://netarz.ir/api/fx/v1/alerts/42/test \
  -H "Authorization: Bearer $NETARZ_FX_KEY"
# { "data": { "delivery_id": "…", "status": "delivered", "response_code": 200, "attempts": 1 } }
ایده‌ها

قیمت محصولات فروشگاه را با هر rate.update دوباره حساب کنید · با above/below پیام تلگرام به تیم فروش بفرستید · با change ۰٫۵٪ کش نرخ خود را باطل کنید.