emailr_
Todos los artículos
usecase·9 min

Email para marketplaces: Notificaciones multiparte

marketplacenotificationspatterns

Las plataformas de marketplace se enfrentan a desafíos de email únicos: múltiples partes, flujos de transacción complejos y la necesidad de mantener la confianza entre desconocidos. Aquí te contamos cómo diseñar sistemas de notificaciones multiparte eficaces.

El desafío del email en marketplaces

A diferencia de las aplicaciones de una sola parte, los marketplaces deben comunicarse con:

  • Compradores que realizan compras
  • Vendedores que cumplen pedidos
  • La propia plataforma (para disputas, políticas, etc.)

Cada parte necesita información distinta en momentos distintos, y los emails deben generar confianza a la vez que protegen la privacidad.

Tipos de notificaciones esenciales

Emails del ciclo de vida del pedido

Para el comprador:

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

Para el vendedor:

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

Ejemplo: Confirmación de pedido (comprador)

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}}
`;

Ejemplo: Nuevo pedido (vendedor)

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}}
`;

Comunicación que preserva la privacidad

Los marketplaces a menudo necesitan facilitar la comunicación entre comprador y vendedor sin exponer emails personales.

Reenvío de email enmascarado

// 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]

Gestión del relay

// 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()
  });
}

Emails de transacciones multiparte

Depósito en garantía (escrow) y flujo de pagos

// 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()
  }
});

Notificaciones de disputas

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`
    }
  });
}

Emails de onboarding de vendedores

Flujo de verificación

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 }
  }
];

Notificaciones de desembolsos

// 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'
  }
});

Comunicaciones de la plataforma

Actualizaciones de políticas

// 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]
      }
    });
  }
}

Confianza y seguridad

// 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`
  }
});

Emails de reseñas y calificaciones

Momento para solicitar reseñas

// 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`
    }
  });
}

Notificación de reseña al vendedor

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`
  }
});

Arquitectura de email para escalar

Notificaciones basadas en eventos

// 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 };

Preferencias de notificación

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
}

Mejores prácticas

  1. Proteger la privacidad - Nunca expongas información de contacto personal entre las partes
  2. Identidad clara del remitente - Deja claro que los emails provienen de la plataforma
  3. Contenido accionable - Cada email debe tener un siguiente paso claro
  4. Tiempos consistentes - Define expectativas sobre cuándo llegarán los emails
  5. Registro de auditoría - Registra todas las comunicaciones para la resolución de disputas
  6. Respeto a las preferencias - Permite desactivar las notificaciones no esenciales

El email en marketplaces consiste en generar confianza entre desconocidos mientras se protegen los intereses de todos. Diseña tus notificaciones para informar, proteger y facilitar transacciones fluidas.

e_

Escrito por el equipo de emailr

Construyendo infraestructura de email para desarrolladores

¿Listo para empezar a enviar?

Obtén tu clave API y envía tu primer email en menos de 5 minutos. No se requiere tarjeta de crédito.