watermark->appid != $appid ) { return $IllegalBuffer; } $data = $result; return $OK; } /** *GET方式请求 */ function httpGet($url){ $ch = curl_init(); //设置选项,包括URL curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //不验证证书 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //不验证证书 //执行并获取HTML文档内容 $output = curl_exec($ch); //释放curl句柄 curl_close($ch); //$result = json_decode($output); //$result->subscribe return $output; } /** * post访问url */ function https_post($url,$data){ $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //不验证证书 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //不验证证书 curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS,$data); $output = curl_exec($ch); curl_close($ch); return $output; } /* *加解密 *函数authcode($string, $operation, $key, $expiry)中的$string:字符串,明文或密文;$operation:DECODE表示解密,其它表示加密;$key:密匙;$expiry:密文有效期。 */ public function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) { // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙 $ckey_length = 4; // 密匙 $key = md5($key ? $key : '' ); //md5($key ? $key : $GLOBALS['discuz_auth_key']); // 密匙a会参与加解密 $keya = md5(substr($key, 0, 16)); // 密匙b会用来做数据完整性验证 $keyb = md5(substr($key, 16, 16)); // 密匙c用于变化生成的密文 $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : ''; // 参与运算的密匙 $cryptkey = $keya.md5($keya.$keyc); $key_length = strlen($cryptkey); // 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b), //解密时会通过这个密匙验证数据完整性 // 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确 $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string; $string_length = strlen($string); $result = ''; $box = range(0, 255); $rndkey = array(); // 产生密匙簿 for($i = 0; $i <= 255; $i++) { $rndkey[$i] = ord($cryptkey[$i % $key_length]); } // 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度 for($j = $i = 0; $i < 256; $i++) { $j = ($j + $box[$i] + $rndkey[$i]) % 256; $tmp = $box[$i]; $box[$i] = $box[$j]; $box[$j] = $tmp; } // 核心加解密部分 for($a = $j = $i = 0; $i < $string_length; $i++) { $a = ($a + 1) % 256; $j = ($j + $box[$a]) % 256; $tmp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $tmp; // 从密匙簿得出密匙进行异或,再转成字符 $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); } if($operation == 'DECODE') { // 验证数据有效性,请看未加密明文的格式 if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) { return substr($result, 26); } else { return ''; } } else { // 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因 // 因为加密后的密文可能是一些特殊字符,复制过程可能会丢失,所以用base64编码 return $keyc.str_replace('=', '', base64_encode($result)); } } /** *微信提现,企业付款到零用钱 *$openid 公众号下的用户openid *$mch_billno 订单号 *$total_amount 提现的金额 *$mark 备注 *@return 错误 false ,成功 */ function wxBusinessPay($openid,$mch_billno,$total_amount,$mark,$MCHID,$APPID,$Key){ $nonce_str=$this->createNoncestr( $length = 32 ); $sendarry=array(); // 随机字符串 $sendarry["nonce_str"]=$nonce_str; // 商户订单号 $sendarry["partner_trade_no"]=$mch_billno; // 商户号 $sendarry["mchid"]=$MCHID; // 公众账号appid $sendarry["mch_appid"]=$APPID; // 用户openid $sendarry["openid"]=$openid; // 付款金额 $sendarry["amount"]=$total_amount*100; // 红包祝福语 $sendarry["check_name"]='NO_CHECK';//不超过20字 // Ip地址 $sendarry["spbill_create_ip"]='62.234.183.107'; // 备注 $sendarry["desc"]=$mark; // 签名 $sign=$this->getSign($sendarry,$Key); $sendarry["sign"]=$sign; //转换XML $sendxml=$this->arrayToXml($sendarry); // 调用的接口 $url='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; // 使用证书,以post方式提交xml到对应的接口url $data=$this->postXmlSSLCurl($sendxml,$url,$seconed=30); if($data == false){ return false; }else{ $obj = $this->xmlToArray($data); //发送成功 if($obj['return_code'] == 'SUCCESS' && $obj['result_code'] == 'SUCCESS'){ return true; //金额不足 }else{ return false; } } } /** * 作用:产生随机字符串,不长于32位 */ public function createNoncestr( $length = 32 ) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str =""; for ( $i = 0; $i < $length; $i++ ) { $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str; } /** * 作用:格式化参数,签名过程需要使用 */ function formatBizQueryParaMap($paraMap, $urlencode) { $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v) { if($urlencode) { $v = urlencode($v); } //$buff .= strtolower($k) . "=" . $v . "&"; $buff .= $k . "=" . $v . "&"; } $reqPar; if (strlen($buff) > 0) { $reqPar = substr($buff, 0, strlen($buff)-1); } return $reqPar; } /** * 作用:生成签名 */ public function getSign($Obj,$KEY) { foreach ($Obj as $k => $v) { $Parameters[$k] = $v; } //签名步骤一:按字典序排序参数 ksort($Parameters); $String = $this->formatBizQueryParaMap($Parameters, false); //echo '【string1】'.$String.'
'; //签名步骤二:在string后加入KEY $String = $String."&key=".$KEY; //echo "【string2】".$String."
"; //签名步骤三:MD5加密 $String = md5($String); //echo "【string3】 ".$String."
"; //签名步骤四:所有字符转为大写 $result_ = strtoupper($String); //echo "【result】 ".$result_."
"; return $result_; } /** * 作用:array转xml */ function arrayToXml($arr) { $xml = ""; foreach ($arr as $key=>$val) { if (is_numeric($val)) { $xml.="<".$key.">".$val.""; } else $xml.="<".$key.">"; } $xml.=""; return $xml; } /** * 作用:将xml转为array */ public function xmlToArray($xml) { //将XML转为array $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $array_data; } /** * 作用:使用证书,以post方式提交xml到对应的接口url */ function postXmlSSLCurl($xml,$url,$second=30) { $ch = curl_init(); //超时时间 curl_setopt($ch,CURLOPT_TIMEOUT,$second); //这里设置代理,如果有的话 //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8'); //curl_setopt($ch,CURLOPT_PROXYPORT, 8080); curl_setopt($ch,CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE); //设置header curl_setopt($ch,CURLOPT_HEADER,FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE); //设置证书 //使用证书:cert 与 key 分别属于两个.pem文件 //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLCERT, ROOT_PATH."/application/app/cacert/apiclient_cert.pem"); //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY, ROOT_PATH."/application/app/cacert/apiclient_key.pem"); //post提交方式 curl_setopt($ch,CURLOPT_POST, true); curl_setopt($ch,CURLOPT_POSTFIELDS,$xml); $data = curl_exec($ch); //返回结果 if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); /* echo "curl出错,错误码:$error"."
"; echo "错误原因查询
";*/ curl_close($ch); return false; } } /******************************* 小程序公用 ******************************************/ } ?>