مرجع API WapFlow OTP
کدهای تأیید را از شمارهی WhatsApp خودتان ارسال و تأیید کنید. همهی پاسخها JSON هستند.
آدرس پایه: https://wapflow.net/api/otp/v1
احراز هویت
در هر درخواست هدر Authorization: Bearer <key> را ارسال کنید. کلیدها را در صفحهی WapFlow OTP پنل WapFlow بسازید؛ کلیدهای زنده با wfo_live_ و کلیدهای آزمایشی با wfo_test_ شروع میشوند. کلید فقط هنگام ساخت یک بار نمایش داده میشود؛ آن را امن نگه دارید و فقط در سمت سرور استفاده کنید.
پاسخ موفق به این شکل است: { "success": true, ... }؛ پاسخ خطا: { "success": false, "error": { "code": "...", "message": "..." } }.
ارسال کد
phone (الزامی) شمارهی گیرنده است. اختیاری: code_length (4–8)، ttl (60–900 ثانیه)، lang (مثلاً tr، en) و app_name. هر موردی که وارد نکنید، از تنظیمات پنل شما گرفته میشود.
{
"phone": "905321234567",
"code_length": 6,
"ttl": 300,
"lang": "tr",
"app_name": "Acme"
}
{
"success": true,
"request_id": "req_...",
"phone": "905321234567",
"expires_at": "2026-11-12T10:05:00.000Z",
"status": "sent" // "sent" | "queued"
}
تأیید کد
phone و code الزامی هستند. با request_id، همان درخواست بررسی میشود؛ بدون آن، آخرین کد منقضینشدهای که با این کلید به این شماره ارسال شده بررسی میشود. پس از ۵ تلاش نادرست، درخواست قفل میشود و کد تأییدشده دوباره قابل استفاده نیست.
{ "request_id": "req_...", "phone": "905321234567", "code": "123456" }
{ "success": true, "valid": true }
{ "success": true, "valid": false,
"reason": "invalid_code", // invalid_code | expired | too_many_attempts | already_verified | not_found
"attempts_left": 3 }
استعلام وضعیت
وضعیت درخواست را برمیگرداند: queued، sent، delivered، read، failed، verified یا expired.
{ "success": true, "request_id": "req_...", "status": "delivered",
"sent_at": "...", "delivered_at": "...", "verified_at": null }
آزمایش اتصال
نشان میدهد کلید معتبر است، بستهی شما چیست، چند حساب متصل است و سهمیهی این ماه چقدر مصرف شده است (دکمهی «آزمایش اتصال» در افزونهی WordPress از این استفاده میکند).
{ "success": true, "plan": "otp-2",
"accounts": { "limit": 2, "connected": 1 },
"quota": { "monthly": 15000, "used": 42, "period": "2026-11" },
"ends_at": "2026-12-12T10:00:00.000Z", "mode": "live" }
نمونهها
این نمونهها کدی ارسال میکنند و سپس کدی را که کاربر وارد میکند تأیید میکنند. بهجای wfo_live_XXXX کلید خود را قرار دهید.
# 1) send
curl -X POST https://wapflow.net/api/otp/v1/send \
-H "Authorization: Bearer wfo_live_XXXX" \
-H "Content-Type: application/json" \
-d '{"phone":"905321234567","app_name":"Acme"}'
# 2) verify
curl -X POST https://wapflow.net/api/otp/v1/verify \
-H "Authorization: Bearer wfo_live_XXXX" \
-H "Content-Type: application/json" \
-d '{"request_id":"req_...","phone":"905321234567","code":"123456"}'<?php
function wapflow_otp(string $path, array $body): array {
$ch = curl_init('https://wapflow.net/api/otp/v1' . $path);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 15,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WAPFLOW_OTP_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($body),
]);
$res = json_decode(curl_exec($ch), true) ?: [];
curl_close($ch);
return $res;
}
$sent = wapflow_otp('/send', ['phone' => '905321234567', 'app_name' => 'Acme']);
// ... kullanıcı kodu girince:
$check = wapflow_otp('/verify', ['request_id' => $sent['request_id'], 'phone' => '905321234567', 'code' => $_POST['code']]);
if (!empty($check['valid'])) { /* giriş başarılı */ }const BASE = 'https://wapflow.net/api/otp/v1';
async function otp(path, body) {
const res = await fetch(BASE + path, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.WAPFLOW_OTP_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
return res.json();
}
const sent = await otp('/send', { phone: '905321234567', app_name: 'Acme' });
// ... when the user submits the code:
const check = await otp('/verify', { request_id: sent.request_id, phone: '905321234567', code: '123456' });
if (check.valid) { /* signed in */ }import os
import requests
BASE = "https://wapflow.net/api/otp/v1"
HEADERS = {"Authorization": "Bearer " + os.environ["WAPFLOW_OTP_KEY"]}
def otp(path, body):
return requests.post(BASE + path, json=body, headers=HEADERS, timeout=15).json()
sent = otp("/send", {"phone": "905321234567", "app_name": "Acme"})
# ... when the user submits the code:
check = otp("/verify", {"request_id": sent["request_id"], "phone": "905321234567", "code": "123456"})
if check.get("valid"):
pass # signed inکدهای خطا
| HTTP | کد | معنی |
|---|---|---|
| 400 | invalid_request | بدنهی درخواست یا پارامترها نامعتبر است. |
| 401 | invalid_key | کلید API نامعتبر است یا لغو شده است. |
| 402 | no_subscription | این حساب اشتراک WapFlow OTP ندارد. |
| 402 | subscription_expired | اشتراک منقضی شده است؛ لطفاً تمدید کنید. |
| 403 | sales_disabled | سرویس بهطور موقت در دسترس نیست. |
| 422 | invalid_phone | شمارهی تلفن نامعتبر است. |
| 429 | rate_limited | از حد مجاز درخواست عبور کردهاید؛ پس از retry_after ثانیهی موجود در پاسخ دوباره تلاش کنید. |
| 429 | quota_exceeded | سهمیهی کد این ماه تمام شده است. |
| 429 | daily_limit_reached | به حد مجاز ارسال روزانهٔ حسابهای متصل واتساپ رسیدهاید؛ پس از ثانیههای retry_after در پاسخ دوباره تلاش کنید (ساعت ۰۰:۰۰ روز بعد، به وقت استانبول). از سهمیه کسر نمیشود. |
| 503 | no_account_connected | هیچ حساب WhatsApp متصل و فعالی وجود ندارد. |
| 503 | send_failed | پیام ارسال نشد؛ کمی بعد دوباره تلاش کنید. |
محدودیت نرخ
- برای هر شماره: ۱ کد در هر ۶۰ ثانیه، ۵ کد در ساعت و ۱۰ کد در روز.
- برای هر کلید API: ۶۰ ارسال در دقیقه.
- برای هر نشانی IP: ۱۲۰ درخواست در دقیقه (شامل تأیید).
- تأیید: ۱۰ تلاش در دقیقه برای هر شماره، و حداکثر ۵ تلاش نادرست برای هر کد.
- سهمیهی ماهانه به بستهی شما بستگی دارد؛ وقتی تمام شود،
quota_exceededبرگردانده میشود. کلیدهای آزمایشی سهمیه مصرف نمیکنند.
گرمکردن حساب و سقف روزانه
- شمارههای واتساپ تازه متصلشده برای کاهش خطر مسدودی، بهتدریج گرم میشوند: در ۳ روز اول روزانه ۳۰ کد، در روزهای ۴ تا ۷ روزانه ۱۰۰ کد، و سپس روزانه ۵۰۰ کد برای هر حساب (مقادیر پیشفرض).
- حسابی که به سقف روزانهاش برسد نادیده گرفته میشود و کدها از سایر حسابهای متصل شما ارسال میشوند. اگر همه پر باشند،
429 daily_limit_reachedبازگردانده میشود؛ شمارنده ساعت ۰۰:۰۰ به وقت استانبول صفر میشود. - برای حجم بیشتر، بستهای با چند حساب انتخاب کنید. کلیدهای آزمایشی تحت تأثیر این محدودیتها نیستند.
کلیدهای آزمایشی
کلیدهایی که با wfo_test_ شروع میشوند پیام WhatsApp ارسال نمیکنند و سهمیه مصرف نمیکنند؛ کد در فیلد test_code برگردانده میشود. قوانین ارسال و محدودیت نرخ مانند کلید زنده است و اشتراک فعال همچنان لازم است. برای رفتن به حالت زنده فقط کلید را عوض کنید.
{ "success": true, "request_id": "req_...", "status": "sent", "test_code": "482913" }
قالب شمارهی تلفن
- شماره فقط به ارقام تبدیل میشود (+، فاصله و خط تیره حذف میشوند) و باید ۱۰ تا ۱۵ رقم باشد.
- کد کشور را وارد کنید (مثلاً
905321234567). شمارهی ۱۱ رقمی که با ۰ شروع میشود، ترکیهای در نظر گرفته میشود و ۹۰ به ابتدای آن اضافه میشود. - شمارهی نامعتبر، پاسخ
422 invalid_phoneبرمیگرداند.
نکات امنیتی
- کدها با مولد تصادفی امن از نظر رمزنگاری تولید میشوند و هرگز بهصورت متن ساده ذخیره نمیشوند.
- هرگز کلید API را در مرورگر، اپلیکیشن موبایل یا کد عمومی به کار نبرید؛ درخواستها را از سرور خود ارسال کنید.
- همیشه کد را با
/verifyدر سرور بررسی کنید. - WapFlow OTP، API رسمی WhatsApp نیست و تحویل پیام را تضمین نمیکند؛ برای عملیات حساس یک کانال پشتیبان داشته باشید.
افزونهی WordPress
- wapflow-otp.zip را دانلود کنید.
- در مدیریت WordPress به افزونهها ← افزودن ← بارگذاری افزونه بروید، فایل zip را بارگذاری و فعال کنید.
- در تنظیمات افزونه، کلید API ساختهشده در پنل WapFlow را وارد کنید.
- با دکمهی «آزمایش اتصال» کلید و بستهی خود را بررسی کنید.
- ابتدا با کلید آزمایشی امتحان کنید، سپس کلید زنده را وارد کنید.