|
|
<?php |
|
|
namespace lib; |
|
|
|
|
|
use Exception; |
|
|
|
|
|
class Plugin { |
|
|
|
|
|
static public function getList(){ |
|
|
$dir = PLUGIN_ROOT; |
|
|
$dirArray[] = NULL; |
|
|
if (false != ($handle = opendir($dir))) { |
|
|
$i = 0; |
|
|
while (false !== ($file = readdir($handle))) { |
|
|
if ($file != "." && $file != ".." && strpos($file, ".")===false) { |
|
|
$dirArray[$i] = $file; |
|
|
$i++; |
|
|
} |
|
|
} |
|
|
closedir($handle); |
|
|
} |
|
|
return $dirArray; |
|
|
} |
|
|
|
|
|
static public function getConfig($name){ |
|
|
$filename = PLUGIN_ROOT.$name.'/'.$name.'_plugin.php'; |
|
|
$classname = '\\'.$name.'_plugin'; |
|
|
if(file_exists($filename)){ |
|
|
include $filename; |
|
|
if (class_exists($classname, false) && property_exists($classname, 'info')) { |
|
|
return $classname::$info; |
|
|
}else{ |
|
|
return false; |
|
|
} |
|
|
}else{ |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
static public function loadForPay($s){ |
|
|
global $DB,$conf,$order,$channel,$ordername; |
|
|
if(preg_match('/^(.[a-zA-Z0-9]+)\/([0-9]+)\/$/',$s, $matchs)){ |
|
|
$func = $matchs[1]; |
|
|
$trade_no = $matchs[2]; |
|
|
|
|
|
$order = $DB->getRow("SELECT A.*,B.name typename,B.showname typeshowname FROM pre_order A left join pre_type B on A.type=B.id WHERE trade_no=:trade_no limit 1", [':trade_no'=>$trade_no]); |
|
|
$userrow = $DB->getRow("SELECT `ordername`,`channelinfo` FROM `pre_user` WHERE `uid`='{$order['uid']}' LIMIT 1"); |
|
|
if (!$order) { |
|
|
$channelinfo = $userrow?$userrow['channelinfo']:null; |
|
|
$channel = \lib\Channel::get($trade_no, $channelinfo); |
|
|
if(!$channel) throw new Exception('该订单号不存在,请返回来源地重新发起请求!'); |
|
|
$trade_no = null; |
|
|
}else{ |
|
|
$channelinfo = $userrow?$userrow['channelinfo']:null; |
|
|
$channel = $order['subchannel'] > 0 ? \lib\Channel::getSub($order['subchannel']) : \lib\Channel::get($order['channel'], $channelinfo); |
|
|
if(!$channel)throw new Exception('当前支付通道信息不存在'); |
|
|
$channel['apptype'] = explode(',',$channel['apptype']); |
|
|
|
|
|
if(!empty($userrow['ordername']))$conf['ordername']=$userrow['ordername']; |
|
|
$ordername = !empty($conf['ordername'])?ordername_replace($conf['ordername'],$order['name'],$order['uid'],$trade_no,$order['out_trade_no']):$order['name']; |
|
|
} |
|
|
|
|
|
$result = self::loadClass($channel['plugin'], $func, $trade_no); |
|
|
if($func == 'submit') { |
|
|
$result['submit'] = true; |
|
|
} |
|
|
return $result; |
|
|
}else{ |
|
|
throw new Exception('URL参数不符合规范'); |
|
|
} |
|
|
} |
|
|
|
|
|
static public function loadForSubmit($plugin, $trade_no, $ismapi=false){ |
|
|
global $DB,$conf,$order,$channel,$ordername,$userrow; |
|
|
if(preg_match('/^(.[a-zA-Z0-9]+)$/',$plugin) && preg_match('/^(.[0-9]+)$/',$trade_no)){ |
|
|
$func = 'submit'; |
|
|
if($ismapi) $func = 'mapi'; |
|
|
|
|
|
$channelinfo = $userrow?$userrow['channelinfo']:null; |
|
|
$channel = $order['subchannel'] > 0 ? \lib\Channel::getSub($order['subchannel']) : \lib\Channel::get($order['channel'], $channelinfo); |
|
|
if(!$channel)throw new Exception('当前支付通道信息不存在'); |
|
|
$channel['apptype'] = explode(',',$channel['apptype']); |
|
|
if(!empty($userrow['ordername']))$conf['ordername']=$userrow['ordername']; |
|
|
$ordername = !empty($conf['ordername'])?ordername_replace($conf['ordername'],$order['name'],$order['uid'],$trade_no,$order['out_trade_no']):$order['name']; |
|
|
|
|
|
return self::loadClass($plugin, $func, $trade_no); |
|
|
}else{ |
|
|
throw new Exception('URL参数不符合规范'); |
|
|
} |
|
|
} |
|
|
|
|
|
static private function loadClass($plugin, $func, $trade_no){ |
|
|
$filename = PLUGIN_ROOT.$plugin.'/'.$plugin.'_plugin.php'; |
|
|
$classname = '\\'.$plugin.'_plugin'; |
|
|
if (file_exists($filename)) { |
|
|
define("IN_PLUGIN", true); |
|
|
define("PAY_PLUGIN", $plugin); |
|
|
define("PAY_ROOT", PLUGIN_ROOT.PAY_PLUGIN.'/'); |
|
|
define("TRADE_NO", $trade_no); |
|
|
include $filename; |
|
|
if (class_exists($classname, false) && method_exists($classname, $func)) { |
|
|
return $classname::$func(); |
|
|
} else { |
|
|
if($func == 'mapi' && class_exists($classname, false) && method_exists($classname, 'submit')){ |
|
|
global $siteurl; |
|
|
return ['type'=>'jump','url'=>$siteurl.'pay/submit/'.TRADE_NO.'/']; |
|
|
}else{ |
|
|
throw new Exception('插件方法不存在:'.$func); |
|
|
} |
|
|
} |
|
|
}else{ |
|
|
throw new Exception('Pay file not found'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static public function exists($name){ |
|
|
$filename = PLUGIN_ROOT.$name.'/'.$name.'_plugin.php'; |
|
|
if(file_exists($filename)){ |
|
|
return true; |
|
|
}else{ |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
static public function isrefund($name){ |
|
|
$filename = PLUGIN_ROOT.$name.'/'.$name.'_plugin.php'; |
|
|
$classname = '\\'.$name.'_plugin'; |
|
|
if(file_exists($filename)){ |
|
|
include $filename; |
|
|
if (class_exists($classname, false) && method_exists($classname, 'refund')) { |
|
|
return true; |
|
|
}else{ |
|
|
return false; |
|
|
} |
|
|
}else{ |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
static public function refund($trade_no, $money, &$message){ |
|
|
global $order,$channel,$DB; |
|
|
if(!preg_match('/^(.[0-9]+)$/',$trade_no))return false; |
|
|
$order = $DB->getRow("SELECT * FROM pre_order WHERE trade_no=:trade_no limit 1", [':trade_no'=>$trade_no]); |
|
|
if(!$order){ |
|
|
$message = '该订单号不存在'; |
|
|
return false; |
|
|
} |
|
|
$channelinfo = $DB->getColumn("SELECT `channelinfo` FROM `pre_user` WHERE `uid`='{$order['uid']}' LIMIT 1"); |
|
|
$channel = $order['subchannel'] > 0 ? \lib\Channel::getSub($order['subchannel']) : \lib\Channel::get($order['channel'], $channelinfo); |
|
|
if(!$channel){ |
|
|
$message = '当前支付通道信息不存在'; |
|
|
return false; |
|
|
} |
|
|
$order['refundmoney'] = $money; |
|
|
$filename = PLUGIN_ROOT.$channel['plugin'].'/'.$channel['plugin'].'_plugin.php'; |
|
|
$classname = '\\'.$channel['plugin'].'_plugin'; |
|
|
$func = 'refund'; |
|
|
if($order['combine'] == 1) $func = 'refund_combine'; |
|
|
if(file_exists($filename)){ |
|
|
include $filename; |
|
|
if (class_exists($classname, false) && method_exists($classname, $func)) { |
|
|
define("IN_PLUGIN", true); |
|
|
define("PAY_PLUGIN", $channel['plugin']); |
|
|
define("PAY_ROOT", PLUGIN_ROOT.PAY_PLUGIN.'/'); |
|
|
define("TRADE_NO", $trade_no); |
|
|
$result = $classname::$func($order); |
|
|
if($result && $result['code']==0){ |
|
|
return true; |
|
|
}else{ |
|
|
$message = $result['msg']; |
|
|
return false; |
|
|
} |
|
|
}else{ |
|
|
$message = '当前支付通道不支持API退款'; |
|
|
return false; |
|
|
} |
|
|
}else{ |
|
|
$message = '支付插件不存在'; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
static public function loadForJsapi($trade_no,$type,$money,$name,$openid = null){ |
|
|
global $channel; |
|
|
$filename = PLUGIN_ROOT.$channel['plugin'].'/'.$channel['plugin'].'_plugin.php'; |
|
|
$classname = '\\'.$channel['plugin'].'_plugin'; |
|
|
$func = 'jsapi'; |
|
|
if(file_exists($filename)){ |
|
|
include $filename; |
|
|
if (class_exists($classname, false) && method_exists($classname, $func)) { |
|
|
define("IN_PLUGIN", true); |
|
|
define("PAY_PLUGIN", $channel['plugin']); |
|
|
define("PAY_ROOT", PLUGIN_ROOT.PAY_PLUGIN.'/'); |
|
|
define("TRADE_NO", $trade_no); |
|
|
try{ |
|
|
$result = $classname::$func($type,$money,$name,$openid); |
|
|
return $result; |
|
|
}catch(Exception $e){ |
|
|
showerrorjson($e->getMessage()); |
|
|
} |
|
|
}else{ |
|
|
showerrorjson('插件方法不存在:jsapi'); |
|
|
} |
|
|
}else{ |
|
|
showerrorjson('支付插件不存在'); |
|
|
} |
|
|
} |
|
|
|
|
|
static public function call($func, $channel, $bizParam){ |
|
|
$filename = PLUGIN_ROOT.$channel['plugin'].'/'.$channel['plugin'].'_plugin.php'; |
|
|
$classname = '\\'.$channel['plugin'].'_plugin'; |
|
|
if(file_exists($filename)){ |
|
|
include_once $filename; |
|
|
if (class_exists($classname, false) && method_exists($classname, $func)) { |
|
|
$result = $classname::$func($channel, $bizParam); |
|
|
return $result; |
|
|
}else{ |
|
|
return ['code'=>-1, 'msg'=>'插件方法不存在:'.$func]; |
|
|
} |
|
|
}else{ |
|
|
return ['code'=>-1, 'msg'=>'支付插件不存在']; |
|
|
} |
|
|
} |
|
|
|
|
|
static public function updateAll(){ |
|
|
global $DB; |
|
|
$DB->exec("TRUNCATE TABLE pre_plugin"); |
|
|
$list = self::getList(); |
|
|
foreach($list as $name){ |
|
|
if($config = self::getConfig($name)){ |
|
|
if($config['name']!=$name)continue; |
|
|
$DB->insert('plugin',['name'=>$config['name'], 'showname'=>$config['showname'], 'author'=>$config['author'], 'link'=>$config['link'], 'types'=>implode(',',$config['types']), 'transtypes'=>$config['transtypes']?implode(',',$config['transtypes']):null]); |
|
|
} |
|
|
} |
|
|
return true; |
|
|
} |
|
|
|
|
|
static public function get($name){ |
|
|
global $DB; |
|
|
$result = $DB->getRow("SELECT * FROM pre_plugin WHERE name=:name", [':name'=>$name]); |
|
|
return $result; |
|
|
} |
|
|
|
|
|
static public function getAll(){ |
|
|
global $DB; |
|
|
$result = $DB->getAll("SELECT * FROM pre_plugin ORDER BY name ASC"); |
|
|
return $result; |
|
|
} |
|
|
} |
|
|
|