EmailVerify LogoEmailVerify

Shopify

Email checker for Shopify. Verify customer emails at checkout and in Shopify apps.

Bescherm uw Shopify-winkel tegen nepaccounts, verminder bounce van verlaten winkelwagen-e-mails en verbeter klantcommunicatie door e-mailadressen te verifiëren.

Waarom e-mails verifiëren in Shopify?

UitdagingImpactOplossing
NepaccountsPromo-misbruik, fraudeVerifiëren bij registratie
Verlaten winkelwagenGebounced herstel-e-mailsVerifiëren voor verzending
OrdernotificatiesMislukte bezorgupdatesVerifiëren bij checkout
MarketingcampagnesLage afleverbaarheidKlantenlijst opschonen

Integratiemethoden

MethodeBeste voorComplexiteit
Shopify FlowGeautomatiseerde workflowsLaag
Shopify FunctionsCheckout-validatieGemiddeld
App van derdenVolledige oplossingLaag
Aangepaste appVolledige controleHoog

Methode 1: Shopify Flow (Aanbevolen)

Gebruik Shopify Flow om e-mails automatisch te verifiëren.

Nieuwe klant-e-mails verifiëren

Maak een workflow om e-mails te verifiëren wanneer klanten zich registreren:

Trigger: Customer created

Conditie: Customer email is not blank

Acties:

  1. HTTP-verzoek verzenden naar EmailVerify
  2. Klanttag toevoegen op basis van resultaat

Flow-configuratie

Workflow: Verify New Customer Email

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 YOUR_API_KEY
    - 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)

Verifiëren voor verlaten winkelwagen-e-mails

Workflow: Verify Before Abandonment Email

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 email

Methode 2: Checkout-validatie met Shopify Functions

Maak een Shopify Function om e-mails tijdens checkout te valideren.

Stap 1: Maak een 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: For real-time validation, use a pre-validated cache
  // or implement async validation via metafield
  return {
    operations: [],
  };
}

Stap 2: Maak een Checkout UI Extension

// 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">
        Please check your email address. It appears to be invalid.
      </Banner>
    );
  }

  if (validationStatus.result?.disposable) {
    return (
      <Banner status="info">
        We recommend using a permanent email for order updates.
      </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();
}

Methode 3: Aangepaste Shopify App

Bouw een complete e-mailverificatie-oplossing.

App Backend (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,
});

// API route for email verification
export async function action({ request }) {
  const { email, customerId } = await request.json();

  try {
    const result = await emailVerify.verify(email);

    // Update customer metafield
    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"
          }
        ]
      }
    }
  });
}

Webhook Handler

Behandel klant-aanmaak webhooks:

// 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 {
    // Verify email
    const result = await emailVerify.verify(email);

    // Update customer with 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);

    // Store verification result
    await updateCustomerVerificationStatus(shop, id, result);

    console.log(`Verified ${email}: ${result.status}`);
  } catch (error) {
    console.error(`Failed to verify ${email}:`, error);
  }
}

Thema-integratie (Liquid)

Voeg verificatie toe aan registratieformulier:

{% 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;

    // Show loading state
    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();

      // Update UI based on result
      updateEmailFieldUI(verificationResult);
    } catch (error) {
      console.error('Verification failed:', error);
    } finally {
      emailInput.classList.remove('verifying');
    }
  });

  function updateEmailFieldUI(result) {
    // Remove existing messages
    const existingMessage = document.querySelector('.email-verification-message');
    if (existingMessage) existingMessage.remove();

    // Create message element
    const message = document.createElement('div');
    message.className = 'email-verification-message';

    if (result.status === 'invalid') {
      message.classList.add('error');
      message.textContent = 'Please enter a valid email address';
      submitButton.disabled = true;
    } else if (result.result?.disposable) {
      message.classList.add('warning');
      message.textContent = 'Please use a permanent email for account recovery';
    } else if (result.status === 'valid') {
      message.classList.add('success');
      message.textContent = '✓ Email verified';
      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>

Gebruiksscenario's

1. Nepaccountregistratie voorkomen

Blokkeer wegwerp- en ongeldige e-mails tijdens aanmelding:

// Theme app extension
async function validateRegistration(email) {
  const result = await verifyEmail(email);

  if (result.status === 'invalid') {
    return {
      valid: false,
      message: 'Please enter a valid email address',
    };
  }

  if (result.result.disposable) {
    return {
      valid: false,
      message: 'Temporary email addresses are not allowed',
    };
  }

  return { valid: true };
}

2. Verlaten winkelwagen-herstel

Verzend alleen herstel-e-mails naar geldige adressen:

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 analytics

3. Orderrisicobeoordeling

Factor e-mailkwaliteit in bij fraudedetectie:

function calculateOrderRiskScore(order, emailVerification) {
  let riskScore = 0;

  // Email verification factors
  if (emailVerification.status === 'invalid') {
    riskScore += 30;
  }

  if (emailVerification.result?.disposable) {
    riskScore += 20;
  }

  if (emailVerification.result?.free && order.total > 500) {
    riskScore += 10; // High value order with free email
  }

  // Other factors...
  if (order.billing_address !== order.shipping_address) {
    riskScore += 15;
  }

  return riskScore;
}

4. Klantsegmentatie

Maak klantsegmenten op basis van e-mailkwaliteit:

SegmentCriteriaMarketingstrategie
Hoge waardeGeverifieerd, zakelijke e-mailPremiumcampagnes
StandaardGeverifieerd, gratis e-mailReguliere campagnes
RisicoNiet geverifieerd, oud accountHerverificatiecampagne
UitgeslotenOngeldig, wegwerpGeen marketing

Metafield-setup

Maak metafields om verificatiegegevens op te slaan:

Klant-metafields

mutation createMetafieldDefinitions {
  metafieldDefinitionCreate(definition: {
    namespace: "email_verification"
    key: "status"
    name: "Email Verification Status"
    type: "single_line_text_field"
    ownerType: CUSTOMER
  }) {
    createdDefinition { id }
  }
}

Aanbevolen metafields:

NamespaceKeyTypeBeschrijving
email_verificationstatussingle_line_text_fieldvalid, invalid, unknown
email_verificationscorenumber_decimal0.0 - 1.0
email_verificationverified_atdate_timeLaatste verificatiedatum
email_verificationdisposablebooleanIs wegwerp-e-mail
email_verificationrole_basedbooleanIs rol-gebaseerde e-mail

Metafields in Liquid benaderen

{% if customer.metafields.email_verification.status == 'valid' %}
  <span class="verified-badge">✓ Verified</span>
{% endif %}

Bulk klantverificatie

Schoon uw bestaande klantenlijst op:

Klanten exporteren

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;

    // Filter unverified customers
    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;
}

Bulk verifiëren en bijwerken

async function bulkVerifyCustomers(customers) {
  const emails = customers.map((c) => c.email);

  // Submit bulk verification job
  const job = await emailVerify.verifyBulk(emails);

  // Wait for completion
  const results = await waitForJobCompletion(job.job_id);

  // Update customers with results
  for (const result of results) {
    const customer = customers.find((c) => c.email === result.email);
    if (customer) {
      await updateCustomerVerificationStatus(customer.id, result);
    }
  }

  return results;
}

Best practices

1. Verifieer op meerdere punten

  • Registratie: Blokkeer nepaccounts
  • Checkout: Zorg dat ordernotificaties klanten bereiken
  • Verlaten winkelwagen: Verspil geen e-mails aan ongeldige adressen

2. Cache resultaten

Cache verificatieresultaten om redundante API-calls te vermijden:

const CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 hours

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. Behandel randgevallen

function handleVerificationResult(result, context) {
  switch (result.status) {
    case 'valid':
      // Normal flow
      break;

    case 'invalid':
      if (context === 'checkout') {
        // Don't block checkout, just log
        logInvalidEmail(result.email, 'checkout');
      } else if (context === 'registration') {
        // Block registration
        throw new Error('Invalid email');
      }
      break;

    case 'unknown':
      // Accept but flag for review
      flagForReview(result.email);
      break;

    case 'accept_all':
      // Valid but monitor for bounces
      markAsCatchAll(result.email);
      break;
  }
}

4. Monitor en optimaliseer

Volg deze metrics:

  • Verificatie-succespercentage
  • Bouncepercentage-reductie
  • Nepaccount-preventiepercentage
  • Verlaten winkelwagen-e-mail afleverbaarheid

Gerelateerde bronnen

On this page