config = $config; } /** 企业付款到零钱API接口 * @param $order_no * @param $code * @param $total_fee */ public function remitPay($order_no, $openid, $total_fee, $body) { $url = self::$remitPayUrl; //创建需要的参数 $params = [ "mch_appid" => $this->config['mch_appid'], // 商户账号appid "mchid" => $this->config['mch_id'], // 商户号 "nonce_str" => $this->createNoncestr(), // 随机字符串 "partner_trade_no" => $order_no, // 商户订单号 "openid" => $openid, // 用户openid "check_name" => "NO_CHECK", // NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名 "amount" => $total_fee, // 企业付款金额,单位为分 "desc" => $body, // 企业付款备注,必填。注意:备注中的敏感词会被转成字符* "spbill_create_ip" => $_SERVER['REMOTE_ADDR'], // Ip地址 ]; $params["sign"] = $this->makeWxSign($params); // 签名 $result = $this->postXmlCurlCancel($this->toXml($params), $url); $prepay = $this->fromXml($result); if (!empty($prepay)) { // 微信通信标识 if (isset($prepay['return_code']) && $prepay['return_code'] == 'SUCCESS') { // 业务结果 if (isset($prepay['result_code'])) { // 业务结果返回成功 if ($prepay['result_code'] == 'SUCCESS') { self::$wxReturnData = array( 'partner_trade_no' => $prepay['partner_trade_no'], 'payment_no' => $prepay['payment_no'], 'payment_time' => $prepay['payment_time'], ); return true; } else { $this->doLogs($this->toXml($prepay)); if ($prepay['err_code'] == 'SYSTEMERROR') { // 请务必用原商户订单号重试,或通过查询接口确认此次付款的结果 return $this->getPayState($order_no);// 此处使用的是查询订单接口 } else { self::$errmsg = isset($prepay['err_code_des']) ? $prepay['err_code_des'] : '付款失败!'; return false; } } } else { self::$errmsg = '微信api接口返回值已修改'; return false; } } else if (isset($prepay['return_code']) && $prepay['return_code'] == 'FAIL') { $this->doLogs($this->toXml($prepay)); $this->doLogs($this->toXml($this->config)); self::$errmsg = isset($prepay['return_msg']) ? $prepay['return_msg'] : '付款失败。'; return false; } else { self::$errmsg = isset($prepay['return_msg']) ? $prepay['return_msg'] : '付款失败'; return false; } } self::$errmsg = "付款失败,微信api接口无任何返回值"; return false; } /** 查询订单是否支付 * @param $order_no */ public function getPayState($order_no) { //暂停一秒查询 $res = $this->searchWxOrder($order_no); // 微信通信标识 if (isset($res['return_code'])) { if ($res['return_code'] == "FAIL") { self::$errmsg = isset($res['return_msg']) ? $res['return_msg'] : "查询微信企业付款订单失败"; return false; } else { // 微信通信标识SUCCESS if (isset($res['result_code']) && $res['result_code'] == 'SUCCESS') { // 业务结果 SUCCESS if (isset($res['status'])) { switch ($res['status']) { case "SUCCESS": // 转账成功 self::$wxReturnData = array( 'partner_trade_no' => $res['partner_trade_no'], 'payment_no' => $res['detail_id'], 'payment_time' => $res['payment_time'], ); return true; break; case "FAILED": // 转账失败 self::$errmsg = isset($res['reason']) ? $res['reason'] : "打款失败"; return false; break; case "PROCESSING": // 处理中 // 继续查询 $time = get_runtime(); if ($time < 20) { sleep(2); return $this->getPayState($order_no); } else { // 将订单标记为处理中订单(让商家或者客户刷新订单重试) self::$errmsg = "微信打款处理中,请稍后查询打款结果"; return 0; } break; } } } else { if (isset($res['err_code'])) { switch ($res['err_code']) { case "CA_ERROR": self::$errmsg = "请求未携带证书,或请求携带的证书出错"; return false; break; case "SIGN_ERROR": self::$errmsg = "商户签名错误"; return false; break; case "FREQ_LIMIT": self::$errmsg = "受频率限制"; return false; break; case "XML_ERROR": self::$errmsg = "请求的xml格式错误,或者post的数据为空"; return false; break; case "SYSTEMERROR": $time = get_runtime(); if ($time < 20) { sleep(2); return $this->getPayState($order_no); } else { // 将订单标记为处理中订单(让商家或者客户刷新订单重试) self::$errmsg = "微信打款处理中,请稍后查询打款结果"; return 0; } break; case "NOT_FOUND": self::$errmsg = "1、指定单号数据不存在 2、指定单号数据不存在,单据查询超过有效期"; return false; break; } } self::$errmsg = isset($res['err_code_des']) ? $res['err_code_des'] : "查询微信企业付款订单失败"; return false; } } } self::$errmsg = isset($res['err_code_des']) ? $res['err_code_des'] : "查询微信企业付款订单失败"; return false; } /** * @param $out_trade_no */ public function searchWxOrder($out_trade_no) { $payModel = self::$payModel; $params = [ "nonce_str" => $this->createNoncestr(), "partner_trade_no" => $out_trade_no ]; if ($payModel) { $params['appid'] = $this->config['mch_appid']; $params['mch_id'] = $this->config['mchid']; } else { $params['appid'] = $this->config['xcx_appid']; $params['mch_id'] = $this->config['xcx_mer_id']; } $params['sign'] = $this->makeWxSign($params); $url = self::$queryBankUrl; // 微信企业付款查询url $xml = $this->toXml($params);//转换为xml $response = $this->postXmlCurlCancel($xml, $url, 30); $response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $response; } /** * 获取微信企业付款到银行卡公钥 * @return bool */ public function getWxPublicKey() { $url = self::$publicKeyUrl; //创建需要的参数 $params = [ "mch_id" => $this->config['mchid'], // 商户号 "nonce_str" => $this->createNoncestr(), // 随机字符串 "sign_type" => 'MD5' // 商户订单号 ]; $params["sign"] = $this->makeWxSign($params); // 签名 $result = $this->postXmlCurlCancel($this->toXml($params), $url); $prepay = $this->fromXml($result); //pre($prepay); if (!empty($prepay)) { // 微信通信标识 if (isset($prepay['return_code']) && $prepay['return_code'] == 'SUCCESS') { // 业务结果 if (isset($prepay['result_code'])) { // 业务结果返回成功 if ($prepay['result_code'] == 'SUCCESS') { self::$wxReturnData = array( 'pub_key' => $prepay['pub_key'] ); return true; } else { $this->doLogs($this->toXml($prepay)); self::$errmsg = isset($prepay['err_code_des']) ? $prepay['err_code_des'] : '公钥获取失败'; return false; } } else { self::$errmsg = '微信api接口返回值已修改'; return false; } } else if (isset($prepay['return_code']) && $prepay['return_code'] == 'FAIL') { $this->doLogs($this->toXml($prepay)); self::$errmsg = isset($prepay['return_msg']) ? $prepay['return_msg'] : '公钥获取失败。'; return false; } else { self::$errmsg = isset($prepay['return_msg']) ? $prepay['return_msg'] : '公钥获取失败'; return false; } } self::$errmsg = "微信企业付款公钥获取失败"; return false; } /** * 调取微信付款到银行卡 * @param $order_no * @param $userData * @param $total_fee * @param $body * @return bool */ public function bankCardPay($order_no, $userData, $total_fee, $body) { $url = self::$payBankUrl; //创建需要的参数 $enc_bank_no = $this->publicEncrypt($userData['enc_bank_no']); $enc_true_name = $this->publicEncrypt($userData['enc_true_name']); $bank_code = $userData['bank_code']; $params = [ "mch_id" => $this->config['mchid'], // 商户号 "nonce_str" => $this->createNoncestr(), // 随机字符串 "partner_trade_no" => $order_no, // 商户订单号 "enc_bank_no" => $enc_bank_no, // 收款方银行卡号(采用标准RSA算法,公钥由微信侧提供) "enc_true_name" => $enc_true_name, // 收款方用户名(采用标准RSA算法,公钥由微信侧提供) "bank_code" => $bank_code, // 银行卡所在开户行编号 "amount" => $total_fee, // 企业付款金额,单位为分 "desc" => $body, // 企业付款备注,必填。注意:备注中的敏感词会被转成字符* ]; $params["sign"] = $this->makeWxSign($params); // 签名 $result = $this->postXmlCurlCancel($this->toXml($params), $url); $prepay = $this->fromXml($result); return $this->bankCardPayHandle($prepay, $params, $url); } /* * 处理微信付款到银行卡返回值 * */ private function bankCardPayHandle($prepay, $params, $url) { $order_no = $params['partner_trade_no']; if (!empty($prepay)) { // 微信通信标识 if (isset($prepay['return_code']) && $prepay['return_code'] == 'SUCCESS') { // 业务结果 if (isset($prepay['result_code'])) { // 业务结果返回成功 if ($prepay['result_code'] == 'SUCCESS') { self::$wxReturnData = array( 'partner_trade_no' => $prepay['partner_trade_no'], 'payment_no' => $prepay['payment_no'], 'cmms_amt' => $prepay['cmms_amt'], ); return true; } else { $this->doLogs($this->toXml($prepay)); if (isset($prepay['err_code_des'])) { $err_code_des = $prepay['err_code_des'] . 'err_code:' . $prepay['err_code']; } else { $err_code_des = ''; } switch ($prepay['err_code']) { case 'SYSTEMERROR': // 请务必用原商户订单号重试,或通过查询接口确认此次付款的结果 return $this->getCardPayState($order_no); // 此处使用的是查询订单接口 break; case 'INVALID_REQUEST': // 无效的请求,商户系统异常导致,商户权限异常、证书错误、频率限制等 // 使用原单号以及原请求参数重试 if($this->reTestNum>3){ self::$errmsg = $err_code_des ? $err_code_des : '无效的请求!err_code:' . $prepay['err_code']; return false; }else{ $this->reTestNum++; } return $this->retryBankCardPay($params, $url, 1, 0); break; case 'FREQUENCY_LIMITED': // 超过每分钟600次的频率限制 稍后用原单号重试 return $this->retryBankCardPay($params, $url, 5, 1); break; case 'SIGNERROR': // 签名错误 self::$errmsg = $err_code_des ? $err_code_des : '签名错误!err_code:' . $prepay['err_code']; return false; break; case 'AMOUNT_LIMIT': // 超额;已达到今日付款金额上限或已达到今日银行卡收款金额上限 self::$errmsg = $err_code_des ? $err_code_des : '超额;已达到今日付款金额上限或已达到今日银行卡收款金额上限!err_code:' . $prepay['err_code']; return false; break; case 'ORDERPAID': // 超过付款重入有效期 self::$errmsg = $err_code_des ? $err_code_des : '超过付款重入有效期!err_code:' . $prepay['err_code']; return false; break; case 'FATAL_ERROR': // 已存在该单,并且订单信息不一致;或订单太老 self::$errmsg = $err_code_des ? $err_code_des : '已存在该单,并且订单信息不一致;或订单太老!err_code:' . $prepay['err_code']; return false; break; case 'NOTENOUGH': // 账号余额不足 self::$errmsg = $err_code_des ? $err_code_des : '账号余额不足!err_code:' . $prepay['err_code']; return false; break; case 'SUCCESS': // Wx侧受理成功 self::$errmsg = $err_code_des ? $err_code_des : 'Wx侧受理成功!err_code:' . $prepay['err_code']; return false; break; case 'RECV_ACCOUNT_NOT_ALLOWED': // 收款账户不在收款账户列表 self::$errmsg = $err_code_des ? $err_code_des : '收款账户不在收款账户列表!err_code:' . $prepay['err_code']; return false; break; case 'PAY_CHANNEL_NOT_ALLOWED': // 本商户号未配置API发起能力 self::$errmsg = $err_code_des ? $err_code_des : '本商户号未配置API发起能力!err_code:' . $prepay['err_code']; return false; break; case 'SENDNUM_LIMIT': // 已达到付款给此用户次数上限 self::$errmsg = $err_code_des ? $err_code_des : '已达到付款给此用户次数上限!err_code:' . $prepay['err_code']; return false; break; case 'NO_AUTH': // 此IP地址不允许调用接口 self::$errmsg = $err_code_des ? $err_code_des : '此IP地址不允许调用接口!err_code:' . $prepay['err_code']; return false; break; default: // 新的错误码 self::$errmsg = $err_code_des ? $err_code_des : '请联系客服确认付款情况!err_code:' . $prepay['err_code']; return false; break; } } } else { self::$errmsg = '微信api接口返回值已修改'; return false; } } else if (isset($prepay['return_code']) && $prepay['return_code'] == 'FAIL') { $this->doLogs($this->toXml($prepay)); $this->doLogs($this->toXml($this->config)); self::$errmsg = isset($prepay['return_msg']) ? $prepay['return_msg'] : '付款失败。'; return false; } else { self::$errmsg = isset($prepay['return_msg']) ? $prepay['return_msg'] : '付款失败'; return false; } } self::$errmsg = "付款失败,微信api接口无任何返回值"; return false; } // 重试 微信付款到银行卡 private function retryBankCardPay($params, $url, $t, $type) { if ($t) { sleep($t); } unset($params["sign"]); if ($type) { $params["nonce_str"] = $this->createNoncestr(); } $params["sign"] = $this->makeWxSign($params); // 签名 $result = $this->postXmlCurlCancel($this->toXml($params), $url); $prepay = $this->fromXml($result); return $this->bankCardPayHandle($prepay, $params, $url); } /* * 循环查询微信付款到银行卡 * */ public function getCardPayState($order_no) { //暂停一秒查询 $res = $this->searchCardPayOrder($order_no); // 微信通信标识 if (isset($res['return_code'])) { if ($res['return_code'] == "FAIL") { self::$errmsg = isset($res['return_msg']) ? $res['return_msg'] : "查询微信企业付款订单失败"; return false; } else { // 微信通信标识SUCCESS if (isset($res['result_code']) && $res['result_code'] == 'SUCCESS') { // 业务结果 SUCCESS if (isset($res['status'])) { switch ($res['status']) { case "SUCCESS": // 付款成功 self::$wxReturnData = array( 'partner_trade_no' => $res['partner_trade_no'], 'payment_no' => $res['payment_no'], // 即为微信内部业务单号 'pay_succ_time' => $res['payment_time'], // 微信侧付款成功时间(依赖银行的处理进度,可能出现延迟返回,甚至被银行退票的情况) 'cmms_amt' => $res['cmms_amt'], // 手续费订单金额 RMB:分 ); return true; break; case "FAILED": // 付款失败,需要替换付款单号重新发起付款 self::$errmsg = isset($res['reason']) ? $res['reason'] : "付款到银行卡失败"; return false; break; case "BANK_FAIL": // 银行退票,订单状态由付款成功流转至退票,退票时付款金额和手续费会自动退还 self::$errmsg = isset($res['reason']) ? $res['reason'] : "付款到银行卡失败,银行退票,订单状态由付款成功流转至退票,退票时付款金额和手续费会自动退还"; return false; break; case "PROCESSING": // 处理中 // 继续查询 $time = get_runtime(); if ($time < 20) { sleep(2); return $this->getCardPayState($order_no); } else { // 将订单标记为处理中订单(让商家或者客户刷新订单重试) self::$errmsg = "微信付款到银行卡处理中,请稍后查询打款结果"; return 0; } break; } } } else { if (isset($res['err_code'])) { switch ($res['err_code']) { case "INVALID_REQUEST": // 无效的请求,商户系统异常导致,商户权限异常、证书错误、频率限制等 //使用原单号以及原请求参数重试 self::$errmsg = "无效的请求,商户系统异常导致,商户权限异常、证书错误、频率限制等"; return false; break; case "PARAM_ERROR": // 参数错误 //按照err_msg指定参数错误信息,修改相应参数 self::$errmsg = "参数错误"; return false; break; case "SIGNERROR": // 签名错误 //签名前没有按照要求进行排序。没有使用商户平台设置的密钥进行签名,参数有空格或者进行了encode后进行签名 self::$errmsg = "签名错误"; return false; break; case "ORDERNOTEXIST": // 订单不存在 //确认订单号是否发起过请求 self::$errmsg = "订单不存在"; return false; break; case "SYSTEMERROR": // 系统繁忙,请稍后重试 //使用原单号以及原请求参数重试 self::$errmsg = "系统繁忙,请稍后重试"; return false; break; case "SUCCESS": // Wx侧查询成功 //使用原单号以及原请求参数重试 self::$errmsg = "微信侧查询成功"; return false; break; case "NOT_FOUND": // 1、指定单号数据不存在 2、指定单号数据不存在,单据查询超过有效期 self::$errmsg = "1、指定单号数据不存在 2、指定单号数据不存在,单据查询超过有效期"; return false; break; } } self::$errmsg = isset($res['err_code_des']) ? $res['err_code_des'] : "查询微信企业付款订单失败"; return false; } } } self::$errmsg = isset($res['err_code_des']) ? $res['err_code_des'] : "查询微信企业付款订单失败"; return false; } /* * 查询微信付款到银行卡 * */ public function searchCardPayOrder($out_trade_no) { $params = [ "nonce_str" => $this->createNoncestr(), "partner_trade_no" => $out_trade_no, "mch_id" => $this->config['mchid'] ]; $params['sign'] = $this->makeWxSign($params); $url = self::$wxQueryUrl; // 微信企业付款查询url $xml = $this->toXml($params);//转换为xml $response = $this->postXmlCurlCancel($xml, $url, 30); $response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $response; } /** * @uses 获取公钥 * @return bool|resource */ private function _getPublicKey() { $publicKeyUrl = $this->config['wx_public_key']; $public_key = file_get_contents('.' . $publicKeyUrl); return $public_key; $GetPublicKey = openssl_pkey_get_public($public_key); if ($GetPublicKey) { echo 1; } else if ($GetPublicKey === false) { echo 2; } else { echo 3; } } function publicEncrypt($source) { $pub_key_string = file_get_contents('.' . $this->config['wx_public_key']); $key_resource = openssl_pkey_get_public($pub_key_string); $crypttext = ''; openssl_public_encrypt($source, $crypttext, $key_resource,OPENSSL_PKCS1_OAEP_PADDING); return base64_encode($crypttext); } /** * @return string */ public function getMsg() { return self::$errmsg; } /** * @return string */ public function getReturnData() { return self::$wxReturnData; } /** 生成签名 * @param $Obj * @return string */ private function makeWxSign($Obj) { if (self::$payModel == 1) { $key = $this->config["wx_secret_key"]; } else { $key = $this->config["xcx_secret_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_; } /** * 作用:格式化参数,签名过程需要使用 */ 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; } /** * 作用:产生随机字符串,不长于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; } /** * 写入日志记录 * @param $values * @return bool|int */ private function doLogs($values) { $years = date('Y-m'); $url = './Uploads/log/'.$years.'/'.date('Ymd').'remit.txt'; $dir_name = dirname($url); //目录不存在就创建 if(!file_exists($dir_name)) { //iconv防止中文名乱码 $res = mkdir(iconv("UTF-8", "GBK", $dir_name),0777,true); } $fp = fopen($url, "a");//打开文件资源通道 不存在则自动创建 fwrite($fp,date("Y-m-d H:i:s").var_export($values, true)."\r\n");//写入文件 fclose($fp);//关闭资源通道 // return write_log($values, __DIR__); // return file_put_contents($values, __DIR__); } /** * 将xml转为array * @param $xml * @return mixed */ private function fromXml($xml) { // 禁止引用外部xml实体 libxml_disable_entity_loader(true); return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); } /** * 以post方式提交xml到对应的接口url * @param $xml * @param $url * @param int $second * @return mixed */ private function postXmlCurl($xml, $url, $second = 30) { $ch = curl_init(); // 设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, $second); 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); // post提交方式 curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); // 运行curl $data = curl_exec($ch); curl_close($ch); return $data; } //带证书的 private function postXmlCurlCancel($xml, $url, $second = 30) { $Domain = $_SERVER['DOCUMENT_ROOT']; if (self::$payModel == 1) { // $apiclient_cert = $Domain . "/" . $this->config['apiclient_cert']; // $apiclient_key = $Domain . "/" . $this->config['apiclient_key']; $apiclient_cert = $this->config['apiclient_cert']; $apiclient_key = $this->config['apiclient_key']; } else { $apiclient_cert = $Domain . $this->config['xcx_apiclient_cert']; $apiclient_key = $Domain . $this->config['xcx_apiclient_key']; } // $apiclient_cert = "/www/wwwroot/oem.ocean666.top/Uploads/Wx/2020-08-07/5f2d26d741e989.437773624617.pem"; // $apiclient_key ="/www/wwwroot/oem.ocean666.top/Uploads/Wx/2020-08-07/5f2d26db1b3ee1.661954136040.pem"; //初始化curl $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); //设置证书 curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM'); curl_setopt($ch, CURLOPT_SSLCERT, $apiclient_cert); curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM'); curl_setopt($ch, CURLOPT_SSLKEY, $apiclient_key); //设置header curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //post提交方式 curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); //运行curl $data = curl_exec($ch); //返回结果 if ($data) { curl_close($ch); return $data; } else { curl_close($ch); return false; } } /** * 生成签名 * @param $values * @return string 本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值 */ private function makeSign($values) { //签名步骤一:按字典序排序参数 ksort($values); $string = $this->toUrlParams($values); //签名步骤二:在string后加入KEY $string = $string . '&key=' . $this->config['xcx_secret_key']; //签名步骤三:MD5加密 $string = md5($string); //签名步骤四:所有字符转为大写 $result = strtoupper($string); return $result; } /** * 格式化参数格式化成url参数 * @param $values * @return string */ private function toUrlParams($values) { $buff = ''; foreach ($values as $k => $v) { if ($k != 'sign' && $v != '' && !is_array($v)) { $buff .= $k . '=' . $v . '&'; } } return trim($buff, '&'); } /** * 输出xml字符 * @param $values * @return bool|string */ private function toXml($values) { if (!is_array($values) || count($values) <= 0 ) { return false; } $xml = ""; foreach ($values as $key => $val) { if (is_numeric($val)) { $xml .= "<" . $key . ">" . $val . ""; } else { $xml .= "<" . $key . ">"; } } $xml .= ""; return $xml; } }