PHP获取Stripe Checkout Session中使用的优惠码问题求助
问题分析与修复方案
核心问题排查
未定义的
$customer_email变量
代码直接使用$customer_email但未赋值,SQL绑定参数时会因变量不存在失败,这是导致数据库写入失败的关键原因之一。优惠码属性访问逻辑错误
$session->total_details->breakdown->discounts是数组类型,不能直接通过->discount访问单个对象(Stripe Checkout仅支持单个优惠码,需取数组第一个元素)- 若用户未使用优惠码,
discounts为空数组,直接访问深层属性会触发PHP错误,中断代码执行但不会被Exception捕获(因为这类属于Notice/Warning级错误)
错误覆盖不完整
PHP的非致命错误(如未定义属性)不会被Exceptioncatch块捕获,导致这类错误静默发生,无法通过现有日志排查。
修复后的代码示例
switch ($event->type) { case 'checkout.session.completed': $sessionMain = $event->data->object; $checkoutID = $sessionMain->id; // 初始化变量,避免未定义 $customer_email = $sessionMain->customer_email ?? ''; $promotionCode = ''; try { $session = \Stripe\Checkout\Session::retrieve([ 'id' => $checkoutID, 'expand' => ['total_details.breakdown'], ]); // 安全读取优惠码 if (!empty($session->total_details->breakdown->discounts)) { $discountItem = $session->total_details->breakdown->discounts[0]; if (isset($discountItem->discount->coupon->name)) { $promotionCode = $discountItem->discount->coupon->name; } } $sql = "INSERT INTO orders (customer_email, discount_code) VALUES (?, ?)"; $stmt = $conn->prepare($sql); $stmt->bind_param("ss", $customer_email, $promotionCode); if ($stmt->execute()) { http_response_code(200); } else { error_log('Database insert failed: ' . $stmt->error); http_response_code(500); } $stmt->close(); } catch (Exception $e) { error_log('General error: ' . $e->getMessage()); http_response_code(500); } // 兜底返回200,避免Stripe重复发送Webhook http_response_code(200); break; }
额外建议
- 开启PHP错误日志的Notice/Warning级别记录,排查静默错误
- 测试两种场景:使用优惠码和不使用优惠码,确保逻辑覆盖完整
- 对Stripe返回的所有嵌套属性,优先用
isset()或empty()做存在性检查
内容的提问来源于stack exchange,提问作者Ralph
相关产品推荐
相关产品推荐

