Authored by xuqi

Merge branch 'develop' of http://git.dev.yoho.cn/web/yohobuy into develop

... ... @@ -518,7 +518,7 @@ class AbstractAction extends Controller_Abstract
* @param type $notModifiedExit 是否在没有修改时返回304状态
* @return void
*/
public static function setLastModified($modifiedTime, $notModifiedExit = true)
public function setLastModified($modifiedTime, $notModifiedExit = true)
{
$modifiedTime = date('D, d M Y H:i:s ', $modifiedTime) . 'GMT';
if ($notModifiedExit && isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $modifiedTime == $_SERVER['HTTP_IF_MODIFIED_SINCE']) {
... ... @@ -534,11 +534,36 @@ class AbstractAction extends Controller_Abstract
* @param int $seconds 单位是秒
* @return void
*/
public static function setExpires($seconds = 180)
public function setExpires($seconds = 180)
{
$time = date('D, d M Y H:i:s ', time() + $seconds) . 'GMT';
header('Expires: ' . $time);
}
/**
* JS 跳转并提示
*
* @param String $message 提示信息
* @param String $expression 附加的JS
* @return void
*/
protected function helpJsRedirect($message = '', $expression = "history.back()")
{
header("content-type: text/html; charset=utf-8");
if ($message != '') {
$message = strtr(addslashes($message), array('\n' => '\\n'));
echo "<script language=\"javascript\">";
echo "alert(\"{$message}\");";
echo "</script>";
}
if ($expression != '') {
echo "<script language=\"javascript\">\n";
echo $expression . "\n";
echo "</script>";
}
exit();
}
}
... ...
... ... @@ -109,7 +109,6 @@ class OrderData
/*
* 支付页面的资源位
* To change this template file, choose Tools | Templates
*/
public static function paymentData($gender, $yh_channel, $code)
... ... @@ -142,20 +141,26 @@ class OrderData
return Yohobuy::get(Yohobuy::SERVICE_URL . '/operations/api/v5/resource/get', $param);
}
/*
* 微信支付签名
/**
* 更新订单的支付方式
*
* @param int $orderCode 订单号
* @param int $payment 支付方式
* @param int $uid 用户ID
* @return array
*/
public static function weixinPaySign($orderCode)
public static function updateOrderPayment($orderCode, $payment, $uid)
{
//构建必传参数
$param['private_key'] = 'adbf5a778175ee757c34d0eba4e932bc';
$param['order_code'] = $orderCode;
$param['payment_code'] = 19;
$param['app_key'] = 'adbf5a778175ee75';
// 构建必传参数
$param = Yohobuy::param();
$param['method'] = 'app.SpaceOrders.updateOrdersPaymentByCode';
$param['order_code'] = (int) $orderCode;
$param['payment'] = $payment;
$param['uid'] = $uid;
$param['client_secret'] = Sign::getSign($param);
//调用接口获得数据
return Yohobuy::get('http://pay.yohobuy.com/payment/data.html', $param);
// 调用接口获得数据
return Yohobuy::post(Yohobuy::API_URL, $param);
}
}
... ...
<?php
namespace Plugin\Pay\aliwap;
class AliwapConfig
{
var $pay_url = "http://wappaygw.alipay.com/service/rest.htm?";
/**
* 服务名,即时到帐为alipay.wap.trade.create. direct
* Enter description here ...
* @var String
*/
var $service = "alipay.wap.trade.create.direct";
/**
* 合作伙伴在支付宝的用户ID
* Enter description here ...
* @var string
*/
var $partner = "2088701661478015";
/**
* 编码
* Enter description here ...
* @var String
*/
var $input_charset = "utf-8";
/**
* 通知url,(用于后台提交)
* Enter description here ...
* @var String
*/
var $notify_url = 'http://testservice.yoho.cn:28077/payment/alipay_notify';//"http://m.yohobuy.com/shopping/pay/aliwapnotice";
/**
* 浏览器的返回
* Enter description here ...
* @var string
*/
var $return_url = "http://m.yohobuy.com/shopping/pay/aliwapreturn";
/**
* 签名方式
* Enter description here ...
* @var String
*/
var $sign_type = "MD5";
/**
* 支付类型,1为购买
* Enter description here ...
* @var Integer
*/
var $payment_type = "1";
/**
* Key
* Enter description here ...
* @var String
*/
var $alipay_key = "kcxawi9bb07mzh0aq2wcirsf9znusobw";
/**
* 销售者mail
* Enter description here ...
* @var String
*/
var $sellerMail = "zfb@yoho.cn";
/**
* 支付不成功跳转的页面
* @var string
*/
var $merchant_url = 'http://m.yohobuy.com/home/orders/detail?order_code=';
/**
* ca证书
* @var unknown
*/
var $cacert = 'cacert.pem';
}
... ...
<?php
namespace Plugin\Pay\aliwap;
use Plugin\Pay\aliwap\AliwapReqparams;
interface AliwapInterface
{
/**
* 获取支付请求的url
* Enter description here ...
* @param Array $params
*/
function getPayRequestPars(AliwapReqparams $params);
/**
* 解析返回的参数
* Enter description here ...
* @param Array $arrResponse
* @return QPay_Utils_Rspparams
*/
function parseResponse(Array $arrResponse);
}
\ No newline at end of file
... ...
<?php
namespace Plugin\Pay\aliwap;
/**
* 请求付款的参数类
*/
class AliwapReqparams
{
public function __construct($_orderCode, $_totalFee, $_goodName, $client_ip, $_orderTime, $_paymentParameter="", $_isTest=false)
{
$this->orderCode = $_orderCode;
$this->totalFee = $_totalFee;
$this->goodsName = $_goodName;
$this->spbill_create_ip = $client_ip;
$this->orderTime = $_orderTime;
$this->paymentParameter = $_paymentParameter;
$this->isTest = $_isTest;
}
/**
* 订单Code
* Enter description here ...
* @var Integer
*/
var $orderCode = 0;
/**
* 付款金额,统一采用分为单位
* Enter description here ...
* @var double
*/
var $totalFee = 0;
/**
* 商品名称
* Enter description here ...
* @var String
*/
var $goodsName = "";
/**
* 客户的ip
* Enter description here ...
* @var Integer
*/
var $spbill_create_ip = "";
/**
* 订单时间
* Enter description here ...
* @var unknown_type
*/
var $orderTime = "";
/**
* 支付方式参数
* Enter description here ...
* @var string
*/
var $paymentParameter = "";
/**
* 是否为测试
* Enter description here ...
* @var bool
*/
var $isTest = false;
}
\ No newline at end of file
... ...
<?php
namespace Plugin\Pay\aliwap;
/**
* 回复参数
*/
class AliwapRspparams
{
/**
* 支付结果,0为成功,1为失败
* Enter description here ...
* @var Integer
*/
var $payResult;
/**
* 付款时间
* Enter description here ...
* @var Integer
*/
var $payTime;
/**
* 订单Code
* Enter description here ...
* @var unknown_type
*/
var $orderCode;
/**
* 支付的总金额
* Enter description here ...
* @var unknown_type
*/
var $totalFee;
/**
* 银行名称,中文名
* Enter description here ...
* @var String
*/
var $bankName = "";
/**
* 银行代码
* Enter description here ...
* @var string
*/
var $bankCode = "";
/**
* 结果信息
* Enter description here ...
* @var string
*/
var $resultMsg;
}
... ...
<?php
namespace Plugin\Pay\aliwap;
use Plugin\Pay\aliwap\AliwapConfig;
use Plugin\Pay\aliwap\AliwapReqparams;
use Plugin\Pay\aliwap\AliwapRspparams;
/**
* 支付宝手机网页支付
*/
class AliwapService
{
var $config;
var $alipay_config;
public function __construct()
{
$this->logProjectPrefix = 'aliwap';
$this->config = new AliwapConfig();
$this->alipay_config = array(
'partner' => $this->config->partner,
'key' => $this->config->alipay_key,
'sign_type' => 'MD5',
'input_charset' => 'utf-8',
'cacert' => dirname(__FILE__) . '/cacert.pem',
'transport' => 'http'
);
require_once("lib/alipay_core.function.php");
require_once("lib/alipay_rsa.function.php");
require_once("lib/alipay_md5.function.php");
require_once("lib/alipay_notify.class.php");
require_once("lib/alipay_submit.class.php");
}
/**
* 构造请求参数
* @see QPay_Utils_Interface::getPayRequestPars()
*/
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",
'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
);
//建立请求
$alipaySubmit = new \AlipaySubmit($this->alipay_config);
$strUrl = $alipaySubmit->buildRequestUrl($parameter);
return array(
'pay_url' => $this->config->pay_url,
'pars' => $strUrl,
'reqType' => 'get'
);
}
/**
* 解析结果
*
* @see AliwapInterface::parseResponse()
*/
public function parseResponse(Array $arrResponse)
{
$rsp = new AliwapRspparams();
if ($arrResponse['type'] == 'return') {
//return 返回
$alipayNotify = new \AlipayNotify($this->alipay_config);
$verify_result = $alipayNotify->verifyReturn();
if ($verify_result) {
//商户订单号
$rsp->orderCode = $_GET['out_trade_no'];
$rsp->payResult = 200;
//支付宝交易号
$trade_no = $_GET['trade_no'];
} else {
$rsp->payResult = 400;
}
} else {
//服务器返回
$alipayNotify = new \AlipayNotify($this->alipay_config);
$verify_result = $alipayNotify->verifyNotify();
if ($verify_result) {
//解密(如果是RSA签名需要解密,如果是MD5签名则下面一行清注释掉)
// $notify_data = $alipayNotify->decrypt($_POST['notify_data']);
//解析notify_data
//注意:该功能PHP5环境及以上支持,需开通curl、SSL等PHP配置环境。建议本地调试时使用PHP开发软件
$doc = new \DOMDocument();
$doc->loadXML($_POST['notify_data']);
if (!empty($doc->getElementsByTagName("notify")->item(0)->nodeValue)) {
//商户订单号
$out_trade_no = $doc->getElementsByTagName("out_trade_no")->item(0)->nodeValue;
//支付宝交易号
$trade_no = $doc->getElementsByTagName("trade_no")->item(0)->nodeValue;
//交易状态
$trade_status = $doc->getElementsByTagName("trade_status")->item(0)->nodeValue;
if ($trade_status == 'TRADE_FINISHED' || $trade_status == 'TRADE_SUCCESS') {
$rsp->orderCode = $out_trade_no;
$rsp->payResult = 200;
} else {
$rsp->payResult = 400;
}
}
} else {
$rsp->payResult = 401;
}
}
return $rsp;
}
private function getTokenReqData($out_trade_no, $subject, $total_fee)
{
return '<direct_trade_create_req><notify_url>' . $this->config->notify_url .
'</notify_url><call_back_url>' . $this->config->return_url .
'</call_back_url><seller_account_name>' . $this->config->sellerMail .
'</seller_account_name><out_trade_no>' . $out_trade_no . '</out_trade_no><subject>' . 'yoho order:' . $out_trade_no .
'</subject><total_fee>' . $total_fee . '</total_fee><merchant_url>' . $this->config->merchant_url . $out_trade_no .
'</merchant_url></direct_trade_create_req>';
}
}
... ...
This diff could not be displayed because it is too large.
<?php
/* *
* 支付宝接口公用函数
* 详细:该类是请求、通知返回两个文件所调用的公用函数核心处理文件
* 版本:3.3
* 日期:2012-07-19
* 说明:
* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
* 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
/**
* 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
* @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;
}
/**
* 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对字符串做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;
}
/**
* 除去数组中的空值和签名参数
* @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;
}
/**
* 对数组排序
* @param $para 排序前的数组
* return 排序后的数组
*/
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');
}
/**
* 远程获取数据,POST模式
* 注意:
* 1.使用Crul需要修改服务器中php.ini文件的设置,找到php_curl.dll去掉前面的";"就行了
* 2.文件夹中cacert.pem是SSL证书请保证其路径有效,目前默认路径是:getcwd().'\\cacert.pem'
* @param $url 指定URL完整路径地址
* @param $cacert_url 指定当前工作目录绝对路径
* @param $para 请求的数据
* @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;
}
/**
* 远程获取数据,GET模式
* 注意:
* 1.使用Crul需要修改服务器中php.ini文件的设置,找到php_curl.dll去掉前面的";"就行了
* 2.文件夹中cacert.pem是SSL证书请保证其路径有效,目前默认路径是:getcwd().'\\cacert.pem'
* @param $url 指定URL完整路径地址
* @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;
}
/**
* 实现多种字符编码方式
* @param $input 需要编码的字符串
* @param $_output_charset 输出的编码格式
* @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;
}
/**
* 实现多种字符解码方式
* @param $input 需要解码的字符串
* @param $_output_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;
}
?>
\ No newline at end of file
... ...
<?php
/* *
* MD5
* 详细:MD5加密
* 版本:3.3
* 日期:2012-07-19
* 说明:
* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
* 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
/**
* 签名字符串
* @param $prestr 需要签名的字符串
* @param $key 私钥
* return 签名结果
*/
function md5Sign($prestr, $key)
{
$prestr = $prestr . $key;
return md5($prestr);
}
/**
* 验证签名
* @param $prestr 需要签名的字符串
* @param $sign 签名结果
* @param $key 私钥
* return 签名结果
*/
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
* 功能:支付宝通知处理类
* 详细:处理支付宝各接口通知返回
* 版本:3.2
* 日期:2011-03-25
* 说明:
* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
* 该代码仅供学习和研究支付宝接口使用,只是提供一个参考
* ************************注意*************************
* 调试通知返回时,可查看或改写log日志的写入TXT里的数据,来检查通知返回是否正常
*/
require_once("alipay_core.function.php");
require_once("alipay_rsa.function.php");
require_once("alipay_md5.function.php");
class AlipayNotify
{
/**
* HTTPS形式消息验证地址
*/
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);
}
/**
* 针对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,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
}
}
/**
* 针对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;
}
/**
* 获取返回时的签名验证结果
* @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;
}
/**
* 获取远程服务器ATN结果,验证返回URL
* @param $notify_id 通知校验ID
* @return 服务器ATN结果
* 验证结果集:
* invalid命令参数不对 出现这个错误,请检测返回处理中partner和key是否为空
* 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;
}
}
?>
... ...
<?php
/* *
* 支付宝接口RSA函数
* 详细:RSA签名、验签、解密
* 版本:3.3
* 日期:2012-07-23
* 说明:
* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
* 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
/**
* RSA签名
* @param $data 待签名数据
* @param $private_key_path 商户私钥文件路径
* return 签名结果
*/
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编码
$sign = base64_encode($sign);
return $sign;
}
/**
* RSA验签
* @param $data 待签名数据
* @param $ali_public_key_path 支付宝的公钥文件路径
* @param $sign 要校对的的签名结果
* return 验证结果
*/
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);
return $result;
}
/**
* RSA解密
* @param $content 需要解密的内容,密文
* @param $private_key_path 商户私钥文件路径
* return 解密后内容,明文
*/
function rsaDecrypt($content, $private_key_path)
{
$priKey = file_get_contents($private_key_path);
$res = openssl_get_privatekey($priKey);
//用base64将内容还原成二进制
$content = base64_decode($content);
//把需要解密的内容,按128位拆开解密
$result = '';
for ($i = 0; $i < strlen($content) / 128; $i++) {
$data = substr($content, $i * 128, 128);
openssl_private_decrypt($data, $decrypt, $res);
$result .= $decrypt;
}
openssl_free_key($res);
return $result;
}
?>
\ No newline at end of file
... ...
<?php
/* *
* 类名:AlipaySubmit
* 功能:支付宝各接口请求提交类
* 详细:构造支付宝各接口表单HTML文本,获取远程HTTP数据
* 版本:3.3
* 日期:2012-07-23
* 说明:
* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
* 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
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?';
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_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;
}
/**
* 生成要请求给支付宝的参数数组
* @param $para_temp 请求前的参数数组
* @return 要请求的参数数组字符串
*/
function buildRequestParaToString($para_temp)
{
//待请求参数数组
$para = $this->buildRequestPara($para_temp);
//把参数组中所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对字符串做urlencode编码
$request_data = createLinkstringUrlencode($para);
return $request_data;
}
/**
* 建立请求,以表单HTML形式构造(默认)
* @param $para_temp 请求参数数组
* @param $method 提交方式。两个值可选:post、get
* @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;
}
return $para_text;
}
/**
* 用于防钓鱼,调用接口query_timestamp来获取时间戳的处理函数
* 注意:该功能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;
}
}
?>
\ No newline at end of file
... ...
... ... @@ -34,7 +34,7 @@ class WxPayConfig
const JS_API_CALL_URL = 'http://m.yohobuy.com/shopping/pay/wechatwap';
//=======【异步通知url设置】===================================
//异步通知url,商户根据实际开发过程设定
const NOTIFY_URL = 'http://pay.yohobuy.com/notify/wechatwap';
const NOTIFY_URL = 'http://testservice.yoho.cn:28077/payment/wechatwap_notify';//'http://pay.yohobuy.com/notify/wechatwap';
//=======【证书路径设置】=====================================
/**
* TODO:设置商户证书路径
... ...
... ... @@ -372,6 +372,16 @@ server
proxy_set_header Accept-Encoding "gzip";
}
## since 2016/01/23
location ^~ /shopping/pay/alipay {
proxy_redirect off;
proxy_pass http://yohobuy;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Accept-Encoding "gzip";
}
location / {
proxy_redirect off;
proxy_pass http://119.254.81.245;
... ...
... ... @@ -828,7 +828,7 @@ class HomeController extends AbstractAction
'payAppInfo' => array(
0 => array(
'appIcon' => '',
'payLink' => Helpers::url('/shopping/pay/index', array('order_code' => $orderCode, 'payment_type' => 18)),
'payLink' => Helpers::url('/shopping/pay/alipay', array('order_code' => $orderCode, 'payment_type' => 18)),
'appId' => 'alipay',
'app' => '支付宝支付',
'hint' => '支付宝钱包支付',
... ...
<?php
use Action\AbstractAction;
use Plugin\Helpers;
use LibModels\Wap\Home\OrderData;
use Plugin\Pay\weixin\JsApiPay;
use Plugin\Pay\weixin\lib\WxPayUnifiedOrder;
use Plugin\Pay\weixin\lib\WxPayApi;
use Plugin\Pay\weixin\lib\WxPayConfig;
use Plugin\Pay\aliwap\AliwapReqparams;
use Plugin\Pay\aliwap\AliwapService;
/**
* 支付相关的控制器
*
* @name PayController
* @package Shopping
* @copyright yoho.inc
* @version 1.0 (2016-1-23 13:12:40)
* @author fei.hong <fei.hong@yoho.cn>
*/
class PayController extends AbstractAction
{
/**
* 支付宝跳转页
*
* @param int order_code 订单号
*/
public function alipayAction()
{
do {
/* 判断是否有订单号参数 */
$orderCode = $this->get('order_code');
if (empty($orderCode)) {
break;
}
/* 判断用户是否登录 */
$uid = $this->getUid(true);
if (!$uid) {
$this->go( Helpers::url('/signin.html', array('refer' => $this->_request->server('HTTP_REFERER'))) );
break;
}
/* 判断订单信息是否存在 */
$orderDetail = OrderData::viewOrderData($orderCode, $uid, $this->_usession);
if (empty($orderDetail['data'])) {
$this->helpJsRedirect('没有找到该订单');
break;
}
/* 判断订单是否已取消 */
if (isset($orderDetail['data']['is_cancel']) && $orderDetail['data']['is_cancel'] === 'Y') {
$this->helpJsRedirect('订单已经取消', 'window.location="' . Helpers::url('/home/orders/detail', array('order_code' => $orderCode)) .'";');
break;
}
$totalFee = $orderDetail['data']['payment_amount'] * 100;
$reqParams = new AliwapReqparams($orderCode, $totalFee, '有货订单号:' . $orderCode, '', $orderDetail['data']['create_time'], '', false);
$aliwapService = new AliwapService();
$payRequestPars = $aliwapService->getPayRequestPars($reqParams);
if (empty($payRequestPars)) {
$this->helpJsRedirect('支付系统繁忙,请稍后再试');
break;
}
// 记录或修改支付方式 说明:由于在web站没有支付宝手机支付的选项,这里就记录支付方式就按照web端支付宝的支付方式平台号为2
// 此处是咨询过JAVA开发任明明,按照老代码的实现方式判断,更新支付方式
$paymentRecod = OrderData::updateOrderPayment($orderCode, 2, $uid);
if (empty($paymentRecod) || $paymentRecod['code'] != 200) {
$this->helpJsRedirect('系统繁忙,请稍后再试');
break;
}
$this->go($payRequestPars['pay_url'] . $payRequestPars['pars']);
}
while (false);
}
/**
* 微信支付 - 获取JSAPI参数
*
* @param int order_code 订单号
* @return json | void
*/
public function wechatwapapiAction()
{
do {
if (!$this->isAjax()) {
break;
}
$uid = $this->getUid(true);
if (!$uid) {
break;
}
$orderCode = $this->get('order_code');
if (empty($orderCode)) {
break;
}
/* 判断订单信息不存在 */
$orderDetail = OrderData::viewOrderData($orderCode, $uid, $this->_usession);
if (empty($orderDetail['data'])) {
break;
}
$totalFee = strval($orderDetail['data']['payment_amount'] * 100);
$openId = $this->getSession('weixinOpenId');
if (empty($openId)) {
break;
}
//统一下单
$tools = new JsApiPay();
$input = new WxPayUnifiedOrder();
$input->SetBody('有货订单号:' . $orderCode);
$input->SetOut_trade_no('YOHOBuy_' . $orderCode); // 商户订单号
$input->SetTotal_fee($totalFee);
$input->SetTime_start(date("YmdHis", (int) $orderDetail['data']['create_time']));
$input->SetTime_expire(date("YmdHis", (int) $orderDetail['data']['create_time'] + 7200));
$input->SetNotify_url(WxPayConfig::NOTIFY_URL);
$input->SetTrade_type("JSAPI");
$input->SetOpenid($openId);
$order = WxPayApi::unifiedOrder($input);
$jsApiParameters = $tools->GetJsApiParameters($order);
$this->echoJson(array('code' => 200, 'data' => array('jsApiParameters' => json_decode($jsApiParameters))));
} while (false);
}
}
... ...
... ... @@ -4,7 +4,7 @@ application.directory = APPLICATION_PATH "/application"
;;website library
application.library = ROOT_PATH "/library"
;;模块配置
application.modules = "Index,Category,Channel,Guang,Passport,Product,Cart"
application.modules = "Index,Category,Channel,Guang,Passport,Product,Cart,Shopping"
;;加载
application.bootstrap = APPLICATION_PATH "/application/Bootstrap.php"
;;view文件的扩展名
... ...
... ... @@ -4,7 +4,7 @@ application.directory = APPLICATION_PATH "/application"
;;website library
application.library = ROOT_PATH "/library"
;;默认模块
application.modules = "Index,Category,Channel,Guang,Passport,Product,Cart"
application.modules = "Index,Category,Channel,Guang,Passport,Product,Cart,Shopping"
;;加载
application.bootstrap = APPLICATION_PATH "/application/Bootstrap.php"
;;view文件的扩展名
... ...
... ... @@ -4,7 +4,7 @@ application.directory = APPLICATION_PATH "/application"
;;website library
application.library = ROOT_PATH "/library"
;;默认模块
application.modules = "Index,Category,Channel,Guang,Passport,Product,Cart"
application.modules = "Index,Category,Channel,Guang,Passport,Product,Cart,Shopping"
;;加载
application.bootstrap = APPLICATION_PATH "/application/Bootstrap.php"
;;view文件的扩展名
... ...
... ... @@ -4,7 +4,7 @@ application.directory = APPLICATION_PATH "/application"
;;website library
application.library = ROOT_PATH "/library"
;;默认模块
application.modules = "Index,Category,Channel,Guang,Passport,Product,Cart"
application.modules = "Index,Category,Channel,Guang,Passport,Product,Cart,Shopping"
;;加载
application.bootstrap = APPLICATION_PATH "/application/Bootstrap.php"
;;view文件的扩展名
... ...
... ... @@ -2,6 +2,8 @@
use Action\WebAction;
use Product\BrandsModel;
use LibModels\Web\Product\SearchData;
use Plugin\Helpers;
/**
* 品牌首页
... ... @@ -33,8 +35,7 @@ class BrandsController extends WebAction
/**
* 品牌接口数据
*
* @param
* string id 获取品牌ID
* @param string brandId 获取品牌ID
* @return json
*/
public function brandinfoAction()
... ...
... ... @@ -8,6 +8,8 @@ use LibModels\Web\Product\BrandData;
use Index\HomeModel;
use Product\SearchModel;
use WebPlugin\Helpers;
use Plugin\Images;
use LibModels\Web\Product\SearchData;
/**
* 品牌首页模板数据模型
... ... @@ -47,10 +49,6 @@ class BrandsModel
return $data;
}
/**
* 品牌介绍页
* @param array $customCondition
... ... @@ -84,21 +82,17 @@ class BrandsModel
if (!empty($brandInfo['data']) && $brandInfo['code'] == 200) {
$result['brandId'] = isset($brandInfo['data']['id']) ? $brandInfo['data']['id'] : '';
$result['node'] = isset($brandInfo['data']['static_content_code']) ? $brandInfo['data']['static_content_code'] : false;
$result['brandBanner'] = isset($brandInfo['data']['brand_banner']) ? $brandInfo['data']['brand_banner']: '';
$result['brandBanner'] = isset($brandInfo['data']['brand_banner']) ? $brandInfo['data']['brand_banner'] : '';
$result['brandNameEn'] = isset($brandInfo['data']['brand_name_en']) ? $brandInfo['data']['brand_name_en'] : '';
$result['brandNameCn'] = isset($brandInfo['data']['brand_name_cn']) ? $brandInfo['data']['brand_name_cn'] : '';
$result['brandAbout'] = isset($brandInfo['data']['brand_intro']) ? $brandInfo['data']['brand_intro'] : '';
} else {
}
else {
return false;
}
return $result;
}
//获取品牌系列数据
public static function getAdNav($brandId, $status = 1)
{
... ... @@ -141,7 +135,6 @@ class BrandsModel
//组合用户浏览记录url
//$urlList['reviewUrl'] = HelperSearch::getReviewUrl($searchCondition['condition']);
//批量调接口
$result = Yohobuy::getMulti($urlList, array(), true);
... ... @@ -206,7 +199,7 @@ class BrandsModel
$brandList[$lk] = $listTmp;
}
//将brandList里的0-9 排序到最后
$numBrand['0~9']=$brandList['0~9'];
$numBrand['0~9'] = $brandList['0~9'];
unset($brandList['0~9']);
$brandList+=$numBrand;
}
... ... @@ -219,30 +212,48 @@ class BrandsModel
/*
* 获取单个广告浮窗内容
*/
public static function getBrandInfo($brandId, $uid)
{
$data = array();
$imgs = array();
//获取品牌简介
$res = BrandData::getBrandIntro($brandId, $uid);
$condition = array(
'viewNum'=>3,
''
);
\LibModels\Web\Product\SearchData::searchElasticByCondition($condition);
if (isset($res['data']) && $res['data']) {
$icoUrlTmp = explode("?", $res['data']['brand_ico']) ;
//获取品牌下的产品信息
$proInfo = self::getProductByBrand($brandId);
$proInfoTmp = $proInfo['data']['product_list'];
if (isset($proInfoTmp) && $proInfoTmp) {
foreach ($proInfoTmp as $v) {
$imgs[] = array(
'src' => Images::getImageUrl($v['default_images'], 80, 100, 3, 'goodsimg')
);
}
}
//整合
$data = array(
'key' => $res['data']['brand_id'],
'icon' => $icoUrlTmp[0],
'icon' => Helpers::getImageUrl($res['data']['brand_ico'], 80, 50, 3),
'title' => $res['data']['brand_name'],
'content' =>$res['data']['brand_intro'],
'content' => $res['data']['brand_intro'],
'subtitle' => 'FEATURED ITEMS',
'imgs' => array(),
'imgs' => $imgs
);
}
return $data;
}
/*
* 根据brandId获取产品信息
*/
public static function getProductByBrand($brandId, $num = 3)
{
$condition['viewNum'] = $num;
$condition['brand'] = $brandId;
return searchData::searchElasticByCondition($condition);
}
/*
* 获取品牌一览资源位&channelType
*/
... ...