/** * Email service powered by Resend. * * Required env vars: * RESEND_API_KEY * STORE_EMAIL_FROM (e.g. "orders@yourstore.com") * STORE_NAME (e.g. "My Store") */ import { Resend } from "resend"; let _resend: Resend | null = null; function getResend(): Resend { if (!_resend) { if (!process.env.RESEND_API_KEY) { throw new Error("RESEND_API_KEY is not configured"); } _resend = new Resend(process.env.RESEND_API_KEY); } return _resend; } const FROM = process.env.STORE_EMAIL_FROM || "noreply@yourstore.com"; const STORE_NAME = process.env.STORE_NAME || "My Store"; export async function sendMagicLink(email: string, token: string, baseUrl: string) { const link = `${baseUrl}/account/verify?token=${token}`; try { await getResend().emails.send({ from: FROM, to: email, subject: `Sign in to ${STORE_NAME}`, html: `

Click the link below to sign in to ${STORE_NAME}. This link expires in 15 minutes.

Sign In →

If you didn't request this, you can safely ignore this email.

`, }); } catch (err) { console.error("[email] sendMagicLink failed:", err); } } export async function sendOrderConfirmation(params: { email: string; orderNumber: string; total: string; items: Array<{ title: string; variantTitle?: string; quantity: number; price: string }>; shippingAddress?: any; }) { const itemsHtml = params.items .map( (item) => ` ${item.title}${item.variantTitle ? ` — ${item.variantTitle}` : ""} ${item.quantity} $${item.price} ` ) .join(""); const addr = params.shippingAddress; const addrHtml = addr ? `

Ship to:
${addr.firstName} ${addr.lastName}
${addr.address1}${addr.address2 ? `, ${addr.address2}` : ""}
${addr.city}, ${addr.state} ${addr.zip}

` : ""; try { await getResend().emails.send({ from: FROM, to: params.email, subject: `Order confirmed — #${params.orderNumber}`, html: `

Thanks for your order!

Order #${params.orderNumber} has been received and is being processed.

${itemsHtml}
Item Qty Price
Total $${params.total}
${addrHtml}

Thank you for shopping with ${STORE_NAME}.

`, }); } catch (err) { console.error("[email] sendOrderConfirmation failed:", err); } } export async function sendShippingNotification(params: { email: string; orderNumber: string; trackingNumber: string; trackingCarrier?: string; }) { try { await getResend().emails.send({ from: FROM, to: params.email, subject: `Your order #${params.orderNumber} has shipped`, html: `

Great news! Your ${STORE_NAME} order #${params.orderNumber} is on its way.

Tracking number: ${params.trackingNumber}${params.trackingCarrier ? ` (${params.trackingCarrier})` : ""}

Thank you for your order!

`, }); } catch (err) { console.error("[email] sendShippingNotification failed:", err); } }