如何处理Stripe Webhook?实现支付成功触发MailerSend邮件通知
解决Stripe Webhook触发MailerSend邮件通知的问题
首先,你代码里的一个潜在问题是checkout.session.completed分支没有添加break,导致执行完该分支逻辑后会继续进入default分支,这可能让你误以为自定义代码没生效。下面是完整的修改方案:
1. 修正分支逻辑并集成邮件发送
在checkout.session.completed分支中,从Stripe返回的session对象提取客户邮箱、订单信息,再调用MailerSend的发信方法,同时添加break避免执行默认分支代码:
public function webhook(Request $request) { $stripe = new \Stripe\StripeClient('sk_XXX'); $endpoint_secret = 'whsec_XXX'; $payload = @file_get_contents('php://input'); $sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE']; $event = null; try { $event = \Stripe\Webhook::constructEvent( $payload, $sig_header, $endpoint_secret ); } catch(\UnexpectedValueException $e) { http_response_code(400); exit(); } catch(\Stripe\Exception\SignatureVerificationException $e) { http_response_code(400); exit(); } // Handle the event switch ($event->type) { case 'checkout.session.completed': $session = $event->data->object; // 1. 提取客户邮箱:优先用session自带的邮箱,无则通过客户ID获取 $customerEmail = $session->customer_email; if (!$customerEmail && $session->customer) { $customer = $stripe->customers->retrieve($session->customer); $customerEmail = $customer->email; } if ($customerEmail) { // 2. 提取订单详情(可选,用于邮件内容) $lineItems = $stripe->checkout->sessions->allLineItems($session->id); $orderItems = []; foreach ($lineItems->data as $item) { $orderItems[] = $item->description . ' x ' . $item->quantity; } $orderSummary = implode('<br>', $orderItems); // 3. 调用MailerSend发送邮件(替换为你已实现的MailerSend逻辑) try { // 示例:初始化MailerSend客户端 $mailerSend = new \MailerSend\MailerSend(['api_key' => 'your_mailersend_api_key']); $emailContent = [ 'from' => ['email' => 'support@yourbusiness.com', 'name' => '你的品牌'], 'to' => [['email' => $customerEmail]], 'subject' => '支付成功!感谢你的订单', 'html' => "<p>您好,你的订单已完成支付:</p><p>{$orderSummary}</p><p>如有疑问请随时联系我们</p>" ]; $mailerSend->email->send($emailContent); // 记录成功日志,方便排查 error_log('支付成功邮件已发送至:' . $customerEmail); } catch (\Exception $e) { // 记录邮件发送失败日志 error_log('发送支付邮件失败:' . $e->getMessage() . ',Session ID:' . $session->id); } } else { error_log('无法获取客户邮箱,跳过邮件发送,Session ID:' . $session->id); } break; // 必须添加break,避免执行default分支 default: echo 'Received unknown event type ' . $event->type; } http_response_code(200); }
2. 关键注意事项
- 异步处理邮件:Stripe要求Webhook端点在10秒内返回响应,若邮件发送耗时较长,建议用队列(如Laravel Queue)异步处理,避免Stripe重复触发事件。示例:把邮件逻辑封装成任务,用
dispatch(new SendPaymentSuccessEmail($customerEmail, $orderSummary))替代直接调用。 - 日志排查:务必记录邮件发送的成功/失败日志,方便后续定位问题。
- 异常隔离:对MailerSend的调用添加try-catch,避免邮件发送失败导致Webhook返回错误,引发Stripe重试。
- 邮箱验证:确保能从session或customer对象中获取有效邮箱,避免无效邮件发送。
内容的提问来源于stack exchange,提问作者Kai
相关产品推荐
相关产品推荐

