Send → Poll → Verify
جریان کامل
جریان پیشنهادی سمت محصول برای ارسال کد، نمایش وضعیت و تایید کاربر.
نمودار
این نمودار مسیر معمول یک verification را نشان می دهد: ارسال کد، پیگیری وضعیت، تایید کد و رسیدن به نتیجه نهایی.
۱
ثبت درخواست ارسال
POST /v1/otp/send شماره کاربر را می گیرد و یک verification_id برمی گرداند. اگر channels داده شود، مسیر همان درخواست را مشخص می کند.
۲
ارسال روی کانال اول
نویدا کانال مناسب را انتخاب می کند، تلاش ارسال را ثبت می کند و در صورت نیاز مسیر جایگزین بعدی را برای زمان مناسب نگه می دارد.
۳
پیگیری وضعیت
GET /v1/otp/{id} کانال فعلی، وضعیت تلاش ارسال و زمان باقی مانده را نشان می دهد. وبهوک هم می تواند همین تغییرات را بدون polling اعلام کند.
۴
تایید کد
POST /v1/otp/verify کد وارد شده را بررسی می کند. موفقیت فقط وقتی قطعی است که پاسخ verified=true باشد.
۵
نتیجه نهایی
فرایند با یکی از وضعیت های
verified، failed، locked یا expired تمام می شود.
verifiedکد درست است و فرایند موفق تمام شده است.
failedمسیرهای ارسال به نتیجه نرسیده اند.
lockedتلاش های اشتباه زیاد شده است.
expiredزمان اعتبار تمام شده است.
گام ها
- برای هر تلاش ارسال، یک Idempotency-Key یکتا ساخته می شود و send اجرا می شود.
- verification_id در session یا دیتابیس محصول ذخیره می شود.
- تا زمان ورود کد توسط کاربر، status هر چند ثانیه خوانده می شود یا webhook ها دریافت می شوند.
- کد وارد شده با verify بررسی می شود و فقط در حالت
verified=trueکاربر تایید شده محسوب می شود. - برای وضعیت های terminal ناموفق، جریان با verification جدید شروع می شود.
نمونه end-to-end
import time
import uuid
import requests
API_KEY = "navidaa_xxx"
BASE = "https://api.navidaa.ir"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
send = requests.post(
f"{BASE}/v1/otp/send",
headers={**headers, "Idempotency-Key": str(uuid.uuid4())},
json={"phone": "09123456789", "channels": ["eitaa", "sms"]},
timeout=10,
)
send.raise_for_status()
verification_id = send.json()["verification_id"]
for _ in range(6):
status_response = requests.get(
f"{BASE}/v1/otp/{verification_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=10,
).json()
if status_response["status"] != "queued":
break
time.sleep(5)
verify = requests.post(
f"{BASE}/v1/otp/verify",
headers=headers,
json={"verification_id": verification_id, "code": "123456"},
timeout=10,
).json()
print(verify)