You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何处理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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 21:28:10