وردپرس و ووکامرس
مرجع REST API
افزونه و سرور Pitchbar در دو جهت از طریق HTTP با دو طرح احراز هویت متفاوت با یکدیگر ارتباط برقرار میکنند. این مرجع هر نقطه پایانی درگیر را مستند میکند — شکل درخواست، شکل پاسخ، کدهای وضعیت و نحوه اعمال احراز هویت.
احراز هویت در یک نگاه
| جهت | اعتبارنامه | محل ذخیره | پنجره پخش مجدد |
|---|---|---|---|
| افزونه → Pitchbar | توکن حامل pbar_… |
Pitchbar فقط هش SHA-256 را ذخیره میکند. افزونه متن ساده را در wp_options نگهداری میکند. |
— |
| افزونه → Pitchbar (تغییردهنده) | حامل + امضای HMAC بدنه | کلید HMAC، خود متن ساده حامل است. | ۵ دقیقه |
| Pitchbar → افزونه | امضای HMAC بدنه | shopper_signing_secret به ازای هر توکن (متن ساده در هر دو طرف). |
۵ دقیقه |
طرح امضای HMAC
X-Pitchbar-Signature: t=<unix_ts>,v1=<hex_sig>
sig = hmac_sha256(secret, "{t}.{raw_body}")
هر دو طرف درخواستهایی را که t آنها بیش از ۳۰۰ ثانیه با ساعت سرور تأییدکننده فاصله دارد، رد میکنند. هر دو طرف امضا را با hash_equals با زمان ثابت مقایسه میکنند. همین طرح برای وبهوکهای خروجی مستند در وبهوکهای خروجی استفاده میشود.
نقاط پایانی Pitchbar (افزونه → Pitchbar)
پایه: آدرس فضای کاری Pitchbar شما. همه مسیرها POST هستند و نیاز به Authorization: Bearer pbar_… با قابلیت wp:integration دارند. مسیرهای تغییردهنده علاوه بر آن نیاز به X-Pitchbar-Signature دارند.
POST /api/v1/wp/handshake
توسط دکمه تست اتصال افزونه برای کشف فضای کاری، لیست دستیاران فروش موجود و دریافت shopper_signing_secret توکن فراخوانی میشود. نیازی به HMAC نیست (حامل کافی است — دست دادن وضعیتی را فراتر از نوشتن last_used_at تغییر نمیدهد).
درخواست:
{
"site_url": "https://shop.example.com",
"plugin_version": "2.0.4",
"woocommerce_active": true,
"wordpress_version": "6.6"
}
پاسخ ۲۰۰:
{
"data": {
"workspace": { "id": "01HZ…", "name": "آکمه" },
"agents": [
{ "id": "01HZ…", "name": "ربات فروشگاه", "site_type": "ecommerce", "language_default": "en", "is_published": true }
],
"token": {
"id": "01HZ…",
"name": "shop.example.com",
"abilities": ["wp:integration"],
"shopper_signing_secret": "sek_…"
},
"recommended_site_type": "ecommerce",
"echo": { "site_url": "https://shop.example.com", "plugin_version": "2.0.4" }
}
}
recommended_site_type به عمودی که دستیار فروش باید اتخاذ کند اشاره میکند: ecommerce زمانی که ووکامرس در سایت فراخوان فعال است، در غیر این صورت null. shopper_signing_secret متن ساده است — افزونه آن را بهطور بیصدا در wp_options ذخیره میکند.
خطاها:
401 invalid_token— حامل وجود ندارد، بدفرم است یا لغو شده است.403 insufficient_ability— توکن قابلیتwp:integrationرا اعطا نمیکند.
POST /api/v1/wp/posts/sync
درج انبوه پست. حداکثر ۵۰ پست در هر درخواست. نیاز به HMAC دارد.
{
"agent_id": "01HZ…",
"site_url": "https://shop.example.com",
"plugin_version": "2.0.4",
"posts": [
{
"wp_id": 142,
"post_type": "page",
"permalink": "https://shop.example/pricing",
"title": "Pricing",
"content_html": "<div class=\"elementor-…\">…</div>",
"excerpt": "سه پلن، دو نتیجه…",
"content_hash": "ab12…ef90",
"modified_at": "2026-05-09T14:30:00+00:00",
"language": "fa-ir",
"taxonomy_terms": ["pricing", "plans"]
}
]
}
پاسخ ۲۰۰:
{
"data": {
"queued": 1,
"skipped_unchanged": 0,
"deleted": 0
}
}
queued = تعداد پستهایی که هش آنها با سند ذخیرهشده متفاوت بوده و برای جستجوی هوشمند در صف قرار گرفتهاند. skipped_unchanged = تعداد پستهایی که هش آنها مطابقت داشته است (بدون هزینه). ذخیرهساز جستجوی هوشمند بهصورت ناهمگام توسط IndexDocumentJob بهروز میشود. بازیابیهای بعدی در عرض چند ثانیه شروع به یافتن محتوای جدید میکنند.
POST /api/v1/wp/posts/changed
دلتای یک پست. همان شکل posts/sync اما با یک آرایه posts به طول ۱ و یک فیلد اضافی action از نوع "upsert" یا "delete". نیاز به HMAC دارد.
POST /api/v1/wp/products/sync
درج انبوه محصولات ووکامرس. حداکثر ۵۰ عدد در هر دسته. نیاز به HMAC دارد.
{
"agent_id": "01HZ…",
"site_url": "https://shop.example.com",
"plugin_version": "2.0.4",
"products": [
{
"wp_id": 9001,
"sku": "T-BLU-M",
"name": "تیشرت آبی",
"permalink": "https://shop.example/product/blue-tee",
"image_url": "https://shop.example/wp-content/uploads/2026/05/blue-tee-300x300.jpg",
"short_description": "<p>تیشرت نخی یقه گرد.</p>",
"description": "<p>۱۰۰٪ پنبه حلقهشده…</p>",
"price": "29.00",
"regular_price": "39.00",
"sale_price": "29.00",
"currency": "USD",
"stock_status": "instock",
"on_sale": true,
"content_hash": "cd34…12ef",
"modified_at": "2026-05-09T14:30:00+00:00",
"categories": ["tees", "summer"],
"attributes": ["color: blue", "size: S, M, L"]
}
]
}
در اولین درج در برابر یک دستیار فروش با site_type = "generic"، دستیار فروش بهطور بیصدا به "ecommerce" تغییر میکند. برای قوانین کامل، همگامسازی محتوا را مشاهده کنید.
POST /api/v1/wp/products/changed
دلتای یک محصول. مشابه posts/changed اما برای محصولات ووکامرس. نیاز به HMAC دارد.
POST /api/v1/wp/coupons/sync
تصویر لحظهای از کوپنهای فعال فروشگاه. Idempotent (جایگزینی کامل).
{
"agent_id": "01HZ…",
"site_url": "https://shop.example.com",
"plugin_version": "2.0.4",
"coupons": [
{ "code": "WELCOME10", "label": "۱۰٪ تخفیف", "discount": "10%", "expires_at": null },
{ "code": "FREESHIP", "label": "۵ دلار تخفیف در سفارش", "discount": "5", "expires_at": "2026-12-31T00:00:00+00:00" }
]
}
لیست در منبع woocommerce_products دستیار فروش تحت config['coupons'] ذخیره میشود. مونتاژ بعدی راهنما شامل کدها بهصورت دقیق است تا هوش مصنوعی هرگز آنها را اختراع نکند.
POST /api/v1/widget/coupon/apply
توسط دکمه اعمال ویجت در یک بلوک چت <coupon/> فراخوانی میشود. احراز هویت JWT ویجت است (نه یک توکن حامل)، محدودیت نرخ ۳۰/دقیقه/IP.
{ "code": "WELCOME10" }
Pitchbar منبع وردپرس / ووکامرس دستیار فروش را حل میکند، بدنه را با کلید مخفی امضای خریدار فضای کاری HMAC امضا کرده و به /wp-json/pitchbar/v1/cart/coupon در سایت WP ارسال میکند. بدنه ارسالشده شامل conversation_id است تا افزونه بتواند کوپن را در یک داده موقت به ازای هر مکالمه مرحلهبندی کند.
نقاط پایانی افزونه (Pitchbar → افزونه)
پایه: {wp_site_url}/wp-json/pitchbar/v1/. همه مسیرها POST هستند. احراز هویت: X-Pitchbar-Signature در برابر shopper_signing_secret ذخیرهشده افزونه تأیید میشود. بدون نانس وردپرس یا احراز هویت کوکی — فراخواننده سرور Pitchbar است، نه یک مرورگر واردشده.
مسیر تأیید
هر کنترلکننده REST افزونه از Pitchbar\Rest\RestController ارثبری میکند که هر درخواست را از طریق verifyOrReject($request) محدود میکند:
- هدر
X-Pitchbar-Signatureرا میخواند. در صورت عدم وجود → ۴۰۱missing_signature. shopper_signing_secretذخیرهشده افزونه را ازwp_optionsمیخواند. در صورت خالی بودن → ۴۰۱plugin_unconfigured.- امضای مورد انتظار را بر روی بدنه درخواست خام محاسبه میکند. اگر
hash_equalsشکست بخورد → ۴۰۱signature_mismatch. - اگر زمانمهر
tبیش از ۳۰۰ ثانیه باtime()فاصله داشته باشد → باsignature_mismatchرد میکند (کلید مخفی هرگز با زمانمهر پخششده مطابقت نداشته است).
پاسخ خطا همیشه بهصورت JSON است:
{ "error": { "code": "signature_mismatch", "message": "HMAC signature did not verify." } }
POST /wp-json/pitchbar/v1/orders/lookup
سفارشات اخیر ووکامرس یک مشتری را جستجو میکند.
{
"wp_user_id": 42,
"limit": 5,
"order_number": "WC-1234" // اختیاری — مجموعه نتایج را فیلتر میکند
}
پاسخ ۲۰۰:
{
"data": {
"count": 2,
"orders": [
{
"id": 9001,
"number": "9001",
"status": "completed",
"total": "49.99",
"currency": "USD",
"date_created": "2026-05-08T11:23:00+00:00",
"items": [{ "name": "تیشرت آبی", "qty": 1, "sku": "T-BLU-M", "total": "29.00" }],
"tracking_url": "https://aftership.com/…",
"order_url": "https://shop.example/my-account/view-order/9001/"
}
]
}
}
tracking_url با بهترین تلاش است: کنترلکننده کلیدهای متاداده سفارش _aftership_tracking_url، _tracking_url و _st_tracking_link را بررسی میکند. اگر هیچکدام مطابقت نداشته باشد، فیلد یک رشته خالی است و هوش مصنوعی به نمایش order_url بازمیگردد.
زمانی که ووکامرس فعال نباشد، کنترلکننده ۲۰۰ را با { "orders": [], "count": 0, "note": "woocommerce_inactive" } برمیگرداند تا دستیار فروش بتواند بهخوبی پاسخ دهد.
POST /wp-json/pitchbar/v1/leads
یک مشتری بالقوه جذبشده Pitchbar را به وردپرس بازمیگرداند.
{
"email": "shopper@example.com",
"name": "الکس بازدیدکننده",
"phone": "+1-555-0123",
"conversation_id": "01HZ…",
"pitchbar_lead_id": "01HZ…"
}
پاسخ ۲۰۰:
{ "data": { "user_id": 199 } }
رفتار:
- اگر یک کاربر وردپرس با آن ایمیل وجود دارد، first_name، billing_phone و کلیدهای متاداده Pitchbar آن را بهروز میکند.
- اگر کاربری وجود ندارد، یک مشتری ووکامرس (
wc_create_new_customer) در صورت فعال بودن ووکامرس ایجاد میکند، در غیر این صورت یک مشترک وردپرس از طریقwp_create_userبا یک رمز عبور ۲۴ کاراکتری تصادفی. - نام کاربری از بخش محلی ایمیل + یک پسوند عددی تا زمانی که منحصربهفرد شود، استخراج میشود.
pitchbar_lead_id+pitchbar_conversation_idدر متاداده کاربر نوشته میشوند تا مالک فروشگاه بتواند همبستگی ایجاد کند.
POST /wp-json/pitchbar/v1/cart/coupon
یک کد کوپن را برای بارگذاری بعدی سبد خرید بازدیدکننده مرحلهبندی میکند.
{
"code": "WELCOME10",
"conversation_id": "01HZ…"
}
پاسخ ۲۰۰:
{
"data": {
"applied": false,
"pending": true,
"message": "کوپن مرحلهبندی شد. زمانی که بازدیدکننده سبد خرید خود را باز کند، اعمال میشود."
}
}
رفتار:
- کوپن را از طریق
new WC_Coupon($code)+get_id()≠ ۰ تأیید میکند. اگر نه، ۴۰۰invalid_couponبرمیگرداند. - کد را در یک داده موقت ۱۵ دقیقهای مرحلهبندی میکند:
pitchbar_pending_coupon_{conversation_id}. - هوک
woocommerce_load_cart_from_sessionافزونه، داده موقت را در بارگذاری بعدی سبد خرید بازدیدکننده (که توسط کوکیpitchbar_conv_idکه ویجت در زمان راهاندازی مینویسد، قرار دارد) میخواند،WC()->cart->apply_coupon($code)را فراخوانی کرده و داده موقت را پاک میکند.
زمانی که ووکامرس فعال نباشد، ۴۰۰ woocommerce_inactive برمیگرداند. دکمه اعمال کارت کوپن در ویجت در آن صورت با یک پرچم قابلیت مخفی میشود.
پوشه خطا
هر نقطه پایانی Pitchbar خطاها را بهصورت زیر برمیگرداند:
{ "message": "…", "code": "…", "errors": { "field": ["…"] } }
هر نقطه پایانی افزونه خطاها را بهصورت زیر برمیگرداند:
{ "error": { "code": "…", "message": "…" } }
تفاوت شکل عمدی است — Pitchbar از قرارداد اعتبارسنجی لاراول پیروی میکند، افزونه از قرارداد REST وردپرس پیروی میکند. هر دو طرف دیگری را بهصورت شفاف تجزیه میکنند.
محدودیت نرخ
مسیرهای /api/v1/wp/* Pitchbar با توکن API محدودیت نرخ دارند (پیشفرض ۶۰ درخواست در دقیقه به ازای هر توکن). مسیرهای /wp-json/pitchbar/v1/* افزونه سهمیهای اعمال نمیکنند — بررسی HMAC + پنجره پخش مجدد ۵ دقیقهای قبلاً از سوءاستفاده جلوگیری میکند و زمانبندی بالادستی Pitchbar (۵ ثانیه در OrderLookupController) زمان اجرا را محدود میکند.
خلاصه کدهای وضعیت
| کد | معنی |
|---|---|
| ۲۰۰ | موفقیت یا "نادیده گرفته شده بهعنوان بدون عملیات" (حذف پست ناشناخته). |
| ۴۰۰ | خطای اعتبارسنجی — شکل بدنه اشتباه است، فیلد وجود ندارد، کوپن نامعتبر است. |
| ۴۰۱ | احراز هویت ناموفق (توکن / امضا وجود ندارد، کلید مخفی اشتباه است). |
| ۴۰۳ | توکن قابلیت مورد نیاز را ندارد. |
| ۴۰۴ | منبع در این فضای کاری وجود ندارد (بیشتر agent_id). |
| ۴۲۲ | خطای اعتبارسنجی از اعتبارسنجی لاراول (سمت Pitchbar). |
| ۴۲۹ | محدودیت نرخ. |