Email Settings

Configure email notifications, sender identity, and email templates for your store.


Email Configuration

  1. Go to Admin → Settings → Email
  2. Configure:
Field Description
Enable Email Auth Allow customers to log in via OTP codes
Sender Name Display name for outgoing emails
Sender Email Verified "From" address (e.g., [email protected])
OTP Template Custom Thymeleaf HTML for verification emails
OTP Expiry Validity period in hours (1-168)
Sending Domain Custom domain for email delivery

All settings are stored per store in the database.


Email Providers

Configure your email delivery provider per store. Go to Admin → Settings → Email and add the following custom fields:

Resend (Default)

Field Description
resendApiKey Your Resend API key (re_...)
senderEmail The verified sender address

SendGrid

Field Description
sendgridApiKey Your SendGrid API key (SG...)
senderEmail The verified sender address

AWS SES

Field Description
awsAccessKey AWS IAM access key
awsSecretKey AWS IAM secret key
senderEmail Verified SES sender address

Provider credentials are stored in the database as part of your store settings, not as server environment variables.


Notification Templates

Go to Admin → Settings → Notifications to configure templates for different events:

Event Channels Description
Order Confirmed Email, SMS Sent when an order is confirmed
Order Shipped Email, SMS Sent with tracking information
Order Delivered Email Delivery confirmation
Payment Received Email Payment success notification
Password Reset Email Password reset link

Each template supports variable placeholders (e.g., {{orderNumber}}, {{customerName}}).


Sample Email Templates

OTP Login / Verification

This template is used when customers sign in via email OTP. The following variables are available:

Variable Description
{{otp}} The one-time code (6+ digits)
{{storeName}} Your store's display name
{{baseUrl}} Your store's base URL
{{expiryMinutes}} OTP validity period in minutes
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="utf-8">
  <style>
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 480px; margin: 0 auto; padding: 24px; }
    .header { text-align: center; padding: 24px 0; }
    .otp-code { font-size: 32px; font-weight: 700; letter-spacing: 8px; background: #f0f0f0; padding: 16px 24px; border-radius: 8px; text-align: center; margin: 20px 0; color: #1a1a1a; }
    .footer { color: #999; font-size: 13px; margin-top: 24px; border-top: 1px solid #eee; padding-top: 16px; }
  </style>
</head>
<body>
  <div class="header">
    <h1 th:text="|Welcome to ${storeName}|">Welcome</h1>
  </div>

  <p>Your verification code is:</p>

  <div class="otp-code" th:text="${otp}">123456</div>

  <p>Enter this code to sign in. It expires in <strong th:text="${expiryMinutes}">10</strong> minutes.</p>

  <p th:if="${baseUrl != null}">
    Or click here:
    <a th:href="|${baseUrl}/verify?code=${otp}|">Verify Now</a>
  </p>

  <div class="footer">
    <p>If you didn't request this code, you can safely ignore this email.</p>
    <p th:text="|${storeName}|">Store Name</p>
  </div>
</body>
</html>

Welcome Email (Storefront Registration)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="utf-8">
  <style>
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 480px; margin: 0 auto; padding: 24px; }
    .header { text-align: center; padding: 24px 0; background: #f9fafb; border-radius: 8px; }
    .cta { display: inline-block; background: #4f46e5; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px; margin: 16px 0; }
  </style>
</head>
<body>
  <div class="header">
    <h1 th:text="|Welcome to ${storeName}!|">Welcome!</h1>
  </div>

  <p>Hi <strong th:text="${customerName}">there</strong>,</p>

  <p>Thanks for creating an account. You can now:</p>
  <ul>
    <li>Track your orders</li>
    <li>Save your addresses</li>
    <li>Check out faster</li>
  </ul>

  <a th:href="${baseUrl}" class="cta">Start Shopping</a>

  <p style="color: #999; font-size: 13px;" th:text="|— The ${storeName} team|">— The team</p>
</body>
</html>

Schema-Driven Settings

Notification templates use a schema-driven system. Each event type + channel combination has its own JSON Schema. The admin panel reads the schema to dynamically generate the form.

GET /api/v1/settings/schemas/notifications/order_confirmation

Schemas are public and can be fetched without authentication. This means new notification types can be added without frontend changes.