Files
CRM_Montzar/docs/MONTACT_CRM_INTEGRATION.md

17 KiB
Raw Permalink Blame History

راهنمای اتصال CRM (MONTACT) به Montify — نسخه کامل v2

۱. خلاصه و دیاگرام جریان

این سند مشخصات اتصال سامانه Montact CRM به زیرسیستم‌های فروشگاهی (مانند Montify) را تعریف می‌کند. هر فروشگاه یک Base URL و یک Token اختصاصی دارد.

[فروشنده/Store] → [پنل Montify] → [صدور Token] → [سرور CRM]
                                        │
                                        ▼
                         GET {Base URL}/montact/customers
                                        │
                                        ▼
                              پاسخ JSON (لیست مشتریان)
                                        │
                                        ▼
                    GET {Base URL}/montact/customers/:id/orders
                                        │
                                        ▼
                              پاسخ JSON (سفارش‌های مشتری)

۲. دریافت اطلاعات اتصال از فروشنده

  1. فروشنده وارد پنل Montify می‌شود.
  2. از مسیر «تنظیمات → یکپارچه‌سازی‌ها → CRM» وارد بخش Montact می‌شود.
  3. دکمه «صدور Token» را می‌زند و مقادیر زیر را در اختیار تیم CRM قرار می‌دهد:
فیلد مقدار نمونه توضیح
Base URL https://store1.montify.com/api/v1 آدرس پایه API فروشگاه
Token mk_live_8f3a1c9d2e... توکن احراز هویت Bearer
Store ID b2f1e4a0-... شناسه فروشگاه

نکته: توکن‌ها می‌توانند منقضی شوند (expires_at). در صورت دریافت خطای ۴۰۱، باید توکن جدید از فروشنده درخواست شود. توکن هرگز نباید در فرانت‌اند ذخیره یا افشا شود؛ تنها باید در سرور CRM نگهداری گردد.

۳. احراز هویت

تمام درخواست‌ها باید هدرهای زیر را داشته باشند:

Authorization: Bearer {Token}
Content-Type: application/json
Accept: application/json

۴. فهرست کامل APIها

Method Path توضیح
GET /montact/customers لیست مشتریان (پشتیبانی از page, limit, updated_after)
POST /montact/customers ثبت/همگام‌سازی مشتری از سمت CRM (اختیاری)
GET /montact/customers/:id جزئیات کامل یک مشتری
GET /montact/customers/:id/orders لیست سفارش‌های مشتری (پشتیبانی از updated_after)
POST /montact/customers/:id/orders ثبت سفارش از CRM (اختیاری، در صورت فعال بودن)
GET /montact/customers/:id/addresses لیست آدرس‌های مشتری
GET /montact/customers/:id/transactions لیست تراکنش‌های مالی مشتری
GET /montact/customers/:id/engagement داده‌های تعاملی (saved, likes, comments)
GET /montact/orders/:orderId جزئیات یک سفارش خاص
POST /montact/webhooks/register ثبت Webhook برای رویدادهای بلادرنگ (فاز ۳)
GET /montact/webhooks/:id مشاهده جزئیات یک Webhook ثبت‌شده
DELETE /montact/webhooks/:id حذف Webhook

پارامتر updated_after یک مقدار ISO 8601 است (مثلاً 2026-07-01T00:00:00Z) و فقط رکوردهای تغییر یافته بعد از آن زمان را برمی‌گرداند (برای Incremental Sync).

نمونه‌های curl

BASE="https://store1.montify.com/api/v1"
TOKEN="mk_live_8f3a1c9d2e..."

# لیست مشتریان
curl -X GET "$BASE/montact/customers?page=1&limit=50" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"

# لیست مشتریان تغییریافته بعد از یک زمان خاص (Incremental Sync)
curl -X GET "$BASE/montact/customers?updated_after=2026-07-01T00:00:00Z" \
  -H "Authorization: Bearer $TOKEN"

# جزئیات یک مشتری
curl -X GET "$BASE/montact/customers/123" \
  -H "Authorization: Bearer $TOKEN"

# سفارش‌های یک مشتری
curl -X GET "$BASE/montact/customers/123/orders?updated_after=2026-07-01T00:00:00Z" \
  -H "Authorization: Bearer $TOKEN"

# آدرس‌های مشتری
curl -X GET "$BASE/montact/customers/123/addresses" \
  -H "Authorization: Bearer $TOKEN"

# تراکنش‌های مشتری
curl -X GET "$BASE/montact/customers/123/transactions" \
  -H "Authorization: Bearer $TOKEN"

# داده‌های تعاملی مشتری
curl -X GET "$BASE/montact/customers/123/engagement" \
  -H "Authorization: Bearer $TOKEN"

# جزئیات یک سفارش خاص
curl -X GET "$BASE/montact/orders/4567" \
  -H "Authorization: Bearer $TOKEN"

# ثبت Webhook (فاز ۳)
curl -X POST "$BASE/montact/webhooks/register" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://crm.montact.com/webhooks/montify","events":["order.created","order.paid"]}'

۵. ساختار پاسخ کامل

۵.۱ فیلدهای مشتری (Customer)

فیلد نوع توضیح
id integer شناسه مشتری
name string نام کامل
first_name string نام
last_name string نام خانوادگی
phone string شماره موبایل
email string|null ایمیل
username string نام کاربری
avatar string|null URL آواتار
birthday date|null تاریخ تولد
gender string|null جنسیت
type string نوع مشتری (حقیقی/حقوقی)
store_id integer شناسه فروشگاه
created_at datetime تاریخ ایجاد
updated_at datetime آخرین بروزرسانی
description string|null توضیحات
bio string|null بیوگرافی
job string|null شغل
cash_balance number موجودی نقدی
gold_balance number موجودی طلا (گرم)
orders array لیست سفارش‌ها
summary object خلاصه آماری مشتری
addresses array لیست آدرس‌ها
transactions array لیست تراکنش‌ها
engagement object داده‌های تعاملی

۵.۲ فیلدهای سفارش (Order)

فیلد نوع توضیح
id integer شناسه سفارش
user_id integer شناسه مشتری
store_id integer شناسه فروشگاه
code string کد پیگیری سفارش
sts string وضعیت سفارش
payment_sts string وضعیت پرداخت
payment_type string نوع پرداخت
total_price number قیمت کل
discount_total_price number قیمت پس از تخفیف
total_discounts number مجموع تخفیف‌ها
total_tax number مجموع مالیات
total_qty integer تعداد کل اقلام
profit number سود
percent_profit number درصد سود
sum_gold number مجموع وزن طلا
sum_silver number مجموع وزن نقره
address object آدرس ارسال
address_id integer شناسه آدرس
note string|null یادداشت
cancel_reason string|null دلیل لغو
cancelled_at datetime|null تاریخ لغو
closed_at datetime|null تاریخ بستن سفارش
transaction_id integer|null شناسه تراکنش مرتبط
code_discount string|null کد تخفیف
discount_code_id integer|null شناسه کد تخفیف
created_at datetime تاریخ ایجاد
updated_at datetime آخرین بروزرسانی
deleted_at datetime|null تاریخ حذف نرم
order_items array اقلام سفارش
user object اطلاعات خلاصه مشتری
store object اطلاعات خلاصه فروشگاه

۵.۳ اقلام سفارش (Order Items)

فیلد نوع توضیح
id integer شناسه قلم سفارش
order_id integer شناسه سفارش
product_id integer شناسه محصول
product_name string نام محصول
qty integer تعداد
price number قیمت واحد
weight number وزن (گرم)
total_price number قیمت کل قلم

۵.۴ آدرس‌ها (Addresses)

فیلد نوع توضیح
id integer شناسه آدرس
user_id integer شناسه مشتری
province string استان
city string شهر
address string متن آدرس
postal_code string کد پستی
receiver_name string نام گیرنده
receiver_phone string شماره گیرنده
is_default boolean آدرس پیش‌فرض

۵.۵ تراکنش‌ها (Transactions)

فیلد نوع توضیح
id integer شناسه تراکنش
user_id integer شناسه مشتری
type string نوع تراکنش (واریز/برداشت)
amount number مقدار
currency string واحد (ریال/گرم طلا)
status string وضعیت تراکنش
reference_code string کد پیگیری بانکی
created_at datetime تاریخ ثبت

۵.۶ داده‌های تعاملی (Engagement)

مسیر: GET /montact/customers/:id/engagement

{
  "saved": [
    { "product_id": 55, "product_name": "سکه بهار آزادی", "saved_at": "2026-06-10T11:22:00Z" }
  ],
  "likes": [
    { "product_id": 78, "liked_at": "2026-06-15T09:00:00Z" }
  ],
  "comments": [
    {
      "id": 301,
      "product_id": 78,
      "text": "کیفیت عالی بود",
      "rating": 5,
      "created_at": "2026-06-16T08:30:00Z"
    }
  ]
}

۵.۷ نمونه پاسخ JSON کامل لیست مشتریان

{
  "data": [
    {
      "id": 123,
      "name": "علی رضایی",
      "first_name": "علی",
      "last_name": "رضایی",
      "phone": "09121234567",
      "email": "ali@example.com",
      "username": "ali_r",
      "avatar": "https://cdn.montify.com/avatars/123.png",
      "birthday": "1990-05-12",
      "gender": "male",
      "type": "individual",
      "store_id": 10,
      "created_at": "2025-01-10T08:00:00Z",
      "updated_at": "2026-07-01T10:15:00Z",
      "description": null,
      "bio": null,
      "job": "مهندس",
      "cash_balance": 1500000,
      "gold_balance": 2.35,
      "orders": [],
      "summary": { "total_orders": 12, "total_spent": 85000000 },
      "addresses": [],
      "transactions": [],
      "engagement": { "saved": [], "likes": [], "comments": [] }
    }
  ],
  "meta": {
    "current_page": 1,
    "per_page": 50,
    "total": 532,
    "last_page": 11
  }
}

۶. قوانین نگاشت پیشنهادی در CRM

فیلد Montify فیلد معادل در CRM
id external_customer_id
name full_name
phone mobile
cash_balance wallet_balance
gold_balance gold_wallet_balance
orders[].code order_reference
orders[].sts order_status

استراتژی Sync گام به گام:

  1. دریافت لیست مشتریان صفحه‌بندی‌شده و Upsert در جدول مشتریان CRM بر اساس id.
  2. برای هر مشتری، دریافت سفارش‌ها، آدرس‌ها و تراکنش‌ها به‌صورت جداگانه و Upsert در جداول مرتبط.
  3. ذخیره updated_at هر رکورد برای استفاده در Sync افزایشی بعدی.

۷. استراتژی Sync سه‌فازی

فاز ۱ — Polling ساده

  • فراخوانی دوره‌ای /montact/customers با page و limit.
  • فاصله پیشنهادی: هر ۵ تا ۱۵ دقیقه (بسته به حجم داده فروشگاه).
  • در صورت دریافت 429 Too Many Requests، باید بر اساس هدر Retry-After صبر و تلاش مجدد شود.

فاز ۲ — Incremental Sync

  • استفاده از updated_after=<ISO8601> روی /montact/customers و /montact/customers/:id/orders.
  • CRM باید مقدار last_sync_timestamp را پس از هر Sync موفق ذخیره کند و در فراخوانی بعدی به‌عنوان updated_after ارسال کند.
curl -X GET "$BASE/montact/customers?updated_after=2026-07-10T12:00:00Z" \
  -H "Authorization: Bearer $TOKEN"

فاز ۳ — Webhook (Push-based، بلادرنگ)

برای دریافت رویدادها بدون تأخیر Polling، CRM باید یک Endpoint عمومی HTTPS در اختیار Montify قرار دهد:

curl -X POST "$BASE/montact/webhooks/register" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://crm.montact.com/webhooks/montify",
    "events": ["customer.created", "customer.updated", "order.created", "order.updated", "order.paid", "order.cancelled"]
  }'

رویدادهای پشتیبانی‌شده:

رویداد توضیح
customer.created ایجاد مشتری جدید
customer.updated بروزرسانی اطلاعات مشتری
order.created ثبت سفارش جدید
order.updated تغییر در سفارش
order.paid پرداخت سفارش
order.cancelled لغو سفارش

نمونه Payload برای order.created:

{
  "event": "order.created",
  "delivery_id": "d2f1c9e0-84a3-4b7f-9c1e-3a2b1c0d9e8f",
  "store_id": 10,
  "data": {
    "id": 4567,
    "user_id": 123,
    "code": "ORD-2026-4567",
    "sts": "pending",
    "payment_sts": "unpaid",
    "total_price": 12500000,
    "total_qty": 2,
    "created_at": "2026-07-10T12:05:00Z"
  }
}

هدرهای ارسالی Webhook:

X-Montact-Signature: sha256=3b4f9a1c7e8d2f...
X-Montact-Event: order.created
X-Montact-Delivery-Id: d2f1c9e0-84a3-4b7f-9c1e-3a2b1c0d9e8f
Content-Type: application/json

وریفای امضا (Node.js):

const crypto = require('crypto');

function verifySignature(rawBody, signatureHeader, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');

  const received = signatureHeader.replace('sha256=', '');
  return crypto.timingSafeEqual(
    Buffer.from(expected, 'hex'),
    Buffer.from(received, 'hex')
  );
}

Retry Policy:

  • در صورت عدم دریافت پاسخ 2xx ظرف ۱۰ ثانیه، تلاش مجدد با backoff نمایی انجام می‌شود.
  • فاصله تلاش‌ها: 1s → 5s → 15s → 60s → 300s (حداکثر ۵ بار).
  • CRM باید سریعاً 200 OK برگرداند و پردازش سنگین را به‌صورت async انجام دهد.
  • Idempotency بر اساس X-Montact-Delivery-Id باید رعایت شود تا پردازش تکراری رخ ندهد.

۸. کدهای خطا

کد HTTP معنی اقدام پیشنهادی
200 موفق -
400 درخواست نامعتبر بررسی پارامترها
401 توکن نامعتبر یا منقضی درخواست توکن جدید از فروشنده
403 عدم دسترسی به منبع بررسی scope توکن
404 منبع یافت نشد بررسی شناسه ارسالی
429 تعداد درخواست بیش از حد مجاز توجه به هدر Retry-After و کاهش نرخ درخواست
500 خطای سرور تلاش مجدد بعد از فاصله زمانی

۹. محدودیت‌ها و رفتار فعلی

  • API برای داده‌های اصلی (مشتری، سفارش، آدرس، تراکنش) صرفاً خواندنی (Read-only) است؛ تنها استثنا ثبت/حذف Webhook است.
  • فیلدهای حساس (مانند رمز عبور، هش‌های داخلی) از پاسخ‌ها حذف شده‌اند.
  • CORS برای دامنه‌های مجاز CRM فعال است.
  • نرخ مجاز درخواست پیشنهادی: ۱۰۰ درخواست در دقیقه به ازای هر Token.

۱۰. چک‌لیست اتصال برنامه‌نویس CRM

  • دریافت Base URL، Token و Store ID از فروشنده
  • تست احراز هویت با GET /montact/customers
  • پیاده‌سازی Polling فاز ۱
  • پیاده‌سازی Incremental Sync با updated_after (فاز ۲)
  • ثبت Webhook Endpoint و تست دریافت رویداد (فاز ۳)
  • پیاده‌سازی وریفای امضای HMAC-SHA256
  • تست Idempotency بر اساس X-Montact-Delivery-Id
  • مدیریت خطاهای ۴۰۱/۴۲۹ و Retry مناسب
  • ذخیره امن Token در سمت سرور (نه فرانت‌اند)

۱۱. پشتیبانی

برای ارسال تیکت پشتیبانی، اطلاعات زیر لازم است:

  • Store ID
  • زمان دقیق درخواست (UTC)
  • کد خطای دریافتی
  • X-Montact-Delivery-Id (در صورت مرتبط بودن به Webhook)
  • نمونه Request/Response (بدون افشای Token کامل)