['payment'=>$payment]]); if(!empty($db_config[0])) { $temp['is_install'] = 1; $temp['id'] = $db_config[0]['id']; $temp['name'] = $db_config[0]['name']; $temp['logo'] = $db_config[0]['logo']; $temp['apply_terminal'] = $db_config[0]['apply_terminal']; $temp['config'] = $db_config[0]['config']; $temp['is_enable'] = $db_config[0]['is_enable']; $temp['is_open_user'] = $db_config[0]['is_open_user']; } $data[] = $temp; } } } closedir($dh); } } return $data; } /** * 获取支付模块配置信息 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @date 2018-09-17 * @desc description * @param [string] $payment [模块名称] */ private static function GetPaymentConfig($payment) { $payment = '\payment\\'.$payment; if(class_exists($payment)) { $obj = new $payment(); if(method_exists($obj, 'Config') && method_exists($obj, 'Pay') && method_exists($obj, 'Respond')) { return $obj->Config(); } } return false; } /** * 数据解析 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @date 2018-09-17 * @desc description * @param [array] $data [插件配置信息] */ private static function DataAnalysis($data) { return [ 'name' => isset($data['base']['name']) ? htmlentities($data['base']['name']) : $payment, 'version' => isset($data['base']['version']) ? htmlentities($data['base']['version']) : '', 'apply_version' => isset($data['base']['apply_version']) ? htmlentities($data['base']['apply_version']) : '', 'desc' => isset($data['base']['desc']) ? $data['base']['desc'] : '', 'author' => isset($data['base']['author']) ? htmlentities($data['base']['author']) : '', 'author_url' => isset($data['base']['author_url']) ? htmlentities($data['base']['author_url']) : '', 'element' => isset($data['element']) ? $data['element'] : [], 'logo' => '', 'is_enable' => 0, 'is_open_user' => 0, 'is_install' => 0, 'apply_terminal'=> empty($data['base']['apply_terminal']) ? array_column(lang('common_platform_type'), 'value') : $data['base']['apply_terminal'], 'config' => '', ]; } /** * 支付方式列表 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @date 2018-09-19 * @desc description * @param [array] $params [输入参数] */ public static function PaymentList($params = []) { $where = empty($params['where']) ? [] : $params['where']; if(isset($params['is_enable'])) { $where['is_enable'] = intval($params['is_enable']); } if(isset($params['is_open_user'])) { $where['is_open_user'] = intval($params['is_open_user']); } $data = Db::name('Payment')->where($where)->field('id,logo,name,sort,payment,config,apply_terminal,apply_terminal,element,is_enable,is_open_user')->order('sort asc')->select(); if(!empty($data) && is_array($data)) { $images_host = config('images_host'); foreach($data as &$v) { $v['logo_old'] = $v['logo']; $v['logo'] = empty($v['logo']) ? null : $images_host.$v['logo']; $v['element'] = empty($v['element']) ? '' : json_decode($v['element'], true); $v['config'] = empty($v['config']) ? '' : json_decode($v['config'], true); $v['apply_terminal'] = empty($v['apply_terminal']) ? '' : json_decode($v['apply_terminal'], true); } } return $data; } /** * 获取支付方式列表 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @date 2018-09-19 * @desc 下订单根据终端自动筛选支付方式 * @param [array] $params [输入参数] */ public static function BuyPaymentList($params = []) { $data = self::PaymentList($params); $result = []; if(!empty($data)) { foreach($data as $v) { // 根据终端类型筛选 if(in_array(APPLICATION_CLIENT_TYPE, $v['apply_terminal'])) { $result[] = $v; } } } return $result; } /** * 获取订单支付名称 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @date 2018-09-19 * @desc description * @param [int] $order_id [订单id] */ public static function OrderPaymentName($order_id = 0) { return empty($order_id) ? null : Db::name('PayLog')->where(['order_id'=>intval($order_id)])->value('payment_name'); } /** * 数据更新 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @date 2018-12-19 * @desc description * @param [array] $params [输入参数] */ public static function PaymentUpdate($params = []) { // 请求类型 $p = [ [ 'checked_type' => 'empty', 'key_name' => 'id', 'error_msg' => '操作id有误', ], [ 'checked_type' => 'length', 'key_name' => 'name', 'checked_data' => '2,60', 'error_msg' => '名称长度 2~60 个字符', ], [ 'checked_type' => 'empty', 'key_name' => 'apply_terminal', 'error_msg' => '至少选择一个适用终端', ], [ 'checked_type' => 'length', 'key_name' => 'sort', 'checked_data' => '3', 'error_msg' => '顺序 0~255 之间的数值', ], ]; $ret = ParamsChecked($params, $p); if($ret !== true) { return DataReturn($ret, -1); } // 附件 $data_fields = ['logo']; $attachment = ResourcesService::AttachmentParams($params, $data_fields); // 数据 $data = [ 'name' => $params['name'], 'apply_terminal' => empty($params['apply_terminal']) ? '' : json_encode(explode(',', $params['apply_terminal'])), 'logo' => $attachment['data']['logo'], 'config' => json_encode(self::GetPlugConfig($params)), 'sort' => intval($params['sort']), 'is_enable' => isset($params['is_enable']) ? intval($params['is_enable']) : 0, 'is_open_user' => isset($params['is_open_user']) ? intval($params['is_open_user']) : 0, ]; $data['upd_time'] = time(); if(Db::name('Payment')->where(['id'=>intval($params['id'])])->update($data)) { return DataReturn('编辑成功', 0); } return DataReturn('编辑失败', -100); } /** * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @date 2018-09-18 * @desc description * @param [array] $params [输入参数] */ private static function GetPlugConfig($params = []) { $data = []; foreach($params as $k=>$v) { if(substr($k, 0, 8) == 'plugins_') { $data[substr($k, 8)] = $v; } } return $data; } /** * 状态更新 * @author Devil * @blog http://gong.gg/ * @version 0.0.1 * @datetime 2016-12-06T21:31:53+0800 * @param [array] $params [输入参数] */ public static function PaymentStatusUpdate($params = []) { // 请求参数 $p = [ [ 'checked_type' => 'empty', 'key_name' => 'id', 'error_msg' => '操作id有误', ], [ 'checked_type' => 'empty', 'key_name' => 'field', 'error_msg' => '未指定操作字段', ], [ 'checked_type' => 'in', 'key_name' => 'state', 'checked_data' => [0,1], 'error_msg' => '状态有误', ], ]; $ret = ParamsChecked($params, $p); if($ret !== true) { return DataReturn($ret, -1); } // 数据更新 if(Db::name('Payment')->where(['payment'=>$params['id']])->update([$params['field']=>intval($params['state']), 'upd_time'=>time()])) { return DataReturn('操作成功'); } return DataReturn('操作失败', -100); } /** * 权限校验 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @datetime 2018-09-29T00:01:49+0800 */ private static function PowerCheck() { // 入口文件目录 if(!is_writable(self::$dir_root_path)) { return DataReturn('目录没有操作权限'.'['.self::$dir_root_path.']', -3); } // 插件权限 if(!is_writable(self::$payment_dir)) { return DataReturn('目录没有操作权限'.'['.self::$payment_dir.']', -3); } } /** * 上传插件 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @date 2018-09-17 * @desc description * @param [array] $params [输入参数] */ public static function Upload($params = []) { // 初始化 self::Init(); // 权限 $ret = self::PowerCheck(); if($ret['code'] != 0) { return $ret; } // 文件上传校验 $error = FileUploadError('file'); if($error !== true) { return DataReturn($error, -1); } // 文件格式化校验 $type = array('text/php'); if(!in_array($_FILES['file']['type'], $type)) { return DataReturn('文件格式有误,必须php文件', -2); } // 是否已有存在插件 if(file_exists(self::$payment_dir.$_FILES['file']['name'])) { return DataReturn('已存在相同插件', -3); } // 存储文件 if(!move_uploaded_file($_FILES['file']['tmp_name'], self::$payment_dir.$_FILES['file']['name'])) { return DataReturn('上传失败', -100); } // 文件校验 $payment = htmlentities(str_replace('.php', '', $_FILES['file']['name'])); $config = self::GetPaymentConfig($payment); if($config === false) { @unlink(self::$payment_dir.$_FILES['file']['name']); return DataReturn('插件编写有误,请参考文档编写', -10); } return DataReturn('上传成功'); } /** * 安装 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @date 2018-09-17 * @desc description * @param [array] $params [输入参数] */ public static function Install($params = []) { // 初始化 self::Init(); // 参数 if(empty($params['id'])) { return DataReturn('参数错误', -1); } // 数据处理 $payment = $params['id']; $config = self::GetPaymentConfig($payment); if($config !== false) { $data = self::DataAnalysis($config); $data['payment'] = $payment; $data['element'] = empty($data['element']) ? '' : json_encode($data['element']); $data['apply_terminal'] = empty($data['apply_terminal']) ? '' : json_encode($data['apply_terminal']); $data['sort'] = 0; $data['add_time'] = time(); // 移除多余的字段 unset($data['is_install']); // 开启事务 Db::startTrans(); if(Db::name('Payment')->insertGetId($data) > 0) { // 入口文件生成 $ret = self::PaymentEntranceCreated($payment); if($ret['code'] == 'code') { // 提交事务 Db::commit(); return DataReturn('安装成功'); } else { // 事务回滚 Db::rollback(); return $ret; } } else { // 事务回滚 Db::rollback(); return DataReturn('安装失败', -100); } } else { return DataReturn('插件配置有误', -10); } } /** * 删除插件 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @date 2018-09-17 * @desc description * @param [array] $params [输入参数] */ public static function Delete($params = []) { // 初始化 self::Init(); // 权限 $ret = self::PowerCheck(); if($ret['code'] != 0) { return $ret; } // 参数 if(empty($params['id'])) { return DataReturn('参数错误', -1); } // 是否禁止删除 $payment = $params['id']; if(in_array($payment, self::$cannot_deleted_list)) { return DataReturn('该支付方式禁止删除', -10); } // 是否存在 $file = self::$payment_dir.$payment.'.php'; if(!file_exists($file)) { return DataReturn('资源不存在或已被删除', -2); } // 权限 if(!is_writable($file)) { return DataReturn('没操作权限', -3); } // 删除 if(!@unlink($file)) { return DataReturn('删除失败', -100); } // 删除入口文件 self::PaymentEntranceDelete($payment); return DataReturn('删除成功'); } /** * 卸载 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @date 2018-09-17 * @desc description * @param [array] $params [输入参数] */ public static function Uninstall($params = []) { // 参数 if(empty($params['id'])) { return DataReturn('参数错误', -1); } // 初始化 self::Init(); // 开始卸载 $payment = $params['id']; if(db('Payment')->where(['payment'=>$payment])->delete()) { // 删除入口文件 self::PaymentEntranceDelete($payment); return DataReturn('卸载成功', 0); } return DataReturn('卸载失败', -100); } /** * [PaymentEntranceCreated 入口文件创建] * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @datetime 2018-09-28T23:38:52+0800 * @param [string] $payment [支付唯一标记] */ private static function PaymentEntranceCreated($payment) { // 权限 $ret = self::PowerCheck(); if($ret['code'] != 0) { return $ret; } // 批量创建 foreach(self::$payment_business_type_all as $v) { $name = strtolower($v['name']); if(defined('IS_ROOT_ACCESS')) { // 异步 $notify=<< php; // 同步 $respond=<< php; } else { // 异步 $notify=<< php; // 同步 $respond=<< php; } @file_put_contents(self::$dir_root_path.'payment_'.$name.'_'.strtolower($payment).'_respond.php', $respond); // 线下支付不生成异步入口文件 if(!in_array($payment, config('under_line_list'))) { @file_put_contents(self::$dir_root_path.'payment_'.$name.'_'.strtolower($payment).'_notify.php', $notify); } } return DataReturn('操作成功', 0); } /** * [PaymentEntranceDelete 入口文件删除] * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @datetime 2018-09-28T23:38:52+0800 * @param [string] $payment [支付唯一标记] */ private static function PaymentEntranceDelete($payment) { // 权限 $ret = self::PowerCheck(); if($ret['code'] != 0) { return $ret; } $payment = strtolower($payment); foreach(self::$payment_business_type_all as $v) { $name = strtolower($v['name']); if(file_exists(self::$dir_root_path.'payment_'.$name.'_'.$payment.'_notify.php')) { @unlink(self::$dir_root_path.'payment_'.$name.'_'.$payment.'_notify.php'); } if(file_exists(self::$dir_root_path.'payment_'.$name.'_'.$payment.'_respond.php')) { @unlink(self::$dir_root_path.'payment_'.$name.'_'.$payment.'_respond.php'); } } return DataReturn('操作成功', 0); } /** * 入库文件检查 * @author Devil * @blog http://gong.gg/ * @version 1.0.0 * @date 2018-12-26 * @desc description * @param [string] $payment [支付标记] * @param [string] $name [支付业务方式名称] */ public static function EntranceFileChecked($payment, $name) { // 同步返回文件 if(!file_exists(self::$dir_root_path.'payment_'.strtolower($name).'_'.strtolower($payment).'_respond.php')) { return DataReturn('支付返回入口文件不存在,请联系管理员处理', -10); } // 线下支付不生成异步入口文件 if(!in_array($payment, config('under_line_list'))) { if(!file_exists(self::$dir_root_path.'payment_'.strtolower($name).'_'.strtolower($payment).'_notify.php')) { return DataReturn('支付通知入口文件不存在,请联系管理员处理', -10); } } return DataReturn('校验成功', 0); } } ?>