diff --git a/extend/service/RoutineService.php b/extend/service/RoutineService.php index 1285691b..e7313a42 100644 --- a/extend/service/RoutineService.php +++ b/extend/service/RoutineService.php @@ -1,6 +1,7 @@ - '.$appid.' - '.$attach.' - '.$body.' - '.$mch_id.' - '.$nonce_str.' - '.$notify_url.' - '.$openid.' - '.$out_trade_no.' - '.$spbill_create_ip.' - '.$total_fee.' - '.$trade_type.' - '.$sign.' - '; -// dump($post_xml); - //统一接口prepay_id - $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; - $xml = self::http_request($url,$post_xml); - $array = self::xml($xml);//全要大写 - if($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS'){ - $time = time(); - $tmp=array();//临时数组用于签名 - $tmp['appId'] = $appid; - $tmp['nonceStr'] = $nonce_str; - $tmp['package'] = 'prepay_id='.$array['PREPAY_ID']; - $tmp['signType'] = 'MD5'; - $tmp['timeStamp'] = "$time"; - $data=array(); - $data['state'] = 1; - $data['timeStamp'] = "$time";//时间戳 - $data['nonceStr'] = $nonce_str;//随机字符串 - $data['signType'] = 'MD5';//签名算法,暂支持 MD5 - $data['package'] = 'prepay_id='.$array['PREPAY_ID'];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=* - $data['paySign'] = self::sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档; - $data['out_trade_no'] = $out_trade_no; - }else{ - $data=array(); - $data['state'] = 0; - $data['text'] = "错误"; - $data['RETURN_CODE'] = $array['RETURN_CODE']; - $data['RETURN_MSG'] = $array['RETURN_MSG']; + $payment = SystemConfigService::more(['site_url','routine_appId','routine_appsecret','pay_routine_mchid','pay_routine_client_cert','pay_routine_client_key','pay_routine_key','pay_weixin_open']); + $config = array( + 'appid' => $payment['routine_appId'], + 'mch_id' => $payment['pay_routine_mchid'], + 'key' => $payment['pay_routine_key'], + ); + $unified = array( + 'appid' => $config['appid'], + 'attach' => $attach, //商家数据包,原样返回,如果填写中文,请注意转换为utf-8 + 'body' => $body, + 'mch_id' => $config['mch_id'], + 'nonce_str' => self::nonce_str(),//随机字符串 + 'notify_url' => $payment['site_url'].Url::build('routine/Routine/notify'), + 'openid' => $openid, + 'out_trade_no' => $out_trade_no, + 'spbill_create_ip' => self::get_server_ip()?:'127.0.0.1',//终端的ip + 'total_fee' => $fee*100, //单位 转为分 + 'trade_type' => 'JSAPI'//交易类型 默认 + ); + $unified['sign'] = self::getSign($unified, $config['key']);//签名 + $responseXml = HttpService::postRequest('https://api.mch.weixin.qq.com/pay/unifiedorder', self::arrayToXml($unified)); + $unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA); + if ($unifiedOrder === false) { + die('parse xml error'); } - return $data; + if ($unifiedOrder->return_code != 'SUCCESS') { + die($unifiedOrder->return_msg); + } + if ($unifiedOrder->result_code != 'SUCCESS') { + die($unifiedOrder->err_code); + } + $time = time(); + $arr = array( + "appId" => $unifiedOrder->appid, + "timeStamp" => "$time", + "nonceStr" => self::nonce_str(),//随机字符串 + "package" => "prepay_id=" . $unifiedOrder->prepay_id, + "signType" => 'MD5', + ); + $arr['paySign'] = self::getSign($arr, $config['key']); + return $arr; } //随机32位字符串 @@ -98,62 +72,49 @@ class RoutineService{ } return $result; } - - public static function order_number($openid){ - return md5($openid.time().rand(10,99));//32位 - } - - //签名 $data要先排好顺序 - public static function sign($data){ - $stringA = ''; - foreach ($data as $key=>$value){ - if(!$value) continue; - if($stringA) $stringA .= '&'.$key."=".$value; - else $stringA = $key."=".$value; - } - $wx_key = self::options()['pay_routine_key'] ? self::options()['pay_routine_key'] : '';//申请支付后有给予一个商户账号和密码,登陆后自己设置key - $stringSignTemp = $stringA.'&key='.$wx_key;//申请支付后有给予一个商户账号和密码,登陆后自己设置key -// dump($stringSignTemp); - return strtoupper(md5($stringSignTemp)); - } - - //curl请求 - public static function http_request($url,$data = null,$headers=array()) + //数组转XML + public static function arrayToXml($arr) { - $curl = curl_init(); - if( count($headers) >= 1 ){ - curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + $xml = ""; + foreach ($arr as $key => $val) { + if (is_numeric($val)) { + $xml .= "<" . $key . ">" . $val . ""; + } else + $xml .= "<" . $key . ">"; } - curl_setopt($curl, CURLOPT_URL, $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); + $xml .= ""; + return $xml; + } + /** + * 获取签名 + */ + public static function getSign($params, $key) + { + ksort($params, SORT_STRING); + $unSignParaString = self::formatQueryParaMap($params, false); + $signStr = strtoupper(md5($unSignParaString . "&key=" . $key)); + return $signStr; + } + protected static function formatQueryParaMap($paraMap, $urlEncode = false) + { + $buff = ""; + ksort($paraMap); + foreach ($paraMap as $k => $v) { + if (null != $v && "null" != $v) { + if ($urlEncode) { + $v = urlencode($v); + } + $buff .= $k . "=" . $v . "&"; + } } - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - $output = curl_exec($curl); - curl_close($curl); - return $output; - } - - //获取xml - public static function xml($xml){ - $p = xml_parser_create(); - xml_parse_into_struct($p, $xml, $vals, $index); - xml_parser_free($p); - $data = ""; - foreach ($index as $key=>$value) { - if($key == 'xml' || $key == 'XML') continue; - $tag = $vals[$value[0]]['tag']; - $value = $vals[$value[0]]['value']; - $data[$tag] = $value; - } - return $data; + $reqPar = ''; + if (strlen($buff) > 0) { + $reqPar = substr($buff, 0, strlen($buff) - 1); + } + return $reqPar; } + //获取IP public static function get_server_ip() { if (isset($_SERVER)) { if($_SERVER['SERVER_ADDR']) {