Skip to main content
Resend is the email service provider used in PC Fix for sending transactional emails including order confirmations, status updates, password resets, and customer notifications.

Overview

PC Fix uses Resend to send:
  • Order Updates: Status changes, shipping notifications
  • Customer Support: Contact confirmations, inquiry replies
  • Authentication: Welcome emails, password resets
  • Marketing: Abandoned cart reminders, stock alerts, price drops

Configuration

1

Create a Resend Account

Sign up for an account at resend.com. The free tier includes 100 emails per day.
2

Generate an API Key

Go to API Keys in your Resend dashboard and create a new API key with send permissions.
3

Verify Your Domain (Optional)

For production use, verify your sending domain in Resend to improve deliverability and remove “via resend.com” from emails.
4

Set Environment Variables

Add these variables to your .env file in the packages/api directory:
RESEND_API_KEY=re_your_api_key
EMAIL_FROM="PCFIX <[email protected]>"
REPLY_TO=[email protected]
ADMIN_EMAIL=[email protected]
FRONTEND_URL=http://localhost:4321
Keep your RESEND_API_KEY secret. Never expose it in client-side code or commit it to version control.

Email Service Implementation

The EmailService class is located at packages/api/src/shared/services/EmailService.ts:
import { Resend } from 'resend';

export class EmailService {
  private resend: Resend;
  private frontendUrl: string;

  constructor() {
    this.resend = new Resend(process.env.RESEND_API_KEY);
    this.frontendUrl = process.env.FRONTEND_URL || 'http://localhost:4321';
  }

  async sendEmail(to: string, subject: string, htmlContent: string) {
    try {
      const fromEmail = process.env.EMAIL_FROM || 'PCFIX <[email protected]>';
      const replyToAddress = process.env.REPLY_TO || '[email protected]';

      const { data, error } = await this.resend.emails.send({
        from: fromEmail,
        replyTo: replyToAddress,
        to,
        subject,
        html: htmlContent,
      });

      if (error) {
        console.error('Error sending email (Resend):', error);
        return false;
      }

      return true;
    } catch (error) {
      console.error('Unexpected error sending email:', error);
      return false;
    }
  }
}

Available Email Templates

The EmailService provides pre-built templates for common scenarios:

Order & Payment Emails

await emailService.sendStatusUpdate(
  userEmail,
  saleId,
  'APROBADO',
  'ENVIO',
  'TR123456789'
);

Authentication Emails

await emailService.sendWelcomeEmail(
  email,
  name
);

Customer Support

await emailService.sendContactConfirmationEmail(
  userEmail,
  userName
);

Marketing Emails

await emailService.sendAbandonedCartEmail(
  userEmail,
  userName,
  products
);

Email Template Structure

All email templates follow a consistent HTML structure:
<div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 
            color: #1f2937; max-width: 600px; margin: 0 auto; 
            background-color: #ffffff; border: 1px solid #e5e7eb; 
            border-radius: 12px; overflow: hidden;">
  
  <!-- Header -->
  <div style="background-color: #111827; padding: 25px; text-align: center;">
    <h1 style="color: #ffffff; margin: 0; font-size: 24px; font-weight: 800;">
      PC FIX
    </h1>
  </div>

  <!-- Content -->
  <div style="padding: 30px;">
    <!-- Email content here -->
  </div>
  
  <!-- Footer -->
  <div style="background-color: #f9fafb; padding: 20px; text-align: center; 
              border-top: 1px solid #e5e7eb; font-size: 12px; color: #9ca3af;">
    <p style="margin: 0;">PC FIX - Experiencia en Hardware</p>
  </div>
</div>
Email templates use inline CSS for maximum compatibility across email clients.

Usage Example

Here’s how to use the email service in your controllers:
sales.controller.ts
import { EmailService } from '@/shared/services/EmailService';

const emailService = new EmailService();

export const updateSaleStatus = async (req: Request, res: Response) => {
  const { id } = req.params;
  const { estado, tipoEntrega, codigoSeguimiento } = req.body;

  // Update sale in database
  const sale = await prisma.venta.update({
    where: { id: Number(id) },
    data: { estado, codigoSeguimiento },
  });

  // Send status update email
  if (sale.cliente?.email) {
    await emailService.sendStatusUpdate(
      sale.cliente.email,
      sale.id,
      estado,
      tipoEntrega,
      codigoSeguimiento
    );
  }

  res.json({ success: true, sale });
};

Order Status Messages

The sendStatusUpdate method automatically generates appropriate messages for each status:
StatusIconMessage
APROBADOYour payment has been approved! We’re preparing your order.
PENDIENTE_APROBACIONWe received your receipt. Our team is verifying the payment.
RECHAZADOWe couldn’t verify your payment. Please check the receipt.
CANCELADO🚫Your order has been cancelled.
ENVIADO (Pickup)🏪Your order is ready for pickup at our store!
ENVIADO (Delivery)🚚Your order is on its way! Track it with code: .
ENTREGADO🚀Thank you for trusting PC FIX! Enjoy your hardware!

Environment Variables

RESEND_API_KEY
string
required
Your Resend API key from the dashboard
EMAIL_FROM
string
default:"PCFIX <[email protected]>"
The sender email address and name
REPLY_TO
string
Reply-to email address for customer responses
ADMIN_EMAIL
string
Admin email for receiving notifications about new inquiries and receipts
FRONTEND_URL
string
default:"http://localhost:4321"
Frontend URL for generating links in emails

Testing Emails

Resend provides a test mode for development:
// Test email in development
if (process.env.NODE_ENV === 'development') {
  console.log('📧 Email would be sent to:', to);
  console.log('📝 Subject:', subject);
}

Deliverability Tips

Add SPF, DKIM, and DMARC records to your domain to improve deliverability and remove “via resend.com” from emails.
Use a recognizable sender name like “PCFIX” rather than just an email address.
Check your Resend dashboard regularly for bounced emails and remove invalid addresses.

Error Handling

The email service includes error handling:
if (error) {
  console.error('🔥 Error sending email (Resend):', error);
  return false; // Email failed to send
}
return true; // Email sent successfully
Always check the return value when sending critical emails:
const sent = await emailService.sendStatusUpdate(...);
if (!sent) {
  // Handle email failure (log, retry, notify admin)
  console.error('Failed to send status update email');
}

Rate Limits

  • Free Tier: 100 emails per day
  • Paid Plans: Higher limits based on plan
Implement rate limiting or queueing for high-volume scenarios to avoid hitting API limits.

Build docs developers (and LLMs) love