Authored by 郝肖肖

支付宝版本升级

... ... @@ -23,16 +23,18 @@ class Yohobuy
// const YOHOBUY_URL = 'http://www.yohobuy.com/';
//java API
const API_URL = 'http://api.yoho.yohoops.org/';
const API_URL2 = 'http://api.yoho.yohoops.org/';
const SERVICE_URL = 'http://service.yoho.yohoops.org/';
const YOHOBUY_URL = 'http://www.yohobuy.com/';
const API_OLD = 'http://api2.open.yohobuy.com/';
// const API_URL = 'http://api.yoho.yohoops.org/';
// const API_URL2 = 'http://api.yoho.yohoops.org/';
// const SERVICE_URL = 'http://service.yoho.yohoops.org/';
// const YOHOBUY_URL = 'http://www.yohobuy.com/';
// const API_OLD = 'http://api2.open.yohobuy.com/';
// const SERVICE_NOTIFY = 'http://service.yoho.cn/';
// 测试环境 */
// const API_URL = 'http://testapi.yoho.cn:28078/'; // 'http://192.168.102.205:8080/gateway/'
// const SERVICE_URL = 'http://testservice.yoho.cn:28077/';
// const YOHOBUY_URL = 'http://www.yohobuy.com/';
const API_URL = 'http://testapi.yoho.cn:28078/'; // 'http://192.168.102.205:8080/gateway/'
const SERVICE_URL = 'http://testservice.yoho.cn:28077/';
const YOHOBUY_URL = 'http://www.yohobuy.com/';
const SERVICE_NOTIFY = 'http://testapi.yoho.cn:28078/';
/* 预览环境 */
// const API_URL = 'http://preapi.yoho.cn/';
... ...
... ... @@ -978,4 +978,21 @@ class Helpers
{
return '//' . strtr($url, array('http://' => '', 'https://' => ''));
}
/**
* 除去数组中的空值和签名参数
* @param $para 签名参数组
* return 去掉空值与签名参数后的新签名参数组
*/
public static function paraFilter(&$para)
{
$para_filter = array();
foreach ($para as $key => $val) {
if ($key === "sign" || $key === "sign_type" || $val === "") {
continue;
}
$para_filter[$key] = $val;
}
return $para_filter;
}
}
... ...
... ... @@ -4,14 +4,14 @@ namespace Plugin\Pay\aliwap;
class AliwapConfig
{
var $pay_url = "http://wappaygw.alipay.com/service/rest.htm?";
var $pay_url = "https://mapi.alipay.com/gateway.do?";
/**
* 服务名,即时到帐为alipay.wap.trade.create. direct
* Enter description here ...
* @var String
*/
var $service = "alipay.wap.trade.create.direct";
var $service = "alipay.wap.create.direct.pay.by.user";
/**
* 合作伙伴在支付宝的用户ID
... ... @@ -32,14 +32,14 @@ class AliwapConfig
* Enter description here ...
* @var String
*/
var $notify_url = 'http://service.yoho.cn/payment/alipaywap_notify';//"http://m.yohobuy.com/shopping/pay/aliwapnotice";
var $notify_url = 'payment/alipay_notify';
/**
* 浏览器的返回
* Enter description here ...
* @var string
*/
var $return_url = "http://m.yohobuy.com/shopping/pay/aliwapreturn";
var $return_url = "shopping/pay/aliwapreturn";
/**
* 签名方式
... ...
... ... @@ -8,15 +8,23 @@ namespace Plugin\Pay\aliwap;
class AliwapReqparams
{
public function __construct($_orderCode, $_totalFee, $_goodName, $client_ip, $_orderTime, $_paymentParameter="", $_isTest=false)
public function __construct($_orderCode, $_totalFee, $_goodName, $client_ip, $_orderTime, $_paymentParameter="", $_isTest=false, $_payExpire = '')
{
$this->orderCode = $_orderCode;
$this->totalFee = $_totalFee;
$this->goodsName = $_goodName;
$this->spbill_create_ip = $client_ip;
$this->orderTime = $_orderTime;
$this->paymentParameter = $_paymentParameter;
$this->isTest = $_isTest;
//到期时间,默认为当前时间加2个小时的时间戳
$_payExpire = empty($_payExpire) ? strtotime('+2 hours') : strtotime($_payExpire);
$payExpireMinute = 0;//剩余分钟数
if ($_payExpire && ($expireTime = $_payExpire - time()) > 0) {
$payExpireMinute = floor($expireTime / 60);
}
$this->orderCode = $_orderCode;
$this->totalFee = $_totalFee;
$this->goodsName = $_goodName;
$this->spbill_create_ip = $client_ip;
$this->orderTime = $_orderTime;
$this->paymentParameter = $_paymentParameter;
$this->isTest = $_isTest;
$this->payExpireMinute = $payExpireMinute;
}
/**
... ...
... ... @@ -5,6 +5,8 @@ namespace Plugin\Pay\aliwap;
use Plugin\Pay\aliwap\AliwapConfig;
use Plugin\Pay\aliwap\AliwapReqparams;
use Plugin\Pay\aliwap\AliwapRspparams;
use Api\Yohobuy;
use Plugin\Helpers;
/**
* 支付宝手机网页支付
... ... @@ -41,54 +43,45 @@ class AliwapService
*/
public function getPayRequestPars(AliwapReqparams $params)
{
$para_token = array(
'service' => 'alipay.wap.trade.create.direct',
'partner' => $this->config->partner,
'sec_id' => $this->config->sign_type,
'format' => 'xml',
'v' => '2.0',
'req_id' => date('Ymdhis') . $params->orderCode,
'req_data' => $this->getTokenReqData($params->orderCode, $params->goodsName, $params->totalFee / 100),
'_input_charset' => $this->config->input_charset
);
//建立请求
$alipaySubmit = new \AlipaySubmit($this->alipay_config);
$html_text = $alipaySubmit->buildRequestHttp($para_token);
//URLDECODE返回的信息
$html_text_decode = urldecode($html_text);
//解析远程模拟提交后返回的信息
$para_html_text = $alipaySubmit->parseResponse($html_text_decode);
if (empty($para_html_text) || empty($para_html_text['request_token'])) {
return false;
// error_log("token获取失败:" . var_export($para_token, true) . "\n" . '返回结果:' . $html_text, 3, '/tmp/aliwap.log');
// throw new Exception('支付系统繁忙,请稍后再试');
}
//获取request_token
$request_token = $para_html_text['request_token'];
//业务详细
$req_data = '<auth_and_execute_req><request_token>' . $request_token . '</request_token></auth_and_execute_req>';
//必填
//构造要请求的参数数组,无需改动
$parameter = array(
"service" => "alipay.wap.auth.authAndExecute",
'service' => $this->config->service,
'partner' => $this->config->partner,
'sec_id' => $this->config->sign_type,
"format" => 'xml',
"v" => '2.0',
"req_id" => date('Ymdhis') . $params->orderCode,
"req_data" => $req_data,
"_input_charset" => $this->config->input_charset
'_input_charset' => $this->config->input_charset,
'notify_url' => Yohobuy::SERVICE_NOTIFY . $this->config->notify_url,
'return_url' => Helpers::url($this->config->return_url),
/* 业务参数 */
'payment_type' => $this->config->payment_type,
'seller_id' => $this->config->partner,
'it_b_pay' => $params->payExpireMinute . 'm',
'payment_type' => $this->config->payment_type,
'out_trade_no' => $params->orderCode,
'subject' => $params->goodsName,
'total_fee' => $params->totalFee / 100, //单位为元
"show_url" => Helpers::url(''),
);
//建立请求
$alipaySubmit = new \AlipaySubmit($this->alipay_config);
$strUrl = $alipaySubmit->buildRequestUrl($parameter);
return array(
ksort($parameter);
reset($parameter);
$param = '';
$sign = '';
$parameter = Helpers::paraFilter($parameter);
foreach ($parameter AS $key => $val) {
$param .= "$key=" . urlencode($val) . "&";
$sign .= "$key=$val&";
}
$param = substr($param, 0, -1);
$sign = substr($sign, 0, -1) . $this->config->alipay_key;
$result = array(
'pay_url' => $this->config->pay_url,
'pars' => $strUrl,
'pars' => $param . "&sign=" . md5($sign) . "&sign_type=" . $this->config->sign_type,
'reqType' => 'get'
);
return $result;
}
/**
... ...
<?php
/* *
* 支付宝接口公用函数
* 详细:该类是请求、通知返回两个文件所调用的公用函数核心处理文件
... ... @@ -15,85 +14,71 @@
* @param $para 需要拼接的数组
* return 拼接完成以后的字符串
*/
function createLinkstring($para)
{
$arg = "";
while (list ($key, $val) = each($para)) {
$arg.=$key . "=" . $val . "&";
}
//去掉最后一个&字符
$arg = substr($arg, 0, count($arg) - 2);
//如果存在转义字符,那么去掉转义
if (get_magic_quotes_gpc()) {
$arg = stripslashes($arg);
}
return $arg;
function createLinkstring($para) {
$arg = "";
while (list ($key, $val) = each ($para)) {
$arg.=$key."=".$val."&";
}
//去掉最后一个&字符
$arg = substr($arg,0,count($arg)-2);
//如果存在转义字符,那么去掉转义
if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
return $arg;
}
/**
* 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对字符串做urlencode编码
* @param $para 需要拼接的数组
* return 拼接完成以后的字符串
*/
function createLinkstringUrlencode($para)
{
$arg = "";
while (list ($key, $val) = each($para)) {
$arg.=$key . "=" . urlencode($val) . "&";
}
//去掉最后一个&字符
$arg = substr($arg, 0, count($arg) - 2);
//如果存在转义字符,那么去掉转义
if (get_magic_quotes_gpc()) {
$arg = stripslashes($arg);
}
return $arg;
function createLinkstringUrlencode($para) {
$arg = "";
while (list ($key, $val) = each ($para)) {
$arg.=$key."=".urlencode($val)."&";
}
//去掉最后一个&字符
$arg = substr($arg,0,count($arg)-2);
//如果存在转义字符,那么去掉转义
if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
return $arg;
}
/**
* 除去数组中的空值和签名参数
* @param $para 签名参数组
* return 去掉空值与签名参数后的新签名参数组
*/
function paraFilter($para)
{
if (isset($para['q'])) {
unset($para['q']);
}
$para_filter = array();
while (list ($key, $val) = each($para)) {
if ($key == "sign" || $key == "sign_type" || $val == "")
continue;
else
$para_filter[$key] = $para[$key];
}
return $para_filter;
function paraFilter($para) {
$para_filter = array();
while (list ($key, $val) = each ($para)) {
if($key == "sign" || $key == "sign_type" || $val == "")continue;
else $para_filter[$key] = $para[$key];
}
return $para_filter;
}
/**
* 对数组排序
* @param $para 排序前的数组
* return 排序后的数组
*/
function argSort($para)
{
ksort($para);
reset($para);
return $para;
function argSort($para) {
ksort($para);
reset($para);
return $para;
}
/**
* 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
* 注意:服务器需要开通fopen配置
* @param $word 要写入日志里的文本内容 默认值:空值
*/
function logResult($word = '')
{
error_log("执行日期:" . strftime("%Y%m%d%H%M%S", time()) . "\n" . $word . "\n", 3, '/tmp/aliwap.log');
function logResult($word='') {
$fp = fopen("log.txt","a");
flock($fp, LOCK_EX) ;
fwrite($fp,"执行日期:".strftime("%Y%m%d%H%M%S",time())."\n".$word."\n");
flock($fp, LOCK_UN);
fclose($fp);
}
/**
... ... @@ -107,25 +92,24 @@ function logResult($word = '')
* @param $input_charset 编码格式。默认值:空值
* return 远程输出的数据
*/
function getHttpResponsePOST($url, $cacert_url, $para, $input_charset = '')
{
if (trim($input_charset) != '') {
$url = $url . "_input_charset=" . $input_charset;
}
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); //SSL证书认证
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); //严格认证
curl_setopt($curl, CURLOPT_CAINFO, $cacert_url); //证书地址
curl_setopt($curl, CURLOPT_HEADER, 0); // 过滤HTTP头
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 显示输出结果
curl_setopt($curl, CURLOPT_POST, true); // post传输数据
curl_setopt($curl, CURLOPT_POSTFIELDS, $para); // post传输数据
$responseText = curl_exec($curl);
//var_dump( curl_error($curl) );//如果执行curl过程中出现异常,可打开此开关,以便查看异常内容
curl_close($curl);
return $responseText;
function getHttpResponsePOST($url, $cacert_url, $para, $input_charset = '') {
if (trim($input_charset) != '') {
$url = $url."_input_charset=".$input_charset;
}
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);//SSL证书认证
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//严格认证
curl_setopt($curl, CURLOPT_CAINFO,$cacert_url);//证书地址
curl_setopt($curl, CURLOPT_HEADER, 0 ); // 过滤HTTP头
curl_setopt($curl,CURLOPT_RETURNTRANSFER, 1);// 显示输出结果
curl_setopt($curl,CURLOPT_POST,true); // post传输数据
curl_setopt($curl,CURLOPT_POSTFIELDS,$para);// post传输数据
$responseText = curl_exec($curl);
//var_dump( curl_error($curl) );//如果执行curl过程中出现异常,可打开此开关,以便查看异常内容
curl_close($curl);
return $responseText;
}
/**
... ... @@ -137,19 +121,18 @@ function getHttpResponsePOST($url, $cacert_url, $para, $input_charset = '')
* @param $cacert_url 指定当前工作目录绝对路径
* return 远程输出的数据
*/
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;
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;
}
/**
... ... @@ -159,22 +142,18 @@ function getHttpResponseGET($url, $cacert_url)
* @param $_input_charset 输入的编码格式
* return 编码后的字符串
*/
function charsetEncode($input, $_output_charset, $_input_charset)
{
$output = "";
if (!isset($_output_charset))
$_output_charset = $_input_charset;
if ($_input_charset == $_output_charset || $input == null) {
$output = $input;
} elseif (function_exists("mb_convert_encoding")) {
$output = mb_convert_encoding($input, $_output_charset, $_input_charset);
} elseif (function_exists("iconv")) {
$output = iconv($_input_charset, $_output_charset, $input);
} else
die("sorry, you have no libs support for charset change.");
return $output;
function charsetEncode($input,$_output_charset ,$_input_charset) {
$output = "";
if(!isset($_output_charset) )$_output_charset = $_input_charset;
if($_input_charset == $_output_charset || $input ==null ) {
$output = $input;
} elseif (function_exists("mb_convert_encoding")) {
$output = mb_convert_encoding($input,$_output_charset,$_input_charset);
} elseif(function_exists("iconv")) {
$output = iconv($_input_charset,$_output_charset,$input);
} else die("sorry, you have no libs support for charset change.");
return $output;
}
/**
* 实现多种字符解码方式
* @param $input 需要解码的字符串
... ... @@ -182,20 +161,16 @@ function charsetEncode($input, $_output_charset, $_input_charset)
* @param $_input_charset 输入的解码格式
* return 解码后的字符串
*/
function charsetDecode($input, $_input_charset, $_output_charset)
{
$output = "";
if (!isset($_input_charset))
$_input_charset = $_input_charset;
if ($_input_charset == $_output_charset || $input == null) {
$output = $input;
} elseif (function_exists("mb_convert_encoding")) {
$output = mb_convert_encoding($input, $_output_charset, $_input_charset);
} elseif (function_exists("iconv")) {
$output = iconv($_input_charset, $_output_charset, $input);
} else
die("sorry, you have no libs support for charset changes.");
return $output;
function charsetDecode($input,$_input_charset ,$_output_charset) {
$output = "";
if(!isset($_input_charset) )$_input_charset = $_input_charset ;
if($_input_charset == $_output_charset || $input ==null ) {
$output = $input;
} elseif (function_exists("mb_convert_encoding")) {
$output = mb_convert_encoding($input,$_output_charset,$_input_charset);
} elseif(function_exists("iconv")) {
$output = iconv($_input_charset,$_output_charset,$input);
} else die("sorry, you have no libs support for charset changes.");
return $output;
}
?>
\ No newline at end of file
... ...
<?php
/* *
* MD5
* 详细:MD5加密
... ... @@ -16,10 +15,9 @@
* @param $key 私钥
* return 签名结果
*/
function md5Sign($prestr, $key)
{
$prestr = $prestr . $key;
return md5($prestr);
function md5Sign($prestr, $key) {
$prestr = $prestr . $key;
return md5($prestr);
}
/**
... ... @@ -29,15 +27,15 @@ function md5Sign($prestr, $key)
* @param $key 私钥
* return 签名结果
*/
function md5Verify($prestr, $sign, $key)
{
$prestr = $prestr . $key;
$mysgin = md5($prestr);
if ($mysgin == $sign) {
return true;
} else {
return false;
}
}
function md5Verify($prestr, $sign, $key) {
$prestr = $prestr . $key;
$mysgin = md5($prestr);
if($mysgin == $sign) {
return true;
}
else {
return false;
}
}
?>
\ No newline at end of file
... ...
<?php
/* *
* 类名:AlipayNotify
* 功能:支付宝通知处理类
... ... @@ -10,171 +9,131 @@
* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
* 该代码仅供学习和研究支付宝接口使用,只是提供一个参考
* ************************注意*************************
*************************注意*************************
* 调试通知返回时,可查看或改写log日志的写入TXT里的数据,来检查通知返回是否正常
*/
require_once("alipay_core.function.php");
require_once("alipay_rsa.function.php");
require_once("alipay_md5.function.php");
class AlipayNotify
{
class AlipayNotify {
/**
* HTTPS形式消息验证地址
*/
var $https_verify_url = 'https://mapi.alipay.com/gateway.do?service=notify_verify&';
/**
var $https_verify_url = 'https://mapi.alipay.com/gateway.do?service=notify_verify&';
/**
* HTTP形式消息验证地址
*/
var $http_verify_url = 'http://notify.alipay.com/trade/notify_query.do?';
var $alipay_config;
function __construct($alipay_config)
{
$this->alipay_config = $alipay_config;
}
function AlipayNotify($alipay_config)
{
$this->__construct($alipay_config);
var $http_verify_url = 'http://notify.alipay.com/trade/notify_query.do?';
var $alipay_config;
function __construct($alipay_config){
$this->alipay_config = $alipay_config;
}
function AlipayNotify($alipay_config) {
$this->__construct($alipay_config);
}
/**
* 针对notify_url验证消息是否是支付宝发出的合法消息
* @return 验证结果
*/
function verifyNotify()
{
if (empty($_POST)) {//判断POST来的数组是否为空
return false;
} else {
//对notify_data解密
$decrypt_post_para = $_POST;
if ($this->alipay_config['sign_type'] == '0001') {
$decrypt_post_para['notify_data'] = rsaDecrypt($decrypt_post_para['notify_data'], $this->alipay_config['private_key_path']);
}
//notify_id从decrypt_post_para中解析出来(也就是说decrypt_post_para中已经包含notify_id的内容)
$doc = new DOMDocument();
$doc->loadXML($decrypt_post_para['notify_data']);
$notify_id = $doc->getElementsByTagName("notify_id")->item(0)->nodeValue;
//生成签名结果
return $this->getSignVeryfy($decrypt_post_para, $_POST["sign"], false);
//写日志记录
//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,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
}
}
function verifyNotify(){
if(empty($_POST)) {//判断POST来的数组是否为空
return false;
}
else {
//生成签名结果
$isSign = $this->getSignVeryfy($_POST, $_POST["sign"]);
//获取支付宝远程服务器ATN结果(验证是否是支付宝发来的消息)
$responseTxt = 'false';
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;
}
}
}
/**
* 针对return_url验证消息是否是支付宝发出的合法消息
* @return 验证结果
*/
function verifyReturn()
{
if (empty($_GET)) {//判断GET来的数组是否为空
return false;
} else {
//生成签名结果
$isSign = $this->getSignVeryfy($_GET, $_GET["sign"], true);
//写日志记录
//if ($isSign) {
// $isSignStr = 'true';
//}
//else {
// $isSignStr = 'false';
//}
//$log_text = "return_url_log:isSign=".$isSignStr.",";
//$log_text = $log_text.createLinkString($_GET);
//logResult($log_text);
//验证
//$responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
//isSign的结果不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
if ($isSign) {
return true;
} else {
return false;
}
}
}
/**
* 解密
* @param $input_para 要解密数据
* @return 解密后结果
*/
function decrypt($prestr)
{
return rsaDecrypt($prestr, trim($this->alipay_config['private_key_path']));
}
/**
* 异步通知时,对参数做固定排序
* @param $para 排序前的参数组
* @return 排序后的参数组
*/
function sortNotifyPara($para)
{
$para_sort['service'] = $para['service'];
$para_sort['v'] = $para['v'];
$para_sort['sec_id'] = $para['sec_id'];
$para_sort['notify_data'] = $para['notify_data'];
return $para_sort;
}
function verifyReturn(){
if(empty($_GET)) {//判断POST来的数组是否为空
return false;
}
else {
//生成签名结果
$isSign = $this->getSignVeryfy($_GET, $_GET["sign"]);
//获取支付宝远程服务器ATN结果(验证是否是支付宝发来的消息)
$responseTxt = 'false';
if (! empty($_GET["notify_id"])) {$responseTxt = $this->getResponse($_GET["notify_id"]);}
//写日志记录
//if ($isSign) {
// $isSignStr = 'true';
//}
//else {
// $isSignStr = 'false';
//}
//$log_text = "responseTxt=".$responseTxt."\n return_url_log:isSign=".$isSignStr.",";
//$log_text = $log_text.createLinkString($_GET);
//logResult($log_text);
//验证
//$responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
//isSign的结果不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
if (preg_match("/true$/i",$responseTxt) && $isSign) {
return true;
} else {
return false;
}
}
}
/**
* 获取返回时的签名验证结果
* @param $para_temp 通知返回来的参数数组
* @param $sign 返回的签名结果
* @param $isSort 是否对待签名数组排序
* @return 签名验证结果
*/
function getSignVeryfy($para_temp, $sign, $isSort)
{
//除去待签名参数数组中的空值和签名参数
$para = paraFilter($para_temp);
//对待签名参数数组排序
if ($isSort) {
$para = argSort($para);
} else {
$para = $this->sortNotifyPara($para);
}
//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
$prestr = createLinkstring($para);
$isSgin = false;
switch (strtoupper(trim($this->alipay_config['sign_type']))) {
case "MD5" :
$isSgin = md5Verify($prestr, $sign, $this->alipay_config['key']);
break;
case "RSA" :
$isSgin = rsaVerify($prestr, trim($this->alipay_config['ali_public_key_path']), $sign);
break;
case "0001" :
$isSgin = rsaVerify($prestr, trim($this->alipay_config['ali_public_key_path']), $sign);
break;
default :
$isSgin = false;
}
return $isSgin;
}
function getSignVeryfy($para_temp, $sign) {
//除去待签名参数数组中的空值和签名参数
$para_filter = paraFilter($para_temp);
//对待签名参数数组排序
$para_sort = argSort($para_filter);
//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
$prestr = createLinkstring($para_sort);
$isSgin = false;
switch (strtoupper(trim($this->alipay_config['sign_type']))) {
case "MD5" :
$isSgin = md5Verify($prestr, $sign, $this->alipay_config['key']);
break;
default :
$isSgin = false;
}
return $isSgin;
}
/**
* 获取远程服务器ATN结果,验证返回URL
... ... @@ -185,22 +144,20 @@ class AlipayNotify
* true 返回正确信息
* false 请检查防火墙或者是服务器阻止端口问题以及验证时间是否超过一分钟
*/
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 . "&notify_id=" . $notify_id;
$responseTxt = getHttpResponseGET($veryfy_url, $this->alipay_config['cacert']);
return $responseTxt;
}
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 . "&notify_id=" . $notify_id;
$responseTxt = getHttpResponseGET($veryfy_url, $this->alipay_config['cacert']);
return $responseTxt;
}
}
?>
... ...
<?php
/* *
* 支付宝接口RSA函数
* 详细:RSA签名、验签、解密
... ... @@ -16,13 +15,12 @@
* @param $private_key_path 商户私钥文件路径
* return 签名结果
*/
function rsaSign($data, $private_key_path)
{
function rsaSign($data, $private_key_path) {
$priKey = file_get_contents($private_key_path);
$res = openssl_get_privatekey($priKey);
openssl_sign($data, $sign, $res);
openssl_free_key($res);
//base64编码
//base64编码
$sign = base64_encode($sign);
return $sign;
}
... ... @@ -34,12 +32,11 @@ function rsaSign($data, $private_key_path)
* @param $sign 要校对的的签名结果
* return 验证结果
*/
function rsaVerify($data, $ali_public_key_path, $sign)
{
$pubKey = file_get_contents($ali_public_key_path);
function rsaVerify($data, $ali_public_key_path, $sign) {
$pubKey = file_get_contents($ali_public_key_path);
$res = openssl_get_publickey($pubKey);
$result = (bool) openssl_verify($data, base64_decode($sign), $res);
openssl_free_key($res);
$result = (bool)openssl_verify($data, base64_decode($sign), $res);
openssl_free_key($res);
return $result;
}
... ... @@ -49,15 +46,14 @@ function rsaVerify($data, $ali_public_key_path, $sign)
* @param $private_key_path 商户私钥文件路径
* return 解密后内容,明文
*/
function rsaDecrypt($content, $private_key_path)
{
function rsaDecrypt($content, $private_key_path) {
$priKey = file_get_contents($private_key_path);
$res = openssl_get_privatekey($priKey);
//用base64将内容还原成二进制
//用base64将内容还原成二进制
$content = base64_decode($content);
//把需要解密的内容,按128位拆开解密
$result = '';
for ($i = 0; $i < strlen($content) / 128; $i++) {
//把需要解密的内容,按128位拆开解密
$result = '';
for($i = 0; $i < strlen($content)/128; $i++ ) {
$data = substr($content, $i * 128, 128);
openssl_private_decrypt($data, $decrypt, $res);
$result .= $decrypt;
... ... @@ -65,5 +61,4 @@ function rsaDecrypt($content, $private_key_path)
openssl_free_key($res);
return $result;
}
?>
\ No newline at end of file
... ...
<?php
/* *
* 类名:AlipaySubmit
* 功能:支付宝各接口请求提交类
... ... @@ -11,99 +10,81 @@
* 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
require_once("alipay_core.function.php");
require_once("alipay_rsa.function.php");
require_once("alipay_md5.function.php");
class AlipaySubmit
{
var $alipay_config;
/**
* 支付宝网关地址
*/
//var $alipay_gateway_new = 'https://mapi.alipay.com/gateway.do?';
var $alipay_gateway_new = 'http://wappaygw.alipay.com/service/rest.htm?';
class AlipaySubmit {
function __construct($alipay_config)
{
$this->alipay_config = $alipay_config;
}
var $alipay_config;
/**
*支付宝网关地址(新)
*/
var $alipay_gateway_new = 'https://mapi.alipay.com/gateway.do?';
function AlipaySubmit($alipay_config)
{
$this->__construct($alipay_config);
function __construct($alipay_config){
$this->alipay_config = $alipay_config;
}
function AlipaySubmit($alipay_config) {
$this->__construct($alipay_config);
}
/**
* 生成签名结果
* @param $para_sort 已排序要签名的数组
* return 签名结果字符串
*/
function buildRequestMysign($para_sort)
{
//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
$prestr = createLinkstring($para_sort);
$mysign = "";
switch (strtoupper(trim($this->alipay_config['sign_type']))) {
case "MD5" :
$mysign = md5Sign($prestr, $this->alipay_config['key']);
break;
case "RSA" :
$mysign = rsaSign($prestr, $this->alipay_config['private_key_path']);
break;
case "0001" :
$mysign = rsaSign($prestr, $this->alipay_config['private_key_path']);
break;
default :
$mysign = "";
}
return $mysign;
}
/**
/**
* 生成签名结果
* @param $para_sort 已排序要签名的数组
* return 签名结果字符串
*/
function buildRequestMysign($para_sort) {
//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
$prestr = createLinkstring($para_sort);
$mysign = "";
switch (strtoupper(trim($this->alipay_config['sign_type']))) {
case "MD5" :
$mysign = md5Sign($prestr, $this->alipay_config['key']);
break;
default :
$mysign = "";
}
return $mysign;
}
/**
* 生成要请求给支付宝的参数数组
* @param $para_temp 请求前的参数数组
* @return 要请求的参数数组
*/
function buildRequestPara($para_temp)
{
//除去待签名参数数组中的空值和签名参数
$para_filter = paraFilter($para_temp);
//对待签名参数数组排序
$para_sort = argSort($para_filter);
//生成签名结果
$mysign = $this->buildRequestMysign($para_sort);
//签名结果与签名方式加入请求提交参数组中
$para_sort['sign'] = $mysign;
if ($para_sort['service'] != 'alipay.wap.trade.create.direct' && $para_sort['service'] != 'alipay.wap.auth.authAndExecute') {
$para_sort['sign_type'] = strtoupper(trim($this->alipay_config['sign_type']));
}
return $para_sort;
}
/**
function buildRequestPara($para_temp) {
//除去待签名参数数组中的空值和签名参数
$para_filter = paraFilter($para_temp);
//对待签名参数数组排序
$para_sort = argSort($para_filter);
//生成签名结果
$mysign = $this->buildRequestMysign($para_sort);
//签名结果与签名方式加入请求提交参数组中
$para_sort['sign'] = $mysign;
$para_sort['sign_type'] = strtoupper(trim($this->alipay_config['sign_type']));
return $para_sort;
}
/**
* 生成要请求给支付宝的参数数组
* @param $para_temp 请求前的参数数组
* @return 要请求的参数数组字符串
*/
function buildRequestParaToString($para_temp)
{
//待请求参数数组
$para = $this->buildRequestPara($para_temp);
//把参数组中所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对字符串做urlencode编码
$request_data = createLinkstringUrlencode($para);
return $request_data;
}
function buildRequestParaToString($para_temp) {
//待请求参数数组
$para = $this->buildRequestPara($para_temp);
//把参数组中所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对字符串做urlencode编码
$request_data = createLinkstringUrlencode($para);
return $request_data;
}
/**
* 建立请求,以表单HTML形式构造(默认)
* @param $para_temp 请求参数数组
... ... @@ -111,111 +92,39 @@ class AlipaySubmit
* @param $button_name 确认按钮显示文字
* @return 提交表单HTML文本
*/
function buildRequestUrl($para_temp)
{
//待请求参数数组
$para = $this->buildRequestPara($para_temp);
$urlArr = array();
foreach ($para as $k => $v) {
$urlArr[] = $k . '=' . $v;
}
return implode('&', $urlArr);
}
/**
* 建立请求,以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果
* @param $para_temp 请求参数数组
* @return 支付宝处理结果
*/
function buildRequestHttp($para_temp)
{
$sResult = '';
//待请求参数数组字符串
$request_data = $this->buildRequestPara($para_temp);
//远程获取数据
$sResult = getHttpResponsePOST($this->alipay_gateway_new, $this->alipay_config['cacert'], $request_data, trim(strtolower($this->alipay_config['input_charset'])));
return $sResult;
}
/**
* 建立请求,以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果,带文件上传功能
* @param $para_temp 请求参数数组
* @param $file_para_name 文件类型的参数名
* @param $file_name 文件完整绝对路径
* @return 支付宝返回处理结果
*/
function buildRequestHttpInFile($para_temp, $file_para_name, $file_name)
{
//待请求参数数组
$para = $this->buildRequestPara($para_temp);
$para[$file_para_name] = "@" . $file_name;
//远程获取数据
$sResult = getHttpResponsePOST($this->alipay_gateway_new, $this->alipay_config['cacert'], $para, trim(strtolower($this->alipay_config['input_charset'])));
return $sResult;
}
/**
* 解析远程模拟提交后返回的信息
* @param $str_text 要解析的字符串
* @return 解析结果
*/
function parseResponse($str_text)
{
//以“&”字符切割字符串
$para_split = explode('&', $str_text);
//把切割后的字符串数组变成变量与数值组合的数组
foreach ($para_split as $item) {
//获得第一个=字符的位置
$nPos = strpos($item, '=');
//获得字符串长度
$nLen = strlen($item);
//获得变量名
$key = substr($item, 0, $nPos);
//获得数值
$value = substr($item, $nPos + 1, $nLen - $nPos - 1);
//放入数组中
$para_text[$key] = $value;
}
if (!empty($para_text['res_data'])) {
//解析加密部分字符串
if ($this->alipay_config['sign_type'] == '0001') {
$para_text['res_data'] = rsaDecrypt($para_text['res_data'], $this->alipay_config['private_key_path']);
}
//token从res_data中解析出来(也就是说res_data中已经包含token的内容)
$doc = new DOMDocument();
$doc->loadXML($para_text['res_data']);
$para_text['request_token'] = $doc->getElementsByTagName("request_token")->item(0)->nodeValue;
function buildRequestForm($para_temp, $method, $button_name) {
//待请求参数数组
$para = $this->buildRequestPara($para_temp);
$sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='".$this->alipay_gateway_new."_input_charset=".trim(strtolower($this->alipay_config['input_charset']))."' method='".$method."'>";
while (list ($key, $val) = each ($para)) {
$sHtml.= "<input type='hidden' name='".$key."' value='".$val."'/>";
}
return $para_text;
}
/**
//submit按钮控件请不要含有name属性
$sHtml = $sHtml."<input type='submit' value='".$button_name."' style='display:none;'></form>";
$sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>";
return $sHtml;
}
/**
* 用于防钓鱼,调用接口query_timestamp来获取时间戳的处理函数
* 注意:该功能PHP5环境及以上支持,因此必须服务器、本地电脑中装有支持DOMDocument、SSL的PHP配置环境。建议本地调试时使用PHP开发软件
* 注意:该功能PHP5环境及以上支持,因此必须服务器、本地电脑中装有支持DOMDocument、SSL的PHP配置环境。建议本地调试时使用PHP开发软件
* return 时间戳字符串
*/
function query_timestamp()
{
$url = $this->alipay_gateway_new . "service=query_timestamp&partner=" . trim(strtolower($this->alipay_config['partner'])) . "&_input_charset=" . trim(strtolower($this->alipay_config['input_charset']));
$encrypt_key = "";
$doc = new DOMDocument();
$doc->load($url);
$itemEncrypt_key = $doc->getElementsByTagName("encrypt_key");
$encrypt_key = $itemEncrypt_key->item(0)->nodeValue;
return $encrypt_key;
}
*/
function query_timestamp() {
$url = $this->alipay_gateway_new."service=query_timestamp&partner=".trim(strtolower($this->alipay_config['partner']))."&_input_charset=".trim(strtolower($this->alipay_config['input_charset']));
$encrypt_key = "";
$doc = new DOMDocument();
$doc->load($url);
$itemEncrypt_key = $doc->getElementsByTagName( "encrypt_key" );
$encrypt_key = $itemEncrypt_key->item(0)->nodeValue;
return $encrypt_key;
}
}
?>
\ No newline at end of file
... ...
... ... @@ -65,7 +65,9 @@ class PayController extends AbstractAction
UdpLog::info("【锁订单接口】,orderCode:{$orderCode}", array('prePayInfo' => $prePayInfo));
$totalFee = $orderDetail['data']['payment_amount'] * 100;
$reqParams = new AliwapReqparams($orderCode, $totalFee, '有货订单号:' . $orderCode, '', $orderDetail['data']['create_time'], '', false);
$reqParams = new AliwapReqparams($orderCode, $totalFee, '有货订单号:' . $orderCode, '',
$orderDetail['data']['create_time'], '', false, $orderDetail['data']['pay_expire']
);
$aliwapService = new AliwapService();
$payRequestPars = $aliwapService->getPayRequestPars($reqParams);
if (empty($payRequestPars)) {
... ...