# افزونهٔ مستقل درگاه واقعی سایاپی برای ووکامرس — ۰.۱.۰ این بسته با افزونهٔ سندباکس قبلی فرق دارد: شناسهٔ روش پرداخت آن `sayapay_live` است و فقط به API سروری `https://saya-pay.com/api/ipg/merchant/` متصل می‌شود. نصب بسته، دریافت واقعی را فعال نمی‌کند. روش پرداخت به‌صورت پیش‌فرض خاموش است؛ فعال‌سازی حساب و پذیرندگی در سایاپی هم مستقل از نصب افزونه انجام می‌شود. ## پیش‌نیاز و نصب محدود 1. PHP 8.1 یا جدیدتر، نسخهٔ ۶۴بیتی و HTTPS معتبر برای فروشگاه لازم است. این بسته فقط برای Checkout **کلاسیک** با ذخیره‌سازی بومی **CPT** است؛ **HPOS، کش شیء سفارش ووکامرس، object cache خارجی و Checkout Blocks پشتیبانی نمی‌شوند**. اگر API رسمی بررسی نوع ذخیره‌سازی و کش یا پاک‌سازی گروهیِ کشِ محلی موجود نباشد، روش پرداخت بسته می‌ماند؛ نسخهٔ قدیمی‌تر به‌صورت حدسی مجاز نمی‌شود. هنگام پرداخت، تعلیق invalidation کش نیز مجاز نیست. 2. در سایاپی مسیر کسب‌وکار، تأیید ایمیل، ورود دومرحله‌ای و بررسی مدارک و مبدأ وب‌سایت فروشگاه باید کامل شود. پروندهٔ شبای خود فروشگاه در `/app/splits` ثبت می‌شود؛ تأیید واقعی آسان‌پرداخت / شاپرک باید جداگانه دریافت و ثبت شود. ثبت پرونده با تأیید آن یکی نیست. 3. فعال‌سازی API پذیرنده، تسهیم تأییدشده، دامنه، IP و محدودهٔ مبلغ سمت سایاپی کنترل می‌شوند. این نسخه ۱۰۰٪ تراکنش را به یک ذی‌نفع متعلق به همان فروشگاه اختصاص می‌دهد؛ کارمزد اضافی، پورسانت یا انتقال به شبای دلخواه ایجاد نمی‌کند. 4. بستهٔ کامل `sayapay-woocommerce-live-0.1.0.zip` را نصب کنید؛ هر سه فایل زیر باید همراه افزونه موجود باشند. فایل PHP اصلی به‌تنهایی بستهٔ کامل نیست: - `sayapay-live-gateway.php` - `lib/wordpress-live.php` - `lib/MerchantClient.php` 5. کلید مستقل `sp_live_...` را از `/app/gateway` با رمز حساب و تأیید دومرحله‌ای بسازید. کلید تست، رمز آسان‌پرداخت یا رمز پورتال در این افزونه کاربرد ندارد. 6. مدیر فنی کلید را فقط در پیکربندی خصوصی سرور فروشگاه قرار دهد. نمونهٔ زیر فقط نام متغیر محیطی را نشان می‌دهد و هیچ کلید واقعی در فایل افزونه نمی‌گذارد: ```php define('SAYAPAY_LIVE_MERCHANT_KEY', (string) getenv('SAYAPAY_LIVE_MERCHANT_KEY')); ``` محیط اجرای PHP باید آن متغیر خصوصی را دریافت کند. کلید را در کد عمومی، فایل دانلودی، گیت، URL، مرورگر، پیام پشتیبانی یا گزارش خطا نگذارید. افزونه عمداً ورودی کلید در صفحهٔ تنظیمات ندارد؛ مقدار کامل در HTML مدیر یا مشتری قرار نمی‌گیرد. دیگر افزونه‌ها و مدیران همان سرور همچنان مرز اعتماد میزبان‌اند؛ ثبت سرآیند Authorization یا query کامل مسیر بازگشت در لاگ‌های میزبان ممنوع شود. 7. در «ووکامرس ← پیکربندی ← پرداخت‌ها»، روش «سایاپی — پذیرنده واقعی» را فقط پس از تأیید پذیرندگی و آزمون محدود جداگانه روشن کنید. واحد سفارش باید `IRR` یا `IRT` باشد. مبلغ با متن ده‌دهی دقیق تبدیل می‌شود؛ هیچ گردکردن یا محاسبهٔ اعشاری شناور انجام نمی‌شود. یک دهم تومان برابر یک ریال است؛ کسرِ ریال رد می‌شود. سقف پروتکل جای سقف واقعی پذیرندگی را نمی‌گیرد. ## بررسی محلیِ آمادگی میزبان در صفحهٔ تنظیمات همین روش پرداخت، بخش «آمادگی میزبان» فقط به کاربر دارای مجوز `manage_woocommerce` نمایش داده می‌شود. مدیر فروشگاه می‌تواند علت پنهان‌بودن درگاه را در مواردی مانند HPOS، کش، واحد پول، قالب کلید یا آدرس بازگشت بررسی کند. فقط وضعیت‌های ثابت نمایش داده می‌شوند؛ کلید، مقدار تنظیمات، آدرس سایت، اطلاعات سفارش یا مشتری و متن خام خطا در این گزارش نیست. وضعیت تعلیق invalidation کش مستقیماً و بدون تغییر پرچم بومی وردپرس خوانده می‌شود؛ تابع `wp_suspend_cache_invalidation()` تنظیم‌کننده است و برای تشخیص فراخوانی نمی‌شود. پرچم اولیهٔ تعریف‌نشده یا `null` مانند رفتار هسته، غیرفعال است؛ تعلیق فعال یا مقدار با نوع نامعتبر، ادامهٔ پرداخت را می‌بندد. گزارش تشخیصی و تکرار آن نباید وضعیت کش فروشگاه را تغییر دهند. پرچم بومی object cache خارجی نیز فقط خوانده می‌شود: مقدار اولیهٔ تعریف‌نشده، `null` یا `false` کش محلی است؛ `true` و نوع‌های نامعتبر مجاز نیستند. تشخیص، تابع ترکیبی getter/setter وردپرس را فراخوانی نمی‌کند و پرچم را تغییر نمی‌دهد. این بررسی فقط قالب و قابلیت‌های محلی را می‌خواند؛ هیچ درخواست شبکه یا بانک، تغییر تنظیمات، ساخت سفارش و قفل، پاک‌سازی کش یا اجرای صف انجام نمی‌دهد. «برقرار در بررسی محلی» تأیید کلید توسط سایاپی، مجوز پذیرندگی، تأیید دامنه یا اثبات واریز بانکی نیست. قالب آدرس HTTPS بررسی می‌شود، نه دسترس‌پذیری آن. وجود API صف و فعال‌بودن تنظیم WP-Cron هم به معنی اجرای موفق صف نیست؛ با خاموش‌بودن WP-Cron، cron مستقل باید جداگانه بررسی شود. نوع واقعی صفحهٔ Checkout کلاسیک، کارکرد دیتابیس و قفل، ذخیره‌سازی سفارش، موجودی، hookها و سازگاری افزونه‌ها همچنان آزمون بومی جداگانه می‌خواهند. این گزارش جای آزمون نصب واقعی یا پرداخت بانکی محدود را نمی‌گیرد و درگاه را روشن نمی‌کند. محدودیت‌های Checkout Blocks، HPOS و کش پایدار تغییری نکرده‌اند. ## جریان سفارش و اثبات پرداخت پیش از اولین درخواست شبکه، مبلغ، ارز اصلی، شناسهٔ خارجی سفارش، عنوان ثابت، URL بازگشت دارای قابلیت تصادفی، کلید تکرارناپذیری و اثرانگشت اقلام مالی سفارش در اطلاعات خصوصی سفارش ذخیره و دوباره خوانده می‌شوند. اطلاعات صورتحساب، ایمیل، تلفن، نشانی مشتری، شرح کالاها یا اطلاعات کارت به API فرستاده نمی‌شوند. تنها چهار فیلد `order_id`، `amount`، `title` و `return_url` ارسال می‌شوند. پس از پاسخ معتبر، شناسهٔ پرداخت هم پیش از هدایت مشتری ذخیره می‌شود. با وجود شناسه، پیگیری فقط `GET /payments/` است؛ درخواست ساخت تازه یا `POST /verify` ارسال نمی‌شود. پارامترهای بازگشت مرورگر، از جمله مبلغ، وضعیت یا شناسهٔ پرداخت ادعایی، مدرک موفقیت نیستند و برای تعیین نتیجه استفاده نمی‌شوند. قابلیت بازگشت به همان سفارش پیش از هر استعلام شبکه و پیش از گرفتن قفل بررسی می‌شود؛ دانستن شمارهٔ سفارش برای قفل‌کردن یا پیگیری آن کافی نیست. تکمیل سفارش فقط با پاسخ معتبر سمت سرور و تطبیق هم‌زمان شناسهٔ ذخیره‌شده، شناسهٔ سفارش، مبلغ صحیح ریالی، ارز `IRR`، حالت `live`، عنوان و URL ثابت ممکن است. افزون بر آن `payment_verified` باید واقعاً بولی `true` باشد و وضعیت فقط `settlement_requested` یا `settled` باشد. وضعیت `verified`، انتظار تسویه، نتیجهٔ نامشخص، شکست یا پاسخ ناسازگار باعث تکمیل سفارش نمی‌شود. این تأیید، اعلام قطعی واریز به حساب بانکی نیست. `bank_credit_status` همچنان `not_reconciled` است؛ گردش بانکی باید جداگانه تطبیق داده شود. در حالت CPT پشتیبانی‌شده، کش محلی گروه‌های post، metadata سفارش و اقلام مرتبط پیش از خواندن دوباره پاک می‌شود؛ این عملیات در کش خارجی اجرا نمی‌شود و چنین میزبانی اصلاً مجاز نیست. بازگشت همان نمونهٔ مشترک کش‌شده پس از شبکه رد می‌شود. بعد از انتظار شبکه، سفارش و اقلام بومی ووکامرس دوباره بارگیری می‌شوند و با شرایط ثابت مقایسه می‌شوند. تغییر مبلغ، ارز یا اقلام با همان جمع کل، ادامه را متوقف می‌کند. قفل افزونه فقط مسیرهای خود افزونه را سری می‌کند؛ ویرایش هم‌زمان مدیر، افزونهٔ دیگر یا عامل بیرونی را قفل نمی‌کند. در پایلوت، ویرایش مالی سفارشِ دارای تلاش پرداخت باید عملیاتی متوقف باشد؛ آزمون واقعی هم‌زمانی روی میزبان بومی پیش از استفادهٔ عمومی هنوز لازم است. ## نتیجهٔ نامعلوم، قفل و تکمیل یک‌باره - نشانگر «درخواست شروع شده» قبل از شبکه ذخیره می‌شود. timeout، پاسخ معیوب، خطای HTTP یا قطع ارتباط شکست قطعی نیستند. افزونه آن درخواست ساخت را حتی با کلیک دوباره خودکار تکرار نمی‌کند و شناسهٔ سفارش، کلید تکرارناپذیری یا کلید اتصال جدید برای شارژ مجدد نمی‌سازد. - اگر پاسخ ساخت از دست رفت و شناسهٔ پرداخت ذخیره نشده باشد، پیگیری خودکار ممکن نیست. مدیر فروشگاه باید با پشتیبانی سایاپی همان شناسهٔ خارجی و تلاش ثابت را بررسی کند؛ حذف snapshot، ساخت تلاش تازه یا پرداخت دوباره راه‌حل نیست. - قفل در جدول options وردپرس با پیشوند مستقل `sayapay_live_lock_` و مقدار مالک تصادفی با `INSERT IGNORE` و شرط ایجاد دقیقاً یک ردیف ساخته می‌شود؛ `add_option` دارای upsert برای قفل استفاده نمی‌شود. حذف نیز اتمی و مقید به همان نام و مالک است. انقضا یا تصاحب خودکار ندارد. قفلِ یک پردازش دیگر حذف نمی‌شود. بعد از قطع فرایند، خطای ذخیره یا خطای تکمیل بومی، قفل برای بررسی مدیر باقی می‌ماند؛ غیرفعال‌سازی افزونه آن را پاک نمی‌کند. - پیش از `payment_complete` نشانگر پایدار `completion_started` ثبت می‌شود. بازگشت تکراری و اجرای هم‌زمان نمی‌توانند همان تکمیل را دوباره اجرا کنند. اگر بین نشانگر و اتمام عملیات بومی قطع رخ دهد، بررسی دستی وضعیت سفارش، موجودی، رسید و اجرای hookها لازم است؛ تکمیل یا کاهش موجودی کورکورانه تکرار نشود. - رفع قفل فقط بعد از احراز توقف پردازش قبلی و تطبیق شواهد توسط مدیر فنی انجام شود. هیچ ابزار «پاک‌کردن همهٔ قفل‌ها» یا پاک‌سازی خودکار در این بسته وجود ندارد. ## پیگیری فقط‌خواندنی بدون وابستگی کامل به بازگشت مشتری اگر Action Scheduler ووکامرس در دسترس باشد، بعد از ذخیرهٔ شناسه حداکثر ۱۲ استعلام با فاصلهٔ پنج دقیقه برای همان سفارش برنامه‌ریزی می‌شود. مصرف هر نوبت پیش از شبکه در سفارش ثبت می‌شود؛ تکرار همان کار، استعلام یا تکمیل دوباره ایجاد نمی‌کند. این صف فقط GET می‌زند؛ پرداخت، تأیید بانک یا استرداد شروع نمی‌کند. پس از ۱۲ نوبت نامشخص، یادداشت بررسی دستی می‌ماند و پرداخت تازه ساخته نمی‌شود. اطلاعات صف فقط شناسهٔ محلی سفارش، شمارهٔ نوبت و شمارندهٔ تعویق است، نه کلید یا قابلیت بازگشت. در تداخل معمول با بازگشت مشتری، همان نوبت حداکثر سه بار با فاصلهٔ یک دقیقه عقب می‌افتد؛ قفل را حذف یا تصاحب نمی‌کند. اگر قفل باقی بماند، پیگیری به بررسی مدیر نیاز دارد؛ تعویق بی‌نهایت انجام نمی‌شود. زمان اجرای صف به سلامت Action Scheduler و WP-Cron یا cron واقعی میزبان وابسته است؛ زمان‌بندی تضمین لحظه‌ای نیست. خاموش‌کردن افزونه فقط کارهای hook و گروه مخصوص همین نسخه را حذف می‌کند؛ مدارک، سفارش‌ها و قفل‌ها حفظ می‌شوند. هنگام راه‌اندازی مجدد، صف به‌طور خودکار برای گذشته بازسازی نمی‌شود؛ سفارش‌های معلق باید توسط مدیر بررسی شوند. با وجود شناسه، مسیر پرداخت دوباره فقط وضعیت همان پرداخت را می‌خواند و سفارش جدید نمی‌سازد. ## مرزهای نسخه و آزمون پیش از استفادهٔ عمومی Checkout Blocks، تمدید خودکار، ذخیرهٔ کارت، برداشت خودکار، webhook، استرداد بومی ووکامرس و واریز دلخواه بانکی در این بسته پشتیبانی نمی‌شوند. روش قدیمی `sayapay` و کلیدها و سفارش‌های سندباکس دست‌نخورده‌اند. تغییر روش یک سفارش قدیمی به `sayapay_live` یا انتقال snapshot بین فروشگاه‌ها مجاز نیست. تست‌های آفلاین PHP و شبیه‌ساز قرارداد میزبان اجرا شده‌اند؛ این‌ها به‌تنهایی نصب واقعی WordPress/WooCommerce نیستند. آزمون محدود بومی زیر مستقل از آن‌هاست. نصب/ارتقا/غیرفعال‌سازی روی فروشگاه عمومی مشتری، PHP 8.1 روی همان میزبان، ذخیره‌سازی CPT، Action Scheduler/WP-Cron بومی، موجودی و hookهای واقعی تکمیل، بازگشت مهمان، تداخل افزونه‌ها، هم‌زمانی مدیر و سفارش، ایمیل و محدودیت دامنه/مبلغ پذیرندگی هنوز روی یک میزبان مجزای مجاز باید آزمون شوند. HPOS و cache پایدار در این نسخه صریحاً رد می‌شوند، نه صرفاً «تست‌نشده». جابه‌جایی واقعی پول با تست‌های آفلاین ادعا نمی‌شود. آزمون رقابت واقعی MySQL/MariaDB برای قید یکتای `option_name`، نتیجهٔ `INSERT IGNORE` و حذف مالک‌مقید با مقایسهٔ باینری نیز پیش از فعال‌سازی عمومی لازم است؛ شبیه‌ساز wpdb جای آزمون واقعی دیتابیس میزبان را نمی‌گیرد. فعال‌سازی عمومی فروشگاه، انتشار این بسته یا نصب روی میزبان مشتری باید پس از این بررسی و یک آزمون بانکی محدود جداگانه انجام شود. قبل از آن روش خاموش بماند. ### آزمون محدود هسته و دیتابیس بومی — ۲۳ اکتبر ۲۰۲۶ ۲۶۶ بررسی در ۱۳ سناریو روی نسخه‌های رسمی و ثابت **WordPress 7.1.3**، **WooCommerce 11.2.1**، **PHP 8.4.26** و **MariaDB 11.4.8** موفق شد. آرشیوها و تمام فایل‌های هسته با manifest رسمی مقایسه شدند؛ نصب و ذخیره‌سازی CPT، API کش، موجودی و hook تکمیل، صف بومی Action Scheduler، قفل SQL بین پردازش‌های مستقل و غیرفعال‌سازی افزونه واقعاً اجرا شدند. رسید نامنطبق، تغییر مبلغ/اقلام هنگام انتظار و نتیجهٔ نامعلوم، نباید تکمیل یا POST تازه ایجاد کنند. فقط `WC_Order` و کلاس رسمی `Automattic\WooCommerce\Admin\Overrides\Order` با ذخیره‌سازی دقیق CPT پذیرفته می‌شوند؛ زیرکلاس‌های دلخواه و ذخیره‌سازی‌های سفارشی رد می‌شوند. آزمون از پاسخ پرداخت ساختگی و مهار ایمیل استفاده می‌کند؛ هیچ درخواست به سایاپی یا بانک و هیچ جابه‌جایی پول انجام نشد. Checkout واقعی مرورگر، TLS عمومی، درگاه `wc-api` و ایمیل میزبان مشتری، ارتقا و سازگاری سایر افزونه‌ها همچنان پذیرش مستقل می‌خواهند. روش پرداخت پیش‌فرض خاموش باقی می‌ماند. ### منابع قرارداد میزبان - [راهنمای رسمی Payment Gateway API ووکامرس](https://developer.woocommerce.com/docs/features/payments/payment-gateway-api/) - [API رسمی add_option وردپرس](https://developer.wordpress.org/reference/functions/add_option/) - [API رسمی درخواست HTTP وردپرس](https://developer.wordpress.org/reference/functions/wp_remote_request/) - [راهنمای رسمی CRUD و HPOS ووکامرس](https://developer.woocommerce.com/docs/features/orders/high-performance-order-storage/recipe-book/) - [قرارداد رسمی پاک‌سازی گروه کش وردپرس](https://developer.wordpress.org/reference/functions/wp_cache_flush_group/)