# ملی‌پیامک برای ورود و ثبت‌نام پلانک

در ۷ سپتامبر ۲۰۲۶ تابع ارسال در Supabase منتشر شد، هر چهار تنظیم محرمانه ذخیره شد و Send SMS Hook و ورود Phone فعال شدند. تأیید شماره اجباری، طول کد شش رقم و زمان اعتبار فعلی آن ۶۰ ثانیه است. یک درخواست آزمایشی امضاشده به شماره مجاز کاربر پاسخ ۲۰۰ دریافت کرد؛ این پاسخ یعنی ملی‌پیامک ارسال را پذیرفته است. استعلام تحویل ابتدا `100` و سپس `255` بود. تصویر پنل ارسالی کاربر در ۸ سپتامبر برای همین رسید، «عدم پذیرش اپراتور» را نشان می‌دهد؛ علت دقیق رد هنوز مشخص نیست. اعتبار حساب مثبت و خط فرستنده متعلق به همین حساب است. تحویل به گوشی موفق نبوده و جریان کامل ثبت‌نام/ورود تأیید نشده است. درخواست بدون امضا نیز در سرویس واقعی با پاسخ ۴۰۱ رد شد.

مسیر ارسال: کاربر درخواست کد می‌دهد؛ Supabase کد را تولید می‌کند و یک درخواست امضاشده به تابع `send-sms-melipayamak` می‌فرستد؛ تابع از متد HTTPS `SendOtp` ملی‌پیامک استفاده می‌کند. بررسی درستی و انقضای کد همچنان با Supabase است. این تابع در کد خود به دیتابیس یا دسترسی مدیر نیاز ندارد.

## اطلاعات موردنیاز

این مقادیر فقط در بخش **Edge Functions → Secrets** پروژه `wlsxzyeernwtsetzyltq` ثبت می‌شوند:

| نام تنظیم | مقدار |
|---|---|
| `MELIPAYAMAK_USERNAME` | نام کاربری پنل ملی‌پیامک |
| `MELIPAYAMAK_API_KEY` | API Key وب‌سرویس ملی‌پیامک؛ در بدنه درخواست به فیلد `password` فرستاده می‌شود |
| `MELIPAYAMAK_FROM` | شماره خط فرستنده مجاز در پنل |
| `SEND_SMS_HOOK_SECRET` | کلید امضای تولیدشده در تنظیم Send SMS Hook؛ مستقل از کلید ملی‌پیامک |
| `SMS_ALLOWED_PHONE` | شماره مجاز با قالب بین‌المللی؛ فعلاً فقط `+989121888745` |

این پنج مقدار در بخش Secrets ثبت شده‌اند. مقادیر کلیدها در کد برنامه، فایل قابل دانلود و متغیرهای عمومی مرورگر قرار ندارند. در ۸ سپتامبر نسخه محدودشده تابع منتشر شد؛ گیرنده غیرمجاز پیش از تماس با ملی‌پیامک رد می‌شود و نبودن شماره مجاز، کل ارسال را متوقف می‌کند. این محدودیت فقط با دستور صریح کاربر تغییر می‌کند. کد اعتبارسنجی مشترک در `_shared/sms-webhook.ts` قرار دارد و فایل مستقل همراه برای ویرایشگر داشبورد همه کد لازم را در خود دارد.

## تنظیمات اعمال‌شده و روش بازسازی

1. تابع `supabase/functions/send-sms-melipayamak` را در همین پروژه منتشر کنید. کد مستقل آماده ویرایشگر داشبورد در فایل همراه `send-sms-melipayamak.ts` است. نام تابع دقیقاً `send-sms-melipayamak` باشد.
2. بررسی JWT در درگاه این تابع باید خاموش باشد (`verify_jwt=false` در فایل تنظیمات پروژه)، زیرا درخواست Auth Hook توکن نشست کاربر ندارد. خود تابع، امضای HMAC درخواست Supabase را پیش از هر ارسال بررسی می‌کند؛ درخواست بدون امضا یا امضای اشتباه رد می‌شود.
3. در **Authentication → Hooks → Send SMS**، نشانی زیر را انتخاب و کلید امضا را تولید کنید:
   `https://wlsxzyeernwtsetzyltq.supabase.co/functions/v1/send-sms-melipayamak`
   کلید نمایش‌داده‌شده Hook را با همان مقدار در `SEND_SMS_HOOK_SECRET` تابع ذخیره کنید. قالب آن `v1,whsec_…` است. هیچ مقدار نمونه‌ای را به‌جای کلید واقعی استفاده نکنید.
4. سه تنظیم ملی‌پیامک را وارد کنید، سپس Hook و ورود Phone را فعال کنید. این تنظیمات روی پروژه اعمال شده‌اند: تأیید خودکار شماره خاموش، تأیید شماره اجباری و طول کد شش رقم است. هیچ شماره با کد ثابت آزمایشی ثبت نشده است.
5. ارسال و ورود واقعی را با شماره آزمایشی خودتان بررسی کنید. ثبت‌نام، ارسال مجدد، کد اشتباه، انقضا، بازیابی رمز و خطاهای پنل باید آزمایش شوند. دریافت شناسه ارسال فقط پذیرش درخواست توسط پنل است، نه تأیید تحویل به گوشی.

آزمایش انجام‌شده از ابزار Test تابع با یک درخواست HMAC معتبر و یک کد تصادفی بود؛ هیچ حساب کاربری ایجاد نشد و این آزمایش جای آزمون تولید/تأیید کد از مسیر Supabase Auth و فرم سایت را نمی‌گیرد. ارسال دوباره خودکار انجام نشد.

## سازگاری و رفتار خطا

- آدرس ارسال ثابت و HTTPS است: `https://rest.payamak-panel.com/api/SendSMS/SendOtp`. مشخصات در بدنه POST قرار می‌گیرند. اعتبار گواهی HTTPS بررسی می‌شود و ریدایرکت به مقصد دیگر دنبال نمی‌شود.
- کد Supabase ممکن است مانند `000123` با صفر شروع شود، درحالی‌که ورودی `code` ملی‌پیامک عدد صحیح است. پنل عدد `123` را دریافت می‌کند؛ کاربر همان عدد را وارد می‌کند و سرور آن را به `000123` تبدیل و برای تأیید به Supabase می‌فرستد. این نگاشت یک‌به‌یک است و فضای کدهای شش‌رقمی را کم نمی‌کند. کد خالی، غیرعددی یا بیش از شش رقم رد می‌شود.
- پاسخ معتبر شامل شناسه ارسال پذیرفته می‌شود؛ تمام کدهای خطای مستندشده و پاسخ نامعتبر، موفق تلقی نمی‌شوند. مبدل، پاسخ عددی/رشته‌ای یا ساختار REST با `Value` و `RetStatus` را پشتیبانی می‌کند. مقادیر کوتاه تا ۹۹۹ شناسه ارسال محسوب نمی‌شوند. قالب دقیق پاسخ حساب شما باید با نخستین ارسال مجاز بررسی شود.
- زمان انتظار ارسال ۳٫۵ ثانیه است تا داخل مهلت پنج‌ثانیه‌ای Hook قرار بگیرد. روی خطای مبهم یا قطع ارتباط، خود تابع ارسال دوم انجام نمی‌دهد.
- امضای درخواست، بدنه دست‌نخورده، شناسه و زمان آن بررسی می‌شوند. درخواست‌های بیش از پنج دقیقه اختلاف زمانی پذیرفته نمی‌شوند. ارسال تکراری با یک شناسه در همان نمونه اجرای تابع ادغام می‌شود؛ این جلوگیری از تکرار، بین چند نمونه اجرا یا بعد از راه‌اندازی مجدد تضمین نشده است. اگر نیاز به تضمین سراسری دارید، پیش از انتشار عمومی یک ذخیره‌ساز مستقل برای شناسه‌های درخواست اضافه شود.
- شماره ایرانی `989…` به `09…` تبدیل می‌شود. شماره بین‌المللی در قالب `+…` می‌ماند؛ پوشش مقصد باید توسط پنل تأیید شود.
- محدودیت‌های IP، خط فرستنده، اعتبار حساب و شماره‌های مسدود در پنل ملی‌پیامک اعمال می‌شوند. اگر پنل IP ثابت بخواهد، مسیر خروجی با IP ثابت لازم است؛ نباید کنترل IP یا بررسی HTTPS برای رفع خطا غیرفعال شود.

## بررسی مستندات رسمی در ۸ سپتامبر ۲۰۲۶

قالب درخواست با [SendOtp رسمی](https://www.melipayamak.com/api/sendotp/) تطبیق داده شد؛ نمونه رسمی نیز شماره `09…` و کد عدد صحیح دارد. مغایرتی در قرارداد ارسال پیدا نشد. [جدول تحویل](https://www.melipayamak.com/api/getdelivery/) کد `255` را تعریف نکرده است؛ نتیجه رد این پیام از تصویر پنل مشخص شده و نگاشت عمومی برای 255 اضافه نشده است.

مسیر پیشنهادی برای OTP محصول، [پترن خدماتی](https://www.melipayamak.com/api/sendbybasenumber2/) با `bodyId` تأییدشده است. این مسیر هنوز پیاده‌سازی یا فعال نشده و رفع قطعی رد فعلی به بررسی اپراتور نیاز دارد. جزئیات و متن آماده پشتیبانی در گزارش پیگیری همراه آمده‌اند.

منابع فنی تکمیلی: [کد رسمی ملی‌پیامک](https://github.com/Melipayamak/melipayamak-node/blob/master/src/sms/restAsync.js)، [Send SMS Hook](https://supabase.com/docs/guides/auth/auth-hooks/send-sms-hook)، [مهلت و خطاهای Hook](https://supabase.com/docs/guides/auth/auth-hooks)، [قرارداد امضای Standard Webhooks](https://github.com/standard-webhooks/standard-webhooks/blob/main/spec/standard-webhooks.md)، [تولید کد با صفر ابتدایی در Supabase](https://github.com/supabase/auth/blob/master/internal/crypto/crypto.go).
