Authored by Rock Zhang

添加alimobilemini支付方式

Code Review By Rock Zhang
<?php
namespace WebPlugin\Pay\Alimobilemini;
/**
* 手机支付配置文件
* @author tongds
*
*/
class Config
{
var $partner = '2088701661478015';
/**
* @var string 日志目录
*/
var $logDir = '/tmp/logs/alimobilemini';
/**
* @var string 日志等级
*/
var $logLevel = 2; // 记录信息日志
}
... ...
<?php
namespace WebPlugin\Pay\Alimobilemini;
use WebPlugin\Pay\PayAbstract;
use WebPlugin\Pay\Rspparams;
use WebPlugin\PhpLog;
/**
* 手机支付返回
* @author tongds
*
*/
class Service extends PayAbstract
{
public $config;
private $log;
private $utils;
public function __construct(array $paymentParams)
{
$this->logProjectPrefix = 'alimobilemini';
$this->utils = new Utils();
$this->config = new Config();
$this->log = new PhpLog($this->config->logDir, 'PRC', $this->config->logLevel);
}
/**
* 处理支付宝极简支付的结果
*
* @param array $arrResponse
* @return Rspparams
*/
public function parseResponse(array $arrResponse)
{
$rsp = new Rspparams();
// ksort($arrResponse);
// ##组织代签名字符串#################
// $sign=$arrResponse['sign'];
// foreach($arrResponse as $a =>$v)
// {
// if(in_array($a,array('sign','sign_type')) || $v=="") continue;
// $data[]=$a.'='.$v;
// }
// $datastr=implode("&", $data);
// ##################################
$isVerify = $this->utils->getSignVeryfy($arrResponse);
if ($isVerify) {
//验证成功
$rsp->bankName = "";
$rsp->orderCode = $arrResponse['out_trade_no'];
$rsp->payResult = $this->convertResult($arrResponse['trade_status']);
$rsp->payTime = $arrResponse["gmt_create"];
$rsp->totalFee = $arrResponse["total_fee"];
$rsp->resultMsg = $arrResponse["trade_no"];
//添加支付订单号和交易号
$rsp->payOrderCode = $arrResponse['out_trade_no'];
$rsp->tradeNo = $arrResponse['trade_no'];
$rsp->bankBillNo = "";
$this->log->logInfo(var_export($arrResponse, true));
$this->log->logInfo('======alimobilemini成功===');
} else {
//不成功
$rsp->payResult = -1;
$this->log->logInfo(var_export($arrResponse, true));
$this->log->logInfo('======alimobilemini失败===订单号----->' . $arrResponse['out_trade_no']);
}
return $rsp;
}
/**
* 转换结果
*
* @param string $resultCode 返回码
* @return int
*/
protected function convertResult($resultCode)
{
if ($resultCode == "TRADE_SUCCESS" || $resultCode == "TRADE_FINISHED") {
return 200;
}
return -1;
}
}
\ No newline at end of file
... ...
<?php
namespace WebPlugin\Pay\Alimobilemini;
use WebPlugin\Pay\PayAbstract;
/**
* 支付宝手机极简支付工具类
* @author Smile
*
*/
class Utils extends PayAbstract
{
/**
* 构造函数
*/
public function __construct()
{
}
/**RSA签名
* $data待签名数据
* 签名用商户私钥,必须是没有经过pkcs8转换的私钥
* 最后的签名,需要用base64编码
* return Sign签名
*/
function sign($data)
{
//转换为openssl密钥,必须是没有经过pkcs8转换的私钥
$res = openssl_get_privatekey($this->priKey);
//调用openssl内置签名方法,生成签名$sign
openssl_sign($data, $sign, $res);
//释放资源
openssl_free_key($res);
//base64编码
$sign = base64_encode($sign);
return $sign;
}
/**
* RSA验签
* 验签用支付宝公钥
*
* return 验签是否通过 bool值
* @param array $data 待签名数据
* @param string $sign 需要验签的签名
* @return bool 验签是否通过 bool值
*/
function verify($data, $sign)
{
$pubKeyPath = dirname(__FILE__) . '/key/alipay_public_key.pem';
//转换为openssl格式密钥
$pubKey = file_get_contents($pubKeyPath);
$res = openssl_get_publickey($pubKey);
if ($res == false) {
while ($text = openssl_error_string())
echo "$text \n";
}
//调用openssl内置方法验签,返回bool值
$result = (bool)openssl_verify($data, base64_decode($sign), $res);
//释放资源
openssl_free_key($res);
//返回资源是否成功
return $result;
}
/**
* 获取返回时的签名验证结果
*
* @param $para_temp 通知返回来的参数数组
* @return string $sign 返回的签名结果
*/
function getSignVeryfy($para_temp)
{
//支付宝公钥路径
$pubKeyPath = dirname(__FILE__) . '/key/alipay_public_key.pem';
//签名类型:RSA
$sign_type = $para_temp['sign_type'];
//签名
$sign = $para_temp['sign'];
//除去待签名参数数组中的空值和签名参数
$para_filter = self::paraFilter($para_temp);
//对待签名参数数组排序
$para_sort = self::argSort($para_filter);
//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
$prestr = self::createLinkstring($para_sort);
switch (strtoupper($sign_type)) {
case "RSA" :
$isSgin = self::rsaVerify($prestr, $pubKeyPath, $sign);
break;
default :
$isSgin = false;
}
return $isSgin;
}
/**
* 除去数组中的空值和签名参数
* @param array $para 签名参数组
* @return array 去掉空值与签名参数后的新签名参数组
*/
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 array $para 排序前的数组
* @return array 排序后的数组
*/
function argSort($para)
{
ksort($para);
reset($para);
return $para;
}
/**
* 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
* @param array $para 需要拼接的数组
* @return string 拼接完成以后的字符串
*/
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;
}
/**
* RSA验签
* @param array $data 待签名数据
* @param string $ali_public_key_path 支付宝的公钥文件路径
* @param string $sign 要校对的的签名结果
* @return bool 验证结果
*/
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;
}
}
\ No newline at end of file
... ...
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnxj/9qwVfgoUh/y2W89L6BkRAFljhNhgPdyPu
BV64bfQNN1PjbCzkIM6qRdKBoLPXmKKMiFYnkd6rAoprih3/PrQEB/VsW8OoM8fxn67UDYuyBTqA
23MML9q1+ilIZwBC2AQ2UBVOrFXfFl75p6/B5KsiNG9zpgmLCUYuLkxpLQIDAQAB
-----END PUBLIC KEY-----
... ...
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDNtQee4Q7qVyjIkrLfIKcOajn4IGQyALkSclFdCrYcZ3WhFWdH
+cjt/CGW8KuxX4CJWZO0LECA9avJFsipqZ339jz4nWma5yMoLpEFu55J2sJE3Mv1
USe+3/egRfOmHGWa3GHAPjglyux10ZStLkUoMSrNZxSeDKnaAaYLYxmB+wIDAQAB
AoGAdqF3Ap5iPq0DPSC0/U7UaNDEG596iQe3s7avy4uY2KqlwL8aL/0SboTgTi7/
pSwhcZRyRQ7cKEMFzdNQ59+E1Gm1XqbZIKAb8D16JtcVrPBdKBCb5DOizW/6nKUk
djo2FjuSB6nZCy5pZoyxjHkvOKZ0I+YfjYiNZGCCcRnYQmkCQQDqI7VsiywgqXUC
anKzo/U8+exVofhe8Lrcd9pPeolaA9L9amCpW7VOBSlwnSuD7xX77/9XLUo3Ry1n
PewANsQ/AkEA4Om+p5ZjR32v4nJkuE5LEMtDIei1Hhz4tdsBq/xIfY/wNy5Z8Kmo
vpn0D1xF4qN99E7pp7SjRx/lW6VSn/4jRQJBAMXEO63fL/q2p7rOpuvNhYtnnpQG
J4Ap3evy4FdZrUJ3EHQ0skjayZ2JBqO0XdkmzW7sHMVJ3/IpENSvnPPhTokCQBw5
ONOO66Zs/0VLVZhLOuBAoYv/x7qfqBYqBWuvnOkkxuAl0OOCZsqERzwmOB7YpVWj
EW8aG+Mw/Xcip9ur6IECQDLwM0wvlCGyQaOClhlzlWPq0pgEpnnJMwkfyXbx03Cb
DyXYdx6FDfqcCKlHcfHevuCVczR4aT4/rUClJB39AqU=
-----END RSA PRIVATE KEY-----
... ...
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNtQee4Q7qVyjIkrLfIKcOajn4
IGQyALkSclFdCrYcZ3WhFWdH+cjt/CGW8KuxX4CJWZO0LECA9avJFsipqZ339jz4
nWma5yMoLpEFu55J2sJE3Mv1USe+3/egRfOmHGWa3GHAPjglyux10ZStLkUoMSrN
ZxSeDKnaAaYLYxmB+wIDAQAB
-----END PUBLIC KEY-----
... ...
... ... @@ -299,6 +299,25 @@ class NoticeController extends WebAction
$this->payResultProc($res, 25);
echo "OK";
}
exit();
}
/**
* 支付宝手机支付(极简)的返回
*/
public function alimobilenoticeminiAction()
{
$payment = PayModel::getPaymentById(20);
$payService = PayFactory::factory($payment);
$res = $payService->parseResponse($_POST); //支付宝通知使用的
if ($res->payResult != -1) {
$this->payResultProc($res, 20);
echo "OK";
} else {
echo 'faile';
}
exit();
}
... ...