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

Stripe自定义支付流CalculateOrderAmount()函数PHP报错咨询

问题排查方向
  • 前端抛出的Unexpected end of JSON input错误,核心成因是后端接口返回了空响应、中途中断执行,没有输出合法的JSON结构,和前端本身逻辑无关,可按以下优先级排查:
    • 函数调用不匹配:当前定义的CalculateOrderAmount()是无参函数,但创建PaymentIntent的代码中给函数传入了$json_obj->items作为参数,PHP会触发参数不匹配的警告,若未做错误捕获会直接中断脚本执行,前端拿到空响应后就会报JSON解析错误。
    • 全局变量作用域失效:原实现中CalculateOrderAmount()通过global关键字获取$price值,必须保证函数执行时,全局作用域的$price已经完成数据库查询赋值,否则会取到空值,触发后续逻辑报错中断。
    • 数据库执行异常:原SQL直接拼接$_SESSION['orderRef']值,没有做参数绑定,若session值为空、类型不匹配会直接导致SQL执行报错,脚本中断返回空响应。
    • 响应输出缺失:原PaymentIntent创建逻辑完成后,没有将结果转成JSON格式输出给前端,前端自然无法解析到有效内容。
正确实现指引

1. 重构金额计算函数

摒弃依赖全局变量的写法,将数据库连接、订单标识作为明确参数传入函数,同时做SQL参数绑定防注入,注意Stripe要求的金额为对应货币的最小粒度值(欧元的最小单位是分,计算结果需乘100转换):

function CalculateOrderAmount(PDO $dbh, string $orderRef): int
{
    // 预处理SQL避免注入风险
    $stmt = $dbh->prepare('SELECT COUNT(*) as card_count FROM card WHERE orderRef = :order_ref');
    $stmt->bindParam(':order_ref', $orderRef, PDO::PARAM_STR);
    $stmt->execute();
    $result = $stmt->fetch(PDO::FETCH_ASSOC);

    // 示例:单商品单价10欧元,转成分单位返回
    return (int)$result['card_count'] * 10 * 100;
}

2. 修正PaymentIntent创建流程

增加全局错误捕获、统一JSON输出逻辑,杜绝脚本中断导致的空响应:

<?php
// 关闭错误直接输出,避免打乱JSON结构
ini_set('display_errors', 0);
header('Content-Type: application/json');

session_start(); // 用到$_SESSION前必须初始化

try {
    // 初始化数据库连接
    $dbh = new PDO( DB_DSN, DB_USER, DB_PASS );
    $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

    // 解析前端POST的JSON入参
    $json_str = file_get_contents('php://input');
    $json_obj = json_decode($json_str, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new Exception('Invalid request format');
    }

    // 调用金额计算函数
    $amount = CalculateOrderAmount($dbh, $_SESSION['orderRef']);

    // 创建PaymentIntent
    $paymentIntent = \Stripe\PaymentIntent::create([
        'amount' => $amount,
        'currency' => 'eur',
        'payment_method_types' => ['card']
    ]);

    // 输出合法JSON响应给前端
    echo json_encode([
        'clientSecret' => $paymentIntent->client_secret
    ]);
    exit;
} catch (Exception $e) {
    // 异常时也返回合法JSON结构,避免空响应
    http_response_code(400);
    echo json_encode([
        'error' => ['message' => $e->getMessage()]
    ]);
    exit;
}
高频避坑提醒
  • 开发阶段不要用var_dump、echo输出调试内容,这类内容会混在JSON响应中,导致前端解析失败
  • 不要使用欧元数值直接当Stripe的传入金额,必须转换为分的整数单位,否则会触发Stripe参数校验报错
  • 不要依赖全局变量传值,跨作用域的依赖要通过函数参数明确传递,减少隐式作用域不匹配的问题
  • 做入参、session值的非空校验,避免空值触发数据库执行报错

内容的提问来源于stack exchange,提问作者SosoK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 22:15:04