注意php 7以上的json_encode 溢出
修改的路径:
vendor/luweiss/wechat/src/Wechat/WechatPay.php
-
- namespace luweiss\Wechat;
-
-
- class WechatPay extends WechatBase
- {
- const SIGN_TYPE_MD5 = 'MD5';
- const TRADE_TYPE_JSAPI = 'JSAPI';
- const TRADE_TYPE_NATIVE = 'NATIVE';
- const TRADE_TYPE_APP = 'APP';
- const TRADE_TYPE_MWEB = 'MWEB';
-
- public $appId;
- public $mchId;
- public $key;
- public $certPemFile;
- public $keyPemFile;
-
- /**
- * WechatPay constructor.
- * @param array $config ['appId', 'mchId', 'key', 'certPemFile', 'keyPemFile']
- */
- public function __construct($config = [])
- {
- foreach ($config as $name => $value) {
- if (property_exists($this, $name)) {
- $this->$name = $value;
- }
- }
- }
-
- /**
- * @param array $result
- * @return array
- * @throws WechatException
- */
- protected function getClientResult($result)
- {
- if (!isset($result['return_code'])) {
- throw new WechatException(
- '返回数据格式不正确: ' . json_encode($result, JSON_UNESCAPED_UNICODE)
- );
- }
- if ($result['return_code'] !== 'SUCCESS') {
- $msg = 'returnCode: ' . $result['return_code'] . ', returnMsg: ' . $result['return_msg'];
- throw new WechatException($msg, 0, null, $result);
- }
- if (!isset($result['result_code'])) {
- throw new WechatException(
- '返回数据格式不正确: ' . json_encode($result, JSON_UNESCAPED_UNICODE)
- );
- }
- if ($result['result_code'] !== 'SUCCESS') {
- $msg = 'errCode: ' . $result['err_code'] . ', errCodeDes: ' . $result['err_code_des'];
- throw new WechatException($msg, 0, null, $result);
- }
- return $result;
- }
-
- /**
- * @param $api
- * @param $args
- * @return array
- * @throws WechatException
- */
- protected function send($api, $args)
- {
- $args['appid'] = !empty($args['appid']) ? $args['appid'] : $this->appId;
- $args['mch_id'] = !empty($args['mch_id']) ? $args['mch_id'] : $this->mchId;
- $args['nonce_str'] = !empty($args['nonce_str']) ? $args['nonce_str'] : md5(uniqid());
- $args['sign'] = $this->makeSign($args);
- $xml = WechatHelper::arrayToXml($args);
- $res = $this->getClient()->setDataType(WechatHttpClient::DATA_TYPE_XML)->post($api, $xml);
- return $this->getClientResult($res);
- }
-
- /**
- * @param $api
- * @param $args
- * @return array
- * @throws WechatException
- */
- protected function sendWithPem($api, $args)
- {
- $args['nonce_str'] = !empty($args['nonce_str']) ? $args['nonce_str'] : md5(uniqid());
- $args['sign'] = $this->makeSign($args);
- $xml = WechatHelper::arrayToXml($args);
- $res = $this->getClient()
- ->setDataType(WechatHttpClient::DATA_TYPE_XML)
- ->setCertPemFile($this->certPemFile)
- ->setKeyPemFile($this->keyPemFile)
- ->post($api, $xml);
- return $this->getClientResult($res);
- }
-
- /**
- *
- * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1
- *
- * @param array $args ['body', 'out_trade_no', 'total_fee', 'notify_url', 'trade_type', 'openid']
- * @return array
- * @throws WechatException
- */
- public function unifiedOrder($args)
- {
- $args['spbill_create_ip'] = !empty($args['spbill_create_ip']) ? $args['spbill_create_ip'] : '127.0.0.1';
- $api = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
- return $this->send($api, $args);
- }
-
- /**
- *
- * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_2
- *
- * @param array $args ['out_trade_no']
- * @return array
- * @throws WechatException
- */
- public function orderQuery($args)
- {
- $api = 'https://api.mch.weixin.qq.com/pay/orderquery';
- return $this->send($api, $args);
- }
-
- /**
- *
- * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_3
- *
- * @param array $args
- * @return array
- * @throws WechatException
- */
- public function closeOrder($args)
- {
- $api = 'https://api.mch.weixin.qq.com/pay/closeorder';
- return $this->send($api, $args);
- }
-
- /**
- *
- * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_4
- *
- * @param array $args
- * @return array
- * @throws WechatException
- */
- public function refund($args)
- {
- $args['appid'] = !empty($args['appid']) ? $args['appid'] : $this->appId;
- $args['mch_id'] = !empty($args['mch_id']) ? $args['mch_id'] : $this->mchId;
- $api = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
- return $this->sendWithPem($api, $args);
- }
-
- /**
- *
- * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_5
- *
- * @param array $args
- * @return array
- * @throws WechatException
- */
- public function refundQuery($args)
- {
- $api = 'https://api.mch.weixin.qq.com/pay/refundquery';
- return $this->send($api, $args);
- }
-
- /**
- *
- * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
- *
- * @param array $args ['partner_trade_no', 'openid', 'amount', 'desc']
- * @return array
- * @throws WechatException
- */
- public function transfers($args)
- {
- $arg = [];
- $arg['out_batch_no'] = $args['partner_trade_no'];
- $arg['batch_name'] = date("Y-m-d H:i:s").$args['transfer_remark'];
- $arg['appid'] = !empty($args['mch_appid']) ? $args['mch_appid'] : $this->appId;
- $arg['batch_remark'] = date("Y-m-d H:i:s").$args['transfer_remark'];
- $arg['total_amount'] = !empty($args['transfer_amount']) ? intval($args['transfer_amount']):$args['amount'];
- $arg['total_num'] = 1;
- $transfer_detail_list = array(
- 'out_detail_no'=>$args['partner_trade_no'],
- 'transfer_amount'=>!empty($args['transfer_amount']) ? intval($args['transfer_amount']):$args['amount'],
- 'transfer_remark'=>date("Y-m-d H:i:s").$args['desc'],
- 'openid'=>$args['openid'],
- );
- if(isset($args['user_name'])&&!empty($args['user_name'])){
- $transfer_detail_list['user_name'] = $args['user_name'];
- }
- $arg['transfer_detail_list'][]=$transfer_detail_list;
- // var_dump($arg);die();
- $api = 'https://api.mch.weixin.qq.com/v3/transfer/batches';
- $token = $this->getToken($arg);//获取token
- return $this->https_request($api, json_encode($arg),$token);
- }
-
- protected function sendBatches($api, $arg)
- {
- $res = $this->getClient()
- ->setDataType(WechatHttpClient::DATA_TYPE_JSON)
- ->setCertPemFile($this->certPemFile)
- ->setKeyPemFile($this->keyPemFile)
- ->post($api, $arg);
- return $this->getClientResult($res);
- }
- public function https_request($url,$data = null,$token){
- try {
- $curl = curl_init();
- curl_setopt($curl, CURLOPT_URL, (string)$url);
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
- curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
- if (!empty($data)) {
- curl_setopt($curl, CURLOPT_POST, 1);
- curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
- }
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- //添加请求头
- $headers = [
- 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $token,
- 'Accept: application/json',
- 'Content-Type: application/json; charset=utf-8',
- 'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
- ];
- if (!empty($headers)) {
- curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
- }
- $output = curl_exec($curl);
- curl_close($curl);
- $data = json_decode($output,true);
- if($data['code']!=200&&isset($data['code'])){
- $data['err_code_des'] = $data['message'];
- throw new WechatException($data['message'], 0, null, $data);
- }
- return $data;
- }catch (WechatException $exception) {
- throw $exception;
- }
- }
- public function getToken($pars)
- {
- $url = 'https://api.mch.weixin.qq.com/v3/transfer/batches';
- $http_method = 'POST';//请求方法(GET,POST,PUT)
- $timestamp = time();//请求时间戳
- $url_parts = parse_url($url);//获取请求的绝对URL
- $nonce = $timestamp.rand('10000','99999');//请求随机串
- $body = json_encode((object)$pars);//请求报文主体
- $stream_opts = [
- "ssl" => [
- "verify_peer"=>false,
- "verify_peer_name"=>false,
- ]
- ];
-
- $apiclient_cert_path = $this->certPemFile;
- $apiclient_key_path = $this->keyPemFile;
-
- $apiclient_cert_arr = openssl_x509_parse(file_get_contents($apiclient_cert_path,false, stream_context_create($stream_opts)));
- $serial_no = $apiclient_cert_arr['serialNumberHex'];//证书序列号
- $mch_private_key = file_get_contents($apiclient_key_path,false, stream_context_create($stream_opts));//密钥
- $merchant_id = !empty($args['mch_id']) ? $args['mch_id'] : $this->mchId;//商户id
- $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
- $message = $http_method."\n".
- $canonical_url."\n".
- $timestamp."\n".
- $nonce."\n".
- $body."\n";
- openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
- $sign = base64_encode($raw_sign);//签名
- $schema = 'WECHATPAY2-SHA256-RSA2048';
- $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
- $merchant_id, $nonce, $timestamp, $serial_no, $sign);//微信返回token
- return $token;
- }
-
- // public function transfers($args)
- // {
- // $args['mch_appid'] = !empty($args['mch_appid']) ? $args['mch_appid'] : $this->appId;
- // $args['mchid'] = !empty($args['mchid']) ? $args['mchid'] : $this->mchId;
- // $args['spbill_create_ip'] = !empty($args['spbill_create_ip']) ? $args['spbill_create_ip'] : '127.0.0.1';
- // $args['check_name'] = !empty($args['check_name']) ? $args['check_name'] : 'NO_CHECK';
- // $api = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
- // return $this->sendWithPem($api, $args);
- // }
-
- /**
- *
- * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3
- *
- * @param array $args ['partner_trade_no']
- * @return array
- * @throws WechatException
- */
- public function getTransferInfo($args)
- {
- $args['appid'] = !empty($args['appid']) ? $args['appid'] : $this->appId;
- $args['mch_id'] = !empty($args['mch_id']) ? $args['mch_id'] : $this->mchId;
- $api = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo';
- return $this->sendWithPem($api, $args);
- }
-
- /**
- *
- * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_2
- *
- * @param array $args
- * @return array
- * @throws WechatException
- */
- public function payBank($args)
- {
- $args['mch_id'] = !empty($args['mch_id']) ? $args['mch_id'] : $this->mchId;
- $api = 'https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank';
- return $this->sendWithPem($api, $args);
- }
-
- /**
- *
- * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_3
- *
- * @param array $args
- * @return array
- * @throws WechatException
- */
- public function queryBank($args)
- {
- $args['mch_id'] = !empty($args['mch_id']) ? $args['mch_id'] : $this->mchId;
- $api = 'https://api.mch.weixin.qq.com/mmpaysptrans/query_bank';
- return $this->sendWithPem($api, $args);
- }
-
- /**
- * 通过数组数据验证签名
- * @param array $array
- * @return bool
- */
- public function validateSignByArrayResult($array)
- {
- if (!isset($array['sign'])) {
- return false;
- }
- $inputSign = $array['sign'];
- $truthSign = $this->makeSign($array);
- return $inputSign === $truthSign;
- }
-
- /**
- * 通过XML数据验证签名
- * @param string $xml
- * @return bool
- */
- public function validateSignByXmlResult($xml)
- {
- $array = WechatHelper::xmlToArray($xml);
- return $this->validateSignByArrayResult($array);
- }
-
- /**
- * 数据签名
- * @param array $args
- * @param string $signType
- * @return string
- */
- public function makeSign($args, $signType = self::SIGN_TYPE_MD5)
- {
- if (isset($args['sign'])) {
- unset($args['sign']);
- }
- ksort($args);
- $string = '';
- foreach ($args as $i => $arg) {
- if ($arg === null || $arg === '') {
- continue;
- } else {
- $string .= ($i . '=' . $arg . '&');
- }
- }
- $string = $string . "key={$this->key}";
- $string = md5($string);
- $result = strtoupper($string);
- return $result;
- }
- }