Shopify
Email checker for Shopify. Verify customer emails at checkout and in Shopify apps.
Proteja sua loja Shopify de contas falsas, reduza devoluções de e-mails de carrinho abandonado e melhore a comunicação com clientes verificando endereços de e-mail.
Por que Verificar E-mails no Shopify?
| Desafio | Impacto | Solução |
|---|---|---|
| Contas falsas | Abuso de promoção, fraude | Verificar no registro |
| Carrinho abandonado | E-mails de recuperação devolvidos | Verificar antes de enviar |
| Notificações de pedido | Falha na entrega de atualizações | Verificar no checkout |
| Campanhas de marketing | Baixa entregabilidade | Limpar lista de clientes |
Métodos de Integração
| Método | Melhor Para | Complexidade |
|---|---|---|
| Shopify Flow | Fluxos de trabalho automatizados | Baixa |
| Shopify Functions | Validação de checkout | Média |
| Aplicativo de Terceiros | Solução completa | Baixa |
| Aplicativo Personalizado | Controle total | Alta |
Método 1: Shopify Flow (Recomendado)
Use Shopify Flow para verificar e-mails automaticamente.
Verificar E-mails de Novos Clientes
Crie um fluxo de trabalho para verificar e-mails quando os clientes se registrarem:
Gatilho: Cliente criado
Condição: E-mail do cliente não está em branco
Ações:
- Enviar solicitação HTTP para EmailVerify
- Adicionar tag ao cliente com base no resultado
Configuração de Fluxo
Fluxo: Verificar E-mail de Novo Cliente
Gatilho:
Evento: Cliente criado
Condição:
- E-mail do cliente não está em branco
Ação 1:
Tipo: Enviar solicitação HTTP
URL: https://api.emailverify.ai/v1/verify
Método: POST
Cabeçalhos:
- Authorization: Bearer SUA_CHAVE_API
- Content-Type: application/json
Corpo: {"email": "{{customer.email}}"}
Aguardar:
Duração: 1 segundo
Ação 2:
Tipo: Adicionar tags ao cliente
Tags:
- email_verificado (se status = válido)
- email_inválido (se status = inválido)Verificar Antes de E-mails de Carrinho Abandonado
Fluxo: Verificar Antes do E-mail de Abandono
Gatilho:
Evento: Checkout abandonado
Atraso: 1 hora
Condição:
- E-mail do cliente não está em branco
- Cliente não tem a tag "email_inválido"
Ação 1:
Tipo: Enviar solicitação HTTP para EmailVerify
Corpo: {"email": "{{checkout.email}}"}
Ação 2:
Tipo: Ramificação
Se status = "válido":
- Continuar para sequência de e-mail de abandono
Se status = "inválido":
- Adicionar tag "email_inválido"
- Não enviar e-mailMétodo 2: Validação de Checkout com Shopify Functions
Crie uma Shopify Function para validar e-mails durante o checkout.
Passo 1: Criar uma Função de Transformação de Carrinho
// extensions/email-validation/src/run.js
import { EmailVerify } from '@emailverify/node';
export function run(input) {
const { cart } = input;
const email = cart?.buyerIdentity?.email;
if (!email) {
return { operations: [] };
}
// Nota: For real-time validation, use a pre-validated cache
// or implement async validation via metafield
return {
operations: [],
};
}Passo 2: Criar uma Extensão de Interface do Checkout
// extensions/email-validation-ui/src/Checkout.jsx
import {
useExtensionApi,
render,
Banner,
BlockStack,
} from '@shopify/checkout-ui-extensions-react';
import { useState, useEffect } from 'react';
render('Checkout::Contact::RenderAfter', () => <EmailValidation />);
function EmailValidation() {
const { buyerIdentity } = useExtensionApi();
const [validationStatus, setValidationStatus] = useState(null);
useEffect(() => {
const email = buyerIdentity?.email?.current;
if (email) {
validateEmail(email).then(setValidationStatus);
}
}, [buyerIdentity?.email?.current]);
if (!validationStatus) return null;
if (validationStatus.status === 'invalid') {
return (
<Banner status="warning">
Por favor, verifique seu endereço de e-mail. Parece estar inválido.
</Banner>
);
}
if (validationStatus.result?.disposable) {
return (
<Banner status="info">
Recomendamos usar um e-mail permanente para atualizações de pedidos.
</Banner>
);
}
return null;
}
async function validateEmail(email) {
const response = await fetch('/apps/email-verify/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email }),
});
return response.json();
}Método 3: Aplicativo Shopify Personalizado
Crie uma solução completa de verificação de e-mail.
Backend do Aplicativo (Node.js)
// server/index.js
import '@shopify/shopify-app-remix/adapters/node';
import { shopifyApp } from '@shopify/shopify-app-remix/server';
import { EmailVerify } from '@emailverify/node';
const shopify = shopifyApp({
// ... Shopify config
});
const emailVerify = new EmailVerify({
apiKey: process.env.EMAILVERIFY_API_KEY,
});
// Rota de API para verificação de e-mail
export async function action({ request }) {
const { email, customerId } = await request.json();
try {
const result = await emailVerify.verify(email);
// Atualizar metafield do cliente
if (customerId) {
await updateCustomerVerificationStatus(customerId, result);
}
return json(result);
} catch (error) {
return json({ error: error.message }, { status: 500 });
}
}
async function updateCustomerVerificationStatus(customerId, result) {
const { admin } = await shopify.authenticate.admin(request);
await admin.graphql(`
mutation updateCustomerMetafield($input: CustomerInput!) {
customerUpdate(input: $input) {
customer {
id
}
}
}
`, {
variables: {
input: {
id: `gid://shopify/Customer/${customerId}`,
metafields: [
{
namespace: "email_verification",
key: "status",
value: result.status,
type: "single_line_text_field"
},
{
namespace: "email_verification",
key: "score",
value: String(result.score),
type: "number_decimal"
},
{
namespace: "email_verification",
key: "verified_at",
value: new Date().toISOString(),
type: "date_time"
}
]
}
}
});
}Manipulador de Webhook
Manipular webhooks de criação de cliente:
// server/webhooks/customer-created.js
export async function handleCustomerCreated(topic, shop, body) {
const customer = JSON.parse(body);
const { id, email } = customer;
if (!email) return;
try {
// Verificar e-mail
const result = await emailVerify.verify(email);
// Atualizar cliente com tags
const tags = [];
if (result.status === 'valid') {
tags.push('email_verificado');
} else if (result.status === 'invalid') {
tags.push('email_inválido');
}
if (result.result?.disposable) {
tags.push('email_descartável');
}
await updateCustomerTags(shop, id, tags);
// Armazenar resultado da verificação
await updateCustomerVerificationStatus(shop, id, result);
console.log(`Verificado ${email}: ${result.status}`);
} catch (error) {
console.error(`Falha ao verificar ${email}:`, error);
}
}Integração de Tema (Liquid)
Adicione verificação ao formulário de registro:
{% comment %} snippets/email-verification.liquid {% endcomment %}
<script>
document.addEventListener('DOMContentLoaded', function() {
const emailInput = document.querySelector('input[type="email"]');
const submitButton = document.querySelector('form[action="/account"] button[type="submit"]');
let verificationResult = null;
emailInput.addEventListener('blur', async function() {
const email = this.value;
if (!email) return;
// Mostrar estado de carregamento
emailInput.classList.add('verifying');
try {
const response = await fetch('/apps/emailverify/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email })
});
verificationResult = await response.json();
// Atualizar UI com base no resultado
updateEmailFieldUI(verificationResult);
} catch (error) {
console.error('Falha na verificação:', error);
} finally {
emailInput.classList.remove('verifying');
}
});
function updateEmailFieldUI(result) {
// Remover mensagens existentes
const existingMessage = document.querySelector('.email-verification-message');
if (existingMessage) existingMessage.remove();
// Criar elemento de mensagem
const message = document.createElement('div');
message.className = 'email-verification-message';
if (result.status === 'invalid') {
message.classList.add('error');
message.textContent = 'Por favor, insira um endereço de e-mail válido';
submitButton.disabled = true;
} else if (result.result?.disposable) {
message.classList.add('warning');
message.textContent = 'Por favor, use um e-mail permanente para recuperação de conta';
} else if (result.status === 'valid') {
message.classList.add('success');
message.textContent = '✓ E-mail verificado';
submitButton.disabled = false;
}
emailInput.parentNode.appendChild(message);
}
});
</script>
<style>
.email-verification-message {
font-size: 12px;
margin-top: 4px;
}
.email-verification-message.error { color: #c9302c; }
.email-verification-message.warning { color: #f0ad4e; }
.email-verification-message.success { color: #5cb85c; }
input[type="email"].verifying {
background-image: url('/path/to/spinner.gif');
background-position: right 10px center;
background-repeat: no-repeat;
}
</style>Casos de Uso
1. Prevenir Registro de Contas Falsas
Bloqueie e-mails descartáveis e inválidos durante o registro:
// Extensão de aplicativo de tema
async function validateRegistration(email) {
const result = await verifyEmail(email);
if (result.status === 'invalid') {
return {
valid: false,
message: 'Por favor, insira um endereço de e-mail válido',
};
}
if (result.result.disposable) {
return {
valid: false,
message: 'Endereços de e-mail temporários não são permitidos',
};
}
return { valid: true };
}2. Recuperação de Carrinho Abandonado
Envie e-mails de abandono apenas para endereços válidos:
Shopify Flow:
Gatilho: Checkout abandonado (atraso de 1 hora)
Condição: Verificar status de verificação de e-mail
Se válido:
→ Enviar e-mail de abandono
→ Adicionar à audiência de re-marketing
Se inválido:
→ Pular e-mail
→ Registrar para análise3. Avaliação de Risco de Pedido
Considere a qualidade do e-mail na detecção de fraude:
function calculateOrderRiskScore(order, emailVerification) {
let riskScore = 0;
// Fatores de verificação de e-mail
if (emailVerification.status === 'invalid') {
riskScore += 30;
}
if (emailVerification.result?.disposable) {
riskScore += 20;
}
if (emailVerification.result?.free && order.total > 500) {
riskScore += 10; // Pedido de alto valor com e-mail gratuito
}
// Outros fatores...
if (order.billing_address !== order.shipping_address) {
riskScore += 15;
}
return riskScore;
}4. Segmentação de Cliente
Crie segmentos de clientes com base na qualidade do e-mail:
| Segmento | Critérios | Estratégia de Marketing |
|---|---|---|
| Alto Valor | Verificado, e-mail comercial | Campanhas premium |
| Padrão | Verificado, e-mail gratuito | Campanhas regulares |
| Em Risco | Não verificado, conta antiga | Campanha de re-verificação |
| Excluído | Inválido, descartável | Sem marketing |
Configuração de Metafield
Crie metafields para armazenar dados de verificação:
Metafields de Cliente
mutation createMetafieldDefinitions {
metafieldDefinitionCreate(definition: {
namespace: "email_verification"
key: "status"
name: "Status de Verificação de E-mail"
type: "single_line_text_field"
ownerType: CUSTOMER
}) {
createdDefinition { id }
}
}Metafields recomendados:
| Namespace | Chave | Tipo | Descrição |
|---|---|---|---|
| email_verification | status | single_line_text_field | válido, inválido, desconhecido |
| email_verification | score | number_decimal | 0.0 - 1.0 |
| email_verification | verified_at | date_time | Data da última verificação |
| email_verification | disposable | boolean | É e-mail descartável |
| email_verification | role_based | boolean | É e-mail baseado em função |
Acessar Metafields em Liquid
{% if customer.metafields.email_verification.status == 'valid' %}
<span class="verified-badge">✓ Verificado</span>
{% endif %}Verificação em Massa de Clientes
Limpe sua lista de clientes existente:
Exportar Clientes
async function exportCustomersForVerification(admin) {
const query = `
query getCustomers($cursor: String) {
customers(first: 250, after: $cursor) {
edges {
node {
id
email
createdAt
metafield(namespace: "email_verification", key: "status") {
value
}
}
cursor
}
pageInfo {
hasNextPage
}
}
}
`;
let customers = [];
let cursor = null;
do {
const response = await admin.graphql(query, {
variables: { cursor },
});
const { edges, pageInfo } = response.data.customers;
// Filtrar clientes não verificados
const unverified = edges
.filter((e) => !e.node.metafield)
.map((e) => ({
id: e.node.id,
email: e.node.email,
}));
customers.push(...unverified);
cursor = edges[edges.length - 1]?.cursor;
} while (response.data.customers.pageInfo.hasNextPage);
return customers;
}Verificar e Atualizar em Massa
async function bulkVerifyCustomers(customers) {
const emails = customers.map((c) => c.email);
// Enviar tarefa de verificação em massa
const job = await emailVerify.verifyBulk(emails);
// Aguardar conclusão
const results = await waitForJobCompletion(job.job_id);
// Atualizar clientes com resultados
for (const result of results) {
const customer = customers.find((c) => c.email === result.email);
if (customer) {
await updateCustomerVerificationStatus(customer.id, result);
}
}
return results;
}Melhores Práticas
1. Verificar em Vários Pontos
- Registro: Bloquear contas falsas
- Checkout: Garantir que notificações de pedidos atinjam clientes
- Carrinho abandonado: Não desperdice e-mails em endereços inválidos
2. Resultados de Cache
Armazene em cache os resultados da verificação para evitar chamadas de API redundantes:
const CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 horas
async function verifyWithCache(email) {
const cacheKey = `email_verify:${email}`;
const cached = await redis.get(cacheKey);
if (cached) {
return JSON.parse(cached);
}
const result = await emailVerify.verify(email);
await redis.setex(cacheKey, CACHE_DURATION / 1000, JSON.stringify(result));
return result;
}3. Lidar com Casos Extremos
function handleVerificationResult(result, context) {
switch (result.status) {
case 'valid':
// Fluxo normal
break;
case 'invalid':
if (context === 'checkout') {
// Não bloqueie o checkout, apenas registre
logInvalidEmail(result.email, 'checkout');
} else if (context === 'registration') {
// Bloquear registro
throw new Error('E-mail inválido');
}
break;
case 'unknown':
// Aceitar mas marcar para revisão
flagForReview(result.email);
break;
case 'accept_all':
// Válido mas monitorar devoluções
markAsCatchAll(result.email);
break;
}
}4. Monitorar e Otimizar
Rastreie essas métricas:
- Taxa de sucesso de verificação
- Redução de taxa de devolução
- Taxa de prevenção de contas falsas
- Entregabilidade de e-mail de carrinho abandonado