1、微信公眾號、微信小程序開發過程中,第三方服務器與微信服務器數據交互,需要進行數據轉換,必須用到這兩個函數:
分別是xml_to_array、array_to_xml ;
/** * 輸出xml字符(數組轉換成xml) * @param $params 參數名稱 * return string 返回組裝的xml **/ public function array_to_xml( $params ){ if(!is_array($params)|| count($params) <= 0) { return false; } $xml = ""; foreach ($params as $key=>$val) { if (is_numeric($val)){ $xml.="<".$key.">".$val."$key.">"; }else{ $xml.="<".$key.">$val."]]>$key.">"; } } $xml.=""; return $xml; } /** * 將xml轉為array * @param string $xml * return array */ public function xml_to_array($xml){ if(!$xml){ return false; } //將XML轉為array //禁止引用外部xml實體 libxml_disable_entity_loader(true); $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $data; }
2、拼接參數,將數組轉換成鍵值對形式的字符串:key=value&k=v
/** * 將參數拼接為url: key=value&key=value * @param $params * @return string */ public function ToUrlParams( $params ){ $string = ''; if( !empty($params) ){ $array = array(); foreach( $params as $key => $value ){ $array[] = $key.'='.$value; } $string = implode("&",$array); } return $string; }
3、微信小程序生成簽名,makeSign($params,$KEY),第一個參數是微信官方文檔需要的參數;第二個參數是 申請微信支付獲得的KEY
/** * 生成簽名, $KEY就是支付key * @return 簽名 */ public function MakeSign( $params,$KEY){ //簽名步驟一:按字典序排序數組參數 ksort($params); $string = $this->ToUrlParams($params); //參數進行拼接key=value&k=v //簽名步驟二:在string后加入KEY $string = $string . "&key=".$KEY; //簽名步驟三:MD5加密 $string = md5($string); //簽名步驟四:所有字符轉為大寫 $result = strtoupper($string); return $result; }
4、微信小程序的簽名,總共需要三次;期中前兩次是必須的,最后一次盡量加上
4.1 第一次是【統一下單】,將所有需要的信息進行生成簽名,包括:
$post['appid'] = $appid; $post['body'] = $body; $post['mch_id'] = $mch_id; $post['nonce_str'] = $nonce_str;//隨機字符串 $post['notify_url'] = $notify_url; $post['openid'] = $openid; $post['out_trade_no'] = $out_trade_no; $post['spbill_create_ip'] = $spbill_create_ip;//服務器終端的ip $post['total_fee'] = intval($total_fee); //總金額 最低為一分錢 必須是整數 $post['trade_type'] = $trade_type; $sign = $this->MakeSign($post,$KEY); //簽名
..等等信息;
4.2 第二次是根據【統一下單】獲得的"PREPAY_ID",和申請支付獲得的KEY,進行makeSign簽名,返回給前端(如JS、APP等)進行調用wx.requestPayment({...})微信支付,包括:
$tmp['appId'] = $appid; $tmp['nonceStr'] = $nonce_str; $tmp['package'] = 'prepay_id='.$array['PREPAY_ID']; $tmp['signType'] = 'MD5'; $tmp['timeStamp'] = "$time";
//上面是簽名所需數據,下面是返回數據
$data['timeStamp'] = "$time";
$data['nonceStr'] = $nonce_str;
$data['signType'] = 'MD5';
$data['paySign'] = $this->MakeSign($tmp,$KEY);
$data['package'] = 'prepay_id='.$array['PREPAY_ID'];
($array是【統一下單】返回的數據,經過了xml_to_array處理)
4.3 第三次是微信將支付結果通知給商戶,商戶需要進行處理通知結果。(通俗點:就是微信告訴你,用戶支付成功,你要給微信回一句話:我知道了。)
這個時候也需要makeSing簽名,具體代碼如下:
/* 微信支付完成,回調地址url方法 xiao_notify_url() */ public function xiao_notify_url(){ $KEY = '你申請微信支付的KEY'; $post = post_data(); //接受POST數據 $post_data = $this->xml_to_array($post); //微信支付成功,返回回調地址url的數據:XML轉數組Array $postSign = $post_data['sign']; unset($post_data['sign']); //這里很重要哦,一定要將返回的sign剔除掉 /* 微信官方提醒: * 商戶系統對于支付結果通知的內容一定要做【簽名驗證】, * 并校驗返回的【訂單金額是否與商戶側的訂單金額】一致, * 防止數據泄漏導致出現“假通知”,造成資金損失。 */ ksort($post_data);// 對數據進行排序 //正常情況微信是不會返回支付的key的,為保萬一我們判斷一下 --xzz 0622 if($post_data['key']){ $str = $this->ToUrlParams($post_data);//對數組數據拼接成key=value字符串 }else{ $str = $this->ToUrlParams($post_data).'&key='.$KEY; //這里也一定要加上key,不然簽名就錯了 } $user_sign = strtoupper(md5($str)); //再次生成簽名,與$postSign比較 $where['crsNo'] = $post_data['out_trade_no']; $order_msg = M('home_order','xxf_witkey_')->where($where)->find(); /* * 分別判斷返回狀態碼、返回簽名sign、返回訂單總金額,三者同時為真,訂單交易成功,狀態修改為‘ok’ */ if($post_data['return_code']=='SUCCESS'&&$postSign==$user_sign&&$order_msg['order_amount']*100==$post_data['total_fee']){ /* * 首先判斷,訂單是否已經更新為ok,因為微信會總共發送8次回調確認 * 其次,訂單已經為ok的,直接返回SUCCESS * 最后,訂單沒有為ok的,更新狀態為ok,返回SUCCESS */ if($order_msg['order_status']=='ok'){ $this->return_success(); }else{ $updata['order_status'] = 'ok'; if(M('home_order','xxf_witkey_')->where($where)->save($updata)){ $this->return_success(); } } }else{ echo '微信支付失敗'; } } /* * 給微信發送確認訂單金額和簽名正確,SUCCESS信息 -xzz0521 */ private function return_success(){ $return['return_code'] = 'SUCCESS'; $return['return_msg'] = 'OK'; $xml_post = ' '.$return['return_code'].' '.$return['return_msg'].' '; echo $xml_post;exit; }
免責聲明:本站所有文章和圖片均來自用戶分享和網絡收集,文章和圖片版權歸原作者及原出處所有,僅供學習與參考,請勿用于商業用途,如果損害了您的權利,請聯系網站客服處理。
工作日 8:30-12:00 14:30-18:00 周六及部分節假日提供值班服務
工作日 8:30-12:00 14:30-18:30