收藏
回答

微信小程序虚拟支付 用户态签名

问题类型 API/组件名称 终端类型 微信版本 基础库版本
Bug wx.requestVirtualPayment 微信iOS客户端 8.0.68 3.14.1

前端调用虚拟支付报错 用户态签名错误 参数根据文档一样 生成的用户态签名验签不通过

$sessionKey = 'FUJPVE9opnEevvjQ+oBN1Q=='; $params = [ 'amount' => '1', 'currencyType' => 'CNY', 'env' => '1', 'goodsDetail' => '{"goodsId":"test001","goodsName":"书豆","goodsNum":"1","goodsPrice":"100","goodsType":"virtual"}', 'mode' => 'prod', 'offerId' => '****************', 'openid' => '******************', 'outTradeNo' => 'WX202602091536482521', 'ts' => '177062260' ]; $appkey = '******************'; $paySig = self::generatePaySig($params, $appkey); $signature =self:: generateUserSignature($params, $sessionKey); // 返回支付参数 $payParams = [ 'outTradeNo' => $outTradeNo, 'timeStamp' => $timeStamp, 'nonceStr' => $nonceStr, 'package' => $package, 'signType' => 'HMAC-SHA256', 'paySign' => $paySig, 'signature'=>$signature, ]; return app('json')->success($payParams); } else { return app('json')->fail('支付请求失败'); } } /** * 生成支付签名(paySig) * @param array $params 参与签名的参数 * @param string $appKey 米大师AppKey * @return string 小写的HMAC-SHA256签名 */ public static function generatePaySig(array $params, string $appKey): string { // 1. 过滤空值参数 $validParams = self::filterEmptyParams($params); // 2. 按参数名ASCII升序排序 ksort($validParams); // 3. 拼接成 key=value 格式的字符串 $signData = self::buildParamsStr($validParams); // 4. 构建完整的签名字符串 $uri = '/cgi-bin/midas/test/pay'; $signStr = $uri . '&' . $signData; // 5. HMAC-SHA256加密(二进制输出后转十六进制) $paySig = hash_hmac('sha256', $signStr, $appKey, true); return strtolower(bin2hex($paySig)); // 确保返回小写的十六进制字符串 } function calc_pay_sig(string $uri, string $post_body, string $appkey): string { // 拼接待签名字符串:uri + '&' + post_body(与Python逻辑完全一致) $need_sign_msg = $uri . '&' . $post_body; // HMAC-SHA256加密(PHP的hash_hmac第二个参数是msg,第三个是key,与Python相反) // 注意:raw_output=true 表示输出二进制数据,再转十六进制(与Python的hexdigest()一致) $pay_sig = hash_hmac('sha256', $need_sign_msg, $appkey, true); $pay_sig = bin2hex($pay_sig); // 转为小写(Python的hexdigest()默认小写) return strtolower($pay_sig); } /** * 用户登录态signature签名算法 * @param string $post_body HTTP POST的数据包体(JSON字符串) * @param string $session_key 当前用户有效的session_key * @return string 用户登录态签名signature(小写十六进制) */ function calc_signature(string $post_body, string $session_key): string { $need_sign_msg = $post_body; // 同样使用HMAC-SHA256,二进制输出后转十六进制 $signature = hash_hmac('sha256', $need_sign_msg, $session_key, true); $signature = bin2hex($signature); return strtolower($signature); }
回答关注问题邀请回答
收藏

1 个回答

  • 智能回答 智能回答 本次回答由AI生成
    02-09
    有用
    回复
登录 后发表内容