Outdoor Camping Radar Induction Alarm Camping Warning Anti-animal Alarm Device
Lowest price sale only for today! ! ! Our goods are authentic, with genuine patents, counterfeit must be investigated! Customers, please identify our products!
${function() {
const minInventory = parseInt('73');
const maxInventory = parseInt('138');
const randomInventory = Math.round(Math.random() * (maxInventory - minInventory)) + minInventory;
const customText = "Only {stock} item(s) left in stock!".replace(/\{stock\}/g, '' + randomInventory + '');
const barWidth = (randomInventory / maxInventory) * 100 + '%';
return `
`;
}()}
${function() {
const variantData = data.variant || {"id":"569ab440-48fb-4c48-96ee-28ca923a6961","product_id":"2dec4d4a-abe2-429b-8f0e-42734ecef867","title":"1 radar sensor\uff08need to be used with receiver\uff09","weight_unit":"kg","inventory_quantity":0,"sku":"","barcode":"","position":1,"option1":"1 radar sensor\uff08need to be used with receiver\uff09","option2":"","option3":"","note":"","image":{"src":"\/\/img.staticdj.com\/8ac5536afd4c5547e514433566b4f23c.jpg","path":"8ac5536afd4c5547e514433566b4f23c.jpg","width":800,"height":800,"alt":"","aspect_ratio":1},"wholesale_price":[{"price":29.99,"min_quantity":1}],"weight":"0","compare_at_price":"59.98","price":"29.99","retail_price":"59.98","available":true,"url":"\/products\/outdoor-camping-radar-induction-alarm-camping-warning-anti-animal-alarm-device?variant=569ab440-48fb-4c48-96ee-28ca923a6961","available_quantity":999999999,"options":[{"name":"STYLE","value":"1 radar sensor\uff08need to be used with receiver\uff09"}],"off_ratio":50,"flashsale_info":[],"sales":3022};
const saveType = "amount";
const productLabelDiscountOn = true;
return `
-
${saveType == 'percentage'
? `-${variantData.off_ratio}%`
: `-`
}
`;
}()}
The current produc does not participate any Rebate. Switch the participating product to check the design.
(This prompt will not be displayed on the client-side.)
var theme = window.C_SETTINGS && C_SETTINGS.theme && C_SETTINGS.theme.merchant_theme_name;
var isFlash = /Flash/gi.test(theme);
var isGeek = /Geek/gi.test(theme);
var isNova23 = /Nova 2023/gi.test(theme);
var isWind = /Wind/gi.test(theme);
var isOnePage = /OnePage/gi.test(theme);
var isHero = /Hero/gi.test(theme);
var isBoost = /Boost/gi.test(theme);
var isEva = /Eva/gi.test(theme);
var isFarida = /Farida/gi.test(theme);
var isPluto = /Pluto/gi.test(theme);
var isLifeStyle = /Life Style/gi.test(theme);
if(window.self === window.top) {
(window.disabled_exts ||=[]).push('product_detail_rebate');
}
class SpzRebateComponent extends SPZ.BaseElement {
constructor(element) {
super(element);
}
xhr_ = SPZServices.xhrFor(this.win);
viewport_ = this.getViewport();
action_ = null;
lang = document.documentElement.lang || 'en-US';
landPage = "\/promotions\/rebate\/";
pageType = 1;
cart = [];
initData = null;
rebateInfo = null;
renderData = null;
footerImage = `${this.win.SHOPLAZZA["image_domain"]}oss/operation/e8ebb03dbb710457ca3b4b6a70898ab2.svg`;
isLayoutSupported(layout) {
return layout == SPZCore.Layout.LOGIC;
}
buildCallback() {
this.initData = this.getProduct();
this.action_ = SPZServices.actionServiceForDoc(this.element);
this.registerAction("triggerGetRenderData", () => {
const event = SPZUtils.Event.create(this.win, "triggerGetRenderData", this.renderData);
this.action_.trigger(this.element, "getRenderData", event);
});
this.registerAction("bindPropagation", () => {
document.querySelector(".product_detail_rebate_list").addEventListener("click", e => {
e.stopPropagation();
this.win.sa &&
this.win.sa.track("plugin_rebate_promotion_click", {
plugin_timestamp: Date.now(),
plugin_location: "info",
product_id: this.initData.product.id,
discount_id: this.rebateInfo.discount_list.map((item) => item.discount_id)[0],
});
});
});
}
async mountCallback() {
document.addEventListener("dj.variantChange", e => {
const data = e.detail;
if (document.querySelector("#product-select-modal.show")) return;
this.initData = this.getProductJson(data);
if (this.initData && this.initData.product && data.product && this.initData.product.id === data.product.id) {
this.initRebate(this.initData, true);
} else {
this.getRebateInfo();
}
});
document.addEventListener("dj.addToCart", e => {
const v = e.detail;
this.rebateInfo &&
this.win.sa &&
this.win.sa.track("plugin_rebate_atc", {
variant_discount_id: this.getVariantDiscountId(v.variant_id).map(item => item.discount_id),
discount_ids: this.rebateInfo.discount_list.map(item => item.discount_id),
variant_id: v.variant_id,
product_id: v.product_id,
price: v.item_price,
number: v.number,
});
});
await this.getRebateInfo();
setTimeout(()=>{
if (document.querySelector(".plugin-container__bottom-fixed")) {
this.showDiscountPopupsInfoBar();
} else {
this.win.addEventListener("extloaded", () => {
this.showDiscountPopupsInfoBar();
});
}
},1000)
}
getProductJson = (mergeData = {}) => {
const productJson = document.querySelector("#product-json");
let productJsonData = {};
if (productJson && productJson.textContent) {
try {
productJsonData = JSON.parse(productJson.textContent);
} catch (e) {}
}
// 深度合并函数
const deepMerge = (target, source) => {
if (source === null || source === undefined) {
return target;
}
if (typeof source !== 'object' || Array.isArray(source)) {
return source;
}
const result = { ...target };
for (const key in source) {
if (source.hasOwnProperty(key)) {
if (
typeof source[key] === 'object' &&
source[key] !== null &&
!Array.isArray(source[key]) &&
typeof target[key] === 'object' &&
target[key] !== null &&
!Array.isArray(target[key])
) {
result[key] = deepMerge(target[key], source[key]);
} else {
result[key] = source[key];
}
}
}
return result;
};
return deepMerge(productJsonData, mergeData);
}
getProduct = (() => {
document.addEventListener("dj.variantChange", e => {
if (!e.detail || !e.detail.product) return;
let productJsonData = getProductJson(e.detail);
if (this.win.jQuery && this.win.jQuery.fn && this.win.jQuery(document).data("djproduct") && productJsonData) {
this.win.jQuery(document).data("djproduct", productJsonData);
}
});
return () => {
let productData = null;
if (this.win.jQuery && this.win.jQuery.fn) {
try {
let product = this.win.jQuery(document).data("djproduct");
if (product) {
productData = JSON.parse(JSON.stringify(product));
} else {
productData = null;
}
} catch (error) {
productData = null;
}
}
if (!productData) {
const productJson = document.querySelector("#product-json");
productData = (productJson && productJson.textContent && JSON.parse(productJson.textContent)) || null;
}
return productData;
};
})();
clearRebateInfoDom = () => {
// 1. 清除 apis.render 渲染的 DOM (app_rebate_section)
const rebateSection = document.getElementById('app_rebate_section');
if (rebateSection) {
const rebateRuleSection = rebateSection.querySelector('.rebate_rule_section');
if (rebateRuleSection) {
rebateRuleSection.remove();
}
}
// 2. 清除 templates_.renderTemplate 渲染的 DOM (app_rebate_block)
const rebateBlock = document.getElementById('app_rebate_block');
if (rebateBlock) {
const appRebateList = rebateBlock.querySelector('.app_rebate_list');
if (appRebateList) {
appRebateList.remove();
}
}
// 3. 清除 insertProductDetailRebateTag 插入的 DOM
// 清除所有 rebate-tag 元素
document.querySelectorAll('.slider-discount-tag.dj_skin_product_title.rebate-tag').forEach(tag => {
tag.remove();
});
// 移除 data-rebate-tag 属性
const productContainer = document.querySelector('.product-details, .product-details, .page_container, .product-images, [data-section-type="product"]');
if (productContainer && productContainer.hasAttribute('data-rebate-tag')) {
productContainer.removeAttribute('data-rebate-tag');
}
};
initRebate = this.win.SPZCore.Types.debounce(
this.win,
(async (data) => {
let discount_list = Object.assign([], this.rebateInfo?.discount_list);
/* 按子商品的多少对优惠信息进行排序 */
discount_list &&
discount_list.sort((a, b) => {
return b.variant_ids.length - a.variant_ids.length;
});
/* 选中子商品时 筛选子商品的优惠信息 */
if (data.selected && data.selected.id) {
discount_list = this.getVariantDiscountId(data.selected.id);
}
/* 无满减信息 */
if (!(discount_list && discount_list.length)) {
this.clearRebateInfoDom();
return;
}
const isSection = !!document.querySelector(
`div[data-section-type^="shoplazza://apps/publicapp/blocks/rebate"] #rebate_custom_component`
);
if (
(this.rebateInfo.rebate_type == "sku" && data && data.selected && data.selected.id) ||
this.rebateInfo.rebate_type == "spu"
) {
let nowLandpage = this.landPage;
if (discount_list[0]) {
nowLandpage = this.landPage + discount_list[0].discount_id || "";
}
const info = {
rebate: discount_list[0],
maxShowCount: this.win.innerWidth > 768 ? 3 : 1,
landPage: nowLandpage,
modalFooterImg: `url(${`${this.win.SHOPLAZZA["image_domain"]}oss/operation/e8ebb03dbb710457ca3b4b6a70898ab2.svg`})`,
};
this.renderData = info;
if(isSection) {
SPZ.whenApiDefined(
document.getElementById("app_rebate_section")
).then(apis => {
apis.render(info, true);
});
} else {
// 重新渲染 抖动问题处理
this.templates_ = SPZServices.templatesForDoc(this.element);
const rebateBlockHost = document.getElementById('app_rebate_block');
const newTplDom = await this.templates_.findAndRenderTemplate(rebateBlockHost, info)
const parentDiv = document.querySelector('#app_rebate_block');
const oldDom = parentDiv.querySelector('.app_rebate_list');
if(oldDom){
parentDiv.replaceChild(newTplDom, oldDom);
} else {
parentDiv.appendChild(newTplDom);
}
}
}
this.insertProductDetailRebateTag(this.rebateInfo.tag);
var pluginCurrencyEvent = new CustomEvent("plugin_currency_update");
document.dispatchEvent(pluginCurrencyEvent);
}).bind(this),
10
);
getRebateInfo = async () => {
if (this.initData && this.initData.product && this.initData.product.id) {
var variant_ids = this.initData.product.variants.map(variant => variant.id);
const res = await this.xhr_.fetchJson(
"\/api\/discount-rebate\/product-discount",
{
method: "POST",
body: {
product_id: this.initData.product.id,
product_type: this.initData.product.product_type,
variant_ids: variant_ids,
},
}
);
if (!SPZCore.Types.isEmptyObject(res.rebate_info)) {
res.rebate_info.tag = res.tag;
res.rebate_info.rebate_type = res.rebate_type;
this.rebateInfo = res.rebate_info;
this.initRebate(this.initData);
} else {
if (this.win.top !== this.win.self) {
const noActivity = document.getElementById("no-rebate-activity");
noActivity && (noActivity["style"].display = "block");
}
}
}
};
getVariantDiscountId = (variant_id) => {
if (!variant_id || !this.rebateInfo) return [];
var rebateId = this.rebateInfo.variant_discount_map[variant_id];
return this.rebateInfo.discount_list.filter(item => item.discount_id == rebateId) || [];
};
insertProductDetailRebateTag = (tag) => {
if (!tag) return
// 旧判断逻辑
const productSelectModal = document.querySelector('#product-select-modal');
if (productSelectModal && productSelectModal.classList.contains('show')) {
return;
}
setTimeout(() => {
var $tag_container = [];
if (isNova23) {
$tag_container = document.querySelectorAll('.product-details .product-images-container');
} else if (isFlash) {
$tag_container = document.querySelectorAll('.product-detail .product-images .product-main-images-container');
} else if (isGeek) {
$tag_container = document.querySelectorAll('.product-images #product-images-inner-container spz-carousel .i-spzhtml-slide-item');
} else if (isWind) {
$tag_container = document.querySelectorAll('.product-detail .product-images-container .i-spzhtml-slides-container');
} else if (isOnePage) {
$tag_container = document.querySelectorAll('.product-details .product-main-images');
} else if (isHero) {
$tag_container = document.querySelectorAll('.product-detail #product-images-container #product-images-carousel .spz-carousel-slide');
} else if (isBoost) {
$tag_container = document.querySelectorAll('.boost-product-detail .product-image__layout-list .slides .slides-item .product-info__slide .slider-zoom');
} else if (isEva) {
$tag_container = document.querySelectorAll('.page_container [data-section-type="product"] .support-slick');
} else if (isFarida) {
$tag_container = document.querySelectorAll('.product-details .product-images-container');
} else if (isLifeStyle) {
$tag_container = document.querySelectorAll('.page_container [data-section-type="product_detail"] .sep-slider,.support-slick');
} else if (isPluto) {
$tag_container = document.querySelectorAll('.page_container [data-section-type="product_detail"] .sep-slider,.support-slick');
}
if($tag_container.length === 0) return;
// 给商祥页添加满送插件的标识属性
const $product_container = document.querySelector('.product-details, .product-details, .page_container, .product-images, [data-section-type="product"]')
if($product_container) {
$product_container.setAttribute('data-rebate-tag', 'true');
}
// 部分主题需要调整样式
if (isWind) {
Array.from($tag_container).forEach(container => {
container.style.position = 'relative';
});
}
document.querySelectorAll('.slider-discount-tag.dj_skin_product_title.rebate-tag').forEach(tag => tag.remove());
// 遍历所有容器并插入标签
Array.from($tag_container).forEach(container => {
container.insertAdjacentHTML('beforeend', `<div class="slider-discount-tag dj_skin_product_title rebate-tag">${tag}</div>`);
});
}, 1000)
};
fetchInfoBar = async () => {
let discount_ids = [];
if (this.pageType === 1) {
discount_ids = this.rebateInfo && this.rebateInfo.discount_list.map(item => item.discount_id);
} else if (this.pageType === 38) {
discount_ids = [this.win.rebateObj.rebateCollection_id] || [];
}
const productObj = this.getProduct();
const { cart } = await this.xhr_.fetchJson('/api/cart')
return this.xhr_.fetchJson("\/api\/discount-rebate\/global-text", {
method: "POST",
body: {
product_type: productObj && productObj.product && productObj.product.product_type,
line_items: (cart?.line_items || []).map(item => ({
variant_id: item.variant_id,
product_id: item.product_id,
quantity: item.quantity,
price: item.price,
selected: !item.unchecked,
})),
discount_ids: discount_ids,
},
});
};
renderBottomBanner = res => {
if (!res.tips) return;
document.querySelector(".discount__info-bar")?.remove();
var bar_style = `background:linear-gradient(90deg,${res.config.background_color_start},${res.config.background_color_end}); color:${res.config.color};`;
let data = { tips: res.tips, landPage: this.landPage + res.id, bar_style };
const html = SPZCore.Dom.htmlFor(this.element);
const banner = html([
`<a impr="1" imprevt="1" id="rebate_bottom_bar" href=${data.landPage} class="discount__info-bar text-truncate" data-activity-type="rebate" style="${data.bar_style}">${data.tips}</a>`,
]);
document.querySelector(".plugin-container__bottom-fixed").appendChild(banner);
const pluginCurrencyEvent = new CustomEvent("plugin_currency_update");
document.dispatchEvent(pluginCurrencyEvent);
if (res.id) {
var trackParams = {
page: this.pageType,
discount_id: res.id,
product_id: this.getProduct()?.product.id,
};
banner.addEventListener("click", () => {
this.win.sa &&
this.win.sa.track("plugin_rebate_promotion_click", {
plugin_timestamp: Date.now(),
plugin_location: "bottom_bar",
product_id: trackParams.product_id,
discount_id: trackParams.discount_id,
});
});
this.win.sa && this.win.sa.track("plugin_rebate_banner_pv", trackParams);
}
};
showDiscountPopupsInfoBar = () => {
if ([13, 14, 19, 30, 31].includes(this.pageType)) return;
if (document.querySelector(".plugin-container__bottom-fixed .discount__info-bar")) return;
this.fetchInfoBar().then(this.renderBottomBanner);
document.addEventListener("dj.cartChange", () => {
this.fetchInfoBar().then(this.renderBottomBanner);
});
};
}
SPZ.defineElement("spz-custom-rebate", SpzRebateComponent);
${function(){
const tipText = "Please select a {{ name }}".replace(/\{\{\s+name\s+\}\}/g, data);
return `${tipText}
`
}()}
Product was out of stock.
Product is unavailable.
const getPluginI18nMessages = (message, replaceObj = {}) => {
const lang = document.documentElement.lang || "en-US";
const [form, key] = message.split('.')
let text = window.payment_plugin_message['en-US'][form][key];
if (window.payment_plugin_message[lang][form].hasOwnProperty(key)) {
text = window.payment_plugin_message[lang][form][key];
}
Object.keys(replaceObj).forEach(key => {
text = text.replace(new RegExp(`\{${key}\}`, 'gi'), replaceObj[key]);
})
return text;
}
const zhCN = {
ec: {
not_active_channel: "请到收款设置中{channelName}或在「快捷支付按钮」设置中选择其他的服务提供方,否则按钮将无法展示",
not_support_theme: "当前主题不支持添加「快捷支付按钮」",
more_button: "更多支付方式",
skeleton_layer_tips_title: "快捷支付按钮",
skeleton_layer_tips_content: "请点击左侧列表中的「快捷支付按钮」,在设置页面开启想要的展示的支付按钮",
mock_tips: "快捷支付按钮是否展示还取决于买家使用的浏览器以及商品的货币、金额",
not_find_form_tips: "快捷支付按钮组件仅支持配置到商品详情卡片内",
legacy_discontinued_tips: "{channelName} 已下架,买家端将不再展示该按钮",
}
};
const zhTW = {
ec: {
not_active_channel: "请到收款设置中{channelName}或在「快捷支付按钮」设置中选择其他的服务提供方,否则按钮将无法展示",
not_support_theme: "当前主题不支持添加「快捷支付按钮」",
more_button: "更多付款方式",
}
};
const arSA = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "المزيد من خيارات الدفع",
}
};
const deDE = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "Weitere Bezahlmöglichkeiten",
}
};
const esES = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "Más opciones de pago",
}
};
const frFR = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "Plus d'options de paiement",
}
};
const idID = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "Opsi pembayaran lainnya",
}
};
const itIT = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "Altre opzioni di pagamento",
}
};
const jaJP = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "その他の支払いオプション",
}
};
const koKR = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "더 많은 결제 옵션",
}
};
const enUS = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "More payment options",
skeleton_layer_tips_title: "Express Checkout Button",
skeleton_layer_tips_content: "Please click the「Express checkout button」on the block list,then you could enable the payment option you want to display in settings.",
mock_tips: "Whether the Express checkout button is displayed also depends on the browser used by the buyer and the currency and amount of the product.",
not_find_form_tips: "Express Checkout Button could only be added to Product details block.",
legacy_discontinued_tips: "{channelName} has been deprecated and will no longer be displayed to buyers.",
}
};
const nlNL = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "Meer betalingsmogelijkheden",
}
};
const plPL = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "Więcej Opcji Płatności",
}
};
const ptPT = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "Mais opções de pagamento",
}
};
const ruRU = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "Другие варианты оплаты",
}
};
const thTH = {
ec: {
not_active_channel: "Please activate {channelName} on B Admin or select another provider in the「Express checkout button」 settings, otherwise it will not display.",
not_support_theme: "This Theme doesn't support adding「Express checkout button」",
more_button: "ตัวเลือกการชำระเงินเพิ่มเติม",
}
};
window.payment_plugin_message = {
getPluginI18nMessages,
"zh-CN": zhCN,
"zh-TW": zhTW,
"ar-SA": arSA,
"de-DE": deDE,
"es-ES": esES,
"fr-FR": frFR,
"id-ID": idID,
"it-IT": itIT,
"ja-JP": jaJP,
"ko-KR": koKR,
"en-US": enUS,
"nl-NL": nlNL,
"pl-PL": plPL,
"pt-PT": ptPT,
"ru-RU": ruRU,
"th-TH": thTH,
}
document.dispatchEvent(new CustomEvent('payment_plugin_message_reader'));
try {
const dom = document.getElementById('pm-payment-express-button-1539149753700-11');
dom.i18n = window?.payment_plugin_message?.getPluginI18nMessages;
if (dom.i18n) {
document.dispatchEvent(new CustomEvent('payment_ec_core_ready', {
detail: {
i18n: true
}
}))
} else {
document.addEventListener('payment_plugin_message_reader', () => {
dom.i18n = window?.payment_plugin_message?.getPluginI18nMessages;
document.dispatchEvent(new CustomEvent('payment_ec_core_ready', {
detail: {
i18n: true
}
}))
}, {once: true});
}
} catch (e) {
}
// 通用工具方法
try {
const dom = document.getElementById('pm-payment-express-button-1539149753700-11')
const ROOT_URL = (C_SETTINGS && C_SETTINGS.routes && C_SETTINGS.routes.root) || '';
const eventListeners = {};
const commonUtils = function () {
return {
getProduct() {
const productJson = document.querySelector('#product-json');
if (productJson?.textContent) {
return JSON.parse(productJson.textContent);
}
if (window.jQuery) {
const $product = window.jQuery?.(document)?.data('djproduct');
const productData = JSON.parse(JSON.stringify($product || {}));
return productData || {};
}
return {};
},
isChrome() {
return navigator?.userAgent?.indexOf('Chrome') > -1 || navigator?.userAgent?.indexOf('CriOS') > -1;
},
isSafari() {
let userAgentString = navigator.userAgent;
let chromeAgent = userAgentString.indexOf('Chrome') > -1 || navigator?.userAgent?.indexOf('CriOS') > -1;
let safariAgent = userAgentString.indexOf('Safari') > -1;
if (chromeAgent && safariAgent) {
safariAgent = false;
}
return safariAgent;
},
isPreview() {
return !!window?.C_EDITING_SETTINGS?.oseid;
},
multiply(a, b) {
const precision = 2; // 保留两位小数
return Number((a * b).toFixed(precision));
},
loadScript(fnReady, id, src, datasets, onError, attributeConfig = {}) {
const sdkDomId = id + '-sdk';
const loadedEventName = `${id}-loaded`;
if (fnReady()) {
return Promise.resolve({id: true});
}
const existingScript = document.getElementById(sdkDomId);
if (existingScript) {
return new Promise((resolve) => {
const handleLoaded = () => {
if (fnReady()) {
resolve({id: true});
} else {
resolve({id: false});
onError && onError();
}
};
if (existingScript.dataset.loaded === 'true') {
handleLoaded();
} else {
window.addEventListener(loadedEventName, handleLoaded, {once: true});
}
});
}
return new Promise((resolve) => {
const s = document.createElement('script');
s.id = sdkDomId;
s.src = src;
s.defer = true;
if (datasets) {
Object.keys(datasets).map((item) => {
s.dataset[item] = datasets[item];
});
}
s.onload = function () {
s.dataset.loaded = 'true';
window.dispatchEvent(new CustomEvent(loadedEventName));
resolve({id: true});
};
s.onerror = function () {
resolve({id: false});
onError && onError();
};
Object.keys(attributeConfig).forEach((key) => {
s.setAttribute(key, attributeConfig[key]);
});
document.head.appendChild(s);
});
},
track(eventName, data) {
window.sa && window?.sa?.track('pm_' + eventName, JSON.parse(JSON.stringify(data)));
},
getExtUrl(name) {
const url = document.cookie.match(new RegExp('\\b' + name.replace(/_/g, '-') + '-(v[s0-9]+)'));
if (url && url[1]) {
return `${name}.${url[1]}.js`;
} else {
return window?.exts?.[name];
}
},
req: {
post: async (url, data = {}) => {
try {
const response = await fetch(req.ROOT_URL + url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
...data,
body: JSON.stringify(data.body),
});
return await response.json()
} catch (error) {
throw new Error('post request error' + error);
}
},
get: async (url, data = {}) => {
try {
const response = await fetch(ROOT_URL + url);
return await response.json()
} catch (error) {
throw new Error('get request error' + error);
}
}
},
debounce(fn, wait) {
let timeout = null;
return function () {
if (timeout !== null) {
clearTimeout(timeout);
}
timeout = setTimeout(function () {
fn.apply(this, arguments);
}, wait);
}
},
delayCallback(cb) {
window.requestIdleCallback ? requestIdleCallback(cb, {timeout: 50}) : setTimeout(cb, 50);
},
loadFilly(tag, cb, trackEcPerfFn) {
if (!tag) {
return
}
const fireLoaded = function() {
if (trackEcPerfFn && !performance.getEntriesByName('ec_filly_load_end').length) {
performance.mark('ec_filly_load_end');
const fillyStart = performance.getEntriesByName('ec_filly_load_start')[0];
const channels = window?.C_SETTINGS?.payment_settings?.dynamic_config?.express_checkout_config?.express_channels || [];
trackEcPerfFn({
eventName: 'ec_perf_filly_load_end',
extraData: {
filly_load_time: fillyStart ? performance.now() - fillyStart.startTime : null,
payment_channel: channels.join(',')
},
eventType: 'card_expose'
});
}
cb && cb();
};
if (window.FillyEC) {
fireLoaded();
return;
}
const existing = document.querySelector('script[src*="' + tag + '"]');
if (existing) {
existing.addEventListener('load', fireLoaded, {once: true});
return;
}
const script = document.createElement('script');
script.type = 'text/javaScript';
script.src = `//static.staticdj.com/${tag}`;
script.onload = fireLoaded;
document.getElementsByTagName('head')[0].appendChild(script);
},
ecEvent: {
on: (eventName, listener, useCapture) => {
eventListeners[eventName] = listener;
window.addEventListener(eventName, listener, useCapture);
},
emit: (eventName, data) => window.dispatchEvent(new CustomEvent(eventName, {detail: data})),
},
trackEcPerf({ eventName, extraData, eventType }) {
const skeletonStart = performance.getEntriesByName('ec_skeleton_start')[0];
const sinceSkeletonStart = skeletonStart ? performance.now() - skeletonStart.startTime : null;
window.sa &&
window.sa.track('function_expose', {
function_name: 'payment_platform',
plugin_name: 'payment_platform',
business_type: 'product_payment',
module: 'payment',
module_type: 'payment_platform',
event_type: eventType || 'expose',
event_developer: 'cartoon',
event_info: JSON.stringify(
Object.assign(
{
process_name: eventName,
process_type: 'perf',
since_skeleton: sinceSkeletonStart
},
extraData || {}
)
)
});
}
}
}
dom.commonUtilsFn = commonUtils;
document.dispatchEvent(new CustomEvent('payment_ec_core_ready', {
detail: {
commonUtils: true
}
}))
} catch (e) {
}
// 核心数据
try {
const dom = document.getElementById('pm-payment-express-button-1539149753700-11');
const coreData = function () {
const {getProduct} = dom.commonUtils;
let productDetail = getProduct();
let productPrice = productDetail?.selected?.price
|| 29.99;
const shopCurrencyCode = "USD";
const expressCheckoutList = {
sdkErrorList: [],
paymentChannelList: [],
disabledChannelList: [],
showChannelList: [],
blockChannelList: [],
extraChannelList: [],
};
const channelType = {
googlepay: ['shoplazzagoogle'],
applepay: ['shoplazzaapple'],
credit: ['paypal']
};
const ecGlobalVarEnums = {
paypal: 'pluginPaypalEC'
};
const providerEnums = {
SHOPLAZZA: 'shoplazza',
STRIPE: 'stripe',
PAYPAL: 'paypal'
};
const channelEnums = {
SHOPLAZZA_GOOGLE: 'shoplazzagoogle',
SHOPLAZZA_APPLE: 'shoplazzaapple',
STRIPE_GOOGLE: 'stripegoogle',
STRIPE_APPLE: 'stripeapple',
PAYPAL: 'paypal'
};
const channelThemeConfig = {
[channelEnums.PAYPAL]: {
default: {
url: 'oss/operation/f557c83808e1cd456411170286a1ea95.svg',
classList: ['paypal-card'],
},
},
[channelEnums.SHOPLAZZA_GOOGLE]: {
light: {
url: 'oss/operation/778afb93da43adf75bdc80b078e5d4fd.svg',
classList: ['googlepay-light'],
},
dark: {
url: 'oss/operation/e53180c224f0b0af44b44663775aa930.svg',
classList: ['googlepay-dark'],
},
},
[channelEnums.SHOPLAZZA_APPLE]: {
light: {
url: 'oss/operation/dadceb884044e0a9bbfe26c15192f542.svg',
classList: ['applepay-light'],
},
dark: {
url: 'oss/operation/6597f66eac8b0681ebfb75941e8f6f52.svg',
classList: ['applepay-dark'],
},
},
};
function getContainerDomId() {
const domIDSuffix = '-express-button-container';
const prefix = 'pm-';
const formatId = (channel) => `${prefix}${channel}${domIDSuffix}-1539149753700-11`;
return {
[providerEnums.PAYPAL]: formatId(providerEnums.PAYPAL),
[channelEnums.SHOPLAZZA_GOOGLE]: formatId(channelEnums.SHOPLAZZA_GOOGLE),
[channelEnums.SHOPLAZZA_APPLE]: formatId(channelEnums.SHOPLAZZA_APPLE),
};
}
return {
ecGlobalVarEnums,
providerEnums,
channelEnums,
productPrice,
shopCurrencyCode,
getChannelThemeConfig(ecName) {
const themeType = window.PaymentEC?.settings?.express_theme_configs?.[ecName]?.theme_type?.toLowerCase() ||
'default';
return channelThemeConfig[ecName][themeType] || channelThemeConfig[ecName]['dark'];
},
getProductPrice() {
return productDetail?.selected?.price;
},
getProductDetail() {
return productDetail;
},
setProductDetail(data) {
productDetail = data;
},
isRequiresShipping() {
return productDetail?.product?.requires_shipping
},
getOpenChannelType() {
const {paymentChannelList, blockChannelList} = expressCheckoutList
const openList = paymentChannelList.filter(item => blockChannelList.includes(item)) || [];
return {
hasApplepay: openList.filter(item => channelType.applepay.includes(item))?.length > 0,
hasGooglepay: openList.filter(item => channelType.googlepay.includes(item))?.length > 0,
hasCredit: openList.filter(item => channelType.credit.includes(item))?.length > 0
}
},
containerDomId: getContainerDomId(),
channel2ProviderEnums: {
[channelEnums.PAYPAL]: channelEnums.PAYPAL,
[channelEnums.SHOPLAZZA_GOOGLE]: channelEnums.SHOPLAZZA_GOOGLE,
[channelEnums.SHOPLAZZA_APPLE]: channelEnums.SHOPLAZZA_APPLE,
[channelEnums.STRIPE_GOOGLE]: providerEnums.STRIPE,
[channelEnums.STRIPE_APPLE]: providerEnums.STRIPE,
},
getExpressCheckoutList() {
return expressCheckoutList;
},
setShowChannel(showChannelList = []) {
expressCheckoutList.showChannelList = showChannelList;
return expressCheckoutList;
},
setBlockChannel(blockChannelList = []) {
expressCheckoutList.blockChannelList = blockChannelList;
return expressCheckoutList;
},
setPaymentChannelList(paymentChannelList = []) {
expressCheckoutList.paymentChannelList = paymentChannelList;
return expressCheckoutList;
},
setSdkErrorList(paymentChannelList = []) {
expressCheckoutList.sdkErrorList = paymentChannelList;
return expressCheckoutList;
},
setExtraChannelList(extraChannelList = []) {
expressCheckoutList.extraChannelList = extraChannelList;
return expressCheckoutList;
},
setDisabledChannelList(disabledChannelList = []) {
expressCheckoutList.disabledChannelList = disabledChannelList;
return expressCheckoutList;
}
}
}
dom.coreDataFn = coreData;
document.dispatchEvent(new CustomEvent('payment_ec_core_ready', {
detail: {
coreData: true
}
}))
} catch (e) {
console.log(e);
}
// 通用业务数据处理方法
try {
const dom = document.getElementById('pm-payment-express-button-1539149753700-11')
const businessUtils = function () {
const {track, isChrome, isSafari, req, isPreview, multiply, loadScript, trackEcPerf} = dom.commonUtils;
const {getProductPrice, containerDomId, ecGlobalVarEnums, channelType, getOpenChannelType} = dom.coreData;
const {
channelEnums,
shopCurrencyCode,
isRequiresShipping,
getProductDetail,
setShowChannel,
setBlockChannel,
setSdkErrorList,
setExtraChannelList,
setDisabledChannelList,
setPaymentChannelList,
getExpressCheckoutList
} = dom.coreData;
const _businessUtils = {
getECConfig: async () => {
if (window.PaymentEC?.settings) {
return window.PaymentEC?.settings;
}
// 优先从 C_SETTINGS 获取 express_checkout_config
let ecConfig = window?.C_SETTINGS?.payment_settings?.dynamic_config?.express_checkout_config;
// 如果 C_SETTINGS 中没有,使用接口请求作为兜底
if (!ecConfig) {
const result = await req.get('/api/payment/settings');
ecConfig = result?.settings?.express_checkout_config || {};
}
const {blockChannelList} = getExpressCheckoutList();
const filteredExpressChannels = blockChannelList.filter(ecName =>
ecConfig?.express_channels?.includes(ecName)) || [];
setPaymentChannelList(filteredExpressChannels);
window.PaymentEC.settings = {
...ecConfig,
express_channels: filteredExpressChannels,
currencyCode: shopCurrencyCode
};
return window.PaymentEC.settings;
},
getAttributeConfig(channelInfo) {
const {ecGlobalVar, ecName} = channelInfo;
const config = {
paypal: {
'data-namespace': ecGlobalVar
}
};
return config[ecName] || {};
},
getThemeFormData() {
let themeFormData = {};
const formDOM = dom.closest("form");
if (formDOM) {
themeFormData = {
note: '',
product_id: '',
variant_id: '',
quantity: 1,
properties: {},
};
const formData = new FormData(formDOM);
const formDataKey = formData.keys();
for (const key of formDataKey) {
const value = formData.get(key);
const propertiesKey = key.match(/^properties(?:\.(\w+)$|\[(\w+)\]$)/);
if (!propertiesKey) {
themeFormData[key] = value;
continue;
}
const objKey = propertiesKey[1] || propertiesKey[2];
themeFormData['properties'] = {...themeFormData['properties'], [objKey]: value};
}
}
if (isPreview() && (!themeFormData.product_id || !themeFormData.variant_id)) {
const previewProduct = (dom.commonUtils.getProduct() || {}).product;
if (previewProduct) {
themeFormData.product_id = themeFormData.product_id || previewProduct.id;
const previewVariant = previewProduct.selected_or_first_available_variant || (previewProduct.variants || [])[0];
themeFormData.variant_id = themeFormData.variant_id || (previewVariant && previewVariant.id);
}
}
return themeFormData;
},
getProductFormData() {
const themeFormData = _businessUtils.getThemeFormData()
return [{
...themeFormData,
note: themeFormData?.note || "",
product_id: themeFormData?.product_id || "",
variant_id: themeFormData?.variant_id || "",
quantity: themeFormData?.quantity || 1,
// 与主题确认,只以一个为准,防止form不存在的数据仍被传递
properties: themeFormData?.properties || {},
}]
},
getOrderFetchParams(data) {
if (!data) {
return {};
}
return {
line_items: data.map((item) => ({
...item,
note: item?.note || "",
quantity: item?.quantity || 1,
product_id: item?.product_id,
variant_id: item?.variant_id,
properties: item?.properties,
})),
refer_info: {
source: 'buy_now',
},
customer_note: '',
};
},
isAllowTheme() {
const allowThemeList = ['Nova 2023', 'Dropshiping', 'Geek', 'Hero', 'Eva'];
const currentTheme = window?.C_SETTINGS?.theme?.merchant_theme_name;
return allowThemeList.includes(currentTheme);
},
getSubscriptionIdInit() {
let defaultID;
const selectSubscriptionEnum = {
CLOSE: 1,
ACTIVE: 2,
}
const productDetail = getProductDetail();
const sellingPlan = "";
if (!sellingPlan || typeof sellingPlan !== "object") {
return null;
}
let sellingItems;
if (sellingPlan?.spu?.[productDetail?.product?.id]) {
sellingItems = sellingPlan.spu[productDetail?.product?.id]
}
if (sellingPlan?.sku?.[productDetail?.selected?.id]) {
sellingItems = sellingPlan.sku[productDetail?.product?.id]
}
if (sellingItems?.cycles === selectSubscriptionEnum.ACTIVE && sellingItems?.selected_selling_plan_option_id) {
defaultID = sellingItems?.selected_selling_plan_option_id
}
return defaultID ?? null
},
getSubscriptionId() {
const formData = _businessUtils.getThemeFormData();
const defaultID = _businessUtils.getSubscriptionIdInit();
console.log(`[paymentEC]订阅信息:form-${formData?.properties?._selling_plan_option_id},默认-${defaultID}`);
if (formData?.properties) {
return formData?.properties?._selling_plan_option_id
}
return defaultID ?? null;
},
isSubscription() {
return !!_businessUtils.getSubscriptionId();
},
isAllowSubscriptionPay(channel) {
if (!_businessUtils.isSubscription()) {
return true;
}
return [channelEnums.PAYPAL].includes(channel);
},
checkApplePayAvailability(channel) {
let available = false;
let reason = 'no_session';
const isApplePay = channelType?.applepay?.includes?.(channel);
if(!isApplePay){
return true;
}
if (window.ApplePaySession) {
if (window.ApplePaySession.canMakePayments()) {
available = true;
reason = 'available';
} else {
reason = 'cannot_make_payments';
}
}
trackEcPerf({
eventName: 'ec_applepay_availability_check',
extraData: {
available: available,
reason: reason,
layer: 'pike_init',
payment_channel: channel
},
eventType: 'expose'
});
return available;
},
getEcLegacyLists() {
const dc = window?.C_SETTINGS?.payment_settings?.dynamic_config || {};
const asArray = (v) => (Array.isArray(v) ? v : []);
return {
ec_legacy_apple_pay_block_store_ids: asArray(dc.ec_legacy_apple_pay_block_store_ids),
ec_legacy_google_pay_block_store_ids: asArray(dc.ec_legacy_google_pay_block_store_ids)
};
},
isLegacyShopKept(storeIds) {
const legacyShopId = String(window?.C_SETTINGS?.shop?.shop_id || '');
return Array.isArray(storeIds) &&
storeIds.some((id) => !!legacyShopId && String(id).trim() === legacyShopId);
},
getLegacyDiscontinuedChannels() {
const legacyCfg = _businessUtils.getEcLegacyLists();
const discontinued = [];
if (true &&
!_businessUtils.isLegacyShopKept(legacyCfg?.ec_legacy_google_pay_block_store_ids)) {
discontinued.push('Google Pay');
}
if (true &&
!_businessUtils.isLegacyShopKept(legacyCfg?.ec_legacy_apple_pay_block_store_ids)) {
discontinued.push('Apple Pay');
}
return discontinued;
},
blockChannelHandler() {
const legacyCfg = _businessUtils.getEcLegacyLists();
const keepApple = _businessUtils.isLegacyShopKept(legacyCfg?.ec_legacy_apple_pay_block_store_ids);
const keepGoogle = _businessUtils.isLegacyShopKept(legacyCfg?.ec_legacy_google_pay_block_store_ids);
const block_googlePay = keepGoogle &&
true &&
"shoplazzagoogle";
const block_applePay = keepApple &&
true &&
"shoplazzaapple";
const block_credit = true &&
"paypal";
const blockChannel = {
googlepay: block_googlePay,
applepay: block_applePay,
credit: block_credit
};
if (!isPreview()) {
const expressChannels = window?.C_SETTINGS?.payment_settings?.dynamic_config?.express_checkout_config?.express_channels || [];
const hasStripe = (keepApple || keepGoogle) &&
(expressChannels.includes('shoplazzagoogle') || expressChannels.includes('shoplazzaapple'));
const {hasApplepay} = getOpenChannelType();
if (hasStripe) {
loadScript(() => window.Stripe, 'Stripe', 'https://js.stripe.com/v3/');
}
if (hasApplepay) {
loadScript(() => {
const hasAppURL = document.getElementById('applepay-sdk');
return !!hasAppURL;
}, 'applepay', 'https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js');
}
}
const sortList = ['credit', 'googlepay', 'applepay'];
const methodSort = Object.keys(blockChannel).filter(key => blockChannel[key] && key).sort((a, b) => {
const indexA = sortList.indexOf(a);
const indexB = sortList.indexOf(b);
return indexA - indexB;
}).map(key => blockChannel[key]);
const result = setBlockChannel(methodSort);
track('setBlockChannel', result);
return result;
},
showECButtonHandler() {
const {
paymentChannelList,
sdkErrorList,
disabledChannelList,
extraChannelList,
} = getExpressCheckoutList();
const showChannelList = paymentChannelList.filter((ecName) =>
!sdkErrorList.includes(ecName) && !disabledChannelList.includes(ecName) &&
!extraChannelList.includes(ecName)) || [];
const result = setShowChannel(showChannelList);
track('showECButton', result);
return result;
},
filterECButtonHandler({type}, cb) {
const {
paymentChannelList,
sdkErrorList,
disabledChannelList,
extraChannelList,
} = getExpressCheckoutList();
const showChannelList = paymentChannelList.filter((ecName) =>
!sdkErrorList.includes(ecName) && !disabledChannelList.includes(ecName) &&
!extraChannelList.includes(ecName)) || [];
const result = setShowChannel(showChannelList.filter((ecName) => ecName !== type) || []);
cb && cb();
track('filterECButton', result);
return result;
},
loadSDKErrorHandler(type) {
const {sdkErrorList} = getExpressCheckoutList();
const result = setSdkErrorList([...sdkErrorList, type]);
track('loadSDKError', result);
return result;
},
extraFilterShowHandler(channel) {
const {extraChannelList} = getExpressCheckoutList();
const result = setExtraChannelList(extraChannelList.filter(ecName => ecName !== channel));
track('extraFilterEvent_show', result);
return result;
},
extraFilterHideHandler(channel) {
const {extraChannelList} = getExpressCheckoutList();
const result = setExtraChannelList([...extraChannelList, channel]);
track('extraFilterEvent_hide', result);
return result;
},
disabledChannelListHandler(checkoutData = {}, cb) {
const {paymentChannelList} = getExpressCheckoutList();
const productDetail = getProductDetail();
const disabledChannelList = paymentChannelList.filter(ecName => {
let mustDisable = false;
if(!_businessUtils.checkApplePayAvailability(ecName)){
mustDisable = true;
}
if (!isRequiresShipping() && ecName !== channelEnums.PAYPAL) {
mustDisable = true;
}
if (!_businessUtils.isAllowSubscriptionPay(ecName)) {
mustDisable = true;
}
if (!productDetail?.selected?.available) {
mustDisable = true;
}
const {payment_due} = checkoutData?.prices;
const paymentDueNum = Number(payment_due || 0) * 100;
const showFlag = paymentDueNum > 0;
return mustDisable || !showFlag;
})
const result = setDisabledChannelList(disabledChannelList)
result?.disabledChannelList?.forEach(ecName => {
cb && cb(ecName);
})
track('disabledChannelListEvent', result);
},
async getCheckoutData() {
const formData = _businessUtils.getProductFormData();
const totalPrice = multiply(getProductPrice(), formData?.[0]?.quantity || 0);
return {
prices: {payment_due: totalPrice, subtotal_price: totalPrice},
orderParams: _businessUtils.getOrderFetchParams(_businessUtils.getProductFormData()),
containerDOMIdEnums: containerDomId,
ecGlobalVarEnums,
paymentMode: _businessUtils.isSubscription() ? 'subscription' : 'payment'
}
},
}
return _businessUtils
}
dom.businessUtilsFn = businessUtils;
document.dispatchEvent(new CustomEvent('payment_ec_core_ready', {
detail: {
businessUtils: true
}
}))
} catch (e) {
}
// 通用渲染方法
try {
const dom = document.getElementById('pm-payment-express-button-1539149753700-11');
const containerDOM = 'pm-payment-express-button-container-1539149753700-11';
const commonRenderUtils = function () {
return {
addChildrenDOM(id, allowShow, options = {}) {
if (!id) {
return;
}
const paymentEl = document.getElementById(containerDOM);
const childrenEL = document.getElementById(id);
if (paymentEl && childrenEL) {
childrenEL.style.display = allowShow ? 'block' : 'none';
return;
}
if (paymentEl && !childrenEL) {
const dom = document.createElement('div');
dom.id = id;
dom.style.display = allowShow ? 'block' : 'none';
if (options?.style) {
Object.keys(options?.style).forEach(key => {
dom.style[key] = options.style[key];
})
}
if (Array.isArray(options?.classList)) {
dom.classList.add(...options.classList)
}
paymentEl.appendChild(dom);
}
},
removeChildrenDOM(id) {
if (!id) {
return;
}
const paymentEl = document.getElementById(containerDOM);
const childrenEL = document.getElementById(id);
if (paymentEl && childrenEL) {
// childrenEL.remove();
childrenEL.style.display = 'none';
}
},
mockAddChildrenDOM(id, allowShow, options = {}) {
if (!id) {
return;
}
const paymentEl = document.getElementById(containerDOM);
const childrenEL = document.getElementById(id);
if (paymentEl && childrenEL) {
childrenEL.style.display = allowShow ? 'flex' : 'none';
return;
}
if (paymentEl && !childrenEL) {
const dom = document.createElement('div');
dom.id = id;
dom.style.display = allowShow ? 'flex' : 'none';
if (options?.style) {
Object.keys(options?.style).forEach(key => {
dom.style[key] = options.style[key];
})
}
if (Array.isArray(options?.classList)) {
dom.classList.add(...options.classList)
}
dom.classList.add('mock-img');
const img = document.createElement('img');
img.src = `//static.staticdj.com/${options?.url}`;
dom.appendChild(img);
paymentEl.appendChild(dom);
}
},
resetRenderDOM() {
const resetStyleList = [
"pm-payment-express-error-tips-1539149753700-11",
"pm-payment-express-more-button-1539149753700-11",
"pm-payment-express-mock-tips-1539149753700-11",
"pm-payment-express-skeletonLayer-1539149753700-11",
]
const resetHtmlList = [
"pm-payment-express-skeletonLayer-title-content-1539149753700-11",
"pm-payment-express-skeletonLayer-content-1539149753700-11",
"pm-payment-express-mock-tips-1539149753700-11",
"pm-payment-express-error-tips-1539149753700-11",
"pm-payment-express-button-container-1539149753700-11",
"pm-payment-express-more-button-1539149753700-11",
]
resetStyleList.forEach(domID => {
const content = document.getElementById(domID);
if (content) {
content.style.display = 'none';
}
})
resetHtmlList.forEach(domID => {
const content = document.getElementById(domID);
if (content) {
content.innerHTML = '';
}
})
}
}
}
dom.commonRenderUtilsFn = commonRenderUtils;
document.dispatchEvent(new CustomEvent('payment_ec_core_ready', {
detail: {
commonRenderUtils: true
}
}))
} catch (e) {
}
// 错误提示渲染
try {
const dom = document.getElementById('pm-payment-express-button-1539149753700-11');
const renderTipsUtils = function () {
const {i18n} = dom;
const {isPreview} = dom.commonUtils;
const {channelEnums} = dom.coreData;
return {
showChannelNotOpenTips(channelList) {
const tipsDom = document.getElementById('pm-payment-express-error-tips-1539149753700-11');
if (!isPreview()) {
return;
}
if (!tipsDom) {
return;
}
tipsDom.style.display = channelList.length > 0 ? 'block' : 'none';
const channelName = {
[channelEnums.SHOPLAZZA_GOOGLE]: "ShoplazzaPayments - GooglePay",
[channelEnums.SHOPLAZZA_APPLE]: "ShoplazzaPayments - ApplePay",
[channelEnums.PAYPAL]: "PayPal",
}
channelList.forEach(ecName => {
const id = `pm-payment-express-error-tips-1539149753700-11-${ecName}`;
const hasDom = document.getElementById(id)
if (!hasDom) {
const dom = document.createElement('div');
dom.id = id;
dom.innerHTML = i18n('ec.not_active_channel', {channelName: channelName[ecName]});
tipsDom.appendChild(dom);
}
})
},
disabledThemTips() {
const tipsDom = document.getElementById('pm-payment-express-error-tips-1539149753700-11');
if (!isPreview()) {
return;
}
if (!tipsDom) {
return;
}
tipsDom.style.display = 'block';
const id = 'pm-payment-express-error-tips-1539149753700-11-theme';
const hasDom = document.getElementById(id);
if (!hasDom) {
const dom = document.createElement('div');
dom.id = id;
dom.innerHTML = i18n('ec.not_support_theme');
tipsDom.appendChild(dom);
}
},
notFindFormTips() {
const tipsDom = document.getElementById('pm-payment-express-error-tips-1539149753700-11');
if (!isPreview()) {
return;
}
if (!tipsDom) {
return;
}
tipsDom.style.display = 'block';
const id = 'pm-payment-express-error-tips-1539149753700-11-theme';
const hasDom = document.getElementById(id);
if (!hasDom) {
const dom = document.createElement('div');
dom.id = id;
dom.innerHTML = i18n('ec.not_find_form_tips');
tipsDom.appendChild(dom);
}
},
showSkeletonLayerTips() {
const skeletonLayerDOMId = 'pm-payment-express-skeletonLayer-1539149753700-11';
const skeletonLayerDOM = document.getElementById(skeletonLayerDOMId);
const titleDOM = document.getElementById('pm-payment-express-skeletonLayer-title-content-1539149753700-11');
const contentDOM = document.getElementById('pm-payment-express-skeletonLayer-content-1539149753700-11');
if (!skeletonLayerDOM || !titleDOM || !contentDOM) {
return;
}
skeletonLayerDOM.style.display = 'block';
titleDOM.innerHTML = i18n('ec.skeleton_layer_tips_title');
contentDOM.innerHTML = i18n('ec.skeleton_layer_tips_content');
},
showMockTips() {
const tipsDOM = document.getElementById('pm-payment-express-mock-tips-1539149753700-11');
if (!tipsDOM) {
return;
}
tipsDOM.style.display = 'block';
tipsDOM.innerHTML = i18n('ec.mock_tips');
},
showLegacyDiscontinuedTips(channelNames) {
const tipsDom = document.getElementById('pm-payment-express-error-tips-1539149753700-11');
if (!isPreview()) {
return;
}
if (!tipsDom || !channelNames?.length) {
return;
}
tipsDom.style.display = 'block';
channelNames.forEach((channelName) => {
const id = `pm-payment-express-error-tips-1539149753700-11-discontinued-${channelName.replace(/\s/g, '')}`;
const hasDom = document.getElementById(id);
if (!hasDom) {
const dom = document.createElement('div');
dom.id = id;
dom.innerHTML = i18n('ec.legacy_discontinued_tips', {channelName});
tipsDom.appendChild(dom);
}
});
}
}
}
dom.renderTipsUtilsFn = renderTipsUtils;
document.dispatchEvent(new CustomEvent('payment_ec_core_ready', {
detail: {
renderTipsUtils: true
}
}))
} catch (e) {
}
// 更多信息渲染
try {
const dom = document.getElementById('pm-payment-express-button-1539149753700-11');
const moreDOM = document.getElementById('pm-payment-express-more-button-1539149753700-11');
const moreButtonConfig = {
firstClick: true,
maxSize: isNaN(2) ? 1 : 2
};
const renderMoreUtils = function () {
const {i18n} = dom;
const {getExpressCheckoutList, channelEnums} = dom.coreData;
function moreButtonEvent(cb) {
if (!moreDOM) {
return;
}
moreDOM.style.display = 'none';
moreButtonConfig.firstClick = false;
cb && cb();
}
return {
getMoreButtonConfig() {
return moreButtonConfig
},
showMoreButton(cb) {
if (!moreDOM) {
return;
}
let {showChannelList} = getExpressCheckoutList();
const showLength = showChannelList.length;
const {firstClick, maxSize} = moreButtonConfig;
moreDOM.style.display = (firstClick && showLength > 0 && showLength > maxSize) ? 'block' : 'none';
moreDOM.innerHTML = i18n('ec.more_button');
moreDOM.onclick = () => moreButtonEvent(cb);
},
}
}
dom.renderMoreUtilsFn = renderMoreUtils;
document.dispatchEvent(new CustomEvent('payment_ec_core_ready', {
detail: {
renderMoreUtils: true
}
}))
} catch (e) {
}
try {
const dom = document.getElementById('pm-payment-express-button-1539149753700-11');
function start() {
const {
getExtUrl,
loadFilly,
delayCallback,
ecEvent,
track,
loadScript,
debounce,
trackEcPerf
} = dom.commonUtils;
const {
blockChannelHandler,
getAttributeConfig,
showECButtonHandler,
filterECButtonHandler,
loadSDKErrorHandler,
extraFilterShowHandler,
extraFilterHideHandler,
disabledChannelListHandler,
getECConfig,
isAllowTheme,
getCheckoutData,
getThemeFormData
} = dom.businessUtils;
const {addChildrenDOM, removeChildrenDOM} = dom.commonRenderUtils;
const {getMoreButtonConfig, showMoreButton} = dom.renderMoreUtils;
const {
ecGlobalVarEnums,
providerEnums,
channelEnums,
getExpressCheckoutList,
getProductPrice,
getProductDetail,
setProductDetail,
containerDomId,
channel2ProviderEnums,
getChannelThemeConfig
} = dom.coreData;
const expressChannels = window?.C_SETTINGS?.payment_settings?.dynamic_config?.express_checkout_config?.express_channels || [];
if (!performance.getEntriesByName('ec_skeleton_start').length) {
performance.mark('ec_skeleton_start');
trackEcPerf({
eventName: 'ec_perf_skeleton_start',
extraData: {
page_start: performance.now(),
payment_channel: expressChannels.join(',')
},
eventType: 'card_expose'
});
}
function getFilly() {
if (!performance.getEntriesByName('ec_filly_load_start').length) {
performance.mark('ec_filly_load_start');
trackEcPerf({
eventName: 'ec_perf_filly_load_start',
extraData: {
payment_channel: expressChannels.join(',')
},
eventType: 'card_expose'
});
}
const fillyTag = getExtUrl('filly');
if (fillyTag) {
loadFilly(fillyTag, init, trackEcPerf);
}
}
function extraFilterEvent(e) {
const {channel, domId, allowShow} = e?.detail || {};
if (channel && domId) {
if (allowShow) {
extraFilterShowHandler(channel);
const container = document.getElementById(domId);
if (container) {
container.style.border = 'none';
container.style.backgroundColor = 'transparent';
}
} else {
extraFilterHideHandler(channel);
filterECButtonHandler({type: channel},
() => removeChildrenDOM(domId)
);
}
renderEC();
}
}
const renderEC = () => {
showECButtonHandler();
const expressCheckoutList = getExpressCheckoutList();
var {showChannelList} = expressCheckoutList;
const {firstClick, maxSize} = getMoreButtonConfig();
if (showChannelList.length === 0) {
showMoreButton(renderEC);
}
showChannelList.forEach((ecName, index) => {
const disableShow = firstClick && index >= maxSize;
const containerId = containerDomId[channel2ProviderEnums[ecName]];
addChildrenDOM(containerId, !disableShow, getChannelThemeConfig(ecName));
showMoreButton(renderEC);
});
}
const loadErrorEvent = (type) => {
const domID = containerDomId[type];
if (!domID) {
return;
}
loadSDKErrorHandler(type);
filterECButtonHandler({type},
() => removeChildrenDOM(domID)
);
showMoreButton(renderEC);
};
async function loadEC() {
const themeFormData = getThemeFormData?.() || {};
if (!themeFormData?.product_id || !themeFormData?.variant_id) {
return;
}
const ecConfig = await getECConfig();
const expressCheckoutList = getExpressCheckoutList();
track('loadEC', expressCheckoutList);
if (ecConfig) {
const checkoutData = await getCheckoutData();
disabledChannelListHandler(checkoutData, (ecName) => {
filterECButtonHandler({type: ecName},
() => removeChildrenDOM(containerDomId[channel2ProviderEnums[ecName]])
);
});
renderEC();
window.PaymentEC.handleEcPluginsLoad =
({
channelInfos = [],
loadedCbFn = () => {
}
}) => {
const expressCheckoutLoadList = [];
const { showChannelList } = getExpressCheckoutList();
const hasStripeChannels = channelInfos.some(info => info.ecGlobalVar === 'Stripe');
const stripeExpressChannels = (window?.C_SETTINGS?.payment_settings?.dynamic_config?.express_checkout_config?.express_channels || [])
.filter(ch => ['shoplazzagoogle'].includes(ch));
if (hasStripeChannels && !performance.getEntriesByName('ec_stripe_load_start').length) {
performance.mark('ec_stripe_load_start');
trackEcPerf({
eventName: 'ec_perf_stripe_load_start',
extraData: {
payment_channel: stripeExpressChannels.join(',')
},
eventType: 'card_expose'
});
}
channelInfos.map((channelInfo) => {
const {ecGlobalVar, ecName = '', sdkPath = '', datasets, fnReady, sdkReadyCb, sdkName} = channelInfo;
let hasContainer = document.getElementById(containerDomId[ecName]);
if (!hasContainer) {
return;
}
const scriptName = sdkName || ecName === 'paypal' ? ecGlobalVar : ecName;
performance.mark('ec_third_party_sdk_load_start');
trackEcPerf({
eventName: 'ec_third_party_sdk_load_start',
extraData: {
payment_channel: ecName,
sdk_path: sdkPath
},
eventType: 'expose'
});
const attributeConfig = getAttributeConfig(channelInfo) || {};
const loadPromise = loadScript(fnReady ? fnReady : () => window[ecGlobalVar], scriptName, sdkPath, datasets, () => {
loadErrorEvent(ecName);
}, attributeConfig).then(() => {
if (ecGlobalVar === 'Stripe' && !performance.getEntriesByName('ec_stripe_load_end').length) {
performance.mark('ec_stripe_load_end');
const stripeStart = performance.getEntriesByName('ec_stripe_load_start')[0];
trackEcPerf({
eventName: 'ec_perf_stripe_load_end',
extraData: {
stripe_load_time: stripeStart ? performance.now() - stripeStart.startTime : null,
payment_channel: stripeExpressChannels.join(',')
},
eventType: 'card_expose'
});
}
performance.mark('ec_third_party_sdk_load_end');
const sdkStartLoadTime = performance.getEntriesByName('ec_third_party_sdk_load_start')[0];
trackEcPerf({
eventName: 'ec_third_party_sdk_load_end',
extraData: {
sdk_load_time: sdkStartLoadTime ? performance.now() - sdkStartLoadTime.startTime : null,
payment_channel: ecName,
sdk_path: sdkPath
},
eventType: 'expose'
});
sdkReadyCb?.({
...checkoutData,
loadSpent: 0,
paymentExpressChannels: showChannelList
});
});
expressCheckoutLoadList.push(loadPromise);
});
const startLoadSDKTime = Date.now();
Promise.all(expressCheckoutLoadList).then(() => {
const finishLoadSDKTime = Date.now();
const loadSpent = finishLoadSDKTime - startLoadSDKTime;
loadedCbFn({...checkoutData, loadSpent, paymentExpressChannels: showChannelList});
});
};
// 通知外部数据变更
ecEvent.emit('tc_payment_ec_data_change', {
ecGlobalVarEnums,
containerDOMIdEnums: containerDomId
});
}
}
const loadECDebounce = debounce(loadEC, 300)
async function refreshEC(data = {}, sources) {
if (!sources) {
console.warn('[paymentEC]hide: sources is null');
return;
}
if (data?.detail?.selected?.price) {
setProductDetail(data?.detail)
}
loadECDebounce();
}
function init() {
ecEvent.on('shoplazza_express_channels_change', extraFilterEvent, false);
ecEvent.on('shoplazza_express_channels_change_ready', extraFilterEvent, false);
if (typeof window.PaymentEC === 'object') {
window.PaymentEC.getCheckoutData = getCheckoutData;
}
document.addEventListener('dj.variantChange', (data) => refreshEC(data, 'variantChange'));
document.addEventListener('payment_ec_refresh', (data) => refreshEC(data, data?.detail?.sources));
refreshEC({}, 'init');
}
if (isAllowTheme()) {
blockChannelHandler();
// 提前加载 filly:如果 DOM 已经准备好,立即加载;否则在 DOMContentLoaded 时加载
// 使用 DOMContentLoaded 替代 load 事件,提前加载时机(比 window.load 更早)
if (document.readyState === 'complete' || document.readyState === 'interactive') {
getFilly();
} else if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', getFilly, {once: true});
} else {
// 兜底:如果 readyState 未知,立即加载
getFilly();
}
}
}
dom.startFn = start;
document.dispatchEvent(new CustomEvent('payment_ec_core_ready', {
detail: {
start: true
}
}))
} catch (e) {
console.log(e);
}
// 预览模式
try {
const dom = document.getElementById('pm-payment-express-button-1539149753700-11');
function start() {
const {track} = dom.commonUtils;
const {showMoreButton, getMoreButtonConfig} = dom.renderMoreUtils;
const {
showECButtonHandler,
getECConfig,
blockChannelHandler,
getLegacyDiscontinuedChannels,
isAllowTheme,
getThemeFormData
} = dom.businessUtils;
const {
disabledThemTips,
showChannelNotOpenTips,
showSkeletonLayerTips,
showMockTips,
notFindFormTips,
showLegacyDiscontinuedTips
} = dom.renderTipsUtils;
const {mockAddChildrenDOM, resetRenderDOM} = dom.commonRenderUtils;
const {
channelEnums,
getChannelThemeConfig,
getExpressCheckoutList,
getOpenChannelType
} = dom.coreData;
const mockDomId = {
[channelEnums.PAYPAL]: channelEnums.PAYPAL,
[channelEnums.SHOPLAZZA_GOOGLE]: channelEnums.SHOPLAZZA_GOOGLE,
[channelEnums.SHOPLAZZA_APPLE]: channelEnums.SHOPLAZZA_APPLE,
[channelEnums.STRIPE_GOOGLE]: channelEnums.STRIPE_GOOGLE,
[channelEnums.STRIPE_APPLE]: channelEnums.STRIPE_APPLE,
}
const renderNotOpenTips = () => {
const {blockChannelList, paymentChannelList} = getExpressCheckoutList();
const notOpenChannel = blockChannelList.filter(ecName => !paymentChannelList.includes(ecName));
showChannelNotOpenTips(notOpenChannel);
}
const renderMockTips = () => {
const {hasApplepay, hasGooglepay} = getOpenChannelType();
if (hasApplepay || hasGooglepay) {
showMockTips();
}
}
const renderEC = () => {
showECButtonHandler();
const {showChannelList} = getExpressCheckoutList();
const {firstClick, maxSize} = getMoreButtonConfig();
if (showChannelList.length === 0) {
showMoreButton(renderEC);
}
showChannelList.forEach((ecName, index) => {
const disableShow = firstClick && index >= maxSize;
mockAddChildrenDOM(mockDomId[ecName], !disableShow, getChannelThemeConfig(ecName));
showMoreButton(renderEC);
});
}
async function loadEC() {
const date = new Date().getTime();
dom.loadEC_timestamp = date
const ecConfig = await getECConfig();
if (date !== dom.loadEC_timestamp) {
return;
}
const expressCheckoutList = getExpressCheckoutList();
track('preview-loadEC', expressCheckoutList);
resetRenderDOM();
// 初始化时没有事件推送
if (ecConfig) {
renderNotOpenTips();
showLegacyDiscontinuedTips(getLegacyDiscontinuedChannels());
renderEC();
renderMockTips();
}
}
const init = () => {
blockChannelHandler();
const {blockChannelList} = getExpressCheckoutList();
if (!isAllowTheme()) {
disabledThemTips()
return;
}
const themeFormData = getThemeFormData?.() || {};
if (!themeFormData?.product_id || !themeFormData?.variant_id) {
notFindFormTips();
return;
}
if (blockChannelList.length > 0) {
loadEC();
} else {
showLegacyDiscontinuedTips(getLegacyDiscontinuedChannels());
showSkeletonLayerTips()
}
}
init();
}
dom.mockStartFn = start;
document.dispatchEvent(new CustomEvent('payment_ec_core_ready', {
detail: {
start: true
}
}))
} catch (e) {
}
try {
const dom = document.getElementById('pm-payment-express-button-1539149753700-11');
window.PaymentEC = {}
const delayCallback = (cb) => {
window.requestIdleCallback ? requestIdleCallback(cb, {timeout: 50}) : setTimeout(cb, 50);
}
const checkReady = function (data) {
const {
i18n,
commonUtilsFn,
coreDataFn,
businessUtilsFn,
commonRenderUtilsFn,
renderTipsUtilsFn,
renderMoreUtilsFn,
startFn,
mockStartFn
} = dom
let readyData = {
commonUtils: !!(commonUtilsFn) || false,
coreData: !!(coreDataFn) || false,
businessUtils: !!(businessUtilsFn) || false,
commonRenderUtils: !!(commonRenderUtilsFn) || false,
renderTipsUtils: !!(renderTipsUtilsFn) || false,
renderMoreUtils: !!(renderMoreUtilsFn) || false,
start: !!(startFn) || false,
mockStart: !!(mockStartFn) || false,
i18n: !!(i18n) || false
}
if (data?.detail) {
Object.keys(data.detail).forEach(key => {
readyData[key] = data.detail[key]
})
}
let isReady = true;
Object.keys(readyData).forEach(key => {
if (!readyData[key]) {
isReady = false
}
})
return isReady
}
const readyFn = () => {
if (!checkReady()) {
return;
}
document.removeEventListener('payment_ec_core_ready', readyFn);
dom.commonUtils = dom.commonUtilsFn();
dom.coreData = dom.coreDataFn();
dom.businessUtils = dom.businessUtilsFn();
dom.commonRenderUtils = dom.commonRenderUtilsFn();
dom.renderTipsUtils = dom.renderTipsUtilsFn();
dom.renderMoreUtils = dom.renderMoreUtilsFn();
const productData = dom?.commonUtils?.getProduct?.() || {};
if (JSON.stringify(productData) === '{}') {
return;
}
if (dom?.commonUtils?.isPreview()) {
dom.mockStartFn()
} else {
dom.startFn();
}
}
const init = () => {
if (checkReady()) {
readyFn();
} else {
document.addEventListener('payment_ec_core_ready', readyFn)
}
}
// 使用 DOMContentLoaded 替代 window.load,提前初始化时机(与 filly 加载逻辑一致)
if (document.readyState === 'complete' || document.readyState === 'interactive') {
delayCallback(init);
} else if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => delayCallback(init), {once: true});
} else {
// 兜底:如果 readyState 未知,立即执行
delayCallback(init);
}
} catch (e) {
}
${function(){
const variantData = data.variant || {"id":"569ab440-48fb-4c48-96ee-28ca923a6961","product_id":"2dec4d4a-abe2-429b-8f0e-42734ecef867","title":"1 radar sensor\uff08need to be used with receiver\uff09","weight_unit":"kg","inventory_quantity":0,"sku":"","barcode":"","position":1,"option1":"1 radar sensor\uff08need to be used with receiver\uff09","option2":"","option3":"","note":"","image":{"src":"\/\/img.staticdj.com\/8ac5536afd4c5547e514433566b4f23c.jpg","path":"8ac5536afd4c5547e514433566b4f23c.jpg","width":800,"height":800,"alt":"","aspect_ratio":1},"wholesale_price":[{"price":29.99,"min_quantity":1}],"weight":"0","compare_at_price":"59.98","price":"29.99","retail_price":"59.98","available":true,"url":"\/products\/outdoor-camping-radar-induction-alarm-camping-warning-anti-animal-alarm-device?variant=569ab440-48fb-4c48-96ee-28ca923a6961","available_quantity":999999999,"options":[{"name":"STYLE","value":"1 radar sensor\uff08need to be used with receiver\uff09"}],"off_ratio":50,"flashsale_info":[],"sales":3022};
return `
`
}()}
- Handling time>> Priority is given to delivery after payment
- 💯Payments Via PayPal® or Credit Card
- 🌈 Guarantee>> We have a a risk-free 90-day guarantee
- 🎯Shipping takes different depending on location
- 99.6% Reviewers Buy 2 or more!
PRODUCT FEATURES
Outdoor camping alarm, radar sensor for all-day guarding, adjustable sensitivity, all-round monitoring, making camping safer. The wireless distance can reach 100-150 meters!
Microwave radar sensors based on the Doppler effect emit high-frequency electromagnetic waves and receive and process reflected waves, thereby determining whether there are moving objects in the coverage area.
Ipx7 waterproof level waterproof buttons are more durable, waterproof design, can be used in rain or snow, no fear of weather influence
Microwave radar sensing VS Traditional infrared sensing
Microwave radar induction:
Strong penetrating power
Strong anti-interference
not affected by weather
Not affected by the environment
Traditional infrared sensing:
Not available during the day
cannot be blocked
Short sensing distance
Greatly affected by temperature
Microwave radar induction is precise and adjustable: three-section adjustable, directional monitoring, preventing false alarms, 9-meter range sensing distance, 120° sensing angle
Low power consumption design keeps you away from the anxiety of running out of battery, and you don’t have to worry about long-distance travel.
Adjustable alarm mode: vibration/buzzer/vibration+buzzer silent alarm without disturbing others
Lightweight and portable. A single radar weighs 30g. The total weight of four radars + one receiver is about 150g.
The alarm receiver can be connected to ten radars. The communication distance between the radar and the receiver is 50-100 meters. The length of the alarm sound can be used to determine which radar is triggered.
Function Introduction
Alarm Receiver:
- Press and hold the "power button" for 3 seconds to turn on/off. When turned on, the blue light will turn on and vibrate, and when turned off, the red light will flash and the buzzer will sound.
- Press the "MODE" button to switch the alarm mode, which is: vibration, buzzer, vibration + buzzer; memory after shutdown.
- Each receiver is limited to pairing up to 10 transmitters, and the alarm action is different when each radar is triggered.
- Quickly press the mode button three times to enter the pairing mode. After turning on the radar to be paired, the pairing can be triggered and completed. After the pairing is successful, the blue light of the receiver will be on for one second; turn off the paired radar and pair the next one. Click once or automatically exit the pairing mode after thirty seconds;
- Press and hold the mode button for ten seconds, and then quickly press three times to clear all pairings.
Radar Sensor:
- Press and hold the "power button" for 3 seconds to turn on/off. The blue light flashes once when turned on and the red light flashes twice when turned off.
- Press the "MODE button" to adjust the sensing distance. The blue light flashes once for the first gear; flashes twice for the second gear; flashes three times for the third gear (1st gear 1-3 meters; 2nd gear 1-6 meters; 3rd gear 1-9 meters). Automatic memory after shutdown.
- When the radar is triggered, the red light will flash continuously and send a signal to the receiver.
Product Parameters
- Product name: Outdoor alarm
- Battery capacity: 650mah
- Working current: 50uA
- Product guarantee: Lifetime warranty
- Product size: 4*4*7cm
- Product weight: 30g (single)
- Radar frequency: 5.8GHz
- Wireless distance: 100-150m (open space)
NOTES
- Avoid multiple radars from shooting at each other, which is easy to cause interference. Each radar should be more than 1 meter apart.
- Try to avoid pointing the radar antenna directly at the fan or pipe of large metal equipment.
- The higher the gear, the more sensitive it is. Do not use the highest gear when there is more interference.
- The 1-2 meters on the back side of the radar is also the sensing area. To prevent it from being bypassed, you need to be more than two meters away from the tent when deploying.
- The product is made of engineering plastics. Some scratches are normal and not a quality problem.
AFTER SALE SERVICE
- We offer a 100% satisfaction guarantee, a 30-day money-back guarantee.
- We have 24/7/365 Facebook Messenger and email support.
- We strive to make our customers 100% satisfied with the product you have purchased. Please don't hesitate to email us with any questions or problems and we will help you right away.
SHIPPING POLICIES:
- Tip: Buying 2 products or more at the same time will save you quite a lot on shipping fees.
THIS PRODUCT IS A LIMITED PRODUCTION AND IS NOT AVAILABLE IN STORES. WILL SELL OUT FAST!
🌎 Worldwide Shipping ✈
🔥 Fast refund>> Partial or full refund depend on the situation;
🚚 Insured Worldwide Shipping: Each order includes real-time tracking details and insurance coverage in the unlikely event that a package gets lost or stolen in transit.
✉️ 24/7 Customer Support: We have a team of live reps ready to help and answer any questions you have within a 24-hour time frame, 7 days a week.
🔒 Safe & Secure Checkouts: We use state-of-the-art SSL Secure encryption to keep your personal and financial information 100% protected.
We do our best to process & ship all orders as soon as possible. We're proud to offer worldwide shipping