支付宝接口集成及错误排除

我集成了支付宝接口,能够支付成功,但是notify_url.php中始终好像没有回调,因此按照官方文档,我做了如下修改

$verify_result = $alipayNotify->verifyNotify();
if($verify_result) {
	//商户订单号
	$order_id = $_POST['out_trade_no'];
	//支付宝交易号
	$trade_no = $_POST['trade_no'];
	//交易状态
	$trade_status = $_POST['trade_status'];
	//订单总金额
	$total_fee = floatval($_POST['total_fee']);
	//订单支付时间
	$pay_time = $_POST['gmt_payment'];
	//定制的错误机制
	$user_debug=1;
	//退款状态
	$refund_status = $_POST['refund_status'];
	logResult('记录付款后支付宝返回的相关信息[订单编号]:'.$order_id.'[金额]:'.$total_fee.'[时间]:'.$pay_time.'[状态]:'.$_POST['trade_status']);
	if ($_POST['trade_status'] == 'TRADE_SUCCESS' || $_POST['trade_status'] == 'TRADE_FINISHED') {
	}
}
else{
    //验证失败
    logResult('验证失败');
    echo "fail";
}
其实就是用支付宝接口内部方法logResult方法记录了回调的情况,看看是否回调该文件并且看回调到了哪一步

再支付一次我发现log.txt文件中多了“验证失败”,因此我就判断是$alipayNotify->verifyNotify();这个没有返回正确的值

打开alipay_notify.class.php文件,找到verifyNotify方法,发现官方注释了一段语句

function verifyNotify(){
		if(empty($_POST)) {//判断POST来的数组是否为空
			return false;
		}
		else {
			//生成签名结果
			$isSign = $this->getSignVeryfy($_POST, $_POST["sign"]);
			//获取支付宝远程服务器ATN结果(验证是否是支付宝发来的消息)
			$responseTxt = 'true';
			if (! empty($_POST["notify_id"])) {$responseTxt = $this->getResponse($_POST["notify_id"]);}
			
			//写日志记录
			//if ($isSign) {
			//	$isSignStr = 'true';
			//}
			//else {
			//	$isSignStr = 'false';
			//}
			//$log_text = "responseTxt=".$responseTxt."\n notify_url_log:isSign=".$isSignStr.",";
			//$log_text = $log_text.createLinkString($_POST);
			//logResult($log_text);
			
			//验证
			//$responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
			//isSign的结果不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
			if (preg_match("/true$/i",$responseTxt) && $isSign) {
				return true;
			} else {
				return false;
			}
		}
	}

将如上代码的注释取消,再一次支付,再看log.txt发现写入了如下代码

执行日期:20140306121304
responseTxt=
 notify_url_log:isSign=true,discount=0.00&payment_type=1&subject=订单主题[email protected]&gmt_create=2014-03-06 12:12:55¬ify_type=trade_status_sync&quantity=1&out_trade_no=1394079155627&seller_id=2088211562160923¬ify_time=2014-03-06 12:13:03&trade_status=TRADE_SUCCESS&is_total_fee_adjust=N&total_fee=0.10&gmt_payment=2014-03-06 12:13:[email protected]&price=0.10&buyer_id=2088702034696988¬ify_id=ec0149b551db7c645e3e66a3058d3b067g&use_coupon=N&sign_type=MD5&sign=5a46cb0b739f659089330a28293e042e

于是我们可以发现isSign是通过了,那就是$this->getResponse($_POST["notify_id"]这个方法错误了

function getResponse($notify_id) {
		$transport = strtolower(trim($this->alipay_config['transport']));
		$partner = trim($this->alipay_config['partner']);
		$veryfy_url = '';
		if($transport == 'https') {
			$veryfy_url = $this->https_verify_url;
		}
		else {
			$veryfy_url = $this->http_verify_url;
		}
		$veryfy_url = $veryfy_url."partner=" . $partner . "¬ify_id=" . $notify_id;
		$responseTxt = getHttpResponseGET($veryfy_url, $this->alipay_config['cacert']);
		
		return $responseTxt;
	}

可以看出,该函数就是与支付宝进行通信,并且这一次用到了支付宝的证书,我起初怀疑是证书的问题,其实所有的证书都是一样的,不会根据商户不同证书不同,不过也有可能是证书路径的问题$alipay_config['cacert']    = getcwd().'\\cacert.pem';有人也说改成$alipay_config['cacert']    = getcwd().'/cacert.pem';不过我没遇到这个问题

当然最后要看alipay_core.function.php中的getHttpResponseGET方法了

function getHttpResponseGET($url,$cacert_url) {
	$curl = curl_init($url);
	curl_setopt($curl, CURLOPT_HEADER, 0 ); // 过滤HTTP头
	curl_setopt($curl,CURLOPT_RETURNTRANSFER, 1);// 显示输出结果
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);//SSL证书认证
	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//严格认证
	curl_setopt($curl, CURLOPT_CAINFO,$cacert_url);//证书地址
	$responseText = curl_exec($curl);
	//var_dump( curl_error($curl) );//如果执行curl过程中出现异常,可打开此开关,以便查看异常内容
	curl_close($curl);
	
	return $responseText;
}

发现就是个curl_exec方法,于是就自然而然的怀疑是curl_exec方法被禁用了,打开phpinfo一看,果然是curl_exec被禁用了

从中我们可以发现支付宝工作的原理,其实也没有多复杂,支付成功后他会往notify_url post数据过来,系统会根据本地的证书,curl校验

你可能感兴趣的:(支付宝接口集成及错误排除)