Viewer — Βασική ενσωμάτωση στον ιστότοπό σας

Ενσωμάτωση πλήρους οθόνης

Ενσωματώστε το Viewer οπουδήποτε στον ιστότοπό σας με ένα iframe.

Σημαντικό: το τρέχον περιβάλλον ενσωμάτωσης απαιτεί χειραψία postMessage και βραχύβιο token συνεδρίας ενσωμάτωσης. Το token δημιουργείται από το backend σας μέσω του Alter Product Public API και δεσμεύεται στο origin της σελίδας υποδοχής.

Ροή:

  1. Η σελίδα σας φορτώνει το iframe με το URL του Viewer.
  2. Το iframe στέλνει ALTER_CHILD_HELLO και η σελίδα απαντά με ALTER_PARENT_ACK χρησιμοποιώντας το ίδιο nonce.
  3. Το iframe ζητά πρόσβαση με ALTER_TOOL_INIT_SESSION και payload.tool=viewer.
  4. Το backend σας δημιουργεί token συνεδρίας και η σελίδα στέλνει ALTER_TOOL_SESSION_READY με token.
<!DOCTYPE html>
<html>
  <head>
    <title>Alter Product - Full Screen Embed</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      * { box-sizing: border-box; }
      html, body { width: 100%; height: 100%; margin: 0; padding: 0; }
      iframe { width: 100%; height: 100%; border: 0; display: block; }
      #wrapper { width: 100%; height: 100%; }
    </style>
  </head>
  <body>
    <div id="wrapper">        
      <iframe
        id="alter-iframe"
        title="Alter Product Tool"
        src="https://alterproduct.com/app/viewer/1"
        allowfullscreen
      ></iframe>
    </div>
    <script>
      const IFRAME_ORIGIN = "https://alterproduct.com";
      const TOOL = "viewer";
      const DESIGN_ID = 1;
      const iframe = document.getElementById("alter-iframe");

      // Keep nonce per handshake (from iframe) to prevent random messages from being accepted.
      let handshakeNonce = "";
      let handshakeOk = false;

      function postToIframe(payload) {
        iframe.contentWindow.postMessage(payload, IFRAME_ORIGIN);
      }

      /**
       * Your backend owns this endpoint. It should call:
       * POST https://alterproduct.com/public-api/v1/embed/session
       * using server-side Alter Product API credentials.
       */
      async function createEmbedSessionFromYourBackend(payload) {
        const res = await fetch("/api/alter/embed-session", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(payload || {})
        });

        if (!res.ok) throw new Error("Failed to create embed session");
        const data = await res.json();

        // Expected response: { token: "..." }
        if (!data || !data.token) throw new Error("Missing token");
        return data.token;
      }

      window.addEventListener("message", async (event) => {
        // ✅ 1) Always validate origin
        if (event.origin !== IFRAME_ORIGIN) return;

        // ✅ 2) Always validate source
        if (event.source !== iframe.contentWindow) return;

        const msg = event.data || {};

        // -----------------------
        // A) HANDSHAKE
        // iframe -> parent: ALTER_CHILD_HELLO { nonce }
        // parent -> iframe: ALTER_PARENT_ACK  { nonce }
        // -----------------------
        if (msg.type === "ALTER_CHILD_HELLO") {
          if (!msg.nonce || typeof msg.nonce !== "string") return;

          handshakeNonce = msg.nonce;
          handshakeOk = true;

          postToIframe({ type: "ALTER_PARENT_ACK", nonce: handshakeNonce });
          return;
        }

        // Ignore everything until handshake is done
        if (!handshakeOk) return;

        // -----------------------
        // B) TOKEN REQUEST (on-demand)
        // iframe -> parent: ALTER_TOOL_INIT_SESSION
        //   payload: { tool, mode, uiDesignId }
        //
        // parent -> iframe: ALTER_TOOL_SESSION_READY
        //   { token }
        // -----------------------
        if (msg.type === "ALTER_TOOL_INIT_SESSION") {
          try {
            const payload = msg.payload || {};

            const tool = String(payload.tool || TOOL).toLowerCase();
            const designId = Number(payload.uiDesignId || DESIGN_ID);

            const token = await createEmbedSessionFromYourBackend({
              tool,
              designId,
              origin: window.location.origin
            });

            postToIframe({
              type: "ALTER_TOOL_SESSION_READY",
              token
            });
          } catch (e) {
            postToIframe({
              type: "ALTER_TOOL_SESSION_ERROR",
              message: String(e && e.message ? e.message : e)
            });
          }
          return;
        }

        // -----------------------
        // C) OPTIONAL: listen to tool events (examples)
        // -----------------------
        if (msg.type === "ALTER_VIEWER_ADD_TO_CART") {
          console.log("[Alter] Add to cart:", msg.payload);
          return;
        }
      });
    </script>
  </body>
</html>

Βασική μορφοποίηση

Μπορείτε να προσαρμόσετε το Viewer με δύο τρόπους:

  • Με παραμέτρους URL — ρυθμίστε φόντο, περιβάλλον, φωτισμό, πλοήγηση, ορατότητα της προσθήκης στο καλάθι και προεπιλογή παραλλαγής (δείτε Μορφοποίηση (παράμετροι URL)).
  • Με CSS στο στοιχείο κοντέινερ γύρω από το iframe (μέγεθος, περιγράμματα, ακτίνα γωνιών, διάταξη).
#wrapper {
  height: 320px;
  width: 400px;
  overflow: hidden;
  border-radius: 14px;
  background: linear-gradient(0deg, rgba(0,43,133,1) 0%, rgba(0,182,215,1) 100%);
}

iframe {
  width: 100%;
  height: 100%;
  display: block;
  border: 0;
}