Customizer - postMessage ile iletişim İçindekiler Customizer, ana sayfayla postMessage üzerinden iletişim kurar. Ortak nonce el sıkışmasının ardından hem belirteç hem sepet anahtarı döndüren, Customizer’a özel bir oturum isteği kullanır.
Kurulum:
Alter Product uygulamasında E-ticaret ayarları sekmesini açın. Entegrasyon bölümünde iframe’in yerleştirileceği alan adını ayarlayın; örneğin https://yourwebsite.com veya http://localhost:3000 . Akış:
Siteniz Customizer iframe’ini yükler. iframe ALTER_CHILD_HELLO gönderir; sayfanız aynı nonce ile ALTER_PARENT_ACK yanıtı verir. iframe, ALTER_CUSTOMIZER_INIT_SESSION ile oturum ister; veriler alterProductId, uiDesignId ve mode içerir. Backend’iniz Alter Product Public API üzerinden oturumu oluşturur; sayfanız token, cartKey ve mode içeren ALTER_CUSTOMIZER_SESSION_READY ile yanıt verir. Başarılı kayıttan sonra Customizer, yeni sepet satırları için ALTER_CUSTOMIZER_ADD_TO_CART, mevcut satırlar için ALTER_CUSTOMIZER_UPDATE_DESIGN gönderir. Ürün Yapılandırması’nda tanımlanan varyant meta verileri yanıt verisine dahildir.
Tür Açıklama ALTER_CHILD_HELLOEl sıkışması başlangıcı (nonce içerir) ALTER_CUSTOMIZER_INIT_SESSIONAna web sitesinden Customizer oturum belirteci ve sepet anahtarı ister ALTER_CUSTOMIZER_ADD_TO_CARTKullanıcı “Sepete ekle” düğmesine tıkladı (veri, kaydedilmiş tasarım/sipariş bilgilerini içerir) ALTER_CUSTOMIZER_UPDATE_DESIGNKullanıcı mevcut sepet satırı/sipariş için değişiklikleri kaydetti ALTER_WP_CUSTOMIZER_ORDER_REQUESTMevcut müşteri siparişini yüklemek için WordPress/WooCommerce isteği ALTER_WP_CUSTOMIZER_ORDER_SAVE_REQUESTMüşteri siparişi verilerini ve yüklenen dosyaları kaydetmek için WordPress/WooCommerce isteği ALTER_WP_RUNTIME_CONTEXT_REQUESTWordPress/WooCommerce çalışma zamanı bağlamı isteği ALTER_WP_LOCAL_DESIGN_REQUESTwp_local_design=1 olduğunda WordPress yerel tasarım başlangıç verisi isteği
Müşteri Customizer’da Sepete ekle düğmesine tıkladığında varsayılan durumu shopping_cart olan bir sipariş kaydı oluşturulur. Sipariş shopping_cart durumundayken müşteri tasarımı düzenlemeye devam edebilir; örneğin https://alterproduct.com/app/customizer/{customizerId}/{orderId} gibi bir bağlantıyla. Durum shopping_cart veya editable dışında bir değere değiştiğinde müşteri düzenlemesi kilitlenir ve tasarımın görüntüleme sürümü gösterilir.
Tür Açıklama ALTER_PARENT_ACKEl sıkışması onayı (nonce içermelidir) ALTER_CUSTOMIZER_SESSION_READYCustomizer’ı yetkilendirmek için token, cartKey ve mode sağlar ALTER_CUSTOMIZER_SESSION_ERRORCustomizer oturumu isteği başarısız oldu ALTER_WP_CUSTOMIZER_ORDER_RESPONSEMevcut müşteri siparişini içeren WordPress/WooCommerce yanıtı ALTER_WP_CUSTOMIZER_ORDER_SAVE_RESPONSEMüşteri siparişi kaydından sonra WordPress/WooCommerce yanıtı ALTER_WP_RUNTIME_CONTEXT_RESPONSEWordPress/WooCommerce çalışma zamanı bağlamı yanıtı ALTER_WP_LOCAL_DESIGN_RESPONSEWordPress yerel tasarım başlangıç verisi yanıtı
1 <! DOCTYPE html >
2 < html lang = " en " >
3 < head >
4 < meta charset = " UTF-8 " />
5 < meta name = " viewport " content = " width=device-width, initial-scale=1 " />
6 < title > Alter Product Customizer - postMessage (Handshake + Token) </ title >
7 < style >
8 body { font-family : system-ui , -apple-system , Segoe UI , Roboto , sans-serif ; margin : 24 px ; }
9 iframe { width : 100 % ; height : 720 px ; border : 0 ; display : block ; border-radius : 12 px ; }
10 pre { background : #0b1020 ; color : #d7e1ff ; padding : 12 px ; border-radius : 12 px ; overflow : auto ; }
11 </ style >
12 </ head >
13 < body >
14 < h1 > My E-commerce </ h1 >
15
16 < iframe
17 id = " customizerWidget "
18 src = " https://alterproduct.com/app/customizer/1 "
19 title = " Alter Product Customizer "
20 allowfullscreen >
21 </ iframe >
22
23 < h3 > Logs </ h3 >
24 < pre id = " log " > </ pre >
25
26 < script >
27 const IFRAME_ORIGIN = 'https://alterproduct.com' ;
28 const iframe = document . getElementById ( 'customizerWidget' ) ;
29 const logEl = document . getElementById ( 'log' ) ;
30
31 let handshakeOk = false ;
32
33 function log ( ... args ) {
34 const line = args . map ( a => ( typeof a === 'string' ? a : JSON . stringify ( a , null , 2 ) ) ) . join ( ' ' ) ;
35 logEl . textContent += line + '\n' ;
36 }
37
38 function postToIframe ( payload ) {
39 iframe . contentWindow . postMessage ( payload , IFRAME_ORIGIN ) ;
40 }
41
42 45 46
47 async function getCustomizerSessionFromYourBackend ( payload ) {
48 const res = await fetch ( '/api/alter/customizer-session' , {
49 method : 'POST' ,
50 headers : { 'Content-Type' : 'application/json' } ,
51 body : JSON . stringify ( payload || { } ) ,
52 } ) ;
53
54 if ( ! res . ok ) throw new Error ( 'Failed to create customizer session' ) ;
55
56 const data = await res . json ( ) ;
57 if ( ! data || ! data . sessionToken || ! data . cartKey ) {
58 throw new Error ( 'Missing sessionToken or cartKey' ) ;
59 }
60
61 return data ;
62 }
63
64 window . addEventListener ( 'message' , async ( event ) => {
65 // ✅ 1) Validate origin
66 if ( event . origin !== IFRAME_ORIGIN ) return ;
67
68 // ✅ 2) Validate source
69 if ( event . source !== iframe . contentWindow ) return ;
70
71 const msg = event . data || { } ;
72 if ( ! msg . type || typeof msg . type !== 'string' ) return ;
73
74 // -----------------------
75 // A) HANDSHAKE
76 // Customizer -> Host: ALTER_CHILD_HELLO { nonce }
77 // Host -> Customizer: ALTER_PARENT_ACK { nonce }
78 // -----------------------
79 if ( msg . type === 'ALTER_CHILD_HELLO' ) {
80 const nonce = msg . nonce ;
81 if ( ! nonce || typeof nonce !== 'string' ) return ;
82
83 handshakeOk = true ;
84 log ( '[Customizer] -> Host: ALTER_CHILD_HELLO' , { nonce } ) ;
85
86 log ( '[Host] -> Customizer: ALTER_PARENT_ACK' ) ;
87 postToIframe ( { type : 'ALTER_PARENT_ACK' , nonce } ) ;
88 return ;
89 }
90
91 // Ignore everything until handshake is done
92 if ( ! handshakeOk ) return ;
93
94 // -----------------------
95 // B) CUSTOMIZER SESSION INIT
96 // Customizer -> Host: ALTER_CUSTOMIZER_INIT_SESSION { payload: { alterProductId, uiDesignId, mode } }
97 // Host -> Customizer: ALTER_CUSTOMIZER_SESSION_READY { token, cartKey, mode }
98 // -----------------------
99 if ( msg . type === 'ALTER_CUSTOMIZER_INIT_SESSION' ) {
100 try {
101 const payload = msg . payload || { } ;
102 const alterProductId = Number ( payload . alterProductId || 0 ) ;
103 const uiDesignId = Number ( payload . uiDesignId || 0 ) ;
104 const mode = payload . mode === 'edit' ? 'edit' : 'view' ;
105
106 log ( '[Customizer] -> Host: ALTER_CUSTOMIZER_INIT_SESSION' , {
107 alterProductId ,
108 uiDesignId ,
109 mode ,
110 } ) ;
111
112 const session = await getCustomizerSessionFromYourBackend ( {
113 alterProductId ,
114 uiDesignId ,
115 mode ,
116 } ) ;
117
118 log ( '[Host] -> Customizer: ALTER_CUSTOMIZER_SESSION_READY' ) ;
119 postToIframe ( {
120 type : 'ALTER_CUSTOMIZER_SESSION_READY' ,
121 token : session . sessionToken ,
122 cartKey : session . cartKey ,
123 mode : session . mode || mode ,
124 } ) ;
125 } catch ( e ) {
126 log ( '[Host] -> Customizer: ALTER_CUSTOMIZER_SESSION_ERROR' , String ( e && e . message ? e . message : e ) ) ;
127 postToIframe ( {
128 type : 'ALTER_CUSTOMIZER_SESSION_ERROR' ,
129 message : String ( e && e . message ? e . message : e ) ,
130 } ) ;
131 }
132 return ;
133 }
134
135 // -----------------------
136 // C) Customizer events
137 // -----------------------
138 if ( msg . type === 'ALTER_CUSTOMIZER_ADD_TO_CART' ) {
139 log ( '[Customizer] -> Host: ALTER_CUSTOMIZER_ADD_TO_CART' , msg . payload ) ;
140 // Send payload to your backend and add item to cart in your e-commerce system
141 return ;
142 }
143
144 if ( msg . type === 'ALTER_CUSTOMIZER_UPDATE_DESIGN' ) {
145 log ( '[Customizer] -> Host: ALTER_CUSTOMIZER_UPDATE_DESIGN' , msg . payload ) ;
146 // Update an existing cart line/order in your e-commerce system
147 return ;
148 }
149 } ) ;
150 </ script >
151 </ body >
152 </ html > {
"id" : 481 ,
"customizerId" : 10 ,
"userDesignId" : 10 ,
"isSeenByOwner" : false ,
"orderStatus" : "shopping_cart" ,
"createdAt" : "2026-05-28T10:15:00.000Z" ,
"customizerOrderURL" : "https://alterproduct.com/app/customizer/10/481" ,
"customizerURL" : "https://alterproduct.com/app/customizer/10" ,
"customizerName" : "Mug 450ml (15oz)" ,
"totalPrice" : {
"value" : 24.99 ,
"currency" : "EUR"
} ,
"productGroup" : {
"id" : 1 ,
"name" : {
"pl" : "Kubek 450ml (15oz)" ,
"en" : "Mug 450ml (15oz)"
}
} ,
"productItems" : [
{
"id" : 901 ,
"model3d" : {
"id" : 3
} ,
"size" : {
"id" : 9 ,
"name" : {
"pl" : "450ml (15oz)" ,
"en" : "450ml (15oz)"
} ,
"measureSize" : {
"D" : 8.65 ,
"H" : 11.95
} ,
"externalMapping" : {
"attribute" : {
"internalId" : 123 ,
"slug" : "pa_size" ,
"label" : "Size"
} ,
"term" : {
"internalId" : 456 ,
"slug" : "450ml-15oz" ,
"label" : "450ml (15oz)"
}
}
} ,
"material" : {
"id" : 3 ,
"name" : {
"pl" : "Ceramika" ,
"en" : "Ceramic"
} ,
"externalMapping" : {
"attribute" : {
"internalId" : 124 ,
"slug" : "pa_material" ,
"label" : "Material"
} ,
"term" : {
"internalId" : 457 ,
"slug" : "ceramic" ,
"label" : "Ceramic"
}
}
} ,
"printType" : {
"id" : 5 ,
"name" : {
"pl" : "Sublimacja" ,
"en" : "Sublimation"
} ,
"externalMapping" : {
"attribute" : {
"internalId" : 125 ,
"slug" : "pa_printing-method" ,
"label" : "Printing method"
} ,
"term" : {
"internalId" : 458 ,
"slug" : "sublimation" ,
"label" : "Sublimation"
}
}
} ,
"printingMethod" : {
"id" : 5 ,
"name" : {
"pl" : "Sublimacja" ,
"en" : "Sublimation"
} ,
"externalMapping" : {
"attribute" : {
"internalId" : 125 ,
"slug" : "pa_printing-method" ,
"label" : "Printing method"
} ,
"term" : {
"internalId" : 458 ,
"slug" : "sublimation" ,
"label" : "Sublimation"
}
}
} ,
"color" : {
"id" : 11 ,
"name" : {
"pl" : "Domyślny" ,
"en" : "Default"
} ,
"hex" : "#FFFFFF" ,
"customColor" : false ,
"pickedColors" : { } ,
"patternId" : null ,
"externalMapping" : {
"attribute" : {
"internalId" : 126 ,
"slug" : "pa_color" ,
"label" : "Color"
} ,
"term" : {
"internalId" : 459 ,
"slug" : "default" ,
"label" : "Default"
}
}
} ,
"variant" : {
"id" : 11 ,
"productGroupId" : 1 ,
"productModel3dId" : 3 ,
"sizeId" : 9 ,
"materialId" : 3 ,
"printingMethodId" : 5 ,
"colorId" : 11 ,
"metadata" : {
"sku" : "MUG-450-WHITE"
} ,
"minOrderQuantity" : 1 ,
"processingTime" : null ,
"stockQuantity" : null ,
"volume" : null ,
"weight" : null
} ,
"unitPrice" : {
"value" : 24.99 ,
"currency" : "EUR"
} ,
"totalPrice" : {
"value" : 24.99 ,
"currency" : "EUR"
} ,
"quantity" : 1 ,
"mockups" : [
{
"productModel3dId" : 3 ,
"img" : {
"thumb" : "https://api.example.com/file/protected/user_1/10/e-commerce/orders/481/mockup-thumb.webp" ,
"large" : "https://api.example.com/file/protected/user_1/10/e-commerce/orders/481/mockup-large.webp"
}
}
] ,
"updatedAt" : "2026-05-28T10:15:10.000Z"
}
] ,
"cartKey" : "wc_cart_item_key"
}