收藏
回答

JSAPI产品支付 使用wechatpay-guzzle-middleware SDK 报错 ?

微信JSAPI产品支付  使用wechatpay-guzzle-middleware SDK 开发

SAPI调起支付 提示支付验证签名失败

1 统一下单的时候 使用的 构造一个实列 $client = new \GuzzleHttp\Client(['handler' => $stack]);

获取 prepay_id 这一步没有问题

2JSAPI调起支付 提示支付验证签名失败

检查可能造成的原因:
1 微信文档上说 签名方式: 需与统一下单的签名类型一致  ( 签名类型,默认为MD5,支持HMAC-SHA256和MD5。注意此处需与统一下单的签名类型一致 )

2 参数的大小写

2 JSAPI调起支付 的签名 与 统一下单的签名不一致

3 JSAPI调起支付生成签名的参数 随机字符串 与 统一下单的随机字符串不一致

问题一:wechatpay-guzzle-middleware SDK 开发是自动验签的 怎么获取 统一下单的 随机字符串



/**
 *  JSAPI支付下单
 *  同步请求
 * @param $out_trade_no
 * @param $description
 * @param $total
 */
public function JsapiSyncWeChatPay($total,$description,$notify_url,$out_trade_no,$openid,$attach ='')
{
    $data = [];
    try {
        if(!$total || !$description || !$notify_url || !$out_trade_no || !$openid){
            $data['statusCode'] = 400;
            $data['msg']        = '缺少必要参数,稍后再试';
            return $data;
        }
        $time_expire    = date("Y-m-d\TH:i:s\Z",strtotime("30*60 seconds") );
        $order = [
            "time_expire" => $time_expire,                              //交易结束时间--订单失效时间
            "mchid"       => WeChatTwo::$merchantId,                    //直连商户号   Required
            "appid"       => WeChatTwo::$appid,                         //应用ID      Required
            "notify_url"  => $notify_url,                               //通知地址     Required
            "out_trade_no"=> $out_trade_no,                             //商户订单号    Required
            "amount"      => ["total" => $total,"currency" => "CNY"],   //订单金额信息  Required
            "description" => $description,                              //商品描述     Required
            "payer" => [
                "openid" => $openid,                                    //获取微信用户的$openid
            ],
            //"attach"    => "自定义数据说明",                             //附加数据
        ];

        $url ="https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
        $resp = WeChatTwo::$client->request(
            'POST',
            $url, //请求URL
            [
                // JSON请求体
                'json' => $order,
                'headers' => [ 'Accept' => 'application/json' ]
            ]
        );
        $statusCode = $resp->getStatusCode();
        if ($statusCode == 200) { //处理成功
            $getContents = json_decode($resp->getBody()->getContents());
            $data['msg']        = '处理成功';
            $data['statusCode'] = 200;

            $timestamp          = time();
            $nonce              = WeChatTwo::getNonceStr();
            $data['appId']      = WeChatTwo::$appid;     //公众号ID,由商户传入
            $data['timeStamp']  = $timestamp;  //时间戳
            $data['nonceStr']   = $nonce;  //随机串
            $data['package']    = "prepay_id=" . $getContents->prepay_id;
            $data['signType']   = "RSA";     //微信签名方式:
            $data['paySign']    = WeChatTwo::paySign($url, "POST", "",$timestamp,$nonce); //微信签名


        } else if ($statusCode == 204) { //处理成功,无返回Body
            $data['msg']        = '微信支付统一下单失败';//'处理成功,无返回Body,请刷新后再试';
            $data['statusCode'] = 204;
        }
        return $data;
    } catch (RequestException $e) {
        $data['msg']        = $e->getMessage();
        $data['statusCode'] = 400;
        return $data;
        /*// 进行错误处理
        echo $e->getMessage()."\n";
        if ($e->hasResponse()) {
            echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
        }*/
    }
}


/**
 * 生成签名
 * @param $appId
 * @param $timeStamp
 * @param $nonceStr
 * @param $package
 * @return string
 */
public  static function paySign($url = "", $http_method = "POST",  $body = "",$timestamp = "",$nonce="")
{
    if (!in_array('sha256WithRSAEncryption', openssl_get_md_methods(true))) {
        throw new RuntimeException("当前PHP环境不支持SHA256withRSA");
    }
    $url_parts = parse_url($url);
    $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
    //当前时间戳
    $timestamp =  empty($timestamp) ? time() : $timestamp;
    //随机字符串
    $nonce     = empty($nonce) ? WeChatTwo::getNonceStr() : $nonce;
    //POST请求时 需要 转JSON字符串
    $message = $http_method."\n".
        $canonical_url."\n".
        $timestamp."\n".
        $nonce."\n".
        $body."\n";

    //生成签名
    openssl_sign($message, $raw_sign, openssl_get_privatekey(file_get_contents( WeChatTwo::$merchantPrivateKeyFilePath )), 'sha256WithRSAEncryption');
    $sign = base64_encode($raw_sign);

    return $sign;
}



回答关注问题邀请回答
收藏

2 个回答

  • 雅彤
    雅彤
    2021-12-31

    已解决

    2021-12-31
    有用
    回复
  • Memory (私信不回复)
    Memory (私信不回复)
    2021-12-31

    你请求V3,这里只有RSA

    2021-12-31
    有用
    回复 1
    • 雅彤
      雅彤
      发表于移动端
      2021-12-31
      已解决
      2021-12-31
      回复
登录 后发表内容