PHP数组转换成json字符串包含转义字符导致支付签名失败

问题描述

今天,很长时间运行都比较稳定的系统出现了一个错误,错误内容:创建预支付订单失败,原因是签名验证失败。很奇怪,其它的商品都可以支付成功,只有一个叫“一分钱抢购爆浆麻薯\雪糯芝蛋糕”的商品支付不了。对比了正常的请求包,没有什么异常,看了代码发现请求数最终是以json字符串的形式传递的。初步猜测是因为json_econde支付内容不一样了。

问题验证

带着这个猜测,看了签名代码:

1
$subject = '一分钱抢购爆浆麻薯\雪糯芝蛋糕';

签名的时候用了$subject这个变量,得到$sign之后。把$sign、$subject等其它参数json_encode之后(\u4e00\u5206\u94b1\u62a2\u8d2d\u7206\u6d46\u9ebb\u85af\\u96ea\u7cef\u829d\u86cb\u7cd5)传递给第三方服务器。这时候第三方Unicode解码之后拿到的subject是:“一分钱抢购爆浆麻薯\\雪糯芝蛋糕”,和签名的时候是比,多了一个\,这样就报了:签名失败的错误提示。

PHP编程上json_decode是正常转义的,代码如下:

1
2
3
4
5
6
7
8
9
$arr = ['k'=> "好\好"];

$json_str = json_encode($arr);

var_dump($json_str); // string(22) "{"k":"\u597d\\\u597d"}"

$arr1 = json_decode($json_str, true);

var_dump($arr1); // array(1) { ["k"]=>string(7)"好\好"}