真在的只需要一個(gè)class類文件幾個(gè)函數(shù)就可以調(diào)用微信的所有支付,不管是微信公眾號(hào)、h5、app、小程序支付,加密方式都是一樣的,對(duì)比下微信的支付文檔,只需要修改第一步傳入的參數(shù)不同,下單地址不同,加密方式都是一樣的,所以只要看懂下面的第一個(gè)函數(shù),將搞定微信的任何支付。
微信支付class類,第一個(gè)函數(shù)是調(diào)用微信支付,第二個(gè)函數(shù)是支付后回調(diào),其它函數(shù)都是加密相關(guān),無法關(guān)注
<?php /** * 微信支付 * @author 潤(rùn)雪科技 * */ class pay { /** * 獲取支付參數(shù) */ public function pay() { //基本的訂單參數(shù) $param['appid'] = 'xxxxx' ; //微信公眾號(hào)或小程序的appid $param['mch_id'] = 'xxxxx' ; //商戶號(hào)id $param['nonce_str'] = 'xxxxx' ; //隨機(jī)字符轉(zhuǎn),可用弄10位長(zhǎng)度 $param['body'] = '購(gòu)買商品' ; //商品描述,就寫購(gòu)買商品或商品名詞都可以 $param['attach'] = 'xxxxx' ; //附加數(shù)據(jù),一般都是傳訂單號(hào)或支付類型,如果是多個(gè)參數(shù)可通過一定方式拼接成字符串,等異步回調(diào)的時(shí)候通過相同方式解開即可 $param['out_trade_no'] = 'xxxxx' ; //訂單號(hào),在我們自己的系統(tǒng)中必須是唯一的 $param['total_fee'] = 100 ; //支付金額,調(diào)用微信支付單位是分,所以這一般我們都要用脂肪層金額來乘以100 $param['spbill_create_ip'] = 'xxxxx' ; //用戶的ip $param['notify_url'] = 'https://www.runxuekeji/' ; //回調(diào)url $param['trade_type'] = 'JSAPI' ; //交易類型 $param['sign'] = $this->make_sign( $param , '商戶中設(shè)置的32位密鑰key' ) ; //生成簽名 //調(diào)用微信下單地址返回訂單號(hào)等 $xml = $this->to_xml( $param ) ; $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder' ; //生成訂單的地址 $response = $this->from_xml( $this->post_xml_curl( $xml , $url ) ) ; //組裝支付需要的參數(shù) $result['appid'] = 'xxxxx' ; //微信公眾號(hào)或小程序的appid $result['partnerid'] = 'xxxxx' ; //商戶號(hào)id $result['prepayid'] = $response['prepay_id'] ; $result['package'] = 'Sign=WXPay'; $result['noncestr'] = 'xxxxx' ; //隨機(jī)字符串 $result['timestamp'] = time() ; //時(shí)間戳 $result['sign'] = $this->make_sign( $result , '商戶中設(shè)置的32位密鑰key' ) ; //生成簽名 return result($result,1,'獲取成功'); } /** * 生成簽名 * @param $data array 生成前面要傳的參數(shù) * @param $key string 商戶key * @return 簽名,本函數(shù)不覆蓋sign成員變量,如要設(shè)置簽名需要調(diào)用SetSign方法賦值 */ private function make_sign( $data , $key ) { //簽名步驟一:按字典序排序參數(shù) ksort( $data ); $string = $this->to_url_params( $data ); //簽名步驟二:在string后加入KEY $string = $string . "&key=" . $key; //簽名步驟三:MD5加密 $string = md5($string); //簽名步驟四:所有字符轉(zhuǎn)為大寫 $result = strtoupper($string); return $result; } /** * 格式化參數(shù)格式化成url參數(shù) * @return string */ private function to_url_params( $data ) { $buff = ""; foreach ($data as $k => $v) { if($k != "sign" && $v != "" && !is_array($v)){ $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); return $buff; } /** * 輸出xml字符 * @throws WxPayException **/ private function to_xml( $param ) { if(!is_array($param) || count($param) <= 0) { throw new WxPayException("數(shù)組數(shù)據(jù)異常!"); } $xml = "<xml>"; foreach ($param as $key=>$val) { if (is_numeric($val)){ $xml.="<".$key.">".$val."</".$key.">"; }else{ $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"; } } $xml.="</xml>"; return $xml; } /** * 將xml轉(zhuǎn)為array * @param string $xml * @throws WxPayException */ private function from_xml($xml) { libxml_disable_entity_loader(true); return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); } /** * 以post方式提交xml到對(duì)應(yīng)的接口url * * @param string $xml 需要post的xml數(shù)據(jù) * @param string $url url * @param bool $useCert 是否需要證書,默認(rèn)不需要 * @param int $second url執(zhí)行超時(shí)時(shí)間,默認(rèn)30s * @throws WxPayException */ private function post_xml_curl($xml, $url, $useCert = false, $second = 30 , $curl_proxy = false ) { $ch = curl_init(); //設(shè)置超時(shí) curl_setopt($ch, CURLOPT_TIMEOUT, $second); //如果有配置代理這里就設(shè)置代理 if( $curl_proxy ){ curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST); curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT); } curl_setopt($ch,CURLOPT_URL, $url); if(stripos($url,"https://")!==FALSE){ curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); } else { curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//嚴(yán)格校驗(yàn) } //設(shè)置header curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求結(jié)果為字符串且輸出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); if($useCert == true){ //設(shè)置證書 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); //curl_setopt($ch,CURLOPT_SSLCERT, dirname(__FILE__).'/'. '../apiclient_cert.pem' ); //curl_setopt($ch,CURLOPT_SSLKEY, dirname(__FILE__).'/'.'../apiclient_key.pem'); } //post提交方式 curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); //運(yùn)行curl $data = curl_exec($ch); //返回結(jié)果 if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); curl_close($ch); die( "curl出錯(cuò),錯(cuò)誤碼:$error" ) ; } } }