解决用pb微信刷卡支付经常出错的问题(PHP版webserver)

   前端时间改用api函数进行计时,但问题还是存在,没有任何作用,现在把PHP接口重新写一次,用另外一种方法调用微信的支付接口,就是异步通讯的方式。经过这次改写,问题得到了根本上的解决,现在把经过写下来。
	编写思路:
	一、首先用支付或者交易条形码查询数据库是否存在记录,如果不存在,则分成未交易和已交易两种情况。
			1、未交易:进行异步调用微信支付接口,把信息发到接口页面,同时把指定的数组插入数据库,并且返回给调用程序,防止调用程序挂起,造成崩溃。接口页面把信息发送到微信端,并且记录相关日志,刷新交易信息表(主要是给webserver查询用的)
			2、已交易,这里分三种情况
				(1)交易失败或者交易成功,都直接返回失败信息。
				(2)交易中,异步调用微信接口,并且返回交易中的数组给调用的程序。
	相关代码如下:
	server.php
<?php
ini_set("soap.wsdl_cache_enabled", "0");
require_once ("lib/nusoap.php"); 
$server = new soap_server ();

// 避免乱码  
$server->soap_defencoding = 'UTF-8';  
$server->decode_utf8 = false;  
$server->xml_encoding = 'UTF-8'; 
$server->configureWSDL ('wxpb'); // 打开 wsdl 支持  
include_once('MMysql.class.php');
$configArr=array(
	'host'=>'127.0.0.1',
	'port'=>3306,
	'user'=>'root',
	'passwd'=>'root',
	'dbname'=>'wxpay'
);
$mysql = new MMysql($configArr);

//定义返回的json
$server->wsdl->addComplexType(
 'paydone',
 'complexType',
 'struct',
 'all',
 '',
 array(
 'appid' => array('name' => 'appid', 'type' => 'xsd:string'),
 'openid' => array('name' => 'openid', 'type' => 'xsd:string'),
 'result_code' => array('name' => 'result_code', 'type' => 'xsd:string'),
 'time_end' => array('name' => 'time_end', 'type' => 'xsd:string'),
 'total_fee' => array('name' => 'total_fee', 'type' => 'xsd:string'),
 'transaction_id' => array('name' => 'transaction_id', 'type' => 'xsd:string'),
 'order_code' => array('name' => 'order_code', 'type' => 'xsd:string'),
 'wx_error' => array('name' => 'wx_error', 'type' => 'xsd:string') 
 )
);



// Register the methods to expose
$server->register('putdata', // method name
//array('wxpay' => 'tns:wxpay'), // input parameters
array('bar_code' => 'xsd:string','money' => 'xsd:string','order_msg' => 'xsd:string'),
array('paydone' => 'tns:paydone'), // output parameters
'urn:wxpb', // namespace
'urn:wxpb#putdata', // soapaction
'rpc', // style
'encoded', // use
'Returns a list of foo' // documentation
);


// 查询订单
$server->register('getorders', // method name
array('order_code' => 'xsd:string'),
array('paydone' => 'tns:paydone'), // output parameters
'urn:wxpb', // namespace
'urn:wxpb#getorders', // soapaction
'rpc', // style
'encoded', // use
'Returns a list of orders' // documentation
);

// 取消订单
$server->register('cancelorders', // method name
array('order_code' => 'xsd:string'),
array('paydone' => 'tns:paydone'), // output parameters
'urn:wxpb', // namespace
'urn:wxpb#cancelorders', // soapaction
'rpc', // style
'encoded', // use
'cancel a list of orders' // documentation
);



//isset  检测变量是否设置  
$HTTP_RAW_POST_DATA = isset ( $HTTP_RAW_POST_DATA ) ? $HTTP_RAW_POST_DATA : ''; 

//service  处理客户端输入的数据  
$server->service ( $HTTP_RAW_POST_DATA );

exit; 
/** 
 * 供调用的方法,微信订单
 * @param $name 
 */ 
 

function putdata($bar_code,$money,$order_msg){
	global $mysql;
	$renary =array();
	$renary = get_ret_data($funname='wx_server_pay',$bar_code,$order_msg,$money,'');
	$reary=array(
		'appid'=>'1',
		'openid'=>'1',
		'result_code'=>'1',
		'time_end'=>'1',
		'total_fee'=>'1',
		'transaction_id'=>'1',
		'order_code'=>'1',
		'wx_error'=>'1'
	);
	
	if(is_array($renary)){
		foreach($reary as $key=>$val){
			if(isset($renary[$key]))
				$reary[$key]=$renary[$key];
		}
		$reary['wx_error']=serialize($renary);
	}else{
		$reary['wx_error']=serialize($renary);
	}
	$wxary=array(
		'msgflag'=>'微信支付',
		'flags'=>1,		
		'errormsg'=>serialize($renary),
		'allmsg'=>serialize($reary),
		'order_code'=>$reary['order_code']
	);
	$mysql->insert('wxmsg',$wxary);	
	return $reary;
	
}


/** 
 * 供调用的方法,查询订单 
 * @param $name 
 */ 
function getorders($order_code){
	global $mysql;
	$renary = array();
	$renary = get_ret_data('wx_get_order','','',0,$order_code);

	$reary=array(
		'appid'=>'1',
		'openid'=>'1',
		'result_code'=>'1',
		'time_end'=>'1',
		'total_fee'=>'1',
		'transaction_id'=>'1',
		'order_code'=>'1',
		'wx_error'=>'1'
	);

	if(is_array($renary)){
		foreach($reary as $key=>$val){
			if(isset($renary[$key]))
				$reary[$key]=$renary[$key];
		}
	}
	$wxary=array(
		'msgflag'=>'支付查询',
		'flags'=>2,		
		'errormsg'=>serialize($renary),
		'allmsg'=>serialize($reary),
		'order_code'=>$reary['order_code']
	);
	$mysql->insert('wxmsg',$wxary);
	
	return $reary;
}


/** 
 * 供调用的方法,取消订单 
 * @param $name 
 */ 
function cancelorders($order_code){
	global $mysql;
	$renary = array();
	$renary = wx_cancel_pay($order_code);
	
	
	$reary=array(
		'appid'=>'',
		'openid'=>'',
		'result_code'=>'',
		'time_end'=>'',
		'total_fee'=>'',
		'transaction_id'=>'',
		'order_code'=>'',
		'wx_error'=>''
	);
	if(!is_array($renary)){
		$reary['wx_error']=serialize($renary);
	}else{
		foreach($reary as $key=>$val){
			if(isset($renary[$key]))
				$reary[$key]=$renary[$key];
		}
	}
	$wxary=array(
		'msgflag'=>'支付取消',
		'flags'=>3,
		'errormsg'=>serialize($renary),
		'allmsg'=>serialize($reary),
		'order_code'=>$reary['order_code']
	);
	$mysql->insert('wxmsg',$wxary);		
	return $reary;
}


//取消订单
function wx_cancel_pay($order_code='errorerror'){
	require_once "lib/WxPay.Api.php";
	
	require_once "WxPay.MicroPay.php";

	require_once 'log.php';

	//初始化日志
	$logHandler= new CLogFileHandler("logs/".date('Y-m-d').'.log');
	$log = Log::Init($logHandler, 15);

	
	$microPay = new MicroPay();
	$order_result = $microPay->cancel($order_code);
	if(!$order_result){
		$order_result = $microPay->cancel_result($order_code);
		$data = returnary($order_result);
		if(isset($data['err_code_des'])){
			$data['wx_error'] = $data['err_code_des'];
		}elseif($data['result_code']=='SUCCESS'){
			$data['wx_error'] = '退费成功';
		}else{
			$data['wx_error'] = '其他原因,退费不成功';
		}
		//$data['wx_error'] = $data['err_code_des'];
	}else{
		$data=array(
			'appid'=>'',
			'openid'=>'',
			'result_code'=>'SUCCESS',
			'time_end'=>'',
			'total_fee'=>'',
			'transaction_id'=>'',
			'order_code'=>'',
			'wx_error'=>'退费成功'
		);
		//$data = $reary;
	}

	return $data;

		//echo JSON($data);
}

//打印输出数组信息
function returnary($data)
{
	if(!is_array($data))return $data;
	$reary = array();
    foreach($data as $key=>$value){
        //echo "<font color='#00ff55;'>$key</font> : $value <br/>";
		$reary[$key]=$value;
    }
	return $reary;
}

function getMillisecond(){
	list($t1, $t2) = explode(' ', microtime());
	return sprintf('%.0f',(floatval($t1)+floatval($t2))*1000);
}
//异步请求函数
function get_ret_data($funname='',$auth_code='',$mzdjh='',$money=0,$order_code='') {
	global $mysql;
	$res=array();
	//检测窜入参数是否为空
	if(!$funname){
		return false;
	}
	
	//查询数据库,检测交易是否完成
	$sql="select openid,result_code,time_end,total_fee,transaction_id,order_code,wx_error from wxpay ";
	$where='';
	if($auth_code){
		$where=" where auth_code='$auth_code'";
	}
	if($order_code){
		$where=" where order_code='$order_code'";
	}
	
	
	if(!$where)return false;
	
	$sql=$sql.$where;
	
	$result = $mysql->doSql($sql);

	//总共三种情况
	//1、还没有交易
	//2、已交易,但出错(已取消也属于出错交易)
	//3、正在交易
	if($result){

		$checkdata=$result[0];
		if($checkdata['result_code'] == 'FAILED'){
			//2、已交易,但出错
			return $checkdata;
		}elseif($checkdata['result_code'] == 'SUCCESS'){
			//交易成功
			return $checkdata;
		}else{
			$fp=fsockopen('localhost',80,$errno,$errstr,5);
			if(!$fp){
				echo "$errstr ($errno)<br />\n";
			}
			sleep(1);
			fputs($fp,"GET /wxsave.php?funname=$funname&auth_code=$auth_code&mzdjh=$mzdjh&money=$money&order_code=$order_code\r\n"); #请求的资源 URL 一定要写对
			fclose($fp);
			//4、正在交易
			return $checkdata;
		}
	}else{
		//1、还没有交易
		require_once "lib/WxPay.Config.php";
		$order_code = WxPayConfig::MCHID.(string)time(). rand(10000, 99999);
		$insertdata=array(
			'openid'=>'',
			'result_code'=>'',
			'time_end'=>'',
			'total_fee'=>'',
			'transaction_id'=>'',
			'order_code'=>$order_code,
			'wx_error'=>'',
			'auth_code'=>$auth_code,
			'byh'=>$mzdjh
		);

		$mysql->insert('wxpay',$insertdata);
		$fp=fsockopen('localhost',80,$errno,$errstr,5);
		if(!$fp){
			echo "$errstr ($errno)<br />\n";
		}
		sleep(1);
		fputs($fp,"GET /wxsave.php?funname=$funname&auth_code=$auth_code&mzdjh=$mzdjh&money=$money&order_code=$order_code\r\n"); #请求的资源 URL 一定要写对
		fclose($fp);
		return $insertdata;
	}

} 
?>

wxsave.php

<?php

include_once('MMysql.class.php');
$configArr=array(
	'host'=>'127.0.0.1',
	'port'=>3306,
	'user'=>'root',
	'passwd'=>'root',
	'dbname'=>'wxpay'
);
$mysql = new MMysql($configArr);
$funname = '';
$mzdjh = '';
$money = 0;
$order_code = '';
$auth_code = '';
if(isset($_GET['funname']))
	$funname = $_GET['funname'];
if(isset($_GET['mzdjh']))
	$mzdjh = $_GET['mzdjh'];
if(isset($_GET['money']))
	$money = $_GET['money'];
if(isset($_GET['order_code']))
	$order_code = $_GET['order_code'];
if(isset($_GET['auth_code']))
	$auth_code = $_GET['auth_code'];
$wxobj = new wx_save();
$wxobj->mysql_object = $mysql;
$wxobj->input_money = (int)$money;
if($funname=='wx_server_pay'){
	$wxobj->wx_server_pay($auth_code,$money,$mzdjh,$order_code);
}elseif($funname=='wx_get_order'){
	$wxobj->wx_get_order($order_code);
}elseif($funname=='wx_cancel_pay'){
	$wxobj->wx_cancel_pay($order_code);
}
class wx_save{
	var $mysql_object;
	var $input_byh;
	var $input_order_code;
	var $input_money;
	var $input_auth_code;
	
	public function wx_server_pay($auth_code='errorerror',$money=0,$order_msg="刷卡测试样例-支付",$order_code='123'){
		
		require_once "lib/WxPay.Api.php";
		
		require_once "WxPay.MicroPay.php";

		require_once 'log.php';
		
		//初始化日志
		$logHandler= new CLogFileHandler("logs/".date('Y-m-d').'.log');
		
		$log = Log::Init($logHandler, 15);
		
		$input = new WxPayMicroPay();
		$input->SetAuth_code($auth_code);
		$input->SetBody($order_msg);
		$input->SetTotal_fee($money);
		$trade_no = rand(1,9);
		$trade_no = (string)$trade_no;
		
		$trade_no1 = getMillisecond();
		$trade_no2 = (string)$trade_no1.(string)$trade_no;
		
		$trade_no = $order_code;

		$input->SetOut_trade_no($trade_no);
		
		$microPay = new MicroPay();
		
		$data = returnary($microPay->pay($input));
		$reary=array(
			'openid'=>'1',
			'result_code'=>'1',
			'time_end'=>'1',
			'total_fee'=>'1',
			'transaction_id'=>'1',
			'wx_error'=>'1'
		);
		if(is_array($data)){
			foreach($reary as $key=>$val){
				if(isset($data[$key]))
					$reary[$key]=$data[$key];
			}
			$reary['wx_error']=serialize($data);
		}else{
			$reary['wx_error']=serialize($data);
		}	
		$this->mysql_object->where(array('order_code'=>$trade_no))->update('wxpay',$reary);		
	}
	//查询订单
	function wx_get_order($order_code='errorerror'){
		
		require_once "lib/WxPay.Api.php";
		
		require_once "WxPay.MicroPay.php";

		require_once 'log.php';

		//初始化日志
		$logHandler= new CLogFileHandler("logs/".date('Y-m-d').'.log');
		$log = Log::Init($logHandler, 15);
		$microPay = new MicroPay();

		$succResult = 0;
		
		$queryResult =$microPay->query($order_code, $succResult);

		if($succResult==2){
			$data=array(
			'appid'=>'',
			'openid'=>'',
			'result_code'=>'',
			'time_end'=>'',
			'total_fee'=>'',
			'transaction_id'=>'',
			'order_code'=>$order_code,
			'wx_error'=>'用户正在支付'
			);		
		}else if($succResult==1){
			$data = returnary($queryResult);
		}else if($succResult==3){
			$data=array(
			'appid'=>'',
			'openid'=>'',
			'result_code'=>'FAILED',
			'time_end'=>'',
			'total_fee'=>'',
			'transaction_id'=>'',
			'order_code'=>$order_code,
			'wx_error'=>'用户取消支付'
			);
		}else{
			$data=array(
			'appid'=>'',
			'openid'=>'',
			'result_code'=>'FAILED',
			'time_end'=>'',
			'total_fee'=>'',
			'transaction_id'=>'',
			'order_code'=>$order_code,
			'wx_error'=>'订单交易失败'
			);		
		}
		$reary=array(
			'openid'=>'1',
			'result_code'=>'1',
			'time_end'=>'1',
			'total_fee'=>'1',
			'transaction_id'=>'1',
			'wx_error'=>'1'
		);
		if(is_array($data)){
			foreach($reary as $key=>$val){
				if(isset($data[$key]))
					$reary[$key]=$data[$key];
			}
			$reary['wx_error']=serialize($data);
		}else{
			$reary['wx_error']=serialize($data);
		}	
		$this->mysql_object->where(array('order_code'=>$order_code))->update('wxpay',$reary);

	}
	
	//取消订单
	function wx_cancel_pay($order_code='errorerror'){
		require_once "lib/WxPay.Api.php";
		
		require_once "WxPay.MicroPay.php";

		require_once 'log.php';

		//初始化日志
		$logHandler= new CLogFileHandler("logs/".date('Y-m-d').'.log');
		$log = Log::Init($logHandler, 15);

		
		$microPay = new MicroPay();
		$order_result = $microPay->cancel($order_code);
		if(!$order_result){
			$order_result = $microPay->cancel_result($order_code);
			$data = returnary($order_result);
			if(isset($data['err_code_des'])){
				$data['wx_error'] = $data['err_code_des'];
			}elseif($data['result_code']=='SUCCESS'){
				$data['wx_error'] = '退费成功';
			}else{
				$data['wx_error'] = '其他原因,退费不成功';
			}

		}else{
			$data=array(
				'appid'=>'',
				'openid'=>'',
				'result_code'=>'SUCCESS',
				'time_end'=>'',
				'total_fee'=>'',
				'transaction_id'=>'',
				'order_code'=>'',
				'wx_error'=>'退费成功'
			);
			$this->mysql_object->where(array('order_code'=>$order_code))->delete('wxpay');

		}
		
	}
	
}


//打印输出数组信息
function returnary($data)
{
	if(!is_array($data))return $data;
	$reary = array();
    foreach($data as $key=>$value){
        
		$reary[$key]=$value;
    }
	return $reary;
}

function getMillisecond(){
	list($t1, $t2) = explode(' ', microtime());
	return sprintf('%.0f',(floatval($t1)+floatval($t2))*1000);
} 
?>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值