本功能是基于实现微信支付商户转账到用户零钱功能,该功能里要求发送API请求时,HTTP头信息里需要携带Authorization签名字符串。因此,讲解下如何使用php生成微信支付V3版本的签名。
参考文档:
该处实现的签名是依照微信支付官方文档请求参数里带body参数来计算签名的。
请求参数里带Body参数(包体参数),如何计算签名_通用规则|微信支付商户文档中心
实现代码:
function generateAuthorizationHeader($method, $url, $body, $mchid, $serial_no, $private_key_path) {
// 1. 从文件中读取私钥内容
if (!file_exists($private_key_path)) {
throw new Exception("Private key file not found: {$private_key_path}");
}
$private_key = file_get_contents($private_key_path);
if ($private_key === false) {
throw new Exception("Failed to read private key file: {$private_key_path}");
}
// 2. 构造请求方法、URL、时间戳、随机字符串和请求体
$timestamp = time();
$nonce = bin2hex(random_bytes(16)); // 生成随机字符串
$body_json = json_encode($body);
// 3. 构造签名串
$signature_str = "{$method}\n{$url}\n{$timestamp}\n{$nonce}\n{$body_json}\n";
// 4. 生成签名
openssl_sign($signature_str, $signature, $private_key, OPENSSL_ALGO_SHA256);
$signature_base64 = base64_encode($signature);
// 5. 构造 Authorization 头
$authorization = sprintf(
'WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",signature="%s",timestamp="%d",serial_no="%s"',
$mchid,
$nonce,
$signature_base64,
$timestamp,
$serial_no
);
return $authorization;
}
调用方法:
$method = 'POST';
$url = '/v3/fund-app/mch-transfer/transfer-bills';
$body=[
'appid' => "wx955b********87", //绑定微信支付的公众号/小程序appid
'out_bill_no' => "wxzf".date('YmdHis',time()).rand(10000000,99999999), //系统唯一订单编号
'transfer_scene_id' => "1005", //转账场景ID
'openid' => "otcb16_xt*********c__g0", //转账到个人账户的微信在公众号或小程序注册的openid
'transfer_amount' => 10, //转账金额(单位分)
'transfer_remark' => "佣金报酬", //转账备注
'transfer_scene_report_infos' => [ //转账场景报备信息
["info_type"=>"岗位类型","info_content"=>"邀请者"],
["info_type"=>"报酬说明","info_content"=>"邀请奖励提现"],
]
];
$mchid = '156******1'; //微信支付商户号
$serial_no = '19CB540E460E43*********1D10ACD3A0BE8DF3F'; //证书序列号
$private_key_path = './cert/apiclient_key.pem'; // 私钥文件路径(需要根据自己实际项目做更改)
try {
$authorization = generateAuthorizationHeader($method, $url, $body, $mchid, $serial_no, $private_key_path);
echo "Authorization: " . $authorization . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
代码中需要注意的几个点:
一:转账场景ID如何获取
二:转账场景报备信息配置
参考文档:
这里的岗位类型和报酬说明都要配置到代码中,缺一不可。
三:代码中用到的密钥证书和$serial_no证书序列号如何获取
配置API证书可以点击查看指引获取详细步骤,在此不做赘述。
证书生成之后,如下:
上面我们代码中用到的就是这里面的私钥证书。
点击管理证书按钮,可以看到API证书序列号。
注意:微信支付商家转账官方文档里标注的Wechatpay-Serial是微信支付平台证书序列号。
这个标注非常具有迷惑性,不小心就理解成了验证微信支付身份的平台证书了,因为这里的证书也有序列号,如果配置成了该证书的序列号,代码执行时会报非商户API证书序列号的错误。
可以访问下面的链接获取验签工具对上面生成的签名进行验证。