微信支付换模式了,使用微信支付公钥就可以了 具体问题可以看一下这个:https://developers.weixin.qq.com/community/develop/article/doc/000ca894a20c983cad52242286b813
获取商户当前可用的平台证书列表 返回 RESOURCE_NOT_EXISTS调用获取商户当前可用的平台证书列表接口 https://api.mch.weixin.qq.com/v3/certificates 返回 {"code":"RESOURCE_NOT_EXISTS","message":"无可用证书,请先确保已有API证书,再在商户平台-API安全申请使用微信支付公钥用于验签。可查看指引https://pay.weixin.qq.com/docs/merchant/products/platform-certificate/wxp-pub-key-guide.html"} 但是在商户api安全中所有证书均已申请! [图片] 需要怎么配置才能返回证书?
11-02把你的 \HttpClient::request() 换成下面这个试试 (new \GuzzleHttp\Client())->request("POST", $url, [ // 这里用的是 guzzlehttp 'body' => $newBody, 'query' => array_merge(["access_token" => $access_token['access_token']], $query), 'headers' => array_merge(['Content-Type' => 'application/json'], $headers, $signureHeaders), ] );
服务端api 加密签名一直报 errcode: 40235 错误,请问是哪里出了问题?之前提示 签名失败 {"errcode":40234,"errmsg":"invalid signature rid: 660bbf5d-42122766-7111a136"} 目前一直提示无效的加密 {"errcode":40235,"errmsg":"invalid encrypt rid: 660bbb51-3e9b99bb-5a26a227"} 目前感觉应该是签名通过了,但是加密不对,实在找不到问题,下面是所有相关代码,求大佬解答 这是加密的方法 public function getRequestParams($requestParams = []) { $timestamp = time(); $appid = get_setting('app_id');// 能拿到 appid $nonce = rtrim(base64_encode(random_bytes(16)), '='); $iv = random_bytes(12); $AES256GCM = [ 'sn' => '596f0ce97*************f25ad51ad', 'key' => 'ZDdlNDBl******************YjdiZTYwNWQ=', ]; $aad = $this->urlpath . "|" . $appid . "|" . $timestamp . "|" . $AES256GCM['sn']; $requestParams = array_merge($requestParams, [ '_n' => $nonce, '_appid' => $appid, '_timestamp' => $timestamp, ]); $requestParams = json_encode($requestParams); $cipher = openssl_encrypt($requestParams, "aes-256-gcm", base64_decode($AES256GCM['key']), OPENSSL_RAW_DATA, $iv, $tag, $aad); $iv = base64_encode($iv); $data = base64_encode($cipher); $authTag = base64_encode($tag); $finalRequestParams = ["iv" => $iv, "data" => $data, "authtag" => $authTag]; // 这里结果能正常的打印出来 return ['timestamp' => $timestamp, 'request_params' => json_encode($finalRequestParams)]; } 这是签名的方法 public function getSignureHeaders($requestParams) { $RSAwithSHA256 = [ 'sn' => '7a01f48****************f09ee3', 'private_key' => '-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEAtcBZzC2x7hBMH/kWWn/XClEtGrzkgPyj2+CiCA0OogwAL6Q/ CSK2tahY3GFFIP/7zLd3OC16V4Gb93Hf+n9YDjjoExQgkEX06sBzwSwC8PFGAZPw Jr5DEQGoKt64xydIkIAMHynNzltHInz7XD4fuJLxdi3CYitUd6pNATjax3a1OuO5 ******************* 这里打一下码, 删除了很多行 ******************* liDw02EvRE3BWL3nqgEPt/PP1us+LUg3uOKOrOTD+w7hUPRaBIR41hz+9V+YszTs oZk51Bq+/vZG7FoUXc7hB8cS9HANC2kOBU32Yf8fNWlpEMzg08N3yAw= -----END RSA PRIVATE KEY-----' ]; $appid = get_setting('app_id'); // 这里可以拿到 appid $rs_time = $requestParams['timestamp']; // 上一步加密时候的时间戳 $rs_data = $requestParams['request_params']; // 上一步最终加密的数据 $payload = "$this->urlpath\n$appid\n$rs_time\n$rs_data"; // 使用phpseclib3\Crypt\RSA(phpseclib V3)版本生成签名 $signature = RSA::loadPrivateKey($RSAwithSHA256['private_key']) ->withPadding(RSA::SIGNATURE_PSS) ->withHash('sha256') ->withMGFHash('sha256') ->sign($payload); $signature = base64_encode($signature); $checkLocalSig = $this->checkLocalSignature($requestParams, $signature); // 这里验签是可以通过的 if (!$checkLocalSig) { throw new EStoreException('本地验签错误'); } $headers['Wechatmp-Appid'] = $appid; $headers['Wechatmp-TimeStamp'] = $requestParams['timestamp']; $headers['Wechatmp-Signature'] = $signature; return $headers; } private function checkLocalSignature(array $requestParams, string $signature) { $signature = base64_decode($signature); $rsaPubKey = '-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtcBZzC2x7hBMH/kWWn/X ClEtGrzkgPyj2+CiCA0OogwAL6Q/CSK2tahY3GFFIP/7zLd3OC16V4Gb93Hf+n9Y ******************* 这里打一下码 ******************* wLx6tzfnHvRz0vTf5KEoOvbk3UOUJ8xR/J753cHxh9MumN+4IUgoVF01ju64b95B VQIDAQAB -----END PUBLIC KEY-----'; $appid = get_setting('app_id'); // 这里能拿到 appid $rs_time = $requestParams['timestamp']; // 上一步加密时候的时间戳 $rs_data = $requestParams['request_params']; // 上一步最终加密的数据 $payload = "$this->urlpath\n$appid\n$rs_time\n$rs_data"; return RSA::loadPublicKey($rsaPubKey) ->withPadding(RSA::SIGNATURE_PSS) ->withHash('sha256') ->withMGFHash('sha256') ->verify($payload, $signature); } 请求的方法 /** * 微信api 安全请求,自动加密数据,添加签名 */ public function safeRequest($method = 'post', $url = '', $data = []) { $body = $data['body'] ?? []; $query = $data['query'] ?? []; $headers = $data['headers'] ?? []; // 获取加密请求参数 $apiSignure = new ApiSignure($url); // 就是上面的方法的类名 $resultParams = $apiSignure->getRequestParams($body); // 上面的加密方法 $newBody = $resultParams['request_params']; // 加密的结果 // 获取签名 headers 参数 $signureHeaders = $apiSignure->getSignureHeaders($resultParams); // 上面的签名方法 $access_token = $this->getAccessToken(); // 获取 access_token $result = \HttpClient::request($method, $url, [ // 这里用的是 guzzlehttp 'body' => $newBody, 'query' => array_merge(["access_token" => $access_token['access_token']], $query), 'headers' => array_merge(['Content-Type' => 'application/json'], $headers, $signureHeaders), ]); print_r($result->getBody()->getContents());exit; return $result; } 调用方法 // 查询 门店 接口 $url = 'https://api.weixin.qq.com/cgi-bin/express/intracity/querystore'; $result = $this->safeRequest('post', $url, [ 'body' => ['wx_store_id' => '400000*********4017'], // id 打码了 ]);
04-10