Precisa de Ajuda? Atendimento
0
Trocas e devoluções

Solicitação de troca ou devolução

Toda solicitação de troca ou devolução deve ser comunicada à Central de Atendimento para instruções detalhadas sobre o processo. No rodapé do site ou na página de Fale Conosco possui os dados de contato com a nossa central de atendimento.

 

Condições para Troca, Devolução ou Arrependimento da compra

O prazo máximo é de 30 dias após o recebimento do produto.

A mercadoria deverá retornar nas mesmas condições em que foi entregue, ou seja: lacres intactos do fabricante e na embalagem original e com todos acessórios que acompanham o produto. É importante ressaltar que a caixa do produto também deve estar em perfeitas condições, isto é, a embalagem não pode ter sido danificada ou violada.

Esclarece-se que o produto NÃO PODE TER SIDO USADO.

 

Envio para Troca , Devolução ou Arrependimento da compra

O custo de frete para o retorno da mercadoria será de responsabilidade da loja virtual, não tendo custo adicional ao consumidor.

Sendo necessário que o consumidor solicite a troca, devolução ou direito de arrependimento no prazo máximo de 30 dias após o recebimento da mercadoria.

O fluxo de envio será explicado por nossa equipe de atendimento, onde irá depender da quantidade e tamanho do produto que será retornado.

Atenção! Ao chegar o produto será analisado sua condição e caso seja constatado uso do produto, poderá ser recusado a troca ou devolução, sendo retornado o produto.

 

Devolução do valor para Cartão

Após o recebimento do produto em nosso Centro de Distribuição e aprovação da devolução ou troca mediante análise dos itens, enviaremos a solicitação de estorno para a administradora do cartão de crédito que esta por sua vez tem o prazo para processar a requisição de acordo com a política de cada administradora de cartão de crédito.

Poderá ocorrer do valor estornado ser devolvido em faturas futuras, sendo política da administradora de cartão.

 

Devolução do valor Boleto, Pix ou Transferência

A restituição do valor será processada após a aprovação da devolução mediante análise dos itens em nosso Centro de Distribuição e será realizada através de reembolso em uma conta corrente ou poupança.

No momento da solicitação da troca ou devolução deverá ser informado os dados bancários.

`; } else { return '👋 Olá! Bem-vindo à Phoenix Hospitalar™! Estou aqui para te ajudar a escolher o equipamento hospitalar perfeito. O que você está procurando?'; } } function playNotificationSound() { try { const audioContext = new (window.AudioContext || window.webkitAudioContext)(); const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.frequency.value = 800; oscillator.type = 'sine'; gainNode.gain.setValueAtTime(0.1, audioContext.currentTime); gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.1); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + 0.1); } catch (error) { console.error('[Phoenix Widget] Erro ao tocar som:', error); } } // FIX 2: linkify — processa markdown [texto](url), wa.me e URLs brutas function linkify(text) { const WA_MARKER = '\x00WA\x00'; const LINK_MARKER = '\x00LK\x00'; const SEP = '\x00'; // 1. Processar markdown [texto](url) ANTES de escapar HTML let result = text.replace(/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g, function(_, label, url) { var cleanLabel = label.replace(/[\u{1F300}-\u{1FFFF}\u{2600}-\u{27FF}]/gu, '').trim(); if (url.indexOf('wa.me') !== -1) { return WA_MARKER + url + SEP + (cleanLabel || 'Abrir WhatsApp') + SEP; } return LINK_MARKER + url + SEP + (cleanLabel || url) + SEP; }); // 2. Remover emojis soltos antes de URLs brutas result = result.replace(/[\u{1F300}-\u{1FFFF}\u{2600}-\u{27FF}]\s*(?=https?:\/\/)/gu, ''); // 3. Processar URLs brutas restantes result = result.replace(/(https?:\/\/[^\s\x00<>"']+)/g, function(url) { if (url.indexOf('wa.me') !== -1) { return WA_MARKER + url + SEP + 'Abrir WhatsApp' + SEP; } return LINK_MARKER + url + SEP + url + SEP; }); // 4. Escapar HTML no texto puro (entre os marcadores) var parts = result.split(/(\x00(?:WA|LK)\x00[^\x00]+\x00[^\x00]+\x00)/g); var escaped = parts.map(function(part) { if (part.charAt(0) === '\x00') return part; return part.replace(/&/g, '&').replace(//g, '>'); }).join(''); // 5. Substituir marcadores por HTML final return escaped .replace(/\x00WA\x00([^\x00]+)\x00([^\x00]+)\x00/g, function(_, url, label) { return '' + label + ''; }) .replace(/\x00LK\x00([^\x00]+)\x00([^\x00]+)\x00/g, function(_, url, label) { var display = (label === url && url.length > 60) ? url.replace(/https?:\/\/[^/]+/, '').substring(0, 45) + '...' : label; return '' + display + ''; }); } const widgetHTML = `
`; document.body.insertAdjacentHTML('beforeend', widgetHTML); const button = document.getElementById('phoenix-chat-button'); const modal = document.getElementById('phoenix-chat-modal'); const closeBtn = document.getElementById('phoenix-chat-close'); const input = document.getElementById('phoenix-chat-input'); const sendBtn = document.getElementById('phoenix-chat-send'); const messagesContainer = document.getElementById('phoenix-chat-messages'); const flyingBird = document.getElementById('phoenix-flying-bird'); const hoveringBird = document.getElementById('phoenix-hovering'); const typingIndicator = document.getElementById('phoenix-typing-indicator'); state.sessionId = sessionStorage.getItem('phoenix_session_id'); if (!state.sessionId) { state.sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; sessionStorage.setItem('phoenix_session_id', state.sessionId); } // FIX 1: startSession popula renderedMessageIds ANTES do polling iniciar async function startSession() { try { const response = await fetch(`${WIDGET_CONFIG.apiUrl}/start`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sessionId: state.sessionId, productUrl: window.location.href, isLocationPage: isLocationPage(), }), }); const data = await response.json(); if (!state.welcomeRendered) { state.welcomeRendered = true; const initialDiv = document.getElementById('phoenix-initial-message'); if (data.welcomeMessage) { // Sessão nova: renderizar boas-vindas e marcar ID sintético initialDiv.innerHTML = linkify(data.welcomeMessage); state.renderedMessageIds.add('welcome'); } else if (initialDiv) { // Sessão existente: esconder card de boas-vindas const card = initialDiv.closest('div[style]'); if (card) card.style.display = 'none'; } } // Marcar todos os IDs do histórico como já renderizados if (data.messages && data.messages.length > 0) { data.messages.forEach(function(m) { state.renderedMessageIds.add(m.id); if (m.id > (state.lastMessageId || 0)) state.lastMessageId = m.id; }); } } catch (error) { console.error('[Phoenix Widget] Error starting session:', error); } } // FIX 1: polling passa id para check-and-mark interno no addMessage function startPolling() { if (state.pollingTimer) clearInterval(state.pollingTimer); state.pollingTimer = setInterval(async () => { try { const url = `${WIDGET_CONFIG.apiUrl}/messages/${state.sessionId}${state.lastMessageId ? `?lastMessageId=${state.lastMessageId}` : ''}`; const response = await fetch(url); const data = await response.json(); if (data.success) { if (data.isTyping && !state.isTypingVisible) { typingIndicator.style.display = 'block'; state.isTypingVisible = true; } else if (!data.isTyping && state.isTypingVisible) { typingIndicator.style.display = 'none'; state.isTypingVisible = false; } if (data.messages && data.messages.length > 0) { data.messages.forEach(function(msg) { if (msg.sender !== 'user') { // FIX 1: passa msg.id para check-and-mark — evita duplicação com send addMessage(msg.content, msg.sender === 'vendor' ? 'vendor' : 'ai', msg.id); if (msg.id > (state.lastMessageId || 0)) state.lastMessageId = msg.id; playNotificationSound(); } }); if (state.isTypingVisible) { typingIndicator.style.display = 'none'; state.isTypingVisible = false; } } } } catch (error) { console.error('[Phoenix Widget] Error polling messages:', error); } }, WIDGET_CONFIG.pollingInterval); } function stopPolling() { if (state.pollingTimer) { clearInterval(state.pollingTimer); state.pollingTimer = null; } } async function openModal(autoOpened = false) { button.style.display = 'none'; flyingBird.style.display = 'block'; flyingBird.style.animation = 'flyUp 1.5s ease-out forwards'; setTimeout(async () => { modal.style.display = 'flex'; flyingBird.style.display = 'none'; hoveringBird.style.display = 'block'; input.focus(); // FIX 1: startSession PRIMEIRO, polling só inicia depois (sem race condition) await startSession(); startPolling(); }, 1000); markAsVisited(); } function closeModal() { modal.style.display = 'none'; hoveringBird.style.display = 'none'; button.style.display = 'flex'; stopPolling(); } if (!hasVisitedBefore()) { setTimeout(() => { openModal(true); }, WIDGET_CONFIG.autoOpenDelay); } button.addEventListener('click', openModal); closeBtn.addEventListener('click', closeModal); async function sendMessage() { const message = input.value.trim(); if (!message) return; addMessage(message, 'user'); input.value = ''; try { const response = await fetch(`${WIDGET_CONFIG.apiUrl}/send-message`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sessionId: state.sessionId, message, productUrl: window.location.href, isLocationPage: isLocationPage() }), }); const data = await response.json(); if (data.success && data.response) { // FIX 1: avançar lastMessageId para evitar re-exibição pelo polling if (data.aiMessageId && data.aiMessageId > (state.lastMessageId || 0)) { state.lastMessageId = data.aiMessageId; } if (data.welcomeMessageId && data.welcomeMessageId > (state.lastMessageId || 0)) { state.lastMessageId = data.welcomeMessageId; } // FIX 1: passa aiMessageId para check-and-mark — polling não re-exibe addMessage(data.response, 'ai', data.aiMessageId || null); if (data.welcomeMessageId) { state.renderedMessageIds.add(data.welcomeMessageId); } } else if (!data.success) { addMessage('Erro ao enviar mensagem. Tente novamente.', 'ai'); } } catch (error) { console.error('Erro ao enviar mensagem:', error); addMessage('Erro ao enviar mensagem. Tente novamente.', 'ai'); } } // FIX 1 + FIX 2 + FIX 3: addMessage com check-and-mark e linkify function addMessage(text, sender, id) { id = id || null; // FIX 1: check-and-mark — quem renderizar primeiro marca; segundo cai no return if (id && state.renderedMessageIds.has(id)) return; const isUser = sender === 'user'; const isVendor = sender === 'vendor'; const bgColor = isUser ? '#667eea' : (isVendor ? '#25D366' : '#f3f4f6'); const textColor = isUser || isVendor ? 'white' : '#1f2937'; const marginLeft = isUser ? '40px' : '0'; // FIX 2 + FIX 3: linkify processa markdown, URLs e remove emojis antes de URLs const formattedText = isUser ? text.replace(/&/g, '&').replace(//g, '>') : linkify(text); const messageHTML = `
${!isUser ? `
Phoenix
${isVendor ? 'Consultor Phoenix' : 'Phoenix Hospitalar'}
` : ''}
${formattedText}
`; messagesContainer.insertAdjacentHTML('beforeend', messageHTML); messagesContainer.scrollTop = messagesContainer.scrollHeight; // FIX 1: marcar APÓS render if (id) state.renderedMessageIds.add(id); } sendBtn.addEventListener('click', sendMessage); input.addEventListener('keypress', (e) => { if (e.key === 'Enter') sendMessage(); }); })();