@expresta/sdk
Version:
A lightweight JS SDK for embedding Expresta's order button into websites using HTML or JavaScript.
232 lines (193 loc) • 9.54 kB
JavaScript
/**
* ============================================
* Expresta Order Button JS SDK
* Version: 1.2
* ============================================
*
* Description:
* This SDK provides a customizable JavaScript integration
* for embedding a dynamic "Order Now" button into third-party
* websites or applications.
*
* Usage:
* <div class="expresta-order-button"></div>
* <script src="https://cdn.expresta.com/sdk/src/js/buttons.js"></script>
*
* Initialization (auto or manual) will render the button
* and bind it to your order workflow.
*
* Author: Expresta Collective
* Copyright © 2026 Expresta s.r.o.
* All rights reserved.
*/
const configMap = {
"sk": { "domain": "exprestlac.sk", "buttonText": "Kúpiť na %s" },
"cz": { "domain": "expresta.cz", "buttonText": "Koupit na %s" },
"at": { "domain": "expresta.at", "buttonText": "Bei %s kaufen" },
"de": { "domain": "expresta.de", "buttonText": "Bei %s kaufen" },
"en": { "domain": "expresta.eu", "buttonText": "Buy at %s" },
"hu": { "domain": "expresta.hu", "buttonText": "Vásárlás az %s oldalán" }
};
const OrderButton = {
init(config) {
if (!config.account || !config.public_key || (!config.product_types && !config.product_id)) {
console.error("[Expresta SDK] Missing required parameters.");
return;
}
const wrap = document.querySelector(`.${config.wrap}`);
if (!wrap) {
console.error("[Expresta SDK] Wrap element not found.");
return;
}
this.renderButton(wrap, config);
},
renderButton(wrap, config) {
const {domain, buttonText} = configMap[config.lang] || configMap["en"];
const endpoint = config.product_id ? "recreate-product" : "add-product";
const url = new URL(`https://www.${domain}/order/${endpoint}`);
if (config.product_types?.length === 0 && !config.product_id) {
console.error('[Expresta SDK] You must set either product_id for repeating order or product_type_id for creating order');
return;
}
if (config.product_types?.length > 0 && config.product_id) {
console.error('[Expresta SDK] Cannot set both product_id and product_type_id.');
return;
}
url.searchParams.append("account", config.account);
url.searchParams.append("public_key", config.public_key);
if(!config.product_id){
config.product_types.forEach(product => {
url.searchParams.append(`product_type_id_${product.product_type_id}`, product.qty);
});
}
if(config.product_id){
let existingProductId = config.product_id;
let desiredQty = config.qty;
url.searchParams.append(`product_id_${existingProductId}`, desiredQty);
}
if(config.product_id){
if (config.document_url) url.searchParams.append("document_url", config.document_url);
if (config.page_range) url.searchParams.append("pdf_page_range", config.page_range);
if (config.preview_image_url) url.searchParams.append("preview_image_url", config.preview_image_url);
if (config.product_name) {
url.searchParams.append("product_name", config.product_name.substring(0, 60));
}
}
["utm_source", "utm_medium", "utm_campaign", "utm_content"].forEach(param => {
if (config[param]) url.searchParams.append(param, config[param]);
});
const button = document.createElement("a");
button.href = url.toString();
button.className = "expresta-order-link";
if (config.class == 'dark') button.classList.add("dark");
if (config.class == 'light') button.classList.add("light");
const text = document.createElement("span");
text.textContent = buttonText + " ";
const buttonTextParts = buttonText.split('%s');
const textBefore = document.createTextNode(buttonTextParts[0]);
const textAfter = document.createTextNode(buttonTextParts[1] || '');
const logo = document.createElement("img");
logo.src = config.class == 'dark' ?
"https://cdn.expresta.com/common/images/logos/logo-expresta-negative.svg" :
"https://cdn.expresta.com/common/images/logos/expresta.svg";
logo.alt = "Expresta";
logo.width = 98;
button.appendChild(textBefore);
button.appendChild(logo);
button.appendChild(textAfter);
const arrow = document.createElement("span");
arrow.innerHTML = '<svg width="9" height="21" viewBox="0 0 9 21"><path d="M1.15 18.36c-.09-.1-.14-.23-.14-.38 0-.15.05-.28.14-.38l6.2-7.02-6.2-7.02c-.09-.1-.14-.23-.14-.38s.05-.28.14-.38c.09-.1.2-.15.33-.15.13 0 .24.05.33.15l6.54 7.41c.09.1.14.24.14.38 0 .14-.05.28-.14.38L1.48 18.5c-.09.09-.2.15-.33.15-.13 0-.24-.06-.33-.15Z" fill="#333"/></svg>';
button.appendChild(arrow);
wrap.appendChild(button);
}
};
document.addEventListener('DOMContentLoaded', initExprestaOrderButtons);
// Initialize Expresta order buttons
function initExprestaOrderButtons() {
addButtonCSS();
const buttons = document.querySelectorAll('.expresta-order-button');
buttons.forEach(button => {
const lang = button.dataset.lang || 'en';
const config = configMap[lang] || configMap['en'];
const accountId = button.dataset.account;
const publicKey = button.dataset.public_key;
if (!accountId || !publicKey) {
console.error('[Expresta SDK] Missing required parameters.');
return;
}
const params = {
account: accountId,
'public_key': publicKey,
'utm_source': button.dataset.utm_source || '',
'utm_medium': button.dataset.utm_medium || '',
'utm_campaign': button.dataset.utm_campaign || '',
'utm_content': button.dataset.utm_content || ''
};
if(button.dataset.product_id){
params['document_url'] = button.dataset.document_url;
params['pdf_page_range'] = button.dataset.page_range;
params['preview_image_url'] = button.dataset.preview_image_url || '';
params['product_name'] = button.dataset.product_name
? button.dataset.product_name.substring(0, 60)
: '';
}
const productDivs = button.querySelectorAll('div[data-product_type_id]');
if (productDivs.length === 0 && !button.dataset.product_id) {
console.error('[Expresta SDK] You must set either product_id for repeating order or product_type_id for creating order');
return;
}
if (button.dataset.product_id && productDivs.length > 0) {
console.error('[Expresta SDK] Cannot set both product_id and product_type_id.');
return;
}
if(!button.dataset.product_id){
productDivs.forEach(product => {
const productId = product.dataset.product_type_id;
const qty = product.dataset.qty;
if (productId && qty) {
params[`product_type_id_${productId}`] = qty;
}
});
}
if(button.dataset.product_id){
let existingProductId = button.dataset.product_id;
let desiredQty = button.dataset.qty;
if (existingProductId && desiredQty) {
params[`product_id_${existingProductId}`] = desiredQty;
}
}
const endpoint = button.dataset.product_id ? "recreate-product" : "add-product";
const url = `https://www.${config.domain}/order/${endpoint}?${encodeParams(params)}`;
const link = document.createElement('a');
link.href = url;
// link.textContent = `${config.buttonText}`;
link.className = 'expresta-order-link' + ' ' + (button.classList.contains("dark") ? "dark" : "light");
const [textBefore, textAfter] = config.buttonText.split('%s');
link.appendChild(document.createTextNode(textBefore));
const logo = document.createElement("img");
logo.src = button.classList.contains("dark") ?
"https://cdn.expresta.com/common/images/logos/logo-expresta-negative.svg" :
"https://cdn.expresta.com/common/images/logos/expresta.svg";
logo.alt = "Expresta";
logo.width = 98;
link.appendChild(logo);
if (textAfter) link.appendChild(document.createTextNode(textAfter));
const arrow = document.createElement("span");
arrow.innerHTML = '<svg width="9" height="21" viewBox="0 0 9 21"><path d="M1.15 18.36c-.09-.1-.14-.23-.14-.38 0-.15.05-.28.14-.38l6.2-7.02-6.2-7.02c-.09-.1-.14-.23-.14-.38s.05-.28.14-.38c.09-.1.2-.15.33-.15.13 0 .24.05.33.15l6.54 7.41c.09.1.14.24.14.38 0 .14-.05.28-.14.38L1.48 18.5c-.09.09-.2.15-.33.15-.13 0-.24-.06-.33-.15Z" fill="#333"/></svg>';
link.appendChild(arrow);
button.replaceWith(link);
});
}
function encodeParams(params) {
return Object.keys(params)
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
.join('&');
}
function addButtonCSS() {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://cdn-stage.expresta.com/sdk/dist/css/buttons.min.css';
document.head.appendChild(link);
}
window.OrderButton = OrderButton;
console.log("[Expresta SDK] Loaded successfully.");