微信掃描支付訂單數據生成類[模式二]

微信掃描支付訂單數據生成類[模式二]

*

*必要條件:

*1.微信公共號

*2.微信公共號APPID

*3.微信公共號 【微信支付】 綁定的 商戶號MCH_ID

*4. 微信公共號 商戶支付密鑰

*

* 支付流程:

* 1、調用統一下單,取得code_url,生成二維碼

* 2、用戶掃描二維碼,進行支付

* 3、支付完成之後,微信服務器會通知支付成功

* 4、在支付成功通知中需要查單確認是否真正支付成功

業務流程說明:

(1)商戶後臺系統根據用戶選購的商品生成訂單。

(2)用戶確認支付後調用微信支付【統一下單API】生成預支付交易;

(3)微信支付系統收到請求後生成預支付交易單,並返回交易會話的二維碼鏈接code_url。

(4)商戶後臺系統根據返回的code_url生成二維碼。

(5)用戶打開微信“掃一掃”掃描二維碼,微信客戶端將掃碼內容發送到微信支付系統。

(6)微信支付系統收到客戶端請求,驗證鏈接有效性後發起用戶支付,要求用戶授權。

(7)用戶在微信客戶端輸入密碼,確認支付後,微信客戶端提交授權。

(8)微信支付系統根據用戶授權完成支付交易。

(9)微信支付系統完成支付交易後給微信客戶端返回交易結果,並將交易結果通過短信、微信消息提示用戶。微信客戶端展示支付交易結果頁面。

(10)微信支付系統通過發送異步消息通知商戶後臺系統支付結果。商戶後臺系統需回覆接收情況,通知微信後臺系統不再發送該單的支付通知。

(11)未收到支付通知的情況,商戶後臺系統調用【查詢訂單API】。

(12)商戶確認訂單已支付後給用戶發貨。

<?php

class UnifiedOrder
	{
		protected $signKey='';//商戶支付密鑰,參考開戶郵件設置(必須配置,登錄商戶平臺自行設置)
		protected $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//掃描支付模式二提交接口
		//訂單配置數據	
		protected $orderInfo=array(
				'body'=>'',//商品支付描述
				'attach'=>'',//附加數據
				'out_trade_no'=>'',//交易號
				'total_fee'=>'',//總金額
				'time_start'=>'',//開始時間
				'time_expire'=>'',//有效時間
				'goods_tag'=>'',//商品
				'notify_url'=>'',//異步通知URL
				'trande_type'=>'',//支付類型  NATIVE
				'product_id'=>'',//商品ID
				'Appid'=>'111111',//公共號APPID
				'mch_id'=>'111111',//商戶號
				'bill_create_ip'=>'0.0.0.0',//客戶端IP
				'nonce_str'=>'1111111',//隨機字符串
			);
		
		//必填參數
		protected $needfileds=array(
				'out_trade_no',
				'body',
				'total_fee',
				'trade_type',
				'product_id',
				'notify_url',
				'Appid',
				'mch_id',
				'bill_create_ip',
				'nonce_str',
			);
			
		//獲取訂單配置數據	
		public function getOrderinfo()
			{
				return $this->orderInfo;
			}
			
		//設置訂單數據	
		public function setOrderinfo($info=array())
			{
				if(!empty($info) && is_array($info))
					{
						foreach($info as $key=>$val)
							{
								if(isset($this->orderInfo[$key]))
									{
										$this->orderInfo[$key]=$val;
									}
							}
					}
				return true;
			}
			
		//檢查必填參數
		protected function checkOrderinfo()
			{
				foreach($this->orderInfo as $key=>$val)
					{
						if(in_array($key,$this->needfileds))
							{
								if(!$val)
									{
										throw new Exception('缺少統一支付接口必填參數'.$key.'!');
									}
							}
					}
			}
		
		//生成簽名
		protected function setSign()
			{
				ksort($this->orderInfo);
				$signstr=$this->ToKeyVal();
				$signstr=$signstr.'&key='.$this->signKey;
				$signstr=strtoupper(md5($signstr));
				$this->orderInfo['sign']=$signstr;
				return $signstr;
			}
			
		protected function checkSign()
			{
				if(!$this->orderInfo['sign'])
					{
						throw new Exception('簽名錯誤!');
					}
					
				$sign=$this->setSign();
				
				if($this->orderInfo['sign']==$sign)
					{
						return true;
					}
				throw new Exception('簽名錯誤!');
			}
			
		//生成KEY=VAL參數個數
		protected function ToKeyVal()
			{
				$keyval='';
				foreach($this->orderInfo as $key=>$val)
					{
						if(strtolower($key)!='sign' && $val !='' && !is_array($val))
							{
								$keyval .=$key.'='.$val.'&';
							}
					}
				$keyval=trim($keyval,'&');
				return $keyval;
			}
			
		//數組轉換成XML格式數據	
		protected function arrayToXml()
			{
				if(!is_array($this->orderInfo) && count($this->orderInfo)<=0)
					{
						throw new Exception('數組數據異常!');
					}
					else
						{
							$xml='<xml>';
							foreach($this->orderInfo as $k=>$v)
								{
									if(is_numeric($v))
										{
											$xml.='<'.$k.'>'.$v.'</'.$k.'>';
										}
										else
											{
												$xml.='<'.$k.'>![CDATA['.$v.']]</'.$k.'>';
											}
								}
							$xml.='</xml>';
							return $xml;
						}
			}	
			
		//XML格式數據轉換成數組數據
		protected function xmlToArray($xml='')
			{
				if(!$xml)
					{
							throw new Exception('xml數據異常!');
					}
					else
						{
							libxml_disable_entity_loader(true);
							$this->returnData=json_decode(json_encode(@simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
							return $this->returnData;
						}
			}
			
		//以curl方式提交數據到微信服務器
		protected function curlXml($xml, $url, $ca = false, $second = 30)
			{
				$ch = curl_init();
				//設置超時
				curl_setopt($ch, CURLOPT_TIMEOUT, $second);

				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, false);
			
				if($ca == true)
					{
						//設置證書
						//使用證書:cert 與 key 分別屬於兩個.pem文件
						curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
						curl_setopt($ch,CURLOPT_SSLCERT, './apiclient_cert.pem');
						curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
						curl_setopt($ch,CURLOPT_SSLKEY, './apiclient_key.pem');
					}
				//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);
							curl_close($ch);
							throw new Exception("curl出錯,錯誤碼:$error");
						}
			}
			
		protected function wxReply($reply='')
			{
				$this->orderInfo=$this->xmlToArray($reply);
				if($this->orderInfo['return_code'] != 'SUCCESS')
					{
						 return $this->orderInfo;
					}
					
				$this->CheckSign();
				return $this->orderInfo;
			}
			
		//發送請求數據到微信服務器
		public function requestXml($info=array())
			{
				$this->setOrderinfo($info);//設置數據
				$this->checkOrderinfo();//檢查必填參數
				$this->setSign();//生成簽名
				
				$xml=$this->arrayToXml();//數據格式轉換
				$result=$this->curlXml($xml,$this->url,false);//curl發送數據
				$result=$this->wxReply($result);//返回結果處理 
				
				return $result;
			}
			
		
	}

	$class = new UnifiedOrder();
	$info=array(
				'body'=>'test',
				'attach'=>'test',
				'out_trade_no'=>date("YmdHis"),
				'total_fee'=>'1',
				'time_start'=>date("YmdHis"),
				'time_expire'=>date("YmdHis", time() + 600),
				'goods_tag'=>'test',
				'notify_url'=>'http://localhost/WXqrpay/notify.php',
				'trande_type'=>'NATIVE',
				'product_id'=>'10000000111',
			);
	$class->requestXml($info);
	$result=$class->getOrderinfo();
	var_dump($result);
?>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章