php 實現app微信支付
阿新 • • 發佈:2018-11-20
class Wxpay { /* 配置引數 */ private $config = array( 'appid' => "wxc888888888", /*微信開放平臺上的應用id*/ 'mch_id' => "88888888", /*微信申請成功之後郵件中的商戶id*/ 'api_key' => "5d82747060a5873e0d3de256b8485094", /*在微信商戶平臺上自己設定的api金鑰 32位*/ 'notify_url' => 'http://www.xxxxx.com/app/index.php/Api/modifyPayState' /*自定義的回撥程式地址*/ ); //下單 public function getPrePayOrder($body, $out_trade_no, $total_fee){ $url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; $notify_url = $this->config["notify_url"]; $onoce_str = $this->createNoncestr(); $data["appid"] = $this->config["appid"]; $data["body"] = $body; $data["mch_id"] = $this->config['mch_id']; $data["nonce_str"] = $onoce_str; $data["notify_url"] = $notify_url; $data["out_trade_no"] = $out_trade_no; $data["spbill_create_ip"] = $this->get_client_ip(); $data["total_fee"] = $total_fee; $data["trade_type"] = "APP"; $sign = $this->getSign($data); $data["sign"] = $sign; $xml = $this->arrayToXml($data); $response = $this->postXmlCurl($xml, $url); //將微信返回的結果xml轉成陣列 $response = $this->xmlToArray($response); //返回資料 return $respone; } /*生成簽名*/ public function getSign($Obj){ foreach ($Obj as $k => $v){ $Parameters[$k] = $v; } //簽名步驟一:按字典序排序引數 ksort($Parameters); $String = $this->formatBizQueryParaMap($Parameters, false); //echo '【string1】'.$String.'</br>'; //簽名步驟二:在string後加入KEY $String = $String."&key=".$this->config['api_key']; //echo "【string2】".$String."</br>"; //簽名步驟三:MD5加密 $String = md5($String); //echo "【string3】 ".$String."</br>"; //簽名步驟四:所有字元轉為大寫 $result_ = strtoupper($String); //echo "【result】 ".$result_."</br>"; return $result_; } /** * 作用:產生隨機字串,不長於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; } //陣列轉xml public function arrayToXml($arr){ $xml = "<xml>"; foreach ($arr as $key=>$val){ if (is_numeric($val)){ $xml.="<".$key.">".$val."</".$key.">"; }else{ $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"; } } $xml.="</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 */ public function postXmlCurl($xml,$url,$second=30){ //初始化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); //設定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{ $error = curl_errno($ch); echo "curl出錯,錯誤碼:$error"."<br>"; curl_close($ch); return false; } } /* 獲取當前伺服器的IP */ public function get_client_ip(){ if ($_SERVER['REMOTE_ADDR']) { $cip = $_SERVER['REMOTE_ADDR']; } elseif (getenv("REMOTE_ADDR")) { $cip = getenv("REMOTE_ADDR"); } elseif (getenv("HTTP_CLIENT_IP")) { $cip = getenv("HTTP_CLIENT_IP"); } else { $cip = "unknown"; } return $cip; } /** * 作用:格式化引數,簽名過程需要使用 */ public function formatBizQueryParaMap($paraMap, $urlencode){ $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v){ if($urlencode){ $v = urlencode($v); } $buff .= $k . "=" . $v . "&"; } $reqPar; if (strlen($buff) > 0){ $reqPar = substr($buff, 0, strlen($buff)-1); } return $reqPar; }