غیر اختصاصی-آزمایشی WordPress / WooCommerce

افزونه وردپرس (آزمایشی)

آموزش فارسی نصب و استفاده از افزونه رسمی پوشفا در WordPress و WooCommerce؛ از Prompt و Service Worker تا Topic، هویت، Alias، Bracket و ارسال خودکار با Hook.

دانلود افزونه رسمی پوشفا

نسخه ۱.۰.۱ افزونه برای WordPress 6.0 یا جدیدتر و PHP 7.4 یا جدیدتر آماده است. فایل ZIP را بدون خارج‌کردن از حالت فشرده از پیشخوان وردپرس نصب کنید.

برای نصب نسخه جدید روی نسخه قبلی، همان ZIP را از «افزونه‌ها ← افزودن افزونه تازه ← بارگذاری افزونه» انتخاب کنید و جایگزینی نسخه را بپذیرید.
مشخصاتمقدار
نسخه افزونه 1.0.1
حداقل WordPress 6.0
حداقل PHP 7.4
سرویس مناسب Web / PWA
WooCommerce اختیاری؛ فقط برای قابلیت‌های فروشگاهی

نصب و اتصال اولیه

ساخت سرویس

در پنل پوشفا یک سرویس Web/PWA برای دامنه HTTPS دقیق سایت بسازید. دامنه سرویس باید با دامنه‌ای که وردپرس واقعاً روی آن باز می‌شود یکسان باشد.

نصب ZIP

در وردپرس وارد «افزونه‌ها ← افزودن افزونه تازه ← بارگذاری افزونه» شوید، فایل ZIP را انتخاب و افزونه را فعال کنید.

ثبت کلیدها

از «پوشفا ← تنظیمات» Public Key را وارد کنید. برای ارسال از وردپرس، ساخت Topic و همگام‌سازی امن هویت، Private Key را نیز وارد کنید.

ذخیره و بررسی

تنظیمات را ذخیره کنید و در «پوشفا ← وضعیت و راهنما» وضعیت HTTPS، SDK، کلیدها و Service Worker را ببینید.

آزمایش عضویت

یک دکمه Prompt در صفحه آزمایشی بگذارید، اجازه اعلان را صادر کنید و سپس از پنل وردپرس یک پیام آزمایشی بفرستید.

Public Key قابل استفاده در مرورگر است، اما Private Key محرمانه است و نباید در قالب، JavaScript، صفحه سایت، Git یا Log قرار بگیرد.

نگهداری امن کلیدها در wp-config.php

در محیط Production می‌توانید کلیدها و آدرس‌ها را در wp-config.php تعریف کنید. در این حالت فیلد متناظر در پیشخوان غیرفعال می‌شود و Private Key فقط در PHP باقی می‌ماند.

آدرس سمت‌سرور افزونه باید https://pushfa.com/api باشد. دامنه api.pushfa.com برای SDKهای عمومی است و مسیرهای خصوصی /api/webservices/* را عمداً با 404 رد می‌کند.
define('PUSHFA_API_PUBLIC_KEY', 'YOUR_PUBLIC_KEY');
define('PUSHFA_API_PRIVATE_KEY', 'YOUR_PRIVATE_KEY');
define('PUSHFA_SDK_BASE_URL', 'https://sdk.pushfa.com');
define('PUSHFA_API_BASE_URL', 'https://pushfa.com/api');

هر قسمت افزونه چه کاری انجام می‌دهد؟

گزینه «حذف داده هنگام Uninstall» فقط زمان حذف کامل افزونه اجرا می‌شود. غیرفعال‌کردن افزونه به‌تنهایی تنظیمات و نگاشت‌های محلی را پاک نمی‌کند.
بخش پیشخوانکاربرد
پوشفا ← تنظیمات کلیدها، Prompt، Foreground، هویت، Aliasها، Bracketها، انتشار خودکار، RetenX، Debug و سیاست حذف داده
پوشفا ← ارسال اعلان انتخاب گیرنده، ساخت پیام، زمان‌بندی، گزارش‌ها، گزینه‌های پیشرفته و استعلام Notification ID
پوشفا ← Topicها ساخت Topic، تعیین مجوزهای عضویت و کپی شورت‌کد دکمه
پوشفا ← وضعیت و راهنما بررسی HTTPS، کلیدها، SDK، Service Worker، WooCommerce و مشاهده شورت‌کدهای آماده

راهنمای گزینه‌های صفحه تنظیمات

گروه تنظیماتاثر
فعال‌بودن Pushfa بارگذاری SDK و قابلیت‌های Frontend را برای کل سایت روشن یا خاموش می‌کند
SDK Base URL محل دریافت notification-v2.js؛ مقدار رسمی https://sdk.pushfa.com
API Base URL مسیر درخواست‌های امن Backend؛ مقدار رسمی https://pushfa.com/api
Prompt mode نمایش خودکار طبق پنل پوشفا یا نمایش دستی فقط پس از دکمه/کد
Foreground behavior ارث‌بری، مخفی‌کردن یا اجبار اعلان سیستمی در تب فعال
اعلان درون‌صفحه‌ای نمایش پیام Foreground به‌شکل Toast داخل سایت
Identity sync اتصال Login/Logout وردپرس به External ID تصادفی Pushfa
External ID prefix فقط پیشوند شناسه تصادفی؛ User ID عددی به آن افزوده نمی‌شود
Email / Mobile Alias همگام‌سازی اختیاری ایمیل و متای موبایل؛ کلید پیش‌فرض موبایل billing_phone است
User Brackets همگام‌سازی first_name، last_name و display_name برای شخصی‌سازی
انتشار خودکار ارسال اولین انتشار نوع‌های محتوای انتخاب‌شده به all یا Topic UUID
تصویر شاخص استفاده از Featured Image به‌عنوان تصویر بزرگ پیام انتشار
WooCommerce RetenX ثبت رویدادهای فروشگاه برای Journey؛ نیازمند Pro و Private Key
Debug ثبت خطاهای افزونه بدون چاپ کلید خصوصی؛ فقط هنگام عیب‌یابی روشن بماند
Delete data on uninstall پاک‌کردن تنظیمات و فهرست Topic محلی فقط هنگام حذف کامل افزونه

Service Worker و خطای 404

افزونه مسیر pushfa-messaging-sw.js را در ریشه دامنه ایجاد می‌کند و پس از فعال‌سازی یا ذخیره تنظیمات Rewrite وردپرس را نوسازی می‌کند. آدرس زیر باید با JavaScript پاسخ دهد، نه صفحه HTML یا 404.

پیوندهای یکتا را ذخیره کنید

یک بار وارد «تنظیمات ← پیوندهای یکتا» شوید و بدون تغییر روی «ذخیره تغییرات» کلیک کنید.

Cache و CDN را پاک کنید

Cache افزونه، وب‌سرور و CDN را پاک و آدرس Worker را در پنجره ناشناس باز کنید.

Rewrite وب‌سرور را بررسی کنید

اگر 404 قبل از WordPress تولید می‌شود، وب‌سرور باید این مسیر را به index.php وردپرس عبور دهد. افزونه در document root قابل‌نوشتن یک fallback فیزیکی نیز می‌سازد.

اگر فایل pushfa-messaging-sw.js از قبل متعلق به سیستم دیگری باشد، افزونه آن را بازنویسی نمی‌کند. محتوای Workerها باید با هم ادغام شود یا مالکیت مسیر مشخص گردد.
https://example.com/pushfa-messaging-sw.js

Prompt عضویت؛ خودکار یا دستی

در حالت خودکار، زمان نمایش از تنظیمات سرویس پوشفا پیروی می‌کند. در حالت دستی، درخواست اجازه فقط بعد از کلیک کاربر نمایش داده می‌شود که معمولاً تجربه بهتری دارد.

اگر کاربر Permission را Deny کرده باشد، سایت نمی‌تواند Prompt اصلی مرورگر را دوباره اجبار کند؛ کاربر باید مجوز دامنه را از تنظیمات مرورگر تغییر دهد.
نیازشورت‌کد
دکمه فعال‌سازی اعلان [pushfa_button]
دکمه با متن دلخواه [pushfa_button label="خبرم کن"]
راهنمای نصب در iPhone/iPad [pushfa_ios_button]
[pushfa_button
    label="فعال‌سازی اعلان سفارش‌ها"
    subscribed_label="اعلان‌های سفارش فعال است"
    denied_label="اعلان‌ها در مرورگر مسدود شده است"
]

عضویت و لغو عضویت Topic با یک دکمه

Topic یک گروه از Subscriberهاست؛ مانند «تخفیف‌ها»، «اخبار محصول» یا «موجودشدن کالا». از «پوشفا ← Topicها» Topic را بسازید و شورت‌کد تولیدشده را در برگه، نوشته، ابزارک یا Shortcode Widget صفحه‌ساز قرار دهید.

کاربر روی دکمه می‌زند

اگر Permission صادر نشده باشد، افزونه همان‌جا درخواست اجازه اعلان را اجرا می‌کند.

عضویت ثبت می‌شود

برای دستگاه فعلی، subscribeTopic اجرا و متن دکمه به حالت لغو عضویت تبدیل می‌شود.

کلیک دوباره عضویت را لغو می‌کند

افزونه وضعیت واقعی Topic را می‌خواند و فقط عملیات لازم را انجام می‌دهد؛ Refresh صفحه نباید درخواست تکراری بسازد.

هنگام ساخت Topic گزینه‌های «عضویت از JavaScript»، «لغو عضویت از JavaScript» و «خواندن وضعیت عضویت» را فعال کنید. عضویت مربوط به همان مرورگر یا دستگاه است؛ دستگاه دیگر عضویت جداگانه دارد.
[pushfa_topic_button
    topic="TOPIC_UUID"
    subscribe_label="عضویت در تخفیف‌ها"
    unsubscribe_label="لغو عضویت از تخفیف‌ها"
]

Topic با دکمه اختصاصی JavaScript

اگر شورت‌کد کافی نیست، دکمه HTML خودتان را بسازید. کد را بعد از رویداد pushfaWordPressReady اجرا کنید تا SDK آماده باشد. UUID موضوع را از «پوشفا ← Topicها» کپی کنید؛ نام نمایشی Topic جای UUID نمی‌نشیند.

این توابع در مرورگر اجرا می‌شوند و فقط دستگاه فعلی را تغییر می‌دهند. برای ارسال پیام به Topic از «پوشفا ← ارسال اعلان» استفاده کنید؛ عضویت در Topic خودش پیام ارسال نمی‌کند.
تابع SDKورودیخروجی/اثر
requestPermission() ندارد درخواست مجوز Push پس از عمل کاربر
subscribeTopic(topicUuid) UUID موضوع عضویت دستگاه فعلی
unsubscribeTopic(topicUuid) UUID موضوع لغو عضویت دستگاه فعلی
getTopics() ندارد Promise شامل آرایه UUIDهای دستگاه
const topicUuid = 'TOPIC_UUID_FROM_PUSHFA';

window.addEventListener('pushfaWordPressReady', ({ detail }) => {
    const Pushfa = detail.Pushfa;

    document.querySelector('#join-sales').addEventListener('click', async () => {
        await Pushfa.requestPermission();
        await Pushfa.subscribeTopic(topicUuid);
        alert('عضویت انجام شد');
    });

    document.querySelector('#leave-sales').addEventListener('click', async () => {
        await Pushfa.unsubscribeTopic(topicUuid);
        alert('عضویت لغو شد');
    });

    document.querySelector('#check-sales').addEventListener('click', async () => {
        const topics = await Pushfa.getTopics();
        alert(topics.includes(topicUuid) ? 'عضو است' : 'عضو نیست');
    });
});

هویت کاربر؛ Subscriber ID و External ID

افزونه برای هر حساب WordPress یک External ID پایدار و غیرقابل‌حدس مانند wp-UUID در Backend می‌سازد. شناسه عددی User ID در Pushfa افشا نمی‌شود. هر مرورگر یا دستگاه نیز Subscriber ID جداگانه دارد.

در Logout، افزونه External ID را از مرورگر مشترک پاک می‌کند تا پیام کاربر قبلی به شخص بعدی نرسد.
شناسهمعناکاربرد پیشنهادی
Subscriber ID یک مرورگر یا دستگاه مشخص ارسال دقیق به یک دستگاه
External ID حساب کاربر WordPress روی دستگاه‌های متصل روش پیش‌فرض ارسال به کاربر یا فروشنده
FCM Token توکن فنی و قابل تغییر Push عیب‌یابی یا ارسال فنی؛ برای منطق کسب‌وکار پیشنهاد نمی‌شود

تفاوت Alias و Custom Alias

در پوشفا، Alias اصلی همان External ID حساب است. Custom Alias یک شناسه برچسب‌دار مستقل مانند crm_id، vendor_id، mobile یا email است. مقدار External ID با wp_user_ref تکرار نمی‌شود؛ wp_user_ref نسخه‌های قبلی در نخستین همگام‌سازی موفق حذف می‌شود.

Aliasهای هویتی را از داده قابل‌ویرایش مرورگر نسازید. برای Backend-only، Private Key را تنظیم و مجوز تغییر Alias از JavaScript را در سرویس خاموش کنید.
نوعنمونهچه زمانی استفاده شود؟
External ID wp-f4ffb3fb-... ارسال معمول به کاربر WordPress
Custom Alias vendor_id = V-204 هدف‌گیری با شناسه مستقل CRM، فروشنده یا سیستم دیگر
Custom Alias سفارش مهمان wp_order_ref = wp-order-UUID وقتی سفارش مهمان حساب و External ID ندارد
add_filter('pushfa_wordpress_identity_aliases', function ($aliases, $user) {
    $vendor_id = get_user_meta($user->ID, 'vendor_id', true);

    if ($vendor_id) {
        $aliases['vendor_id'] = (string) $vendor_id;
    }

    return $aliases;
}, 10, 2);

Custom Alias را چطور روی کاربر ثبت کنیم؟

مرحله ثبت با مرحله ارسال فرق دارد. کد زیر مقدار معتبر را از User Meta وردپرس می‌خواند. هنگام ورود کاربر و همگام‌شدن Subscriber، افزونه آن را در پوشفا ثبت می‌کند. سپس می‌توانید با همان Label و Value پیام بفرستید.

مقدار را در Backend ذخیره کنید

مثلاً crm_id را در User Meta همان کاربر قرار دهید.

Filter را اضافه کنید

افزونه هنگام همگام‌سازی، آرایه Aliasها را از این Filter می‌گیرد.

کاربر Push را فعال کند

Subscriber باید ساخته و به حساب واردشده متصل شود.

با همان Label و Value ارسال کنید

crm_id و CRM-42 باید دقیقاً با مقدار ثبت‌شده برابر باشند.

External ID اصلی کاربر را افزونه خودکار می‌سازد؛ برای ارسال معمول به یک User نیازی به ساخت Custom Alias ندارید.
// این کد را یک بار در MU Plugin سایت قرار دهید.
add_filter('pushfa_wordpress_identity_aliases', function ($aliases, $user) {
    $crm_id = get_user_meta($user->ID, 'crm_id', true);

    if ($crm_id !== '') {
        $aliases['crm_id'] = (string) $crm_id;
    }

    return $aliases;
}, 10, 2);

// این خط باید داخل Hook رویداد موردنظر اجرا شود، نه در ابتدای فایل.
pushfa_send_to_alias('crm_id', 'CRM-42', $message);

Bracket و شخصی‌سازی متن پیام

Bracket برای نگهداری ویژگی نمایشی مخاطب است، نه شناسایی او. افزونه می‌تواند first_name، last_name و display_name را از WordPress همگام کند. هنگام ارسال گزینه «شخصی‌سازی Bracket» را فعال کنید.

برای ثبت از مرورگر، مجوزهای Bracket سرویس لازم است؛ با Private Key، افزونه ابتدا همگام‌سازی امن Backend را انجام می‌دهد.
Bracket پیش‌فرضمنبع در WordPress
first_name متای first_name
last_name متای last_name
display_name نام نمایشی حساب
سلام {first_name:کاربر عزیز}
سفارش شما آماده ارسال است.

ارسال اعلان از پیشخوان WordPress

در «پوشفا ← ارسال اعلان» گیرنده، متن و گزینه‌های پیشرفته را انتخاب کنید. Public Key و Private Key هر دو برای ارسال سروری لازم‌اند.

اگر هیچ Subscriber یا مقصد معتبری وجود نداشته باشد، درخواست نباید وارد صف بی‌پایان شود و افزونه/API خطای قابل‌فهم برمی‌گرداند.
روش هدف‌گیریکاربرد
همه یا Topic ارسال عمومی با all یا UUID یک Topic
Subscriber ID یک یا چند دستگاه پایدار
External ID حساب کاربر روی دستگاه‌های متصل
Custom Alias یک Label و حداکثر ۱۰۰ Value
کاربر WordPress / فروشنده ورود User ID و هدف‌گیری خودکار با External ID
خریدار سفارش WooCommerce ورود Order ID و انتخاب خودکار مقصد مناسب

اجزای پیام و گزینه‌های پیشرفته

فیلدتوضیح
title / body عنوان و متن اصلی اعلان
link_url آدرس مقصد بعد از کلیک
image_url تصویر بزرگ اعلان
btn_left / btn_right عنوان و URL دکمه‌های اعلان
sendTime / time ارسال فوری یا زمان‌بندی‌شده
ttl مدت اعتبار پیام برحسب ثانیه
collapse_idCollapse IDPro جایگزینی پیام قبلی با شناسه یکسان
silentپوش بی‌صدا نمایش اعلان بدون صدا و لرزش
additional_dataAdditional DataPro داده JSON برای منطق اختصاصی سایت
get_delivery_status / get_click_status فعال‌کردن گزارش تحویل و کلیک
use_brackets جایگزینی Bracketها برای هر گیرنده
only_last_device در هدف‌گیری هویتی فقط آخرین دستگاه فعال را انتخاب می‌کند
smart_targeting انتخاب هوشمند مقصد مناسب در ارسال با Alias

کدهای PHP را کجا قرار دهیم؟

کد ارسال را داخل فایل افزونه پوشفا یا قالب اصلی ننویسید. روش پایدار، ساخت یک MU Plugin اختصاصی یا استفاده از افزونه Code Snippets است.

مسیر فایل پیشنهادی: wp-content/mu-plugins/pushfa-site-events.php. اگر پوشه mu-plugins وجود ندارد، آن را بسازید؛ افزونه‌های این پوشه خودکار بارگذاری می‌شوند.
تابع ارسال را مستقیم در ابتدای فایل اجرا نکنید؛ در غیر این صورت ممکن است با هر درخواست صفحه پیام تکراری ارسال شود. همیشه آن را داخل Hook یا رویداد مشخص قرار دهید.
<?php
/**
 * Plugin Name: Pushfa Site Events
 */

defined('ABSPATH') || exit;

// Hookها و تابع‌های ارسال سایت را از اینجا به بعد اضافه کنید.

تابع‌های آماده ارسال در افزونه

این تابع‌ها را فقط در کد PHP سمت سرور و داخل یک Hook اجرا کنید. شکل کلی همه آن‌ها این است: ابتدا شناسه مقصد، سپس آرایه پیام و در پایان آرایه اختیاری تنظیمات. همه تابع‌ها پاسخ API پوشفا یا WP_Error برمی‌گردانند.

وجود User ID، Order ID یا Alias به‌تنهایی به معنی وجود مشترک فعال نیست. گیرنده باید قبلاً اعلان را فعال کرده باشد و شناسه او در پوشفا ثبت شده باشد.
تابع کاملورودی اولکاربرد
pushfa_send_to_user($user_id, $message, $options = []) User ID عددی وردپرس ارسال به حساب کاربر با External ID
pushfa_send_to_order_purchaser($order_id, $message, $options = []) Order ID ووکامرس ارسال به خریدار عضو یا مهمان
pushfa_send_to_seller($seller_user_id, $message, $options = []) User ID فروشنده ارسال به حساب فروشنده
pushfa_send_to_product_seller($product_id, $message, $options = []) Product ID ووکامرس پیداکردن مالک محصول و ارسال به او
pushfa_send_to_subscribers($subscriber_ids, $message, $options = []) یک ID یا آرایه IDها ارسال به دستگاه‌های مشخص
pushfa_send_to_alias($label, $values, $message, $options = []) Label و سپس Valueها ارسال به Custom Alias ثبت‌شده
pushfa_send_to_token($token, $message, $options = []) FCM Token ارسال فنی مستقیم به یک Token

ورودی $message دقیقاً چیست؟

متغیر $message یک آرایه PHP است. حداقل title و body را بدهید. کلیدهای دیگر اختیاری‌اند. نام کلیدها را دقیقاً مانند نمونه بنویسید.

کلیدنوع و نمونهمعنی
title string — «پرداخت موفق» عنوان کوتاه اعلان؛ الزامی
body string — «سفارش شما ثبت شد» متن اعلان؛ الزامی
link_url URL — home_url(...) صفحه‌ای که با کلیک باز می‌شود
image_url URL تصویر بزرگ اعلان
sendTime current یا delay ارسال فوری یا زمان‌بندی
time تاریخ/ساعت معتبر API زمان اجرا وقتی sendTime برابر delay است
platform all/android/ios/desktop پلتفرم مقصد؛ پیش‌فرض all
ttl عدد ثانیه مدت اعتبار پیام
collapse_idCollapse IDPro string جایگزینی اعلان قبلی با شناسه یکسان
additional_dataAdditional DataPro آرایه یا JSON مورد قبول API داده اختصاصی برنامه
get_delivery_status true/false گزارش تحویل؛ پیش‌فرض true
get_click_status true/false گزارش کلیک؛ پیش‌فرض true
use_brackets true/false جایگزینی مقادیر Bracket در متن
$message = [
    'title'       => 'پرداخت موفق',
    'body'        => 'سفارش شما ثبت شد.',
    'link_url'    => home_url('/my-account/orders/'),
    'image_url'   => 'https://example.com/uploads/order-ready.jpg',
    'platform'    => 'all',
    'sendTime'    => 'current',
    'collapse_id' => 'order-status-123',
];

ورودی $options دقیقاً چیست؟

$options آرایه سوم و اختیاری است. اگر آن را ندهید، افزونه امن‌ترین مقصد پیش‌فرض را انتخاب می‌کند. فقط وقتی می‌خواهید روش هدف‌گیری را عوض کنید از آن استفاده کنید.

در ارسال معمول به کاربر، $options را اصلاً نفرستید؛ حالت auto خودکار از External ID تصادفی و امن افزونه استفاده می‌کند.
کلیدمقادیرکجا قابل استفاده است؟
target_mode auto / external_id / subscriber / custom_alias تابع کاربر، فروشنده و سفارش
subscriber_ids string یا array وقتی target_mode برابر subscriber است
external_id string Override شناسه کاربر؛ معمولاً لازم نیست
label string مانند mobile یا wp_order_ref وقتی target_mode برابر custom_alias است
values string یا array مقادیر Custom Alias؛ در صورت حذف از هویت کاربر/سفارش خوانده می‌شود
only_last_device true/false فقط آخرین دستگاه هدف‌گیری شود
smart_targeting true/false هدف‌گیری هوشمند در ارسال هویتی
$options = [
    'target_mode'     => 'external_id',
    'only_last_device'=> true,
];

$result = pushfa_send_to_user(25, $message, $options);

از کجا بفهمیم ارسال موفق بوده است؟

خروجی تابع را داخل $result بگیرید. WP_Error یعنی درخواست قبل از پذیرش یا هنگام تماس با API شکست خورده است. پاسخ غیرخطا یعنی درخواست توسط API پذیرفته شده؛ این لزوماً تضمین نمایش روی دستگاه نیست.

$result = pushfa_send_to_user(25, $message);

if (is_wp_error($result)) {
    // فقط در محیط عیب‌یابی Log کنید؛ کلید خصوصی را چاپ نکنید.
    error_log('Pushfa error: ' . $result->get_error_message());
    return;
}

// در این نقطه API درخواست را پذیرفته است.

ارسال پیام به یک کاربر WordPress

User ID فقط در Backend وردپرس استفاده می‌شود. افزونه External ID تصادفی همان حساب را پیدا و درخواست احراز‌شده را به پوشفا ارسال می‌کند.

کاربر باید قبلاً روی حداقل یک دستگاه Push را فعال کرده و هویت او با افزونه همگام شده باشد. اگر گیرنده معتبری وجود نداشته باشد، ارسال با خطا برمی‌گردد.
$result = pushfa_send_to_user($user_id, [
    'title'    => 'پیام جدید',
    'body'     => 'یک پیام جدید برای شما ثبت شده است.',
    'link_url' => home_url('/my-account/'),
]);

if (is_wp_error($result)) {
    error_log('Pushfa: ' . $result->get_error_message());
}

تابع pushfa_send_to_order_purchaser؛ ارسال به خریدار

ورودی اول شماره داخلی سفارش است، نه شماره نمایشی سفارش. در حالت auto افزونه ابتدا Subscriber ذخیره‌شده سفارش را امتحان می‌کند؛ برای کاربر عضو از External ID و برای مهمان از Alias سفارش/اطلاعات صورتحساب استفاده می‌کند.

برای مهمانی که قبل از بازکردن صفحه تشکر اعلان را فعال نکرده، هنوز Subscriber سفارش وجود ندارد و پیامی قابل ارسال نیست.
حالت هدف‌گیریرفتار
auto انتخاب خودکار؛ انتخاب پیشنهادی برای اکثر سایت‌ها
subscriber ارسال فقط به Subscriber IDهای ذخیره‌شده سفارش/حساب
external_id فقط برای سفارش کاربر عضو؛ ارسال به تمام دستگاه‌های حساب
custom_alias با label مانند wp_order_ref، mobile، email یا order_id
$order_id = 1842;
$message = [
    'title'    => 'سفارش آماده ارسال است',
    'body'     => 'بسته شما تحویل پست شد.',
    'link_url' => home_url('/my-account/orders/'),
];

$result = pushfa_send_to_order_purchaser($order_id, $message);

تابع‌های فروشنده؛ User ID یا Product ID؟

اگر User ID فروشنده را دارید از pushfa_send_to_seller استفاده کنید. اگر فقط Product ID را دارید، pushfa_send_to_product_seller مالک محصول را پیدا می‌کند. هر دو در پایان با هویت امن حساب وردپرس ارسال می‌کنند.

در فروشگاه چندفروشندگی، مالک واقعی محصول ممکن است post_author نباشد. فیلتر pushfa_wordpress_product_seller_user_id را مطابق Dokan/WCFM خود تنظیم کنید.
// حالت ۱: شناسه کاربری فروشنده را دارید.
$result = pushfa_send_to_seller(73, [
    'title' => 'سفارش جدید',
    'body'  => 'یک سفارش جدید برای شما ثبت شد.',
]);

// حالت ۲: فقط شناسه محصول را دارید.
$result = pushfa_send_to_product_seller(915, [
    'title' => 'محصول شما فروخته شد',
    'body'  => 'برای مشاهده سفارش وارد پنل شوید.',
]);

تابع pushfa_send_to_subscribers؛ ارسال به دستگاه مشخص

Subscriber ID شناسه یک عضویت مرورگر است. می‌توانید یک رشته، چند مقدار جداشده با ویرگول/خط جدید، یا آرایه بدهید. مقادیر خالی و تکراری حذف می‌شوند.

Subscriber ID را از ورودی آزاد کاربر نپذیرید. آن را از نگاشت معتبر افزونه، سفارش یا Backend خود بخوانید.
// یک دستگاه
pushfa_send_to_subscribers('f1444a41-b3af-4e30-8655-9a70de1e0915', $message);

// چند دستگاه
pushfa_send_to_subscribers([
    'SUBSCRIBER_UUID_1',
    'SUBSCRIBER_UUID_2',
], $message);

تابع pushfa_send_to_alias؛ ارسال به Custom Alias

این تابع چهار ورودی دارد: ۱) نام Label، ۲) یک Value یا آرایه Valueها، ۳) پیام و ۴) تنظیمات اختیاری. Label و Value باید قبلاً روی Subscriber ثبت شده باشند.

مثال crm_id فقط زمانی کار می‌کند که قبلاً crm_id=CRM-42 را با فیلتر هویت یا Backend روی Subscriber آن شخص ثبت کرده باشید. تابع ارسال، Alias جدید ایجاد نمی‌کند.
$message = [
    'title' => 'پیام حسابداری',
    'body'  => 'یک فاکتور جدید برای شما صادر شد.',
];

// یک مقدار
pushfa_send_to_alias('crm_id', 'CRM-42', $message);

// چند مقدار با Label یکسان؛ حداکثر ۱۰۰ مقدار در هر درخواست
pushfa_send_to_alias('vendor_id', ['V-10', 'V-11'], $message, [
    'only_last_device' => true,
]);

تابع pushfa_send_to_token؛ ارسال مستقیم به FCM Token

این روش برای یک Token فنی است. Token ممکن است Refresh یا منقضی شود؛ بنابراین برای منطق کاربر، فروشنده یا سفارش از External ID/Subscriber ID استفاده کنید.

FCM Token را در HTML، JavaScript، URL یا Log عمومی نمایش ندهید.
$result = pushfa_send_to_token($fcm_token, [
    'title' => 'پیام آزمایشی',
    'body'  => 'این پیام مستقیماً به Token ارسال شد.',
]);

Hookهای مهم WooCommerce برای ارسال

Hook نقطه‌ای از اجرای WooCommerce است که کد شما در زمان مشخص اجرا می‌شود. یک پیام واحد را هم‌زمان به چند Hook مشابه متصل نکنید.

زمانHook پیشنهادی
پرداخت موفق woocommerce_payment_complete
ورود سفارش به پردازش woocommerce_order_status_processing
تکمیل سفارش woocommerce_order_status_completed
تغییر هر وضعیت woocommerce_order_status_changed
ساخته‌شدن سفارش Checkout woocommerce_checkout_order_processed
نمایش صفحه تشکر woocommerce_thankyou

نمونه کامل ارسال بعد از پرداخت موفق

این نمونه از متای سفارش برای جلوگیری از ارسال تکراری استفاده می‌کند و فقط بعد از پذیرفته‌شدن درخواست توسط پوشفا، علامت ارسال‌شده را ذخیره می‌کند.

برای سفارش مهمانِ اولین خرید، Hook پرداخت ممکن است پیش از بازشدن صفحه تشکر اجرا شود؛ در آن لحظه Subscriber سفارش هنوز ذخیره نشده است. برای این حالت از Hook وضعیت بعدی یا یک Retry کنترل‌شده استفاده کنید.
add_action('woocommerce_payment_complete', function ($order_id) {
    if (!function_exists('pushfa_send_to_order_purchaser')) {
        return;
    }

    $order = wc_get_order($order_id);
    if (!$order || $order->get_meta('_pushfa_payment_notification_sent')) {
        return;
    }

    $result = pushfa_send_to_order_purchaser($order_id, [
        'title'       => 'پرداخت موفق',
        'body'        => sprintf(
            'پرداخت سفارش شماره %s با موفقیت انجام شد.',
            $order->get_order_number()
        ),
        'link_url'    => $order->get_view_order_url(),
        'collapse_id' => 'payment-' . $order_id,
    ]);

    if (!is_wp_error($result)) {
        $order->update_meta_data(
            '_pushfa_payment_notification_sent',
            current_time('mysql')
        );
        $order->save();
    } elseif (defined('WP_DEBUG') && WP_DEBUG) {
        error_log('Pushfa: ' . $result->get_error_message());
    }
}, 20);

ارسال اعلان سفارش جدید به فروشنده

در فروشگاه ساده، مالک محصول معمولاً post_author است. نمونه زیر فروشندگان سفارش را یکتا می‌کند تا فروشنده‌ای که چند محصول در سفارش دارد چند پیام یکسان نگیرد.

در Dokan، WCFM یا افزونه‌های Marketplace ممکن است مالک واقعی فروشنده در post_author نباشد. در آن حالت فیلتر pushfa_wordpress_product_seller_user_id را با منطق همان Marketplace تنظیم کنید.
add_action('woocommerce_payment_complete', function ($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) {
        return;
    }

    $seller_ids = [];
    foreach ($order->get_items() as $item) {
        $product_id = $item->get_product_id();
        $seller_id = (int) get_post_field('post_author', $product_id);

        if ($seller_id > 0) {
            $seller_ids[$seller_id] = true;
        }
    }

    foreach (array_keys($seller_ids) as $seller_id) {
        pushfa_send_to_seller($seller_id, [
            'title'    => 'سفارش جدید',
            'body'     => 'یک سفارش جدید برای محصولات شما ثبت شد.',
            'link_url' => admin_url('post.php?post=' . $order_id . '&action=edit'),
        ]);
    }
}, 30);

ارسال با Subscriber ID یا Custom Alias

صرف ارسال یک Alias در تابع هدف‌گیری، آن را روی Subscriber ایجاد نمی‌کند. Alias باید قبلاً هنگام همگام‌سازی هویت یا از Backend معتبر ثبت شده باشد.
// ارسال به دستگاه‌های مشخص
pushfa_send_to_subscribers([
    'SUBSCRIBER_UUID_1',
    'SUBSCRIBER_UUID_2',
], $message);

// ارسال با شناسه CRM
pushfa_send_to_alias('crm_id', ['CRM-42'], $message);

// هدف‌گیری صریح سفارش مهمان با شناسه داخلی سفارش
pushfa_send_to_order_purchaser($order_id, $message, [
    'target_mode' => 'custom_alias',
    'label'       => 'wp_order_ref',
]);

ارسال خودکار هنگام انتشار محتوا

در تنظیمات افزونه می‌توانید اولین انتشار نوشته، برگه یا محصول را به Topic موردنظر یا all ارسال کنید. افزونه با متای داخلی از ارسال دوباره در ویرایش‌های بعدی جلوگیری می‌کند.

برای ارسال خودکار، Private Key لازم است. در صورت انتخاب Topic، UUID آن را وارد کنید؛ برای همه مشترکان مقدار all را بگذارید.
متغیر قالبمقدار
{post_title} عنوان محتوا
{post_excerpt} خلاصه یا متن کوتاه‌شده
{site_name} نام سایت
{author_name} نام نمایشی نویسنده

مرجع کامل Filterهای افزونه

Filter مقداری را از افزونه می‌گیرد، شما آن را تغییر می‌دهید و حتماً با return برمی‌گردانید. عدد 10 اولویت و عدد آخر تعداد ورودی‌های Callback است.

فیلترهای URL، Payload و HTTP برای توسعه پیشرفته‌اند. Payload شامل کلید خصوصی است؛ آن را Log نکنید و از ورودی کاربر تغییر ندهید.
Filter و ورودی Callbackچه چیزی باید return شود؟کاربرد
pushfa_wordpress_identity_aliases($aliases, $user) array افزودن Custom Alias معتبر مثل crm_id
pushfa_wordpress_identity_brackets($brackets, $user) array افزودن ویژگی شخصی‌سازی مثل city
pushfa_wordpress_external_id($external_id, $user) string Override شناسه اصلی؛ معمولاً تغییر ندهید
pushfa_wordpress_seller_user_id($seller_user_id, $options) int تغییر User ID در ارسال مستقیم به فروشنده
pushfa_wordpress_product_seller_user_id($seller_id, $product, $options) int تعیین مالک واقعی محصول در Marketplace
pushfa_wordpress_auto_notification_message($message, $post, $old_status) array تغییر پیام انتشار خودکار
pushfa_wordpress_frontend_config($config) array تغییر تنظیمات عمومی Frontend افزونه
pushfa_wordpress_sdk_url($url) string URL تغییر URL فایل SDK؛ استفاده پیشرفته
pushfa_wordpress_worker_dynamic_url($url) string URL تغییر URL اسکریپت Worker؛ استفاده پیشرفته
pushfa_wordpress_api_url($url, $endpoint) string URL تغییر URL نهایی Backend
pushfa_wordpress_api_payload($payload, $endpoint) array تغییر Payload درخواست Backend
pushfa_wordpress_http_args($args, $endpoint) array تغییر آرگومان‌های wp_remote_post
add_filter('pushfa_wordpress_product_seller_user_id', function ($seller_id, $product, $options) {
    // شناسه فروشنده را با API افزونه Marketplace خودتان پیدا کنید.
    $marketplace_seller_id = (int) get_post_meta($product->ID, '_vendor_user_id', true);

    return $marketplace_seller_id ?: $seller_id;
}, 10, 3);

مثال Filterهای هویت، Bracket و پیام خودکار

هر Filter را فقط یک بار ثبت کنید. اجرای add_filter پیام نمی‌فرستد؛ فقط رفتار افزونه را هنگام رخ‌دادن عملیات بعدی تغییر می‌دهد.
// ۱) Custom Alias معتبر از User Meta
add_filter('pushfa_wordpress_identity_aliases', function ($aliases, $user) {
    $aliases['vendor_id'] = get_user_meta($user->ID, 'vendor_id', true);
    return array_filter($aliases);
}, 10, 2);

// ۲) Bracket شهر برای متن‌هایی مانند «ارسال به {city:شهر شما}»
add_filter('pushfa_wordpress_identity_brackets', function ($brackets, $user) {
    $brackets['city'] = get_user_meta($user->ID, 'billing_city', true);
    return array_filter($brackets);
}, 10, 2);

// ۳) تغییر پیام ارسال خودکار محصول
add_filter('pushfa_wordpress_auto_notification_message', function ($message, $post, $old_status) {
    if ($post->post_type === 'product') {
        $message['title'] = 'محصول جدید: ' . get_the_title($post);
        $message['link_url'] = get_permalink($post);
    }
    return $message;
}, 10, 3);

Actionهای آماده افزونه و مثال استفاده

Action فقط خبر می‌دهد که اتفاقی رخ داده است؛ لازم نیست چیزی return کنید. افزونه دو Action عمومی دارد.

در Action ذخیره Subscriber دوباره همان Subscriber را ثبت نکنید؛ این کار حلقه یا درخواست تکراری می‌سازد.
Action و ورودی‌هاچه زمانی اجرا می‌شود؟
pushfa_wordpress_subscriber_stored($subscriber_id, $user_id, $order_id) پس از ذخیره نگاشت Subscriber برای کاربر یا سفارش
pushfa_wordpress_auto_notification_sent($post, $result) پس از پذیرفته‌شدن ارسال خودکار انتشار
// مثال ۱: بعد از ذخیره Subscriber، کار جانبی سایت خودتان را انجام دهید.
add_action('pushfa_wordpress_subscriber_stored', function ($subscriber_id, $user_id, $order_id) {
    if ($user_id) {
        update_user_meta($user_id, '_pushfa_last_connected_at', current_time('mysql'));
    }
}, 10, 3);

// مثال ۲: نتیجه ارسال خودکار انتشار را بررسی کنید.
add_action('pushfa_wordpress_auto_notification_sent', function ($post, $result) {
    if (is_wp_error($result) && defined('WP_DEBUG') && WP_DEBUG) {
        error_log('Pushfa auto send failed for post ' . $post->ID . ': ' . $result->get_error_message());
    }
}, 10, 2);

API آماده JavaScript افزونه

برای کد مرورگر ابتدا منتظر pushfaWordPressReady بمانید. شیء window.PushfaWordPress سه تابع کمکی افزونه دارد و detail.Pushfa توابع اصلی SDK مانند Topic و Prompt را در اختیار می‌گذارد.

Private Key و Alias هویتی قابل اعتماد را در JavaScript قرار ندهید. کد مرورگر قابل مشاهده و قابل دستکاری است.
تابع/رویدادورودیکاربرد
PushfaWordPress.track(eventName, params = {}, aliases = {}) نام، پارامترها، Aliasهای اختیاری ثبت رویداد RetenX
PushfaWordPress.syncIdentity(options = {}) آرایه اختیاری همگام‌سازی دوباره هویت تنظیم‌شده توسط Backend
PushfaWordPress.refresh() ندارد به‌روزرسانی متن دکمه Prompt و وضعیت Topicها
pushfaWordPressReady CustomEvent؛ detail.Pushfa اعلام آماده‌شدن SDK و افزونه
pushfaMessage CustomEvent؛ detail پیام دریافت پیام Foreground داخل صفحه
pushfaSubscriberId CustomEvent؛ detail شناسه اعلام ایجاد/تغییر Subscriber
window.addEventListener('pushfaWordPressReady', async ({ detail }) => {
    // رویداد سفارشی RetenX
    await window.PushfaWordPress.track('article_read', {
        post_id: 125,
        category: 'آموزش'
    });

    // وضعیت دکمه‌های افزونه را دوباره بخوان.
    await window.PushfaWordPress.refresh();

    // تابع‌های SDK اصلی نیز اینجا آماده‌اند.
    const topics = await detail.Pushfa.getTopics();
    console.log(topics);
});

WooCommerce و RetenX

با فعال‌کردن RetenX، افزونه رویدادهای استاندارد فروشگاه را برای ساخت Journeyهای نگهداشت ارسال می‌کند. این بخش اختیاری است و به دسترسی Pro و Private Key نیاز دارد.

RetenX با اعلان تراکنشی Hook پرداخت یکی نیست. فعال‌کردن RetenX به‌تنهایی پیام «پرداخت موفق» نمی‌فرستد؛ برای آن باید Hook ارسال تعریف کنید.
رویدادزمان ثبت
view_item مشاهده محصول
add_to_cart افزودن به سبد
remove_from_cart حذف از سبد
begin_checkout شروع Checkout
checkout_completed ثبت خرید تکمیل‌شده

اعلان در تب فعال و iPhone/iPad

در تنظیمات می‌توانید رفتار Foreground را از سرویس ارث‌بری کنید، اعلان سیستمی را در تب فعال مخفی کنید یا نمایش را اجبار کنید. گزینه اعلان درون‌صفحه‌ای پیام Foreground را به‌شکل Toast نمایش می‌دهد.

موضوعقاعده
Foreground suppression فقط وقتی همان صفحه focused و visible است؛ تب پنهان باید اعلان را نمایش دهد
Safari/WebKit پیام Normal باید user-visible بماند و Worker نباید آن را بی‌صدا مصرف کند
iOS Web Push iOS/iPadOS 16.4+، نصب سایت از Safari روی Home Screen و بازکردن از آیکن لازم است

امنیت و حریم خصوصی

کنترلاقدام لازم
Private Key فقط Backend یا wp-config.php؛ هرگز Frontend و Log
External ID UUID تصادفی افزونه؛ نه User ID قابل‌حدس
Custom Alias تجاری تولید از Backend و فیلتر معتبر؛ نه ورودی آزاد مرورگر
Logout پاک‌کردن هویت از مرورگر مشترک
Subscriber ID اعتبارسنجی مالکیت کاربر یا order_key پیش از ذخیره
Privacy Policy اعلام ارسال Token، Subscriber ID، اطلاعات دستگاه و رویدادهای فعال‌شده به Pushfa

عیب‌یابی سریع

مشکلچه چیزی را بررسی کنیم؟
Service Worker = 404 ذخیره پیوندهای یکتا، Cache/CDN، Rewrite وب‌سرور و مسیر دقیق ریشه
Permission = denied بازکردن مجوزهای دامنه از تنظیمات مرورگر؛ Prompt قابل اجبار نیست
Subscriber ساخته نمی‌شود HTTPS، دامنه سرویس، Firebase/VAPID، حالت Incognito و Worker
Topic یا Alias = 403 مجوزهای JavaScript همان Topic یا سرویس
brackets/add = 404 Deploy وایت‌لیست Nginx دامنه api.pushfa.com؛ وجود route در Laravel به‌تنهایی کافی نیست
/api/webservices/* = 404 Base URL سمت‌سرور باید https://pushfa.com/api باشد
alias/set در هر Refresh نسخه جدید باید sync(true) و مقایسه وضعیت واقعی را انجام دهد؛ Cache نسخه قدیمی را پاک کنید
ارسال به کاربر نتیجه ندارد کاربر باید قبلاً Push را فعال کرده، Subscriber ذخیره شده و External ID همگام باشد
سفارش مهمان نتیجه ندارد صفحه تشکر باید باز شده باشد یا Retry بعدی برای ذخیره Subscriber انجام شود
Ctrl+I