Ενσωμάτωση Public API του Alter Product

Το Public API προορίζεται για συνδέσεις μεταξύ διακομιστών με καταστήματα, συστήματα ηλεκτρονικού εμπορίου, πρόσθετα WordPress/WooCommerce και εξωτερικές ροές παραγωγής.

Έλεγχος ταυτότητας και βασικό URL

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

Δημιουργήστε διαπιστευτήρια API στις ρυθμίσεις ηλεκτρονικού εμπορίου. Το Access Token εμφανίζεται μία φορά, οπότε αποθηκεύστε το αμέσως στο ασφαλές αποθετήριο μυστικών του backend.

Κρατήστε τα Access Key και Access Token στον διακομιστή σας. Τα endpoints με έλεγχο ταυτότητας απορρίπτουν κλήσεις από προγράμματα περιήγησης που περιλαμβάνουν κεφαλίδες 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ναιΜυστικό token που αντιστοιχεί στο κλειδί πρόσβασης.
x-alter-client-fingerprintόχιΠροαιρετικό σταθερό αποτύπωμα για περιορισμό ρυθμού συνεδριών ενσωμάτωσης.
Authorizationμόνο κατά την εκτέλεσηToken Bearer που επιστρέφει το POST /embed/session και χρησιμοποιείται από το /runtime/bootstrap.

Δοκιμή σύνδεσης

Χρησιμοποιήστε το endpoint ελέγχου ταυτότητας πριν ενεργοποιήσετε λειτουργίες συγχρονισμού ή ενσωμάτωσης σε παραγωγική εγκατάσταση.

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;
}

Επισκόπηση endpoints

Ο πίνακας παρακάτω αντιστοιχεί στις δημόσιες διαδρομές του backend-public-api/app.js. Οι διαδρομές εμφανίζονται με το πρόθεμα δημόσιου proxy που χρησιμοποιούν οι εξωτερικές ενσωματώσεις.

ΜέθοδοςEndpointΠεριγραφήΠρόσβαση
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 παραγγελίες βάσει ID.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 ενσωμάτωσης.token ενσωμάτωσης Bearer
GET/public-api/v1/assetsΠαραθέτει πόρους καταλόγου του ζητούμενου τύπου.οποιαδήποτε έγκυρα διαπιστευτήρια
GET/public-api/v1/assets/:type/:assetIdΕπιστρέφει manifest πόρου με ρόλους αρχείων διαθέσιμων για λήψη.οποιαδήποτε έγκυρα διαπιστευτήρια
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Επιστρέφει την πιο πρόσφατη ή την επιλεγμένη αναθεώρηση έργου, το πρότυπο και το manifest αρχείων.embed:session:create
GET/public-api/v1/model-generator/projects/:projectId/revisions/:revisionΕπιστρέφει την πιο πρόσφατη ή την επιλεγμένη αναθεώρηση έργου, το πρότυπο και το manifest αρχείων.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

Παραγγελίες πελατών

Τα endpoints παραγγελιών επιτρέπουν σε εξωτερικό κατάστημα να διαβάζει διαμορφωμένα στοιχεία, να ενημερώνει ποσότητες, να μετακινεί παραγγελίες σε καταστάσεις εκτέλεσης και να αφαιρεί εγκαταλελειμμένες παραγγελίες.

ΠαράμετροςΥποχρεωτικόΛεπτομέρειες
nameόχιΑναζητά όνομα σχεδίου και αριθμητικό ID παραγγελίας.
category_idόχιΦιλτράρει βάσει 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" }
  }
}

Προϊόντα καταστήματος

Τα endpoints προϊόντων επιστρέφουν σχέδια καταστήματος που μπορούν να ενσωματωθούν ως 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
  }
}

Συνεδρίες ενσωμάτωσης και αρχική φόρτωση περιβάλλοντος εκτέλεσης

Δημιουργήστε βραχύβιο token ενσωμάτωσης στον διακομιστή, περάστε το στο iframe/περιβάλλον εκτέλεσης και αφήστε το περιβάλλον να καλέσει bootstrap με token Bearer.

ΠαράμετροςΥποχρεωτικόΛεπτομέρειες
runtimeBindingIdσυνιστάταιΠροτιμώμενο αναγνωριστικό για ενεργές συνδέσεις εκτέλεσης.
toolυποχρεωτικό χωρίς runtimeBindingIddesigner | viewer | configurator | customizer | model-generator
toolIdtool: model-generatorΘετικό αριθμητικό ID του τοπικού έργου της γεννήτριας, όχι το UUID του ή το ID προϊόντος WooCommerce.
originναιOrigin όπου εμφανίζεται η ενσωμάτωση, π.χ. https://yourstore.com.
designIdένα αναγνωριστικόID σχεδίου Alter Product. Μην το συνδυάζετε με orderId.
orderIdένα αναγνωριστικόID παραγγελίας 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

Τα endpoints εισαγωγής της γεννήτριας δέχονται μόνο αιτήματα ανάγνωσης μεταξύ διακομιστών. Απαιτούν τις τυπικές κεφαλίδες API, το δικαίωμα embed:session:create και ενεργό πρόγραμμα. Η εξουσιοδότηση εισαγωγής δεν δημιουργεί συνεδρία επεξεργασίας και δεν καταναλώνει το μηνιαίο όριό της. Το άνοιγμα του επεξεργαστή χρησιμοποιεί τον ίδιο μετρητή monthlyEmbedTokenLimit με τα υπόλοιπα ενσωματωμένα εργαλεία.

Εύρεση και εισαγωγή μοντέλων με γεννήτρια

Χρησιμοποιήστε το /model-generator/models για να εμφανίσετε τα διαθέσιμα μοντέλα με γεννήτριες. Ο περιγραφέας generator καθορίζει συγκεκριμένα projectId, revision, configurationId, templateRevision, productId και productModel3dId. Ακολουθήστε το importPath του για να ανακτήσετε ακριβώς αυτήν την αναθεώρηση προέλευσης. Τα manifests πόρων προϊόντων παρέχουν επίσης το generators και τον περιγραφέα generator κάθε μοντέλου. Τα πρότυπα μπορούν να εισαχθούν ξεχωριστά, βάσει διαμόρφωσης και αναθεώρησης.

Φίλτρα καταλόγων

EndpointΛεπτομέρειες
/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. Ο δημόσιος proxy χρησιμοποιεί από προεπιλογή scope all.
/model-generator/image-libraries/:kind/assetsΒιβλιοθήκες υφών και φόντων: το kind είναι texture ή background· τα q, category και mapType φιλτράρουν τους διαθέσιμους πόρους.

Η εισαγωγή ενός έργου περιέχει document, revision, template και ένα manifest files. Κάθε αρχείο παρέχει ένα path κάτω από το /v1/model-generator/· προσθέστε μπροστά του το /public-api κατά τη λήψη από το Alter Product. Αντιγράψτε τα απαραίτητα αρχεία στον δικό σας χώρο αποθήκευσης και αντικαταστήστε τις αναφορές προέλευσης με τοπικές αναφορές. Εισαγάγετε τις κούκλες και τις βιβλιοθήκες υφών μέσω των αντίστοιχων endpoints καταλόγου· το 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 του ούτε το ID προϊόντος WooCommerce) και το επιτρεπόμενο origin του καταστήματος. Μη μεταβιβάζετε designId, orderId, runtimeBindingId ή πεδία καλαθιού για αυτό το εργαλείο. Το UUID του έργου της γεννήτριας είναι ξεχωριστό αναγνωριστικό. Μεταβιβάστε το token που επιστρέφεται μέσω του handshake iframe· το runtime bootstrap επιστρέφει το περιβάλλον της γεννήτριας με 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Το θυγατρικό iframe ξεκινά το handshake με ένα nonce· η γονική σελίδα επιβεβαιώνει το ίδιο nonce.
ALTER_CUSTOMIZER_INIT_SESSION / ALTER_CUSTOMIZER_SESSION_READYΤο θυγατρικό iframe ζητά μια συνεδρία επεξεργασίας model-generator· η γονική σελίδα επιστρέφει το εξουσιοδοτημένο token.
ALTER_MODEL_GENERATOR_REQUESTΤο θυγατρικό iframe στέλνει 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, με τις συνήθεις συνδέσεις προϊόντων και τους ελέγχους συνδρομής. Ο επεξεργαστής της γεννήτριας παραμένει εργαλείο του εμπόρου. Οι σύνδεσμοι των παραγγελιών διατηρούν το αποθηκευμένο έργο και την αναθεώρηση, ώστε οι μεταγενέστερες αλλαγές να μην τροποποιούν αυτόματα παλαιότερες παραγγελίες.

Κατάλογος πόρων

Ο κατάλογος πόρων παρέχει πηγαίους πόρους προϊόντων, φόντα, περιβάλλοντα, στοιχεία γραφικής βιβλιοθήκης, πρότυπα σχεδίων και πόρους μακετών. Τα endpoints λίστας επιστρέφουν συνοπτικές περιγραφές· τα endpoints λεπτομερειών περιλαμβάνουν manifests αρχείων.

ΤύποςΠεριγραφή
productsΒασικοί πόροι προϊόντων, προεπισκοπήσεις, μοντέλα 3D, περιγραφές υλικών και υφών.
backgroundsΣτατικά φόντα Viewer.
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 για εξωτερική παραγωγή ή μεταφορά δεδομένων. Το API ελέγχει αν πληρούνται οι προϋποθέσεις του προγράμματος Business.

ΠαράμετροςΥποχρεωτικόΛεπτομέρειες
searchόχιΑναζητά τίτλο ή ID σχεδίου.
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. Οι γραμματοσειρές και τα νομίσματα έχουν δημόσια endpoints ανάγνωσης.

EndpointΠρόσβασηΛεπτομέρειες
/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 και προηγμένα backend καταστημάτων.

ΠαράμετροςΥποχρεωτικόΛεπτομέρειες
designIdόχιID σχεδίου Alter Product που ανήκει στο κατάστημα.
externalProductIdναι για συγχρονισμόΕξωτερικό ID προϊόντος, π.χ. ID προϊόντος WooCommerce.
runtimeTypeναι για συγχρονισμόviewer, configurator ή customizer.
statusόχιdraft, active, inactive, archived ή legacy_active.
legacyStorefrontProductIdόχιΠροαιρετικό ID παλαιάς αντιστοίχισης.
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

Το endpoint ανταλλαγής σύνδεσης WordPress καταναλώνει κωδικό μεταβίβασης μίας χρήσης και επιστρέφει διαπιστευτήρια API στο πρόσθετο. Δεν αποτελεί endpoint γενικής δημιουργίας διαπιστευτηρίων.

Παράδειγμα αιτήματος (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. Το middleware ελέγχου ταυτότητας και οι περιοριστές ρυθμού μπορούν να επιστρέφουν απάντηση 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 δευτερόλεπτα