174 lines
5.1 KiB
PHP
174 lines
5.1 KiB
PHP
<?php
|
||
/**
|
||
* Created by PhpStorm.
|
||
* User: lock
|
||
* Date: 2019/2/24
|
||
* Time: 12:35 PM
|
||
*/
|
||
|
||
namespace app\common\wxpay;
|
||
|
||
|
||
use app\common\wxpay\lib\WxPayApi;
|
||
use app\common\wxpay\lib\WxPayException;
|
||
use app\common\wxpay\lib\WxPayOrderQuery;
|
||
use app\common\wxpay\lib\WxPayReverse;
|
||
|
||
class MicroPay
|
||
{
|
||
/**
|
||
*
|
||
* 提交刷卡支付,并且确认结果,接口比较慢
|
||
* @param WxPayMicroPay $microPayInput
|
||
* @throws WxpayException
|
||
* @return 返回查询接口的结果
|
||
*/
|
||
public function pay($microPayInput)
|
||
{
|
||
//①、提交被扫支付
|
||
$config = new WxPayConfig();
|
||
$result = WxPayApi::micropay($config, $microPayInput, 5);
|
||
//如果返回成功
|
||
if(!array_key_exists("return_code", $result)
|
||
|| !array_key_exists("result_code", $result))
|
||
{
|
||
echo "接口调用失败,请确认是否输入是否有误!";
|
||
throw new WxPayException("接口调用失败!");
|
||
}
|
||
|
||
//取订单号
|
||
$out_trade_no = $microPayInput->GetOut_trade_no();
|
||
|
||
//sub_mch_id
|
||
$sub_mch_id = $microPayInput->GetSubMch_id();
|
||
|
||
//②、接口调用成功,明确返回调用失败
|
||
if($result["return_code"] == "SUCCESS" &&
|
||
$result["result_code"] == "FAIL" &&
|
||
$result["err_code"] != "USERPAYING" &&
|
||
$result["err_code"] != "SYSTEMERROR")
|
||
{
|
||
return $result;
|
||
}
|
||
|
||
//③、确认支付是否成功
|
||
$queryTimes = 10;
|
||
$times = 0;
|
||
while($queryTimes > 0)
|
||
{
|
||
$times++;
|
||
$succResult = 0;
|
||
$queryResult = $this->query($out_trade_no,$sub_mch_id, $succResult);
|
||
//如果需要等待1s后继续
|
||
if($succResult == 2){
|
||
sleep(2);
|
||
continue;
|
||
} else if($succResult == 1){//查询成功
|
||
return $queryResult;
|
||
} else {//订单交易失败
|
||
break;
|
||
}
|
||
}
|
||
//④、次确认失败,则撤销订单
|
||
if(!$this->cancel($out_trade_no,$sub_mch_id))
|
||
{
|
||
//throw new WxpayException("撤销单失败!");
|
||
}
|
||
return array(
|
||
'result_code' => 'FAIL',
|
||
'err_code_des' => '支付失败'
|
||
);
|
||
}
|
||
|
||
/**
|
||
*
|
||
* 查询订单情况
|
||
* @param string $out_trade_no 商户订单号
|
||
* @param int $succCode 查询订单结果
|
||
* @return 0 订单不成功,1表示订单成功,2表示继续等待
|
||
*/
|
||
public function query($out_trade_no,$sub_mch_id, &$succCode)
|
||
{
|
||
$queryOrderInput = new WxPayOrderQuery();
|
||
$queryOrderInput->SetOut_trade_no($out_trade_no);
|
||
$queryOrderInput->SetSubMch_id($sub_mch_id);
|
||
$config = new WxPayConfig();
|
||
$result = array();
|
||
try{
|
||
$result = WxPayApi::orderQuery($config, $queryOrderInput);
|
||
} catch(Exception $e) {
|
||
Log::ERROR(json_encode($e));
|
||
}
|
||
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;
|
||
}
|
||
else if($result["trade_state"] == "NOTPAY"){
|
||
$succCode = 0;
|
||
return $result;
|
||
}
|
||
}
|
||
//如果返回错误码为“此交易订单号不存在”则直接认定失败
|
||
if (array_key_exists('err_code',$result))
|
||
{
|
||
if($result["err_code"] == "ORDERNOTEXIST")
|
||
{
|
||
$succCode = 0;
|
||
} else{
|
||
//如果是系统错误,则后续继续
|
||
$succCode = 2;
|
||
}
|
||
}else
|
||
{
|
||
//如果是系统错误,则后续继续
|
||
$succCode = 2;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
*
|
||
* 撤销订单,如果失败会重复调用10次
|
||
* @param string $out_trade_no
|
||
* @param 调用深度 $depth
|
||
*/
|
||
public function cancel($out_trade_no, $sub_mch_id,$depth = 0)
|
||
{
|
||
try {
|
||
if($depth > 10){
|
||
return false;
|
||
}
|
||
|
||
$clostOrder = new WxPayReverse();
|
||
$clostOrder->SetOut_trade_no($out_trade_no);
|
||
$clostOrder->SetSubMch_id($sub_mch_id);
|
||
$config = new WxPayConfig();
|
||
$result = WxPayApi::reverse($config, $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);
|
||
}
|
||
} catch(Exception $e) {
|
||
Log::ERROR(json_encode($e));
|
||
}
|
||
return false;
|
||
}
|
||
} |