使用:
$this->data['time_start'] = date('YmdHis',time()); $this->data['notify_url'] = $this->_new_notify_url; $this->data['out_trade_no'] =$this->random_str; $this->data['total_fee'] = $this->total_fee; $this->data['notify_url'] = 'https://sungroow.com/phone/pay/Wxpay/api/notify.php'; $this->data['nonce_str'] = $this->nonce_str; $this->data['openid'] = $this->openId; $this->data['sign'] = $this->_get_sign(); $this->xmlData = $this->_get_xml(); $this->_curl();
//请求并解析放回数据
private function _curl(){ $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $this->url); //定义表单提交地址 curl_setopt($curl, CURLOPT_POST, 1); //定义提交类型 1:POST ;0:GET curl_setopt($curl, CURLOPT_HEADER, 0); //定义是否显示状态头 1:显示 ; 0:不显示 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);//定义是否直接输出返回流 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_HTTPHEADER, 'Content-type: text/xml'); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_POSTFIELDS, $this->xmlData); //定义提交的数据,这里是XML文件 $returnData = curl_exec($curl); curl_close($curl); $returnData = $this->xmlstr_to_array($returnData); if(!empty($returnData['err_code_des'])){ output_error('请按首次操作微信支付'); }
重点:.
//将数组转换成XML格式 private function _get_xml(){ $xml = '<xml>'; foreach ($this->data as $key=>$val){ if (is_numeric($val)){ //检测变量是否为数字或数字字符串 $xml.="<".$key.">".$val."</".$key.">"; }else{ $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"; } } $xml .= '</xml>'; return $xml; }
//将返回的XMl解析成数组 private function xmlstr_to_array($xmlstr) { $doc = new DOMDocument(); $doc->loadXML($xmlstr); return $this->domnode_to_array($doc->documentElement); } //将返回的XMl解码 private function domnode_to_array($node) { $output = array(); switch ($node->nodeType) { case XML_CDATA_SECTION_NODE: case XML_TEXT_NODE: $output = trim($node->textContent); break; case XML_ELEMENT_NODE: for ($i=0, $m=$node->childNodes->length; $i<$m; $i++) { $child = $node->childNodes->item($i); $v = $this->domnode_to_array($child); if(isset($child->tagName)) { $t = $child->tagName; if(!isset($output[$t])) { $output[$t] = array(); } $output[$t][] = $v; } elseif($v) { $output = (string) $v; } } if(is_array($output)) { if($node->attributes->length) { $a = array(); foreach($node->attributes as $attrName => $attrNode) { $a[$attrName] = (string) $attrNode->value; } $output['@attributes'] = $a; } foreach ($output as $t => $v) { if(is_array($v) && count($v)==1 && $t!='@attributes') { $output[$t] = $v[0]; } } } break; } return $output; }
附加:
//随机32位字符串 private function nonce_str(){ $result = ''; $str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz'; for ($i=0;$i<32;$i++){ $result .= $str[rand(0,48)]; } return $result; } //正确生成微信签名:
$time = time(); $tmp='';//临时数组用于签名 $tmp['appId'] = 'wx3670f6b94f08b57e'; $tmp['nonceStr'] = $this->nonce_str; $tmp['package'] = 'prepay_id='.$returnData['prepay_id']; $tmp['signType'] = 'MD5'; $tmp['timeStamp'] = "$time"; $data['test']=$returnData; $data['state'] = 200; $data['timeStamp'] = "$time";//时间戳 $data['nonceStr'] = $this->nonce_str;//随机字符串 $data['signType'] = 'MD5';//签名算法,暂支持 MD5 $data['package'] = 'prepay_id='.$returnData['prepay_id'];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=* $data['paySign'] = $this->sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档; $data['out_trade_no'] = $this->random_str;
//签名 $data要先排好顺序 private function sign($data){ $stringA = ''; foreach ($data as $key=>$value){ if(!$value) continue; if($stringA) $stringA .= '&'.$key."=".$value; else $stringA = $key."=".$value; } $wx_key = '';//申请支付后有给予一个商户账号和密码,登陆后自己设置的key $stringSignTemp = $stringA.'&key='.$wx_key; return strtoupper(md5($stringSignTemp)); }