17 KiB
راهنمای اتصال 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 (سفارشهای مشتری)
۲. دریافت اطلاعات اتصال از فروشنده
- فروشنده وارد پنل Montify میشود.
- از مسیر «تنظیمات → یکپارچهسازیها → CRM» وارد بخش Montact میشود.
- دکمه «صدور 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 | شماره موبایل |
| 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 گام به گام:
- دریافت لیست مشتریان صفحهبندیشده و Upsert در جدول مشتریان CRM بر اساس
id. - برای هر مشتری، دریافت سفارشها، آدرسها و تراکنشها بهصورت جداگانه و Upsert در جداول مرتبط.
- ذخیره
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 کامل)