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
相关产品推荐
相关产品推荐

