前端时间改用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);
}
?>