emailr_
Tous les articles
usecase·9 min

E-mails pour les marketplaces : notifications multipartites

marketplacenotificationspatterns

Les plateformes de marketplace font face à des défis e-mail uniques : plusieurs parties, des flux de transaction complexes et la nécessité d’instaurer la confiance entre inconnus. Voici comment concevoir des systèmes de notifications multipartites efficaces.

Le défi e-mail des marketplaces

Contrairement aux applications mono-partie, les marketplaces doivent communiquer avec :

  • Des acheteurs qui effectuent des achats
  • Des vendeurs qui exécutent les commandes
  • La plateforme elle-même (litiges, politiques, etc.)

Chaque partie a besoin d’informations différentes à des moments différents, et les e-mails doivent inspirer confiance tout en protégeant la vie privée.

Types de notifications principaux

E-mails du cycle de vie de la commande

À l'acheteur :

Order confirmed → Payment processed → Shipped → Delivered → Review request

Au vendeur :

New order → Payment received → Ship reminder → Delivery confirmed → Payout processed

Exemple : Confirmation de commande (acheteur)

interface BuyerOrderEmail {
  buyer: {
    name: string;
    email: string;
  };
  order: {
    id: string;
    items: OrderItem[];
    total: number;
    estimatedDelivery: string;
  };
  seller: {
    storeName: string;
    // Note: No seller email or personal details
  };
}

const buyerOrderTemplate = `
Hi {{buyer.name}},

Your order #{{order.id}} is confirmed!

Items from {{seller.storeName}}:
{{#each order.items}}
- {{this.name}} × {{this.quantity}}: ${{this.price}}
{{/each}}

Total: ${{order.total}}
Estimated delivery: {{order.estimatedDelivery}}

Track your order: {{trackingUrl}}
`;

Exemple : Nouvelle commande (vendeur)

interface SellerOrderEmail {
  seller: {
    name: string;
    email: string;
  };
  order: {
    id: string;
    items: OrderItem[];
    revenue: number;
    platformFee: number;
    payout: number;
    shippingAddress: Address;
    shipBy: string;
  };
  buyer: {
    // Only what seller needs
    shippingName: string;
  };
}

const sellerOrderTemplate = `
Hi {{seller.name}},

New order #{{order.id}}!

Items to ship:
{{#each order.items}}
- {{this.name}} × {{this.quantity}}
{{/each}}

Ship to:
{{buyer.shippingName}}
{{order.shippingAddress.line1}}
{{order.shippingAddress.city}}, {{order.shippingAddress.state}} {{order.shippingAddress.zip}}

Ship by: {{order.shipBy}}

Revenue: ${{order.revenue}}
Platform fee: -${{order.platformFee}}
Your payout: ${{order.payout}}
`;

Communication respectueuse de la confidentialité

Les marketplaces doivent souvent faciliter la communication entre acheteurs et vendeurs sans exposer les e-mails personnels.

Relais d’e-mails masqués

// Generate masked addresses
function createMaskedEmail(orderId: string, party: 'buyer' | 'seller'): string {
  const token = generateSecureToken(orderId, party);
  return `${token}@relay.marketplace.com`;
}

// When buyer wants to contact seller
const buyerMaskedEmail = createMaskedEmail(order.id, 'buyer');
// [email protected]

// When seller wants to contact buyer  
const sellerMaskedEmail = createMaskedEmail(order.id, 'seller');
// [email protected]

Gestion du relais

// Inbound email handler
async function handleRelayEmail(inbound: InboundEmail) {
  const { token, party } = parseRelayAddress(inbound.to);
  const order = await getOrderByToken(token);
  
  if (!order) {
    return sendBounce(inbound.from, 'Invalid relay address');
  }
  
  // Determine recipient
  const recipient = party === 'buyer' 
    ? order.seller.email 
    : order.buyer.email;
  
  // Forward with masked reply-to
  await sendEmail({
    to: recipient,
    from: '[email protected]',
    replyTo: inbound.to, // Keep the relay address
    subject: `Re: Order #${order.id} - ${inbound.subject}`,
    html: sanitizeHtml(inbound.html),
    headers: {
      'X-Marketplace-Order': order.id,
      'X-Marketplace-Thread': inbound.headers['message-id']
    }
  });
  
  // Log for dispute resolution
  await logMessage({
    orderId: order.id,
    from: party === 'buyer' ? 'seller' : 'buyer',
    content: inbound.text,
    timestamp: new Date()
  });
}

E-mails de transaction multipartites

Séquestre et flux de paiement

// Payment held in escrow
await sendEmail({
  to: buyer.email,
  template: 'payment-held',
  data: {
    amount: order.total,
    releaseCondition: 'Funds will be released to seller upon delivery confirmation'
  }
});

await sendEmail({
  to: seller.email,
  template: 'payment-pending',
  data: {
    amount: order.payout,
    releaseCondition: 'Ship within 3 days to receive payment'
  }
});

// After delivery confirmed
await sendEmail({
  to: seller.email,
  template: 'payment-released',
  data: {
    amount: order.payout,
    arrivalDate: calculatePayoutDate()
  }
});

Notifications de litige

interface DisputeEmail {
  disputeId: string;
  orderId: string;
  reason: string;
  filedBy: 'buyer' | 'seller';
  deadline: string;
}

// Notify both parties
async function notifyDispute(dispute: DisputeEmail) {
  const order = await getOrder(dispute.orderId);
  
  // To the party who filed
  await sendEmail({
    to: dispute.filedBy === 'buyer' ? order.buyer.email : order.seller.email,
    template: 'dispute-filed-confirmation',
    data: {
      disputeId: dispute.disputeId,
      nextSteps: 'We\'ll review and respond within 48 hours'
    }
  });
  
  // To the other party
  await sendEmail({
    to: dispute.filedBy === 'buyer' ? order.seller.email : order.buyer.email,
    template: 'dispute-notification',
    data: {
      disputeId: dispute.disputeId,
      reason: dispute.reason,
      deadline: dispute.deadline,
      responseUrl: `${baseUrl}/disputes/${dispute.disputeId}/respond`
    }
  });
}

E-mails d’intégration des vendeurs

Parcours de vérification

const sellerOnboardingSequence = [
  {
    trigger: 'signup',
    delay: 0,
    template: 'seller-welcome',
    data: { nextStep: 'Verify your identity' }
  },
  {
    trigger: 'identity-submitted',
    delay: 0,
    template: 'identity-review',
    data: { reviewTime: '1-2 business days' }
  },
  {
    trigger: 'identity-approved',
    delay: 0,
    template: 'identity-approved',
    data: { nextStep: 'Add your first listing' }
  },
  {
    trigger: 'first-listing',
    delay: 0,
    template: 'listing-live',
    data: { tips: 'Optimize your listing for search' }
  },
  {
    trigger: 'first-sale',
    delay: 0,
    template: 'first-sale-congrats',
    data: { payoutInfo: true }
  }
];

Notifications de versement

// Weekly payout summary
await sendEmail({
  to: seller.email,
  template: 'payout-summary',
  data: {
    period: 'Dec 23-29, 2025',
    orders: 12,
    grossRevenue: 1250.00,
    platformFees: 125.00,
    refunds: 45.00,
    netPayout: 1080.00,
    payoutDate: 'Dec 31, 2025',
    payoutMethod: 'Bank account ending in 4242'
  }
});

Communications de la plateforme

Mises à jour des politiques

// Segment by user type
async function sendPolicyUpdate(policy: PolicyUpdate) {
  const affectedUsers = await getUsersByType(policy.affectsUserTypes);
  
  for (const user of affectedUsers) {
    await sendEmail({
      to: user.email,
      template: 'policy-update',
      data: {
        policyName: policy.name,
        effectiveDate: policy.effectiveDate,
        summary: policy.summary,
        // Customize based on user type
        impact: policy.impactByUserType[user.type],
        actionRequired: policy.actionRequired[user.type]
      }
    });
  }
}

Confiance et sécurité

// Account warning
await sendEmail({
  to: user.email,
  template: 'account-warning',
  data: {
    violation: 'Policy violation detected',
    details: 'Your listing "XYZ" was removed for...',
    consequence: 'This is your first warning',
    appealUrl: `${baseUrl}/appeals/new`
  }
});

// Account suspension
await sendEmail({
  to: user.email,
  template: 'account-suspended',
  data: {
    reason: 'Multiple policy violations',
    pendingOrders: 'Active orders will be cancelled and refunded',
    pendingPayouts: 'Payouts are on hold pending review',
    appealDeadline: '14 days',
    appealUrl: `${baseUrl}/appeals/new`
  }
});

E-mails d’avis et de notation

Moment d’envoi de la demande d’avis

// Request review after confirmed delivery
async function scheduleReviewRequest(order: Order) {
  const deliveryDate = order.deliveredAt;
  
  // Wait 2 days after delivery
  await scheduleEmail({
    sendAt: addDays(deliveryDate, 2),
    to: order.buyer.email,
    template: 'review-request',
    data: {
      orderId: order.id,
      sellerName: order.seller.storeName,
      items: order.items,
      reviewUrl: `${baseUrl}/orders/${order.id}/review`
    }
  });
}

Notification d’avis au vendeur

await sendEmail({
  to: seller.email,
  template: 'new-review',
  data: {
    rating: 5,
    reviewText: 'Great product, fast shipping!',
    orderDate: 'Dec 15, 2025',
    // Don't include buyer name for privacy
    responseUrl: `${baseUrl}/reviews/${review.id}/respond`
  }
});

Architecture e-mail pour l’échelle

Notifications pilotées par les événements

// Central event handler
async function handleMarketplaceEvent(event: MarketplaceEvent) {
  const notifications = getNotificationsForEvent(event.type);
  
  for (const notification of notifications) {
    const recipients = await getRecipients(event, notification.recipientType);
    
    for (const recipient of recipients) {
      await queueEmail({
        to: recipient.email,
        template: notification.template,
        data: await buildTemplateData(event, recipient, notification),
        priority: notification.priority
      });
    }
  }
}

// Event types
type MarketplaceEvent = 
  | { type: 'order.created'; order: Order }
  | { type: 'order.shipped'; order: Order; tracking: TrackingInfo }
  | { type: 'order.delivered'; order: Order }
  | { type: 'dispute.opened'; dispute: Dispute }
  | { type: 'payout.processed'; payout: Payout }
  | { type: 'review.submitted'; review: Review };

Préférences de notification

interface MarketplaceNotificationPrefs {
  // Buyer preferences
  orderUpdates: boolean;        // Can't disable
  shippingUpdates: boolean;     // Can't disable
  promotions: boolean;          // Can disable
  reviewReminders: boolean;     // Can disable
  
  // Seller preferences
  newOrders: boolean;           // Can't disable
  payoutNotifications: boolean; // Can't disable
  performanceReports: boolean;  // Can disable
  sellerTips: boolean;          // Can disable
}

Bonnes pratiques

  1. Protéger la confidentialité - Ne jamais exposer les coordonnées personnelles entre les parties
  2. Identité de l’expéditeur claire - Il doit être évident que les e-mails proviennent de la plateforme
  3. Contenu actionnable - Chaque e-mail doit proposer une prochaine étape claire
  4. Calendrier cohérent - Définir des attentes sur le moment d’arrivée des e-mails
  5. Piste d’audit - Journaliser toutes les communications pour la résolution des litiges
  6. Respect des préférences - Permettre de désactiver les notifications non essentielles

L’e-mail en marketplace consiste à instaurer la confiance entre inconnus tout en protégeant les intérêts de chacun. Concevez vos notifications pour informer, protéger et faciliter des transactions fluides.

e_

Écrit par l'équipe emailr

Nous construisons l'infrastructure email pour les développeurs

Prêt à commencer à envoyer ?

Obtenez votre clé API et envoyez votre premier email en moins de 5 minutes. Aucune carte de crédit requise.