تكامل Alter Product Public API

صُمّمت Public API للتكامل بين الخوادم مع واجهات المتاجر وخلفيات التجارة البرمجية وإضافات WordPress/WooCommerce ومسارات الإنتاج الخارجية.

المصادقة وعنوان URL الأساسي

https://alterproduct.com/public-api/v1

أنشئ بيانات اعتماد API في لوحة إعدادات التجارة الإلكترونية. يُعرض Access Token مرة واحدة، لذا احفظه فورًا في مخزن الأسرار لخلفيتك البرمجية.

احتفظ بـ Access Key وAccess Token على خادمك. ترفض نقاط النهاية التي تتطلب مصادقة الاستدعاءات القادمة من المتصفح التي تتضمن ترويسات Origin أو Referer.

يمكن تحديد نطاقات صلاحيات بيانات الاعتماد. استخدم GET /auth/check للتحقق من واجهة المتجر النشطة وإمكانات الخطة ونطاقات الصلاحيات المعادة لبيانات الاعتماد.

x-alter-access-key: YOUR_API_KEY
x-alter-access-token: YOUR_API_TOKEN
المعلمةمطلوبالتفاصيل
x-alter-access-keyنعممعرّف عام لبيانات الاعتماد.
x-alter-access-tokenنعمرمز سري مقترن بمفتاح الوصول.
x-alter-client-fingerprintلابصمة ثابتة اختيارية لتحديد معدل طلبات جلسات التضمين.
Authorizationبيئة التشغيل فقطرمز Bearer تعيده POST /embed/session وتستخدمه /runtime/bootstrap.

اختبار الاتصال

استخدم نقطة نهاية فحص المصادقة قبل تفعيل المزامنة أو ميزات التضمين في تكامل قيد التشغيل الفعلي.

GET https://alterproduct.com/public-api/v1/auth/check

مثال طلب (fetch)

const response = await fetch('https://alterproduct.com/public-api/v1/auth/check', {
  method: 'GET',
  headers: {
    'x-alter-access-key': process.env.ALTER_ACCESS_KEY,
    'x-alter-access-token': process.env.ALTER_ACCESS_TOKEN
  }
});

const payload = await response.json();

if (!response.ok) {
  throw new Error(payload?.code || payload?.error || `Alter API ${response.status}`);
}

console.log(payload);

مثال رد

{
  "ok": true,
  "message": "success",
  "storefrontId": 12,
  "userOwnerId": 34,
  "credentialId": 56,
  "scopes": ["orders:read", "orders:write", "products:read"],
  "plan": {
    "requiredPlan": "Business",
    "currentPlanName": "Business",
    "eligible": true,
    "runtimeFlags": {
      "viewer": true,
      "configurator": true,
      "customizer": true
    },
    "limits": {
      "activeRuntimeBindingsLimit": 100,
      "monthlyReassignmentLimit": 1000,
      "monthlyEmbedTokenLimit": 50000
    }
  }
}

تستخدم الأمثلة التالية الدالة المساعدة أدناه. وهي تعتمد على fetch مباشرة وتعمل في Node.js 18+ أو أي بيئة تشغيل خادم توفر fetch.

const ALTER_API_BASE = 'https://alterproduct.com/public-api/v1';

const authHeaders = {
  'x-alter-access-key': process.env.ALTER_ACCESS_KEY,
  'x-alter-access-token': process.env.ALTER_ACCESS_TOKEN
};

async function alterFetch(path, options = {}) {
  const response = await fetch(`${ALTER_API_BASE}${path}`, {
    ...options,
    headers: {
      ...authHeaders,
      ...(options.body ? { 'Content-Type': 'application/json' } : {}),
      ...options.headers
    }
  });

  const payload = await response.json().catch(() => null);

  if (!response.ok) {
    throw new Error(payload?.code || payload?.error || `Alter API ${response.status}`);
  }

  return payload;
}

نظرة عامة على نقاط النهاية

يعكس الجدول أدناه المسارات العامة المسجّلة في backend-public-api/app.js. تُعرض المسارات مع بادئة الوكيل العام المستخدمة في التكاملات الخارجية.

الطريقةنقطة النهايةالوصفالوصول
GET/public-api/healthzفحص جاهزية الخدمة.عام
GET/public-api/v1/auth/checkالتحقق من بيانات الاعتماد وإعادة واجهة المتجر ونطاقات الصلاحيات وإمكانات الخطة.أي بيانات اعتماد تمت مصادقتها
GET/public-api/v1/customer-ordersإعادة قائمة طلبات العملاء مع تقسيم الصفحات وإمكانية التصفية.orders:read
GET/public-api/v1/customer-orders/:idإعادة طلب عميل واحد مع عناصر المنتجات التي جرت تهيئتها.orders:read
POST/public-api/v1/customer-orders/batchإعادة ما يصل إلى 100 طلب بحسب المعرّف.orders:read
PATCH/public-api/v1/customer-orders/:id/statusتحديث حالة الطلب.orders:write
PATCH/public-api/v1/customer-orders/:orderId/quantityتحديث كميات عناصر الطلب المحددة.orders:write
PATCH/public-api/v1/customer-orders/:orderId/quantity/allتعيين كمية واحدة لكل عنصر في الطلب.orders:write
DELETE/public-api/v1/customer-orders/:idحذف طلب عميل تابع لمالك واجهة المتجر.orders:write
GET/public-api/v1/productsإعادة منتجات/تصاميم واجهة المتجر مع إتاحة التضمين وعناوين URL للوسائط.products:read
GET/public-api/v1/products/:idإعادة منتج/تصميم واحد لواجهة المتجر.products:read
POST/public-api/v1/embed/sessionيصدر JWT قصير الأجل للأدوات المضمّنة، بما فيها مولّد النماذج.embed:session:create
GET/public-api/v1/runtime/bootstrapاستخلاص سياق التشغيل من JWT للتضمين.رمز تضمين Bearer
GET/public-api/v1/assetsسرد عناصر كتالوج الأصول من النوع المطلوب.أي بيانات اعتماد تمت مصادقتها
GET/public-api/v1/assets/:type/:assetIdإعادة بيان الأصل مع أدوار الملفات القابلة للتنزيل.أي بيانات اعتماد تمت مصادقتها
GET/public-api/v1/assets/:type/:assetId/files/:roleتنزيل ملف أصل بحسب دوره.أي بيانات اعتماد تمت مصادقتها
GET/public-api/v1/design-importsسرد التصاميم المستضافة لدى Alter والمتاحة للاستيراد.بيانات اعتماد تمت مصادقتها، تتطلب خطة Business
GET/public-api/v1/design-imports/:idإعادة حمولة استيراد تصميم وأوصاف الملفات.بيانات اعتماد تمت مصادقتها، تتطلب خطة Business
GET/public-api/v1/design-imports/:id/files/:fileIdتنزيل ملف من وصف استيراد تصميم.بيانات اعتماد تمت مصادقتها، تتطلب خطة Business
GET/public-api/v1/file/public/products/:productId/:sizeإعادة معاينة عامة للمنتج. يجب أن يكون الحجم small.png أو medium.png أو big.png.عام
GET/public-api/v1/file/protected/:keyإعادة ملف محمي باستخدام مفتاح التخزين.عنوان URL موقّع أو files:read
GET/public-api/v1/fontsإعادة جميع الخطوط المتاحة.عام
GET/public-api/v1/currenciesإعادة جميع العملات.عام
POST/public-api/v1/runtime-bindings/sync-from-wordpressإنشاء روابط بيئة التشغيل أو تحديثها من روابط منتجات WordPress.أي بيانات اعتماد تمت مصادقتها
PATCH/public-api/v1/runtime-bindings/:idتحديث رابط بيئة تشغيل.أي بيانات اعتماد تمت مصادقتها
POST/public-api/v1/runtime-bindings/:id/activateتفعيل رابط بيئة تشغيل.أي بيانات اعتماد تمت مصادقتها
POST/public-api/v1/runtime-bindings/:id/deactivateتعطيل رابط بيئة تشغيل.أي بيانات اعتماد تمت مصادقتها
POST/public-api/v1/wp-connect/exchangeاستبدال رمز تسليم الاتصال التلقائي في WordPress ببيانات اعتماد API.رمز تسليم للاستخدام مرة واحدة
GET/public-api/v1/model-generator/catalogيسرد منتجات المولّد وتهيئاته ونسخ القوالب المرئية.embed:session:create
GET/public-api/v1/model-generator/modelsيسرد النماذج مع واصفات مصادر المولّد المثبّتة على نسخ محددة للاستيراد.embed:session:create
GET/public-api/v1/model-generator/designer-catalogيعيد كتالوج نماذج المولّد الذي يستخدمه Designer.embed:session:create
GET/public-api/v1/model-generator/projectsيسرد مشاريع المولّد الخاصة بالمالك والمتاحة للجميع.embed:session:create
GET/public-api/v1/model-generator/projects/:projectIdيعيد أحدث نسخة من المشروع أو النسخة المحددة، مع القالب وقائمة الملفات.embed:session:create
GET/public-api/v1/model-generator/projects/:projectId/revisions/:revisionيعيد أحدث نسخة من المشروع أو النسخة المحددة، مع القالب وقائمة الملفات.embed:session:create
GET/public-api/v1/model-generator/projects/:projectId/artifacts/:artifactIdينزّل ملفًا ناتجًا بعد التحقق من الوصول إلى مشروعه.embed:session:create
GET/public-api/v1/model-generator/configurations/:configurationId/revisions/:revision/templateيعيد مستند قالب متاح الوصول لنسخة التهيئة المحددة.embed:session:create
GET/public-api/v1/model-generator/configurations/:configurationId/revisions/:revision/importيعيد حزمة استيراد القالب مع ملفات الاعتماديات.embed:session:create
GET/public-api/v1/model-generator/mannequinsيعيد كلا المانيكانين وواصفات مواردهما.embed:session:create
GET/public-api/v1/model-generator/image-libraries/:kind/assetsيسرد موارد مكتبة الخامات أو الخلفيات مع الملفات القابلة للاستيراد.embed:session:create
GET/public-api/v1/model-generator/image-libraries/:kind/assets/:assetIdيعيد مورد خامة أو خلفية واحدًا مع ملفاته القابلة للاستيراد.embed:session:create
GET/public-api/v1/model-generator/public-files/:keyينزّل ملف اعتماد مسموحًا به للمولّد.embed:session:create

طلبات العملاء

تتيح نقاط نهاية طلبات العملاء للمتجر الخارجي قراءة العناصر التي جرت تهيئتها وتحديث الكميات ونقل الطلب بين حالات التنفيذ وحذف الطلبات المتروكة.

المعلمةمطلوبالتفاصيل
nameلاالبحث باسم التصميم ومعرّف الطلب الرقمي.
category_idلاالتصفية بحسب معرّف فئة المنتج.
order_statusلاإحدى حالات الطلب المسموحة.
offsetلاالقيمة الافتراضية 0. يجب أن تكون >= 0.
limitلاالقيمة الافتراضية 9 لهذه الوحدة، والحد الأقصى 50.
order_byلاid أو created_at أو design_name.
directionلاASC أو DESC.

مثال طلب (fetch)

const params = new URLSearchParams({
  limit: '20',
  offset: '0',
  order_status: 'shopping_cart',
  order_by: 'created_at',
  direction: 'DESC'
});

const orders = await alterFetch(`/customer-orders?${params.toString()}`);

const order = await alterFetch('/customer-orders/123');

const batch = await alterFetch('/customer-orders/batch', {
  method: 'POST',
  body: JSON.stringify({
    customerOrderIds: [123, 124, 125]
  })
});

القيم المسموحة

الحالةالوصف
shopping_cartمرحلة السلة؛ ما زال بإمكان العميل تعديل التهيئة.
editableيظل الطلب قابلًا للتعديل من العميل.
paidتم دفع الطلب وأصبح جاهزًا للتنفيذ.
processingالطلب قيد التنفيذ.
completedتم تنفيذ الطلب.
cancelledأُلغي الطلب.

مثال طلب (fetch)

await alterFetch('/customer-orders/123/status', {
  method: 'PATCH',
  body: JSON.stringify({
    status: 'processing'
  })
});

await alterFetch('/customer-orders/123/quantity', {
  method: 'PATCH',
  body: JSON.stringify({
    items: [
      { orderDetailId: 987, quantity: 3 }
    ]
  })
});

await alterFetch('/customer-orders/123/quantity/all', {
  method: 'PATCH',
  body: JSON.stringify({
    quantity: 2
  })
});

await alterFetch('/customer-orders/123', {
  method: 'DELETE'
});

مثال رد

{
  "order": {
    "id": 123,
    "customizerId": 381,
    "orderStatus": "shopping_cart",
    "createdAt": "2026-05-28T10:15:00.000Z",
    "customizerOrderURL": "https://alterproduct.com/app/customizer/381/123",
    "productItems": [
      {
        "id": 987,
        "model3d": { "id": 381 },
        "size": {
          "id": 395,
          "name": { "pl": "M", "en": "M" },
          "measureSize": null
        },
        "material": {
          "id": 2,
          "name": { "pl": "Bawełna", "en": "Cotton" }
        },
        "printType": {
          "id": 1,
          "name": { "pl": "DTG", "en": "DTG" }
        },
        "color": {
          "id": 418,
          "name": { "pl": "Domyślny", "en": "Default" },
          "hex": "#ffffff"
        },
        "variant": {
          "id": 531,
          "metadata": null,
          "stockQuantity": 25
        },
        "unitPrice": { "value": 12.5, "currency": "EUR" },
        "totalPrice": { "value": 37.5, "currency": "EUR" },
        "quantity": 3
      }
    ],
    "customizerName": "Men's T-Shirt",
    "productGroup": {
      "id": 4,
      "name": { "pl": "Koszulka", "en": "T-Shirt" }
    },
    "totalPrice": { "value": 37.5, "currency": "EUR" }
  }
}

منتجات واجهة المتجر

تعيد نقاط نهاية المنتجات تصاميم واجهة المتجر التي يمكن تضمينها كتجارب viewer أو configurator أو customizer.

المعلمةمطلوبالتفاصيل
nameلاالبحث باسم المنتج/التصميم.
customizerلاtrue أو false.
offsetلاالقيمة الافتراضية 0. يجب أن تكون >= 0.
limitلاالقيمة الافتراضية 9، والحد الأقصى 50.
order_byلاid أو name أو created_at.
directionلاASC أو DESC.

مثال طلب (fetch)

const params = new URLSearchParams({
  limit: '20',
  offset: '0',
  name: 't-shirt',
  customizer: 'true',
  order_by: 'created_at',
  direction: 'DESC'
});

const products = await alterFetch(`/products?${params.toString()}`);
const product = await alterFetch('/products/381');

مثال رد

{
  "products": {
    "items": [
      {
        "id": 381,
        "name": "Men's T-Shirt",
        "createdAt": "2026-01-03T23:55:05.000Z",
        "productId": 4,
        "media": {
          "img": {
            "big": "https://alterproduct.com/public-api/v1/file/public/products/4/big.png",
            "medium": "https://alterproduct.com/public-api/v1/file/public/products/4/medium.png",
            "small": "https://alterproduct.com/public-api/v1/file/public/products/4/small.png"
          },
          "mockups": []
        },
        "storefrontProduct": {
          "id": 89,
          "idUserDesign": 381,
          "shareAccess": "public",
          "isCustomizer": 1
        },
        "runtimeBindings": [
          {
            "id": 42,
            "runtimeType": "customizer",
            "status": "active",
            "externalProductId": "wc_123"
          }
        ],
        "embeddable": {
          "viewer": true,
          "configurator": true,
          "customizer": true
        }
      }
    ],
    "total": 1
  }
}

جلسات التضمين وتهيئة التشغيل

أنشئ رمز تضمين قصير الأجل من خادمك ومرّره إلى iframe/بيئة التشغيل، ثم دع بيئة التشغيل تستدعي bootstrap باستخدام رمز Bearer.

المعلمةمطلوبالتفاصيل
runtimeBindingIdموصى بهالمعرّف المفضل لروابط بيئة التشغيل النشطة.
toolمطلوب عند غياب runtimeBindingIddesigner | viewer | configurator | customizer | model-generator
toolIdtool: model-generatorالمعرّف الرقمي الموجب لمشروع المولّد المحلي، وليس UUID الخاص به أو معرّف منتج WooCommerce.
originنعمأصل الموقع الذي يُعرض فيه التضمين، مثل https://yourstore.com.
designIdمعرّف واحدمعرّف تصميم Alter Product. لا تجمعه مع orderId.
orderIdمعرّف واحدمعرّف طلب Customizer. صالح فقط لـ customizer.
cartKey + cartModeلاسياق سلة خاص بـ customizer فقط. تكون cartMode إما view أو edit.

مثال طلب (fetch)

const session = await alterFetch('/embed/session', {
  method: 'POST',
  headers: {
    'x-alter-client-fingerprint': '9f1b7a5e4b3c2d1f9f1b7a5e4b3c2d1f'
  },
  body: JSON.stringify({
    runtimeBindingId: 42,
    origin: 'https://yourstore.com'
  })
});

const bootstrapResponse = await fetch('https://alterproduct.com/public-api/v1/runtime/bootstrap', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${session.token}`
  }
});

const bootstrap = await bootstrapResponse.json();
console.log({ session, bootstrap });

ملاحظات

await alterFetch('/embed/session', {
  method: 'POST',
  body: JSON.stringify({
    tool: 'customizer',
    origin: 'https://yourstore.com',
    orderId: 123
  })
});

await alterFetch('/embed/session', {
  method: 'POST',
  body: JSON.stringify({
    tool: 'viewer',
    origin: 'https://yourstore.com',
    designId: 381
  })
});

مثال رد

{
  "token": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ...",
  "expiresIn": 900,
  "kid": "1",
  "mode": "design",
  "runtimeBindingId": 42,
  "runtimeType": "customizer"
}

Runtime bootstrap

{
  "runtimeBindingId": 42,
  "designId": 381,
  "productId": "wc_123",
  "runtimeType": "customizer",
  "storageMode": "wordpress_local",
  "manifestUrl": "https://yourstore.com/wp-content/uploads/alter/381/manifest.json",
  "assetBaseUrl": "https://yourstore.com/wp-content/uploads/alter/381/",
  "manifestHash": "a3b1...",
  "planCapabilities": {
    "viewer": true,
    "configurator": true,
    "customizer": true
  },
  "cartKey": null,
  "cartMode": null,
  "orderId": null
}

مولّد النماذج ثلاثية الأبعاد 3D

تدعم نقاط نهاية استيراد المولّد طلبات القراءة فقط بين الخوادم. وتتطلب ترويسات API القياسية والصلاحية embed:session:create وخطة نشطة. لا ينشئ تفويض الاستيراد جلسة محرّر ولا يستهلك حصتها الشهرية. يستخدم فتح المحرّر عدّاد monthlyEmbedTokenLimit نفسه الذي تستخدمه الأدوات المضمّنة الأخرى.

اكتشاف النماذج التي تتضمن مولّدًا واستيرادها

استخدم /model-generator/models لسرد النماذج المتاحة التي تتضمن مولّدات. يثبّت الواصف generator قيم projectId وrevision وconfigurationId وtemplateRevision وproductId وproductModel3dId. اتبع importPath الخاص به لاسترجاع نسخة المصدر المحددة نفسها. تعرض قوائم ملفات موارد المنتجات أيضًا generators والواصف generator لكل نموذج. ويمكن استيراد القوالب بشكل مستقل بحسب التهيئة والنسخة.

مرشحات الكتالوج

نقطة النهايةالتفاصيل
/model-generator/modelsقائمة النماذج: name أو q، وcategoryId، وscope بقيم all وown وglobal، وlimit ضمن 1–50، وoffset.
/model-generator/catalogكتالوج القوالب: generatorType وproductId وaudience وq وtemplateKey وconfigurationId وlimit وoffset.
/model-generator/projectsقائمة المشاريع: configurationId وq وscope بقيم all وown وglobal، وlimit وoffset. يضبط الوكيل العام scope على all افتراضيًا.
/model-generator/image-libraries/:kind/assetsمكتبات الخامات والخلفيات: تكون قيمة kind هي texture أو background؛ وتُرشّح q وcategory وmapType الموارد المتاحة.

تتضمن حزمة استيراد المشروع document وrevision وtemplate وقائمة files. يوفّر كل ملف path ضمن /v1/model-generator/؛ أضف /public-api قبله عند تنزيله من Alter Product. انسخ الملفات المطلوبة إلى مساحة التخزين الخاصة بك واستبدل المراجع المصدرية بمراجع محلية. استورد المانيكانات ومكتبات الخامات عبر نقاط نهاية كتالوجاتها؛ يقتصر public-files على مسارات الموارد المسموح بها، ويجب أن تجتاز القوالب التحقق من الوصول إلى التهيئة والنسخة.

مثال طلب (fetch)

// Server-side: uses the alterFetch helper and authHeaders defined above.
const catalog = await alterFetch('/model-generator/models?' + new URLSearchParams({
  scope: 'all', limit: '24', offset: '0'
}));

const selected = catalog.items[0];
if (!selected?.generator) throw new Error('Select an available generator model');

const importPath = selected.generator.importPath;
if (!importPath.startsWith('/v1/model-generator/projects/')) {
  throw new Error('Invalid generator import path');
}
const bundle = await alterFetch(importPath.slice('/v1'.length));

for (const file of bundle.files) {
  if (!file.path.startsWith('/v1/model-generator/')) {
    throw new Error('Invalid generator file path');
  }
  const response = await fetch('https://alterproduct.com/public-api' + file.path, {
    headers: authHeaders,
    redirect: 'error'
  });
  if (!response.ok) throw new Error(`File download failed: ${response.status}`);
  const bytes = new Uint8Array(await response.arrayBuffer());
  // Persist bytes in your local storage; record the mapping from
  // file.sourceHref / file.href to the resulting local file reference.
}
// Persist bundle.document, bundle.template and revision metadata locally.
// Import the related product asset and its textures/mockups as needed:
const product = await alterFetch('/assets/products/' + selected.generator.productId);
const mannequins = await alterFetch('/model-generator/mannequins');
console.log({ product, mannequins });

جلسة المحرّر والتخزين المحلي

أنشئ جلسة المحرّر باستخدام tool: model-generator وtoolId رقمي موجب يعرّف مشروع المولّد المحلي، وليس UUID الخاص به أو معرّف منتج WooCommerce، مع origin المتجر المسموح به. لا تمرّر designId أو orderId أو runtimeBindingId أو حقول السلة لهذه الأداة. يُعد UUID مشروع المولّد معرّفًا منفصلًا. مرّر token المُعاد عبر مصافحة iframe؛ وتعيد تهيئة بيئة التشغيل الأولية سياق المولّد مع storageMode: wordpress_local.

// Server-side, after authorizing the merchant's access to this local project.
const localProjectId = 42; // Local generator project ID, not its UUID or WC product ID.
const session = await alterFetch('/embed/session', {
  method: 'POST',
  body: JSON.stringify({
    tool: 'model-generator',
    toolId: localProjectId,
    origin: 'https://yourstore.com'
  })
});

// The iframe receives session.token through ALTER_CUSTOMIZER_SESSION_READY.
// Do not put API credentials or the token in the iframe URL.
const bootstrapResponse = await fetch('https://alterproduct.com/public-api/v1/runtime/bootstrap', {
  headers: { Authorization: `Bearer ${session.token}` }
});
if (!bootstrapResponse.ok) throw new Error('Generator bootstrap failed');
const context = await bootstrapResponse.json();
console.log(context);

مثال رد

{
  "runtimeBindingId": null,
  "designId": null,
  "productId": 42,
  "toolId": 42,
  "runtimeType": "model-generator",
  "storageMode": "wordpress_local",
  "parentOrigin": "https://yourstore.com"
}
// Host page: WordPress returns a numeric toolId and a UUID in id.
const url = new URL('https://alterproduct.com/app/model-generator');
url.search = new URLSearchParams({
  embedded: '1',
  lng: 'en',
  parentOrigin: window.location.origin,
  toolId: String(localProject.toolId),
  serverProjectId: localProject.id
}).toString();
// Optional: serverProjectRevision pins an existing saved revision.
iframe.src = url.toString();
// Install the authenticated handshake and storage bridge described below.
// Setting iframe.src alone does not authorize the editor or provide storage.

رسائل iframe التي يستخدمها جسر WordPress

تستضيف إضافة WordPress جسر التخزين وتتحقق من صلاحيات المسؤول أو مدير WooCommerce. وتتحقق من origin الخاص بـ iframe والنافذة المصدرية وnonce ومعرّف الطلب ومسارات المشروع المسموح بها. يوجّه الجسر عمليات القراءة والكتابة المحلية إلى /wp-json/alter-wc/v1/model-generator. تبقى بيانات اعتماد API على الخادم. ويجب أن تنفّذ أي تكاملات مخصصة معالجة تخزين مكافئة ومصادَقًا عليها؛ فواجهة API العامة للمولّد لا تحفظ المشاريع في Alter Product.

النوعالوصف
ALTER_CHILD_HELLO / ALTER_PARENT_ACKيبدأ الإطار الفرعي المصافحة باستخدام nonce؛ وتؤكد الصفحة الأم nonce نفسه.
ALTER_CUSTOMIZER_INIT_SESSION / ALTER_CUSTOMIZER_SESSION_READYيطلب الإطار الفرعي جلسة تحرير model-generator؛ وتعيد الصفحة الأم الرمز المصرّح به.
ALTER_MODEL_GENERATOR_REQUESTيرسل الإطار الفرعي requestId وnonce وrequest الذي يحتوي على method وpath وdata وresponseType.
ALTER_MODEL_GENERATOR_RESPONSEتجيب الصفحة الأم بـ requestId وnonce نفسيهما، إضافة إلى status وdata وheaders وأي error.
// Messages after ALTER_CHILD_HELLO / ALTER_PARENT_ACK agree on the nonce.
// Iframe -> parent:
const sessionRequest = {
  type: 'ALTER_CUSTOMIZER_INIT_SESSION',
  nonce: handshakeNonce,
  payload: {
    tool: 'model-generator', alterProductId: localProject.toolId, mode: 'edit'
  }
};

// Parent -> iframe, after the server authorizes the merchant and issues a token:
const sessionReady = {
  type: 'ALTER_CUSTOMIZER_SESSION_READY',
  nonce: handshakeNonce,
  token: session.token,
  tool: 'model-generator',
  cartKey: `model-generator:${localProject.id}`,
  mode: 'edit',
  localSession: false,
  adminSession: true
};
// Send only to the validated iframe's exact origin and source window.
// An authorized token and successful bootstrap are still required.

تتضمن عملية الحفظ expectedRevision وtemplateRevision وdocument ومراجع الملفات الناتجة. وتنشئ نسخة غير قابلة للتغيير؛ وإذا كانت expectedRevision قديمة، تُعاد استجابة HTTP 409. يخزّن WordPress البيانات الوصفية في قاعدة بياناته والملفات في مجلد uploads. يُصغّر JSON ويُضغط باستخدام gzip عندما يؤدي الضغط إلى تقليل حجمه.

// Example message from the iframe; savedSnapshot and artifact IDs come
// from the generator. The host checks origin/source/nonce/project permissions.
const message = {
  type: 'ALTER_MODEL_GENERATOR_REQUEST',
  requestId: crypto.randomUUID(),
  nonce: handshakeNonce,
  request: {
    method: 'POST',
    path: `/pattern-generator/projects/${projectUuid}/revisions`,
    data: {
      expectedRevision: loadedRevision,
      name: projectName,
      templateRevision,
      document: savedSnapshot,
      references: { artifactIds: savedArtifactIds }
    },
    responseType: 'json'
  }
};

ينشر إجراء «استخدام النموذج المحفوظ في التصميم» نسخة محفوظة كاملة إلى تصميم مرتبط. يراها العملاء بعد ذلك عبر Customizer أو Configurator أو Viewer الحالي، مع روابط المنتجات وفحوص الاشتراك المعتادة. يظل محرّر المولّد أداة للتاجر. تحتفظ روابط الطلبات بالمشروع والنسخة المحفوظين، كي لا تؤدي التعديلات اللاحقة إلى تغيير الطلبات السابقة دون تنبيه.

كتالوج الأصول

يتيح كتالوج الأصول الوصول إلى أصول المنتجات المصدرية والخلفيات والبيئات وعناصر مكتبة الرسومات وقوالب التصميم وأصول النماذج التسويقية. تعيد نقاط نهاية القوائم أوصافًا خفيفة، بينما تتضمن نقاط نهاية التفاصيل بيانات الملفات.

النوعالوصف
productsأصول المنتجات الأساسية والمعاينات والنماذج ثلاثية الأبعاد وأوصاف الخامات والأنسجة.
backgroundsخلفيات ثابتة للعارض.
environmentsخرائط البيئات وصور المعاينة.
image_libraryأصول مكتبة الرسومات، بما فيها الرسومات المخصصة لواجهة المتجر.
design_templatesمعاينات قوالب التصميم ومراجع ملفات الطبقات. يدعم فلتر product_id.
mockupsأصول مولّد النماذج التسويقية والخلفيات وخرائط التراكب. يدعم فلتر product_id.

مثال طلب (fetch)

const assets = await alterFetch('/assets?' + new URLSearchParams({
  type: 'products',
  limit: '20',
  offset: '0',
  search: 'mug'
}));

const details = await alterFetch('/assets/products/4');

const fileResponse = await fetch(
  'https://alterproduct.com/public-api/v1/assets/products/4/files/preview_medium',
  {
    headers: authHeaders
  }
);

const fileBlob = await fileResponse.blob();

مثال رد

{
  "type": "products",
  "items": [
    {
      "assetType": "products",
      "assetId": "4",
      "title": "Mug 450ml",
      "slug": "product-4",
      "description": "Base product 4",
      "primaryRole": "preview_big",
      "fileCount": 8,
      "remoteVersion": "1.0",
      "thumbnail": {
        "role": "preview_small",
        "fileName": "product-4-preview-small.png",
        "mime": "image/png",
        "downloadPath": "/v1/assets/products/4/files/preview_small"
      },
      "metadata": {
        "productCategoryId": 2,
        "productModelCount": 1,
        "isDedicated": false
      }
    }
  ],
  "total": 1,
  "limit": 20,
  "offset": 0
}

استيراد التصاميم

تتيح عمليات استيراد التصاميم الوصول إلى التصاميم المستضافة لدى Alter Product وملفاتها لمسارات الإنتاج الخارجية أو الترحيل. تتحقق API من الأهلية بحسب خطة Business.

المعلمةمطلوبالتفاصيل
searchلاالبحث بعنوان التصميم أو معرّفه.
offsetلاالقيمة الافتراضية 0.
limitلاالقيمة الافتراضية 20، والحد الأقصى 100.

مثال طلب (fetch)

const imports = await alterFetch('/design-imports?' + new URLSearchParams({
  limit: '20',
  offset: '0',
  search: 'mug'
}));

const details = await alterFetch('/design-imports/381');

const fileId = details.files[0].id;
const fileResponse = await fetch(
  `https://alterproduct.com/public-api/v1/design-imports/381/files/${fileId}`,
  {
    headers: authHeaders
  }
);

const fileBlob = await fileResponse.blob();

مثال رد

{
  "eligible": true,
  "requiredPlan": "Business",
  "currentPlanName": "Business",
  "designs": [
    {
      "id": 381,
      "title": "Men's T-Shirt",
      "createdAt": "2026-01-03T23:55:05.000Z",
      "sourceStorefrontId": 12,
      "productId": 4,
      "productName": {
        "pl": "Koszulka",
        "en": "T-Shirt"
      },
      "storageMode": "alter",
      "runtimeStatus": {
        "designer": true,
        "viewer": true,
        "configurator": true,
        "customizer": true
      },
      "thumbnail": {
        "kind": "design-mockup",
        "fileId": "7df7...",
        "downloadPath": "/v1/design-imports/381/files/7df7..."
      }
    }
  ],
  "total": 1
}

الملفات والخطوط والعملات

تلائم ملفات المعاينة العامة الاستخدام في المتصفح. تتطلب الملفات المحمية عنوان URL موقّعًا أو بيانات اعتماد API بصلاحية files:read. أما الخطوط والعملات فتوفرها نقاط نهاية عامة للقراءة.

نقطة النهايةالوصولالتفاصيل
/file/public/products/:productId/small.pngعاممعاينة صغيرة للمنتج.
/file/public/products/:productId/medium.pngعاممعاينة متوسطة للمنتج.
/file/public/products/:productId/big.pngعاممعاينة كبيرة للمنتج.
/file/protected/:keyعنوان URL موقّع أو files:readملف محمي في تخزين الكائنات.
/fontsعاممصفوفة سجلات الخطوط.
/currenciesعاممصفوفة سجلات العملات.

مثال طلب (fetch)

const publicPreview = await fetch(
  'https://alterproduct.com/public-api/v1/file/public/products/4/medium.png'
);

const protectedFile = await fetch(
  'https://alterproduct.com/public-api/v1/file/protected/user_34/381/design/mockup-large.webp',
  {
    headers: authHeaders
  }
);

const fonts = await fetch('https://alterproduct.com/public-api/v1/fonts').then((res) => res.json());
const currencies = await fetch('https://alterproduct.com/public-api/v1/currencies').then((res) => res.json());

مثال رد

[
  {
    "id": 1,
    "family": "Inter",
    "source": "google",
    "category": "sans-serif",
    "variants": ["regular", "600", "700"],
    "subsets": ["latin"],
    "version": "v19",
    "menu": "Inter",
    "files": {
      "regular": "https://..."
    }
  }
]
[
  {
    "id": 1,
    "code": "EUR",
    "name": "Euro",
    "symbol": "€",
    "decimalPlaces": 2
  }
]

روابط بيئة التشغيل

تربط روابط بيئة التشغيل منتجات التجارة الخارجية بتصاميم Alter Product وأنواع بيئات التشغيل. تستخدمها أساسًا تكاملات WordPress/WooCommerce والخلفيات البرمجية المتقدمة لواجهات المتاجر.

المعلمةمطلوبالتفاصيل
designIdلامعرّف تصميم Alter Product التابع لواجهة المتجر.
externalProductIdنعم للمزامنةمعرّف منتج خارجي، مثل معرّف منتج WooCommerce.
runtimeTypeنعم للمزامنةviewer أو configurator أو customizer.
statusلاdraft أو active أو inactive أو archived أو legacy_active.
legacyStorefrontProductIdلامعرّف ربط قديم اختياري.
legacyBindingMetaلابيانات وصفية JSON اختيارية، مثل manifestHash.

مثال طلب (fetch)

await alterFetch('/runtime-bindings/sync-from-wordpress', {
  method: 'POST',
  body: JSON.stringify({
    bindings: [
      {
        externalProductId: 'wc_123',
        runtimeType: 'customizer',
        status: 'active',
        designId: 381,
        legacyBindingMeta: {
          manifestHash: 'a3b1...'
        }
      }
    ]
  })
});

await alterFetch('/runtime-bindings/42', {
  method: 'PATCH',
  body: JSON.stringify({
    status: 'inactive'
  })
});

await alterFetch('/runtime-bindings/42/activate', { method: 'POST' });
await alterFetch('/runtime-bindings/42/deactivate', { method: 'POST' });

wordpress_local

await alterFetch('/runtime-bindings/sync-from-wordpress', {
  method: 'POST',
  body: JSON.stringify({
    bindings: [
      {
        externalProductId: 'wc_123',
        runtimeType: 'viewer',
        status: 'active',
        externalDesign: {
          externalDesignKey: 'wp-design-381',
          productId: 4,
          title: 'WooCommerce local design',
          manifestUrl: 'https://yourstore.com/wp-content/uploads/alter/381/manifest.json',
          assetBaseUrl: 'https://yourstore.com/wp-content/uploads/alter/381/',
          manifestHash: 'a3b1...',
          sourceMeta: {
            pluginVersion: '1.2.0'
          }
        }
      }
    ]
  })
});

مثال رد

{
  "message": "runtimeBinding.syncCompleted",
  "runtimeBindings": [
    {
      "id": 42,
      "designId": 381,
      "externalProductId": "wc_123",
      "runtimeType": "customizer",
      "status": "active"
    }
  ]
}

تبادل بيانات اتصال WordPress

تستهلك نقطة نهاية تبادل اتصال WordPress رمز تسليم يُستخدم مرة واحدة وتعيد بيانات اعتماد API إلى الإضافة. وهي ليست نقطة نهاية عامة لإنشاء بيانات الاعتماد.

مثال طلب (fetch)

const response = await fetch('https://alterproduct.com/public-api/v1/wp-connect/exchange', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    code: 'ONE_TIME_HANDOFF_CODE',
    storeUrl: 'https://yourstore.com/',
    siteOrigin: 'https://yourstore.com',
    codeVerifier: 'PKCE_CODE_VERIFIER_32_TO_128_CHARS'
  })
});

const credentials = await response.json();

مثال رد

{
  "message": "wpConnect.exchange.ok",
  "accessKey": "generated-access-key",
  "accessToken": "generated-access-token",
  "storefrontId": 12
}

الأخطاء وحدود الطلبات

تُوحّد معظم أخطاء وحدات التحكم في رد يحتوي على code. وقد تعيد برمجيات المصادقة الوسيطة ومحددات المعدل ردًا يحتوي على error بدلًا منه.

// Controller error
{
  "code": "assetCatalog.invalidType"
}

// Auth middleware or rate limit
{
  "error": "Unauthorized"
}

{
  "error": "Too Many Requests"
}
النوعالحدالفترة الزمنية
عام600 طلب60 ثانية
GET /auth/check60 طلبًا60 ثانية
قراءة الطلبات/قراءة المنتجات300 طلب60 ثانية
كتابة الطلبات/جلسات التضمين/روابط بيئة التشغيل120 طلبًا60 ثانية
قراءة الأصول/استيراد التصاميم180 طلبًا60 ثانية
الخطوط300 طلب60 ثانية
تبادل اتصال WP30 طلبًا60 ثانية
GET /model-generator/*600 طلب60 ثانية