PHP调用Mollie API发起支付出现JSON解析错误及相关警告
排查与修复方案
报错根因
两个异常的触发逻辑完全同源:
- 你在PHP代码中调用跳转Header前,通过
print_r()输出了Mollie支付对象、自定义数组的调试内容,这些内容会被写入HTTP响应流:- 前端AJAX逻辑默认接口返回JSON格式,收到响应开头是
Mollie\Api\Resources\Payment的首字符M,直接触发Uncaught SyntaxError: Unexpected token M in JSON at position 0的解析错误。 - 提前输出的内容会占用响应缓冲区,后续调用
header()跳转函数时会触发PHP原生的headers already sent警告,对应你截图中的提示内容。
- 前端AJAX逻辑默认接口返回JSON格式,收到响应开头是
可直接落地的修复点
- 移除所有创建支付流程中的
print_r()调试输出,禁止在发送跳转Header前向响应流写入任何可见内容 - 按照Mollie API强制要求处理金额参数:接口要求金额必须是精确到两位小数的字符串,直接透传POST参数会因为格式不匹配触发调用失败,需要通过
number_format()做格式标准化 - 跳转Header发送后必须调用
exit终止后续代码执行,避免残留逻辑继续输出内容 - 扩大异常捕获范围,除Mollie自带的API异常外,同时覆盖参数校验、Header发送相关的原生PHP错误,避免错误信息直接泄露到响应流
- 开发环境调试时,将调试信息写入本地日志文件,不要直接输出到Web响应中
- 生产环境关闭错误直接输出的配置,避免错误信息破坏响应格式
修复后的核心代码参考
try { require_once "vendor/autoload.php"; $mollie = new \Mollie\Api\MollieApiClient(); $mollie->setApiKey("test_XXXX"); $orderId = time(); // 金额合法性校验与格式标准化 $rawAmount = floatval($_POST['amount'] ?? 0); if ($rawAmount <= 0) throw new \Exception("无效的支付金额"); $formattedAmount = number_format($rawAmount, 2, '.', ''); $payment = $mollie->payments->create([ "amount" => [ "currency" => "EUR", "value" => $formattedAmount ], "description" => "Order #{$orderId}", "redirectUrl" => "https://example.com/Mollie/return/".$orderId."/", "webhookUrl" => "https://example.com/Mollie/webhook/", "metadata" => ["order_id" => $orderId], ]); // 数据库存储支付记录的逻辑(无任何直接输出) $payment_data = [ 'payment_id' => $payment->id, 'user_id' => $_POST['user_id'], 'order_id' => $orderId, 'mode' => $payment->mode, 'description' => $payment->description, 'status' => $payment->status, 'added_date' => date('Y-m-d'), 'added_time' => date('H:i:s') ]; // 此处替换为数据库写入操作,禁止直接print_r输出内容 // 最后执行跳转,终止后续执行 header("Location: " . $payment->getCheckoutUrl(), true, 303); exit; } catch (\Throwable $e) { // 统一异常处理,记录错误日志 error_log("Mollie支付异常:" . $e->getMessage()); http_response_code(400); echo json_encode(['error' => '支付创建失败,请重试']); exit; }
内容的提问来源于stack exchange,提问作者Sayali
相关产品推荐
相关产品推荐

