Shopify
Email checker for Shopify. Verify at checkout, registration, and in Shopify Flows.
Protégez votre boutique Shopify contre les faux comptes, réduisez les rebonds d'emails d'abandon de panier et améliorez la communication client en vérifiant les adresses email.
Pourquoi Vérifier les Emails dans Shopify ?
| Défi | Impact | Solution |
|---|---|---|
| Faux comptes | Abus de promos, fraude | Vérifier à l'inscription |
| Abandon de panier | Emails de relance rejetés | Vérifier avant l'envoi |
| Notifications de commande | Échec des mises à jour de livraison | Vérifier au paiement |
| Campagnes marketing | Faible délivrabilité | Nettoyer la liste clients |
Méthodes d'Intégration
| Méthode | Idéal Pour | Complexité |
|---|---|---|
| Shopify Flow | Workflows automatisés | Faible |
| Shopify Functions | Validation au paiement | Moyenne |
| Application tierce | Solution complète | Faible |
| Application personnalisée | Contrôle total | Élevée |
Méthode 1 : Shopify Flow (Recommandé)
Utilisez Shopify Flow pour vérifier les emails automatiquement.
Vérifier les Emails des Nouveaux Clients
Créez un workflow pour vérifier les emails lors de l'inscription client :
Déclencheur : Client créé
Condition : L'email du client n'est pas vide
Actions :
- Envoyer une requête HTTP à EmailVerify
- Ajouter un tag client basé sur le résultat
Configuration du Flow
Workflow: Vérifier l'Email du Nouveau Client
Trigger:
Event: Customer created
Condition:
- Customer email is not blank
Action 1:
Type: Send HTTP request
URL: https://api.emailverify.ai/v1/verify
Method: POST
Headers:
- Authorization: Bearer VOTRE_CLE_API
- Content-Type: application/json
Body: {"email": "{{customer.email}}"}
Wait:
Duration: 1 second
Action 2:
Type: Add customer tags
Tags:
- email_verified (if status = valid)
- email_invalid (if status = invalid)Vérifier Avant les Emails d'Abandon de Panier
Workflow: Vérifier Avant l'Email d'Abandon
Trigger:
Event: Checkout abandoned
Delay: 1 hour
Condition:
- Customer email is not blank
- Customer does not have tag "email_invalid"
Action 1:
Type: Send HTTP request to EmailVerify
Body: {"email": "{{checkout.email}}"}
Action 2:
Type: Branch
If status = "valid":
- Continue to abandonment email sequence
If status = "invalid":
- Add tag "email_invalid"
- Do not send emailMéthode 2 : Validation au Paiement avec Shopify Functions
Créez une Shopify Function pour valider les emails pendant le paiement.
Étape 1 : Créer une Cart Transform Function
// 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: [] };
}
// Note : Pour la validation en temps réel, utilisez un cache pré-validé
// ou implémentez une validation asynchrone via metafield
return {
operations: [],
};
}Étape 2 : Créer une Extension UI de Paiement
// 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">
Veuillez vérifier votre adresse email. Elle semble invalide.
</Banner>
);
}
if (validationStatus.result?.disposable) {
return (
<Banner status="info">
Nous recommandons d'utiliser un email permanent pour les mises à jour de commande.
</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éthode 3 : Application Shopify Personnalisée
Construisez une solution de vérification d'email complète.
Backend de l'Application (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({
// ... Configuration Shopify
});
const emailVerify = new EmailVerify({
apiKey: process.env.EMAILVERIFY_API_KEY,
});
// Route API pour la vérification d'email
export async function action({ request }) {
const { email, customerId } = await request.json();
try {
const result = await emailVerify.verify(email);
// Mettre à jour le metafield du client
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"
}
]
}
}
});
}Gestionnaire de Webhook
Gérez les webhooks de création de client :
// 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 {
// Vérifier l'email
const result = await emailVerify.verify(email);
// Mettre à jour le client avec des tags
const tags = [];
if (result.status === 'valid') {
tags.push('email_verified');
} else if (result.status === 'invalid') {
tags.push('email_invalid');
}
if (result.result?.disposable) {
tags.push('disposable_email');
}
await updateCustomerTags(shop, id, tags);
// Stocker le résultat de vérification
await updateCustomerVerificationStatus(shop, id, result);
console.log(`Verified ${email}: ${result.status}`);
} catch (error) {
console.error(`Failed to verify ${email}:`, error);
}
}Intégration au Thème (Liquid)
Ajoutez la vérification au formulaire d'inscription :
{% 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;
// Afficher l'état de chargement
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();
// Mettre à jour l'UI selon le résultat
updateEmailFieldUI(verificationResult);
} catch (error) {
console.error('Verification failed:', error);
} finally {
emailInput.classList.remove('verifying');
}
});
function updateEmailFieldUI(result) {
// Supprimer les messages existants
const existingMessage = document.querySelector('.email-verification-message');
if (existingMessage) existingMessage.remove();
// Créer l'élément de message
const message = document.createElement('div');
message.className = 'email-verification-message';
if (result.status === 'invalid') {
message.classList.add('error');
message.textContent = 'Veuillez entrer une adresse email valide';
submitButton.disabled = true;
} else if (result.result?.disposable) {
message.classList.add('warning');
message.textContent = 'Veuillez utiliser un email permanent pour la récupération de compte';
} else if (result.status === 'valid') {
message.classList.add('success');
message.textContent = '✓ Email vérifié';
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>Cas d'Usage
1. Prévenir les Fausses Inscriptions
Bloquez les emails jetables et invalides lors de l'inscription :
// Extension d'application de thème
async function validateRegistration(email) {
const result = await verifyEmail(email);
if (result.status === 'invalid') {
return {
valid: false,
message: 'Veuillez entrer une adresse email valide',
};
}
if (result.result.disposable) {
return {
valid: false,
message: 'Les adresses email temporaires ne sont pas autorisées',
};
}
return { valid: true };
}2. Récupération de Panier Abandonné
Envoyez uniquement des emails d'abandon aux adresses valides :
Shopify Flow:
Trigger: Checkout abandoned (1 hour delay)
Condition: Check email verification status
If valid:
→ Send abandonment email
→ Add to remarketing audience
If invalid:
→ Skip email
→ Log for analytics3. Évaluation du Risque de Commande
Intégrez la qualité de l'email dans la détection de fraude :
function calculateOrderRiskScore(order, emailVerification) {
let riskScore = 0;
// Facteurs de vérification d'email
if (emailVerification.status === 'invalid') {
riskScore += 30;
}
if (emailVerification.result?.disposable) {
riskScore += 20;
}
if (emailVerification.result?.free && order.total > 500) {
riskScore += 10; // Commande de grande valeur avec email gratuit
}
// Autres facteurs...
if (order.billing_address !== order.shipping_address) {
riskScore += 15;
}
return riskScore;
}4. Segmentation Client
Créez des segments de clients basés sur la qualité de l'email :
| Segment | Critères | Stratégie Marketing |
|---|---|---|
| Haute Valeur | Vérifié, email professionnel | Campagnes premium |
| Standard | Vérifié, email gratuit | Campagnes régulières |
| À Risque | Non vérifié, compte ancien | Campagne de re-vérification |
| Exclus | Invalide, jetable | Pas de marketing |
Configuration des Metafields
Créez des metafields pour stocker les données de vérification :
Metafields Client
mutation createMetafieldDefinitions {
metafieldDefinitionCreate(definition: {
namespace: "email_verification"
key: "status"
name: "Email Verification Status"
type: "single_line_text_field"
ownerType: CUSTOMER
}) {
createdDefinition { id }
}
}Metafields recommandés :
| Namespace | Key | Type | Description |
|---|---|---|---|
| email_verification | status | single_line_text_field | valid, invalid, unknown |
| email_verification | score | number_decimal | 0.0 - 1.0 |
| email_verification | verified_at | date_time | Date de dernière vérification |
| email_verification | disposable | boolean | Est un email jetable |
| email_verification | role_based | boolean | Est un email basé sur un rôle |
Accéder aux Metafields dans Liquid
{% if customer.metafields.email_verification.status == 'valid' %}
<span class="verified-badge">✓ Vérifié</span>
{% endif %}Vérification en Masse des Clients
Nettoyez votre liste de clients existante :
Exporter les Clients
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;
// Filtrer les clients non vérifiés
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;
}Vérification et Mise à Jour en Masse
async function bulkVerifyCustomers(customers) {
const emails = customers.map((c) => c.email);
// Soumettre le travail de vérification en masse
const job = await emailVerify.verifyBulk(emails);
// Attendre la fin
const results = await waitForJobCompletion(job.job_id);
// Mettre à jour les clients avec les résultats
for (const result of results) {
const customer = customers.find((c) => c.email === result.email);
if (customer) {
await updateCustomerVerificationStatus(customer.id, result);
}
}
return results;
}Bonnes Pratiques
1. Vérifier à Plusieurs Points
- Inscription : Bloquer les faux comptes
- Paiement : Assurer que les notifications de commande atteignent les clients
- Abandon de panier : Ne pas gaspiller d'emails sur des adresses invalides
2. Mettre en Cache les Résultats
Mettez en cache les résultats de vérification pour éviter les appels API redondants :
const CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 heures
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. Gérer les Cas Particuliers
function handleVerificationResult(result, context) {
switch (result.status) {
case 'valid':
// Flux normal
break;
case 'invalid':
if (context === 'checkout') {
// Ne pas bloquer le paiement, juste logger
logInvalidEmail(result.email, 'checkout');
} else if (context === 'registration') {
// Bloquer l'inscription
throw new Error('Invalid email');
}
break;
case 'unknown':
// Accepter mais marquer pour révision
flagForReview(result.email);
break;
case 'accept_all':
// Valide mais surveiller les rebonds
markAsCatchAll(result.email);
break;
}
}4. Surveiller et Optimiser
Suivez ces métriques :
- Taux de réussite de vérification
- Réduction du taux de rebond
- Taux de prévention de faux comptes
- Délivrabilité des emails d'abandon de panier