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

SkipCash支付请求提交失败:BytePositionInLine1错误排查求助

问题分析与修复方案

核心问题定位

从返回的错误信息"-' is invalid within a number..."来看,问题集中在请求格式不匹配、签名生成逻辑错误,以及字段格式不符合API要求:

1. 请求体格式冲突

你设置了Content-Type: application/json,但通过CURLOPT_POSTFIELDS传递的是PHP数组,curl会自动将其编码为application/x-www-form-urlencoded格式,这和声明的Content-Type矛盾,导致API解析JSON时出错。

2. 签名生成逻辑错误

当前代码先把数组转成逗号分隔的query字符串再转JSON,完全不符合支付网关常见的签名规则——通常是直接对原始请求JSON字符串或排序后的键值对字符串签名。

3. 金额字段格式问题

number_format($order->total_amount, 2)会生成带千分位逗号的字符串(比如1,200.00),很多支付网关不支持这种格式,会被当作非法数字解析。


修复后的代码

$formData = [
    "uid" => Str::uuid()->toString(),
    "keyId" => $skipCashKeyId,
    // 去掉千分位逗号,保留两位小数的字符串格式
    "amount" => number_format($order->total_amount, 2, '.', ''),
    "firstName" => $order->user->first_name,
    "lastName" => $order->user->last_name,
    "phone" => $order->user->phone_number,
    "email" => $order->user->email,
    "street" => "CA",
    "city" => "TempCity",
    "state" => "00",
    "country" => "00",
    "postCode" => "01238",
    "transactionId" => $order->reference_no,
    "orderId" => $order->id
];

// 直接将请求数组转为JSON字符串,用于签名和请求体
$requestJson = json_encode($formData);

// 用原始请求JSON生成HMAC签名
$signature = hash_hmac('sha256', $requestJson, $skipCashSecretKey);

$headers = [
    'Authorization: ' . base64_encode($signature),
    'Content-Type: application/json;charset=UTF-8',
    'x-client-id: ' . $skipCashClientId
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $skipCashUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// 传递JSON字符串作为请求体,匹配Content-Type声明
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestJson);

// 新增curl错误排查
if(curl_errno($ch)){
    echo 'Curl error: ' . curl_error($ch);
}

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response);

额外排查建议

  • 确认签名规则:如果上述修复后仍报错,部分网关要求对排序后的键值对字符串签名,可尝试对$formData按键名排序后再转JSON生成签名。
  • 检查字段类型:若orderId或transactionId包含-且被API当作数字解析,需确认API是否要求这两个字段为纯数字,若为字符串类型则确保传递时是字符串格式。
  • 开启调试:添加curl_setopt($ch, CURLOPT_VERBOSE, true);可以查看完整请求头和请求体,便于对比API文档要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:35:24