为何支付页面表单数据无法通过SendGrid正常发送?
SendGrid邮件发送故障排查
可直接定位的问题点
- 代码调用的
api/mail.send.json是SendGrid已全面下线的v2版本接口,故障时间节点刚好匹配该接口的封禁周期。旧接口要求的表单传参认证、x-smtpapi配置逻辑已被永久停用,即便替换了API密钥,也会因为认证协议不匹配被直接拦截。 - 认证参数写法错误:代码中把
$user硬编码为字符串'apikey',将API密钥放在api_key表单字段传递,该写法已不被当前接口支持。合法的认证方式是将API密钥放在请求头中,格式为Authorization: Bearer 你的完整API密钥。 - 收件人逻辑冲突:
$json_string数组里硬编码的to字段优先级远高于外层POST参数的to值,SendGrid会优先按照配置里的两个测试邮箱发信,完全覆盖你传入的用户真实账单邮箱、内部通知邮箱,直接表现就是表单数据没有出现在实际发送的邮件里。 - 模板ID格式非法:当前代码里的模板ID
7c4ecc93-8575-a46a3d-9864-97sabedf54119存在结构错位、混入非法字符,根本无法匹配系统内的合法模板,会触发模板加载失败的报错。如果需要启用模板功能,替换为系统内合法生成的36位UUID格式ID即可,无需保留旧的错误配置。 - curl配置不一致:第一封发往支付用户的邮件请求,没有指定强制TLS1.2版本,SendGrid当前所有API端点都拒绝TLS1.1及更低版本的连接,会直接在SSL握手阶段拦截请求。
- HTML语法错误:代码里的mailto链接
<a href='mailto:email@email.com</a>缺少闭合单引号,会导致邮件正文渲染错乱。 - 冗余重复逻辑:两封邮件的curl初始化、配置逻辑完全重复,且没有对接口返回的错误信息做记录、输出,出现故障时无法快速定位具体报错原因。
修正后可正常运行的核心逻辑
// 配置API端点与密钥 $sendgridEndpoint = 'https://api.sendgrid.com/v3/mail/send'; $sendgridApiKey = '替换为你的完整SendGrid API密钥'; // 提取表单数据 $full_name = $_POST['billing-address-first-name'].' '.$_POST['billing-address-last-name']; $address1 = $_POST['billing-address-address1']; $city = $_POST['billing-address-city']; $state = $_POST['billing-address-state']; $postal = $_POST['billing-address-zip']; $phone = $_POST['billing-address-phone']; $amount = $_POST['billing-address-bill-total']; $email = $_POST['billing-address-email']; $discountField = $_POST['discount-code']; $discCode = $discountField != '' ? $discountField : 'N/A'; // 构建邮件正文 $body = "Thank you for paying online.<br/>This email can serve as your receipt.<br/><br/>"; $body .= "Name: $full_name<br/>"; $body .= "Address: <a href='#' style='text-decoration:none;color: #005044;'>$address1 $city, $state $postal</a><br/>"; $body .= "Phone: $phone<br/>"; $body .= "Amount: $amount<br/><br/>"; $body .= "Discount Code Applied: $discCode<br/><br/>"; $body .= "As always, if there are any questions or concerns please email us at <a href='mailto:email@email.com'>email@email.com</a>."; // 封装通用发送方法,消除重复逻辑 function sendMail($toAddress, $subject, $htmlContent, $endpoint, $apiKey) { $requestBody = [ 'personalizations' => [ [ 'to' => [['email' => $toAddress]], 'subject' => $subject ] ], 'from' => ['email' => 'info@email.com'], 'content' => [ ['type' => 'text/html', 'value' => $htmlContent] ], 'categories' => ['Bill Payment'] ]; $ch = curl_init($endpoint); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $apiKey, 'Content-Type: application/json' ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($requestBody)); curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $errorInfo = curl_error($ch); curl_close($ch); // 预留日志记录位,方便后续排查 return ['result' => $response, 'curlError' => $errorInfo]; } // 分别向付款用户、内部联系人发送邮件 sendMail($email, "Online Payment Receipt", $body, $sendgridEndpoint, $sendgridApiKey); sendMail('steve@email.com', "Nolan Painting - Online Payment Receipt", $body, $sendgridEndpoint, $sendgridApiKey);
内容的提问来源于stack exchange,提问作者devberab
相关产品推荐
相关产品推荐

