API 请求返回成功,但你的 Webhook 没收到事件;或者日志显示“已送达”,你却不确定邮件是否真的进了收件箱。
最快的处理办法:先用 Resend 测试收件地址模拟送达、退信和投诉,检查 Webhook 与应用处理分支;再用你能访问的真实邮箱验收实际收件和客户端显示。模拟事件不能替代真实投递测试。
接入 Resend Webhook 的开发者:需要验证事件接收、签名校验和端点响应。
QA 工程师:需要为送达、退信和投诉分支设计可重复的测试。
独立开发者:希望先用模拟事件检查自家产品流程,再决定是否补做真实收件验收。
最后更新于 2026 年 10 月 22 日;核对了 Resend 官方测试邮件、Webhook 事件可见性、请求验证及事件记录文档。
email.delivered 表示邮件到达收件方邮件服务器;真实邮箱收到邮件并正确显示,则需要另外验收。它们是不同的检查点,不能相互替代。送达验收:确认事件进入应用
Resend 测试收件地址适合模拟哪些结果?
官方测试邮件说明列出了送达、退信和投诉场景:分别使用 delivered@resend.dev、bounced@resend.dev 和 complained@resend.dev 作为测试收件地址。它们用于触发指定事件,帮助你检查自家产品的事件处理逻辑,并不提供一个可供你查看邮件正文的真实收件箱。Resend 官方测试邮件说明
| 选择 | 能验证什么 | 不能据此断定什么 | 适用场景 |
|---|---|---|---|
| Resend 测试收件地址 | 指定事件是否产生、Webhook 是否到达、应用分支是否正确 | 真实收件箱是否收到、正文渲染是否正常、是否进入垃圾邮件 | 可重复的逻辑测试 |
| 受控真实邮箱 | 实际投递、邮件内容与附件、客户端展示及收件箱分类 | 所有服务商和用户环境都会有相同结果 | 发布前的真实收件验收 |
送达事件的检查流程:确认 Webhook 已订阅 email.delivered,然后向 delivered@resend.dev 发送一封用于测试自家产品的邮件。事件到达端点后,核对 type、data.email_id 和 data.to,并确认它们关联到正确的测试记录。事件字段及其含义以Resend Webhook 事件可见性说明为准。
这一步要分开记录三个状态:
- 请求结果:发送邮件的 API 调用是否返回错误,是否提供邮件标识。
- Webhook 结果:端点是否收到事件、验证签名并返回成功响应。
- 业务结果:数据库或产品状态是否按预期更新,是否能用邮件标识追溯测试记录。
API 请求成功不等于收件箱验收通过。官方事件说明中,email.sent 表示请求成功并将尝试投递;email.delivered 则表示邮件已送达收件方邮件服务器。对开发排障来说,这个区别可以避免把“请求被接受”直接记成“用户已收到邮件”。
退信验收:检查失败分支
退信测试的重点,是确认应用能否识别并正确处理失败事件。向 bounced@resend.dev 发送测试邮件后,检查 Webhook 是否收到 email.bounced,并确认相关错误信息、邮件标识和收件对象进入了正确的失败记录。
接着验证自家产品的处理结果:失败状态是否展示给运维人员,是否停止对该测试地址继续执行不合适的后续通知,日志是否足以定位事件。不要只确认“日志里有一条退信”,还要核对事件是否关联到正确的测试用户和邮件。
官方测试情境中,退信地址会触发 SMTP 550 5.1.1 响应。这个结果只说明该模拟场景可用于检查解析与处置逻辑,不代表所有真实收件服务器都会以同样方式拒收邮件。模拟一次退信,也不能作为生产邮件普遍无法送达的结论。
容易漏掉的边界包括:错误只写入日志而没有更新业务状态;不同邮件的事件被关联到同一条记录;永久拒收和可恢复错误被一概而论。测试时应检查自家产品实际需要的处理规则,并以官方测试说明和事件定义为准。
投诉验收:核对后续状态
模拟投诉事件用于验证应用能否接收并处理投诉类事件,不是模拟真实用户在邮件客户端中的操作。向 complained@resend.dev 发送测试邮件后,检查 Webhook 是否收到 email.complained,并确认它触发了你为自家产品设置的处理规则。
例如,你可以核对测试用户是否被标记、后续发送是否按产品规则处理,以及相关记录能否追溯到这次测试。具体动作由你的产品策略决定;不要因为收到一个模拟事件,就修改真实用户资料或据此推断发件信誉。
email.complained 与退信不是同一种结果:投诉关联的是邮件送达后被标记为垃圾邮件的情形;退信则是投递失败分支。两类测试都能帮助你确认事件处理逻辑,但都不能证明邮件在真实用户的收件箱中如何分类。
模拟送达事件不能证明邮件进入真实收件箱。它验证的是事件与应用的处理链路,而不是目标邮箱实际收到邮件、邮件正文完整或客户端展示正常。需要这些证据时,另用你能访问的受控邮箱进行验收,并记录具体观察到的结果。
接收端验收:核对签名与重复处理
签名校验要使用原始请求体和正确的请求头。Resend 官方示例要求在验证时读取原始请求体,并使用 svix-id、svix-timestamp、svix-signature 及对应 Webhook 的 signing secret。先解析 JSON、再重新序列化可能改变请求内容,导致签名验证失败;操作细节可对照Resend 官方 Webhook 管理与验证示例。
export async function POST(req: NextRequest) {
try {
const payload = await req.text();
const event = resend.webhooks.verify({
payload,
headers: {
id: req.headers.get("svix-id")!,
timestamp: req.headers.get("svix-timestamp")!,
signature: req.headers.get("svix-signature")!,
},
webhookSecret: process.env.RESEND_WEBHOOK_SECRET!,
});
// 验证通过后,再交给业务处理逻辑
return Response.json({ received: true });
} catch {
return new Response("Invalid webhook", { status: 400 });
}
}
围绕接收端,按以下顺序测试自家产品:
- 有效签名:确认合法请求通过验证,事件进入业务处理逻辑。
- 缺失或错误签名:确认请求被拒绝,测试记录和业务状态没有被修改。
- 事件分发:分别检查
email.delivered、email.bounced和email.complained,避免未知类型被误当作送达。 - 处理失败:在测试环境中制造业务处理错误,检查端点响应和日志是否便于定位。
- 重复通知:重放同一测试事件,确认不会重复创建记录或执行不可逆动作。可以结合邮件标识、事件类型和收件对象设计幂等判断。
- 交叉核对:对照 Webhook 请求记录、端点响应和应用日志,判断问题出在事件生成、传输、签名校验还是业务处理。
不要在代码中硬编码固定重试次数或间隔。查看当前事件记录和请求尝试结果,再决定如何排查。Resend 的 Headless Webhook API 说明介绍了事件查询、请求尝试记录、响应状态和事件重放能力,可用来对照端点返回内容与自家日志。
真实收件验收:补足模拟覆盖不到的部分
模拟事件无法检查正文是否完整、附件能否打开、客户端是否正确渲染,也不能证明邮件进入收件箱而不是垃圾邮件文件夹。要验证这些情况,就使用你能登录、且适合测试的受控真实邮箱,检查邮件是否到达、发件人和主题是否正确、HTML 与纯文本内容是否符合预期。
测试记录也要限定结论范围:测试地址触发了模拟事件,说明你检查了对应事件与应用逻辑;受控邮箱实际收到邮件,说明本次测试观察到了该目标邮箱的投递结果。单次真实收件测试不能代表所有服务商和客户端都会有相同表现。
如果你还在梳理发送请求与实际收件的区别,可以参考邮件验证码排查指南;测试数据涉及个人信息时,也可查看邮件隐私注意事项。
若只是临时注册自家测试账号、检查验证码邮件或隔离演示环境数据,MsgGone 可以作为真实收件验收时的临时收件方案之一;它不是 Resend Webhook 模拟器,也不能替代事件测试。你可以从 MsgGone 临时邮箱入口判断是否适合这次受控收件。需要长期找回、回复或持续收信的重要账户,仍应使用你长期掌控的邮箱。
需要收信了?两种地址开箱即用
短期注册、一次性验证码,用临时收件箱:复制地址即可收信,到期自动销毁。需要长期接收又不想暴露真实邮箱,就创建一个转发别名。