| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 | 
							- <?php
 
- require_once "../lib/WxPay.Api.php";
 
- /**
 
-  * 
 
-  * 刷卡支付实现类
 
-  * 该类实现了一个刷卡支付的流程,流程如下:
 
-  * 1、提交刷卡支付
 
-  * 2、根据返回结果决定是否需要查询订单,如果查询之后订单还未变则需要返回查询(一般反复查10次)
 
-  * 3、如果反复查询10订单依然不变,则发起撤销订单
 
-  * 4、撤销订单需要循环撤销,一直撤销成功为止(注意循环次数,建议10次)
 
-  * 
 
-  * 该类是微信支付提供的样例程序,商户可根据自己的需求修改,或者使用lib中的api自行开发,为了防止
 
-  * 查询时hold住后台php进程,商户查询和撤销逻辑可在前端调用
 
-  * 
 
-  * @author widy
 
-  *
 
-  */
 
- class MicroPay
 
- {
 
- 	/**
 
- 	 * 
 
- 	 * 提交刷卡支付,并且确认结果,接口比较慢
 
- 	 * @param WxPayMicroPay $microPayInput
 
- 	 * @throws WxpayException
 
- 	 * @return 返回查询接口的结果
 
- 	 */
 
- 	public function pay($microPayInput)
 
- 	{
 
- 		//①、提交被扫支付
 
- 		$result = WxPayApi::micropay($microPayInput, 5);
 
- 		//如果返回成功
 
- 		if(!array_key_exists("return_code", $result)
 
- 			|| !array_key_exists("out_trade_no", $result)
 
- 			|| !array_key_exists("result_code", $result))
 
- 		{
 
- 			echo "接口调用失败,请确认是否输入是否有误!";
 
- 			throw new WxPayException("接口调用失败!");
 
- 		}
 
- 		
 
- 		//签名验证
 
- 		$out_trade_no = $microPayInput->GetOut_trade_no();
 
- 		
 
- 		//②、接口调用成功,明确返回调用失败
 
- 		if($result["return_code"] == "SUCCESS" &&
 
- 		   $result["result_code"] == "FAIL" && 
 
- 		   $result["err_code"] != "USERPAYING" && 
 
- 		   $result["err_code"] != "SYSTEMERROR")
 
- 		{
 
- 			return false;
 
- 		}
 
- 		//③、确认支付是否成功
 
- 		$queryTimes = 10;
 
- 		while($queryTimes > 0)
 
- 		{
 
- 			$succResult = 0;
 
- 			$queryResult = $this->query($out_trade_no, $succResult);
 
- 			//如果需要等待1s后继续
 
- 			if($succResult == 2){
 
- 				sleep(2);
 
- 				continue;
 
- 			} else if($succResult == 1){//查询成功
 
- 				return $queryResult;
 
- 			} else {//订单交易失败
 
- 				return false;
 
- 			}
 
- 		}
 
- 		
 
- 		//④、次确认失败,则撤销订单
 
- 		if(!$this->cancel($out_trade_no))
 
- 		{
 
- 			throw new WxpayException("撤销单失败!");
 
- 		}
 
- 		return false;
 
- 	}
 
- 	
 
- 	/**
 
- 	 * 
 
- 	 * 查询订单情况
 
- 	 * @param string $out_trade_no  商户订单号
 
- 	 * @param int $succCode         查询订单结果
 
- 	 * @return 0 订单不成功,1表示订单成功,2表示继续等待
 
- 	 */
 
- 	public function query($out_trade_no, &$succCode)
 
- 	{
 
- 		$queryOrderInput = new WxPayOrderQuery();
 
- 		$queryOrderInput->SetOut_trade_no($out_trade_no);
 
- 		$result = WxPayApi::orderQuery($queryOrderInput);
 
- 		
 
- 		if($result["return_code"] == "SUCCESS" 
 
- 			&& $result["result_code"] == "SUCCESS")
 
- 		{
 
- 			//支付成功
 
- 			if($result["trade_state"] == "SUCCESS"){
 
- 				$succCode = 1;
 
- 			   	return $result;
 
- 			}
 
- 			//用户支付中
 
- 			else if($result["trade_state"] == "USERPAYING"){
 
- 				$succCode = 2;
 
- 				return false;
 
- 			}
 
- 		}
 
- 		
 
- 		//如果返回错误码为“此交易订单号不存在”则直接认定失败
 
- 		if($result["err_code"] == "ORDERNOTEXIST")
 
- 		{
 
- 			$succCode = 0;
 
- 		} else{
 
- 			//如果是系统错误,则后续继续
 
- 			$succCode = 2;
 
- 		}
 
- 		return false;
 
- 	}
 
- 	
 
- 	/**
 
- 	 * 
 
- 	 * 撤销订单,如果失败会重复调用10次
 
- 	 * @param string $out_trade_no
 
- 	 * @param 调用深度 $depth
 
- 	 */
 
- 	public function cancel($out_trade_no, $depth = 0)
 
- 	{
 
- 		if($depth > 10){
 
- 			return false;
 
- 		}
 
- 		
 
- 		$clostOrder = new WxPayReverse();
 
- 		$clostOrder->SetOut_trade_no($out_trade_no);
 
- 		$result = WxPayApi::reverse($clostOrder);
 
- 		
 
- 		//接口调用失败
 
- 		if($result["return_code"] != "SUCCESS"){
 
- 			return false;
 
- 		}
 
- 		
 
- 		//如果结果为success且不需要重新调用撤销,则表示撤销成功
 
- 		if($result["result_code"] != "SUCCESS" 
 
- 			&& $result["recall"] == "N"){
 
- 			return true;
 
- 		} else if($result["recall"] == "Y") {
 
- 			return $this->cancel($out_trade_no, ++$depth);
 
- 		}
 
- 		return false;
 
- 	}
 
- }
 
 
  |