增加支付通道配置

This commit is contained in:
Anyon 2020-12-12 19:15:06 +08:00
parent 478229e5a1
commit 6aa47275bc
13 changed files with 812 additions and 64 deletions

View File

@ -104,8 +104,23 @@ CREATE TABLE `data_news_x_comment` (
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '数据-文章-评论' ROW_FORMAT = COMPACT;
-- ----------------------------
-- Records of data_news_x_comment
-- Table structure for data_payment
-- ----------------------------
DROP TABLE IF EXISTS `data_payment`;
CREATE TABLE `data_payment` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '支付类型',
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '支付名称',
`content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '支付参数',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '支付说明',
`sort` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '排序权重',
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '支付状态(1使用,0禁用)',
`deleted` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '删除状态',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_data_news_mark_status`(`status`) USING BTREE,
INDEX `idx_data_news_mark_deleted`(`deleted`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '数据-支付-通道' ROW_FORMAT = COMPACT;
-- ----------------------------
-- Table structure for data_user
@ -4506,6 +4521,7 @@ INSERT INTO `system_menu` VALUES (83, 73, '配送区域管理', 'layui-icon layu
INSERT INTO `system_menu` VALUES (84, 68, '微信小程序配置', 'layui-icon layui-icon-set', 'data/config/wxapp', 'data/config/wxapp', '', '_self', 0, 1, '2020-09-21 16:34:08');
INSERT INTO `system_menu` VALUES (85, 68, '会员服务协议', 'layui-icon layui-icon-template-1', 'data/config/agreement', 'data/config/agreement', '', '_self', 30, 1, '2020-09-22 16:00:10');
INSERT INTO `system_menu` VALUES (86, 68, '关于我们描述', 'layui-icon layui-icon-app', 'data/config/about', 'data/config/about', '', '_self', 40, 1, '2020-09-22 16:12:44');
INSERT INTO `system_menu` VALUES (87, 68, '商城支付配置', 'layui-icon layui-icon-set-sm', 'data/payment/index', 'data/payment/index', '', '_self', 0, 1, '2020-12-12 09:08:09');
-- ----------------------------
-- Table structure for system_oplog

View File

@ -0,0 +1,116 @@
<?php
namespace app\data\controller;
use app\data\service\PaymentService;
use think\admin\Controller;
/**
* 支付通道通道
* Class Payment
* @package app\data\controller
*/
class Payment extends Controller
{
/**
* 绑定数据表
* @var string
*/
private $table = 'DataPayment';
/**
* 支付通道类型
* @var array
*/
protected $types = PaymentService::TYPES;
/**
* 支付通道管理
* @auth true
* @menu true
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$this->title = '支付通道管理';
$query = $this->_query($this->table);
$query->where(['deleted' => 0])->order('sort desc,id desc');
$query->equal('type,status')->like('name')->dateBetween('create_at')->page();
}
/**
* 添加支付通道
* @auth true
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function add()
{
$this->title = '添加支付通道';
$this->_form($this->table, 'form');
}
/**
* 编辑支付通道
* @auth true
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function edit()
{
$this->title = '编辑支付通道';
$this->_form($this->table, 'form');
}
/**
* 数据表单处理
* @param array $data
*/
protected function _form_filter(array &$data)
{
if ($this->request->isGet()) {
$data['content'] = json_decode($data['content'] ?? '[]', true) ?: [];
} else {
$data['content'] = json_encode($this->request->post() ?: [], JSON_UNESCAPED_UNICODE);
}
}
/**
* 表单结果处理
* @param boolean $state
*/
protected function _form_result(bool $state)
{
if ($state) {
$this->success('支付通道保存成功!', 'javascript:history.back()');
}
}
/**
* 修改支付通道状态
* @auth true
* @throws \think\db\exception\DbException
*/
public function state()
{
$this->_save($this->table, $this->_vali([
'status.in:0,1' => '状态值范围异常!',
'status.require' => '状态值不能为空!',
]));
}
/**
* 删除支付通道
* @auth true
* @throws \think\db\exception\DbException
*/
public function remove()
{
$this->_delete($this->table);
}
}

View File

@ -23,4 +23,18 @@ class Data extends Controller
$this->success('获取轮播图片数据', $data);
}
/**
* 获取支付通道数据
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getPayment()
{
$map = ['status' => 1, 'deleted' => 0];
$query = $this->app->db->name('DataPayment')->where($map);
$result = $query->order('sort desc,id desc')->field('id,name,type')->select();
$this->success('获取支付通道数据', $result->toArray());
}
}

View File

@ -2,8 +2,8 @@
namespace app\data\controller\api;
use app\data\service\OrderService;
use app\wechat\service\WechatService;
use app\data\service\payment\JoinPayService;
use app\data\service\payment\WechatPayService;
use think\admin\Controller;
/**
@ -14,7 +14,7 @@ use think\admin\Controller;
class Notify extends Controller
{
/**
* 微信支付通知处理
* 微信支付通知
* @param string $scene 支付场景
* @return string
* @throws \WeChat\Exceptions\InvalidResponseException
@ -24,46 +24,27 @@ class Notify extends Controller
*/
public function wxpay(string $scene = 'order'): string
{
$notify = ($payment = WechatService::WePayOrder())->getNotify();
if ($notify['result_code'] == 'SUCCESS' && $notify['return_code'] == 'SUCCESS') {
if ($scene === 'order') {
if ($this->setOrder($notify['out_trade_no'], $notify['cash_fee'] / 100, $notify['transaction_id'], 'wxpay')) {
return $payment->getNotifySuccessReply();
}
}
// ... 其他支付场景
if (strtolower($scene) === 'order') {
return WechatPayService::instance()->notify();
} else {
return 'success';
}
return $payment->getNotifySuccessReply();
}
/**
* 订单状态更新
* @param string $code 订单单号
* @param string $amount 交易金额
* @param string $paycode 交易单号
* @param string $paytype 支付类型
* @return boolean
* 汇聚支付通知
* @param string $scene 支付场景
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function setOrder(string $code, string $amount, string $paycode, string $paytype = 'wxpay'): bool
public function joinpay(string $scene = 'order'): string
{
// 检查订单支付状态
$map = ['order_no' => $code, 'payment_status' => 0, 'status' => 2];
$order = $this->app->db->name('StoreOrder')->where($map)->find();
if (empty($order)) return false;
// 更新订单支付状态
$this->app->db->name('StoreOrder')->where($map)->update([
'status' => 3,
'payment_type' => $paytype,
'payment_code' => $paycode,
'payment_status' => 1,
'payment_amount' => $amount,
'payment_remark' => '微信在线支付',
'payment_datetime' => date('Y-m-d H:i:s'),
]);
// 调用用户升级机制
return OrderService::instance()->syncAmount($order['order_no']);
if (strtolower($scene) === 'order') {
return JoinPayService::instance()->notify();
} else {
return 'success';
}
}
}

View File

@ -5,8 +5,8 @@ namespace app\data\controller\api\auth;
use app\data\controller\api\Auth;
use app\data\service\GoodsService;
use app\data\service\OrderService;
use app\data\service\PaymentService;
use app\data\service\TruckService;
use app\wechat\service\WechatService;
use think\admin\extend\CodeExtend;
use think\exception\HttpResponseException;
@ -169,7 +169,7 @@ class Order extends Auth
$update = ['status' => 2, 'amount_express' => $express['template_amount']];
$update['amount_total'] = $order['amount_goods'] + $amount - $order['amount_reduct'] - $order['amount_discount'];
if ($this->app->db->name('ShopOrder')->where($map)->update($update) !== false) {
$this->success('订单确认成功!', $this->_getPaymentParams($order['order_no'], $order['amount_total']));
$this->success('订单确认成功!', ['order_no' => $order['order_no']]);
} else {
$this->error('订单确认失败,请稍候再试!');
}
@ -183,13 +183,17 @@ class Order extends Auth
*/
public function payment()
{
$map = $this->_vali(['order_no.require' => '订单单号不能为空!']);
$data = $this->_vali([
'payid.require' => '支付通道不能为空!',
'order_no.require' => '订单单号不能为空!',
]);
$map = ['order_no' => $data['order_no']];
$order = $this->app->db->name('ShopOrder')->where($map)->find();
if (empty($order)) $this->error('获取订单数据失败,请稍候再试!');
if ($order['status'] != 2) $this->error('该订单不能发起支付哦!');
if ($order['payment_status']) $this->error('订单已经支付,不需要再次支付哦!');
try {
$params = $this->_getPaymentParams($order['order_no'], $order['amount_total']);
$params = PaymentService::build($data['payid'])->create($this->user['openid'], $order['order_no'], $order['amount_total'], '商城订单支付', '');
$this->success('获取支付参数成功!', $params);
} catch (HttpResponseException $exception) {
throw $exception;
@ -198,30 +202,6 @@ class Order extends Auth
}
}
/**
* 获取订单支付参数
* @param string $code 订单单号
* @param string $amount 支付金额
* @return array
*/
private function _getPaymentParams(string $code, string $amount): array
{
try {
return WechatService::WePayOrder()->create([
'body' => '商城订单支付',
'openid' => $this->user['openid'],
'out_trade_no' => $code,
'total_fee' => $amount * 100,
'trade_type' => 'JSAPI',
'notify_url' => sysuri('@data/api.notify/wxpay/type/order', [], false, true),
'spbill_create_ip' => $this->app->request->ip(),
]);
} catch (\Exception $exception) {
$this->error("创建支付参数失败,{$exception->getMessage()}");
}
}
/**
* 主动取消未支付的订单
* @throws \think\db\exception\DataNotFoundException

View File

@ -0,0 +1,139 @@
<?php
namespace app\data\service;
use app\data\service\payment\JoinPayService;
use app\data\service\payment\WechatPayService;
use think\admin\Service;
/**
* 支付基础服务
* Class PaymentService
* @package app\data\service
*/
abstract class PaymentService extends Service
{
// 微信支付类型
const PAYMENT_WECHAT_GZH = 'wechat_gzh';
const PAYMENT_WECHAT_XCX = 'wechat_xcx';
// 汇聚支付类型
const PAYMENT_JOINPAY_GZH = 'joinpay_gzh';
const PAYMENT_JOINPAY_XCX = 'joinpay_xcx';
// 支付通道描述
const TYPES = [
PaymentService::PAYMENT_WECHAT_XCX => '微信小程序支付',
PaymentService::PAYMENT_WECHAT_GZH => '微信服务号支付',
PaymentService::PAYMENT_JOINPAY_XCX => '汇聚小程序支付',
PaymentService::PAYMENT_JOINPAY_GZH => '汇聚服务号支付',
];
/**
* 默认支付类型
* @var string
*/
protected static $type;
/**
* 当前支付通道
* @var array
*/
protected static $config;
/**
* 支付服务对象
* @var JoinPayService|WechatPayService
*/
protected static $driver = [];
/**
* 根据配置实例支付服务
* @param string $payid 支付通道编号
* @return JoinPayService|WechatPayService
* @throws \think\Exception
*/
public static function build(string $payid): PaymentService
{
if (isset(static::$driver[$payid])) {
return static::$driver[$payid];
}
// 支付通道配置验证
$map = ['id' => $payid, 'status' => 1, 'deleted' => 0];
$payment = app()->db->name('DataPayment')->where($map)->find();
if (empty($payment)) {
throw new \think\Exception("支付通道[#{$payid}]已关闭");
}
static::$config = json_decode(static::$config['content'], true);
if (empty(static::$config)) {
throw new \think\Exception("支付通道[#{$payid}]配置无效");
}
// 支付通道类型验证
if (empty(static::TYPES[$payment['type']])) {
throw new \think\Exception("支付通道[{$payment['type']}]未定义");
}
// 实例化具体支付通道类型
static::$type = $payment['type'];
if (stripos(static::$type, 'wechat_') === 0) {
return static::$driver[$payid] = WechatPayService::instance();
} else {
return static::$driver[$payid] = JoinPayService::instance();
}
}
/**
* 订单更新操作
* @param string $code 订单单号
* @param string $payno 交易单号
* @param string $amount 支付金额
* @param string $paytype 支付类型
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function updateOrder(string $code, string $payno, string $amount, string $paytype): bool
{
// 检查订单支付状态
$map = ['order_no' => $code, 'payment_status' => 0, 'status' => 2];
$order = $this->app->db->name('StoreOrder')->where($map)->find();
if (empty($order)) return false;
// 更新订单支付状态
$this->app->db->name('StoreOrder')->where($map)->update([
'status' => 3,
'payment_type' => $paytype,
'payment_code' => $payno,
'payment_status' => 1,
'payment_amount' => $amount,
'payment_remark' => '微信在线支付',
'payment_datetime' => date('Y-m-d H:i:s'),
]);
// 调用用户升级机制
return OrderService::instance()->syncAmount($order['order_no']);
}
/**
* 支付通知处理
* @return string
*/
abstract public function notify(): string;
/**
* 订单主动查询
* @param string $orderNo
* @return array
*/
abstract public function query(string $orderNo): array;
/**
* 创建支付订单
* @param string $openid 会员OPENID
* @param string $orderNo 交易订单单号
* @param string $payAmount 交易订单金额(元)
* @param string $payTitle 交易订单名称
* @param string $payDescription 订单订单描述
* @return array
*/
abstract public function create(string $openid, string $orderNo, string $payAmount, string $payTitle, string $payDescription): array;
}

View File

@ -0,0 +1,164 @@
<?php
namespace app\data\service\payment;
use app\data\service\PaymentService;
use think\admin\extend\HttpExtend;
/**
* 汇聚支付基础服务
* Class JoinPayService
* @package app\store\service\payment
*/
class JoinPayService extends PaymentService
{
/**
* 请求地址
* @var string
*/
protected $uri;
/**
* 应用编号
* @var string
*/
protected $appid;
/**
* 报备商户号
* @var string
*/
protected $trade;
/**
* 平台商户号
* @var string
*/
protected $mchid;
/**
* 平台商户密钥
* @var string
*/
protected $mchkey;
/**
* 汇聚支付服务初始化
* @return JoinPayService
*/
protected function initialize(): JoinPayService
{
$this->appid = static::$config['joinpay_appid'];
$this->trade = static::$config['joinpay_trade'];;
$this->mchid = static::$config['joinpay_mch_id'];
$this->mchkey = static::$config['joinpay_mch_key'];
return $this;
}
/**
* 创建订单支付参数
* @param string $openid 会员OPENID
* @param string $orderNo 交易订单单号
* @param string $payAmount 交易订单金额(元)
* @param string $payTitle 交易订单名称
* @param string $payDescription 订单订单描述
* @return array
* @throws \think\Exception
*/
public function create(string $openid, string $orderNo, string $payAmount, string $payTitle, string $payDescription): array
{
$types = [
static::PAYMENT_JOINPAY_GZH => 'WEIXIN_GZH',
static::PAYMENT_JOINPAY_XCX => 'WEIXIN_XCX',
];
if (isset($types[static::$type])) {
$type = $types[static::$type];
} else {
throw new \think\Exception('支付类型[' . static::$type . ']未配置定义!');
}
try {
$data = [
'p0_Version' => '1.0',
'p1_MerchantNo' => $this->mchid,
'p2_OrderNo' => $orderNo,
'p3_Amount' => $payAmount * 100,
'p4_Cur' => '1',
'p5_ProductName' => $payTitle,
'p6_ProductDesc' => $payDescription,
'p9_NotifyUrl' => sysuri('@data/api.notify/joinpay/scene/order', [], false, true),
'q1_FrpCode' => $type ?? '',
'q5_OpenId' => $openid,
'q7_AppId' => $this->appid,
'qa_TradeMerchantNo' => $this->trade,
];
if (empty($data['q5_OpenId'])) unset($data['q5_OpenId']);
$this->uri = 'https://www.joinpay.com/trade/uniPayApi.action';
$result = $this->_doReuest($data);
if (is_array($result) && isset($result['ra_Code']) && intval($result['ra_Code']) === 100) {
return json_decode($result['rc_Result'], true);
} elseif (is_array($result) && isset($result['rb_CodeMsg'])) {
throw new \think\Exception($result['rb_CodeMsg']);
} else {
throw new \think\Exception('获取预支付码失败!');
}
} catch (\Exception $exception) {
throw new \think\Exception($exception->getMessage(), $exception->getCode());
}
}
/**
* 查询订单数据
* @param string $orderNo
* @return array
*/
public function query(string $orderNo): array
{
$this->uri = 'https://www.joinpay.com/trade/queryOrder.action';
return $this->_doReuest(['p1_MerchantNo' => $this->mchid, 'p2_OrderNo' => $orderNo]);
}
/**
* 支付结果处理
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function notify(): string
{
$notify = $this->app->request->get();
foreach ($notify as &$item) $item = urldecode($item);
if (empty($notify['hmac']) || $notify['hmac'] !== $this->_doSign($notify)) {
return 'error';
}
if (isset($notify['r6_Status']) && intval($notify['r6_Status']) === 100) {
if ($this->updateOrder($notify['r2_OrderNo'], $notify['r9_BankTrxNo'], $notify['r3_Amount'], 'joinpay')) {
return 'success';
}
}
return 'error';
}
/**
* 请求数据签名
* @param array $data
* @return string
*/
private function _doSign(array $data): string
{
ksort($data);
unset($data['hmac']);
return md5(join('', $data) . $this->mchkey);
}
/**
* 执行数据请求
* @param array $data
* @return array
*/
private function _doReuest($data = []): array
{
$data['hmac'] = $this->_doSign($data);
return json_decode(HttpExtend::post($this->uri, $data), true);
}
}

View File

@ -0,0 +1,105 @@
<?php
namespace app\data\service\payment;
use app\data\service\PaymentService;
use WePay\Order;
/**
* 微信官方公众号支持
* Class WechatPayService
* @package app\store\service\payment
*/
class WechatPayService extends PaymentService
{
/**
* 微信对象对象
* @var Order
*/
protected $payment;
/**
* 微信支付服务初始化
* @return WechatPayService
*/
protected function initialize(): WechatPayService
{
$this->payment = Order::instance([
'appid' => static::$config['wechat_appid'],
'mch_id' => static::$config['wechat_mch_id'],
'mch_key' => static::$config['wechat_mch_key'],
'cache_path' => $this->app->getRuntimePath() . 'wechat',
]);
return $this;
}
/**
* 查询微信支付订单
* @param string $orderNo
* @return array
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \WeChat\Exceptions\LocalCacheException
*/
public function query(string $orderNo): array
{
return $this->payment->query(['out_trade_no' => $orderNo]);
}
/**
* 创建微信支付订单
* @param string $openid 会员OPENID
* @param string $orderNo 交易订单单号
* @param string $payAmount 交易订单金额(元)
* @param string $payTitle 交易订单名称
* @param string $payDescription 订单订单描述
* @return array
* @throws \think\Exception
*/
public function create(string $openid, string $orderNo, string $payAmount, string $payTitle, string $payDescription): array
{
try {
$body = empty($payDescription) ? $payTitle : ($payTitle . '-' . $payDescription);
$data = [
'body' => $body,
'openid' => $openid,
'out_trade_no' => $orderNo,
'total_fee' => $payAmount * 100,
'trade_type' => 'JSAPI',
'notify_url' => sysuri('@data/api.notify/wxpay/scene/order', [], false, true),
'spbill_create_ip' => $this->app->request->ip(),
];
if (empty($data['openid'])) unset($data['openid']);
$info = $this->payment->create($data);
if ($info['return_code'] === 'SUCCESS' && $info['result_code'] === 'SUCCESS') {
return $this->payment->jsapiParams($info['prepay_id']);
}
if (isset($info['err_code_des'])) {
throw new \think\Exception($info['err_code_des']);
} else {
throw new \think\Exception('获取预支付码失败!');
}
} catch (\Exception $exception) {
throw new \think\Exception($exception->getMessage(), $exception->getCode());
}
}
/**
* 支付结果处理
* @return string
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function notify(): string
{
$notify = $this->payment->getNotify();
if ($notify['result_code'] == 'SUCCESS' && $notify['return_code'] == 'SUCCESS') {
if ($this->updateOrder($notify['out_trade_no'], $notify['transaction_id'], $notify['cash_fee'] / 100, 'wechat')) {
return $this->payment->getNotifySuccessReply();
}
} else {
return $this->payment->getNotifySuccessReply();
}
}
}

View File

@ -0,0 +1,66 @@
{extend name="../../admin/view/main"}
{block name='content'}
<form class="layui-form layui-card" action="{:request()->url()}" data-auto="true" method="post" autocomplete="off">
<div class="layui-card-body padding-40">
<label class="layui-form-item relative block">
<span class="color-green font-w7">支付名称</span>
<span class="color-desc margin-left-5">Payment Name</span>
<input class="layui-input" required placeholder="请输入支付名称" name="name" value="{$vo.name|default=''}"/>
<span class="help-block"><b>必填,</b>请填写分类名称微信小程序支付建议字符不要太长一般4-6个汉字</span>
</label>
<div class="layui-form-item">
<span class="color-green font-w7 label-required-prev">支付通道</span>
<span class="color-desc margin-left-5">Payment Channel</span>
<div class="layui-input">
{empty name='vo.type'}{php}$vo['type'] = 'wechat_xcx';{/php}{/empty}
{foreach $types as $k => $v}
<label class="think-radio notselect">
{if $vo.type eq $k}
<input data-payment-type checked type="radio" name="type" value="{$k}" lay-ignore> {$v}
{else}
<input data-payment-type type="radio" name="type" value="{$k}" lay-ignore> {$v}
{/if}
</label>
{/foreach}
</div>
</div>
<div data-payment-type="wechat">{include file='payment/form_wechat'}</div>
<div data-payment-type="joinpay" class="layui-hide">{include file='payment/form_joinpay'}</div>
<div class="layui-form-item relative block">
<span class="color-green font-w7">支付描述</span>
<span class="color-desc margin-left-5">Payment Remark</span>
<label class="relative block">
<textarea class="layui-textarea" placeholder="请输入支付描述" name="desc">{$vo.desc|default=''}</textarea>
</label>
</div>
<div class="hr-line-dashed"></div>
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty}
<div class="layui-form-item text-center">
<button class="layui-btn" type='submit'>保存数据</button>
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-history-back>取消编辑</button>
</div>
</div>
</form>
{/block}
{block name='script'}
<script>
$('input[data-payment-type]').on('change', function () {
var type = $('input[data-payment-type]:checked').val();
if (type.indexOf('wechat') > -1) {
$('[data-payment-type="wechat"]').removeClass('layui-hide')
$('[data-payment-type="joinpay"]').addClass('layui-hide');
} else {
$('[data-payment-type="wechat"]').addClass('layui-hide')
$('[data-payment-type="joinpay"]').removeClass('layui-hide');
}
}).trigger('change');
</script>
{/block}

View File

@ -0,0 +1,23 @@
<label class="layui-form-item margin-bottom-20 block relative">
<span class="color-green font-s14 font-w7 margin-right-10">商户绑定的公众号</span>
<input name="joinpay_appid" required placeholder="请输入商户绑定的公众号(必填)" value="{$vo.content.joinpay_appid|default=''}" class="layui-input">
<span class="help-block">商户绑定的公众号授权给汇聚支付平台的公众号APPID</span>
</label>
<label class="layui-form-item margin-bottom-20 block relative">
<span class="color-green font-s14 font-w7">汇聚支付报备商户号</span>
<input name="joinpay_trade" required maxlength="15" placeholder="请输入汇聚支付报备商户号(必填)" value="{$vo.content.joinpay_trade|default=''}" class="layui-input">
<span class="help-block">汇聚支付报备商户号,需要联系汇聚支付平台的客服获取,通常以 777 开头的15位数字</span>
</label>
<label class="layui-form-item margin-bottom-20 block relative">
<span class="color-green font-s14 font-w7 margin-right-10">汇聚支付的商户编号</span>
<input name="joinpay_mch_id" required maxlength="15" placeholder="请输入汇聚支付的商户编号(必填)" value="{$vo.content.joinpay_mch_id|default=''}" class="layui-input">
<span class="help-block">汇聚支付的商户编号,需要在汇聚支付平台商户中心获取,通常是以 888 开头的15位数字</span>
</label>
<label class="layui-form-item margin-bottom-20 block relative">
<span class="color-green font-s14 font-w7 margin-right-10">汇聚支付的商户密钥</span>
<input name="joinpay_mch_key" required maxlength="32" placeholder="请输入汇聚支付的商户密钥(必填)" value="{$vo.content.joinpay_mch_key|default=''}" class="layui-input">
<span class="help-block">汇聚支付的商户密钥需要在汇聚支付平台商户中心的密钥管理处获取通常为32位字符串</span>
</label>

View File

@ -0,0 +1,29 @@
<label class="layui-form-item margin-bottom-20 block relative">
<span class="color-green font-s14 font-w7 margin-right-10">绑定公众号</span>
<input name="wechat_appid" required placeholder="请输入绑定公众号(必填)" value="{$vo.content.wechat_appid|default=''}" class="layui-input">
<span class="help-block">商户绑定的公众号授权给汇聚支付平台的公众号APPID</span>
</label>
<label class="layui-form-item margin-bottom-20 block relative">
<span class="color-green font-s14 font-w7 margin-right-10">微信商户号</span>
<input name="wechat_mch_id" required placeholder="请输入微信商户ID必填" value="{$vo.content.wechat_mch_id|default=''}" class="layui-input">
<span class="help-block">微信商户编号,需要在微信商户平台获取,微信商户号 公众号APPID 匹配</span>
</label>
<label class="layui-form-item margin-bottom-20 block relative">
<span class="color-green font-s14 font-w7 margin-right-10">微信商户密钥</span>
<input name="wechat_mch_key" required maxlength="32" placeholder="请输入微信商户密钥(必填)" value="{$vo.content.wechat_mch_key|default=''}" class="layui-input">
<span class="help-block">微信商户密钥,需要在微信商户平台操作设置密码并获取密钥,建议定期更换密钥</span>
</label>
<label class="layui-form-item margin-bottom-20 block relative">
<span class="color-green font-s14 font-w7">微信商户密钥文件内容</span><span class="nowrap color-desc"> 需要填写文件的全部内容 </span>
<textarea name="wechat_mch_key_text" placeholder="请输入微信KEY密钥内容" class="layui-textarea">{$vo.content.wechat_mch_key_text|default=''}</textarea>
<span class="help-block">从商户平台上下载支付证书,解压并取得其中的 apiclient_key.pem 用记事本打开并复制文件内容填至此处</span>
</label>
<label class="layui-form-item margin-bottom-20 block relative">
<span class="color-green font-s14 font-w7">微信商户证书文件内容</span><span class="nowrap color-desc"> 需要填写文件的全部内容 </span>
<textarea name="wechat_mch_cert_text" placeholder="请输入微信CERT证书内容" class="layui-textarea">{$vo.content.wechat_mch_cert_text|default=''}</textarea>
<span class="help-block">从商户平台上下载支付证书,解压并取得其中的 apiclient_cert.pem 用记事本打开并复制文件内容填至此处</span>
</label>

View File

@ -0,0 +1,66 @@
{extend name="../../admin/view/main"}
{block name="button"}
<!--{if auth("add")}-->
<button data-open='{:url("add")}' class='layui-btn layui-btn-sm layui-btn-primary'>添加支付</button>
<!--{/if}-->
<!--{if auth("remove")}-->
<button data-action='{:url("remove")}' data-rule="id#{key}" data-confirm="确定要删除这些支付吗?" class='layui-btn layui-btn-sm layui-btn-primary'>删除支付</button>
<!--{/if}-->
{/block}
{block name='content'}
<div class="think-box-shadow table-block">
{include file='payment/index_search'}
<table class="layui-table margin-top-10" lay-skin="line">
{notempty name='list'}
<thead>
<tr>
<th class='list-table-check-td think-checkbox'>
<label><input data-auto-none data-check-target='.list-check-box' type='checkbox'/></label>
</th>
<th class='list-table-sort-td'>
<button type="button" data-reload class="layui-btn layui-btn-xs"> </button>
</th>
<th class="text-left nowrap">支付名称</th>
<th class="text-left nowrap">支付通道</th>
<th class="text-left nowrap">支付状态</th>
<th class="text-left nowrap">创建时间</th>
<th class="text-left nowrap"></th>
</tr>
</thead>
{/notempty}
<tbody>
{foreach $list as $key=>$vo}
<tr data-dbclick>
<td class='list-table-check-td think-checkbox'>
<label><input class="list-check-box" value='{$vo.id}' type='checkbox'/></label>
</td>
<td class='list-table-sort-td'>
<label><input data-action-blur="{:request()->url()}" data-value="id#{$vo.id};action#sort;sort#{value}" data-loading="false" value="{$vo.sort}" class="list-sort-input"></label>
</td>
<td class="text-left nowrap">{$vo.name|default=''}</td>
<td class="text-left nowrap">{$types[$vo.type]??$vo.type}</td>
<td>{if $vo.status eq 0}<span class="color-red">已禁用</span>{elseif $vo.status eq 1}<span class="color-green">已激活</span>{/if}</td>
<td class="text-left nowrap">{$vo.create_at|format_datetime}</td>
<td class='text-left nowrap'>
{if auth("edit")}
<a data-dbclick class="layui-btn layui-btn-xs" data-open="{:url('edit')}?id={$vo.id}"> </a>
{/if}
{if auth("state") and $vo.status eq 1}
<a class="layui-btn layui-btn-xs layui-btn-warm" data-action="{:url('state')}" data-value="id#{$vo.id};status#0"> </a>
{/if}
{if auth("state") and $vo.status eq 0}
<a class="layui-btn layui-btn-xs layui-btn-warm" data-action="{:url('state')}" data-value="id#{$vo.id};status#1"> </a>
{/if}
{if auth("remove")}
<a class="layui-btn layui-btn-xs layui-btn-danger" data-confirm="确定要删除该支付吗?" data-action="{:url('remove')}" data-value="id#{$vo.id}"> </a>
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
{empty name='list'}<span class="notdata">没有记录哦</span>{else}{$pagehtml|raw|default=''}{/empty}
</div>
{/block}

View File

@ -0,0 +1,49 @@
<fieldset>
<legend>条件搜索</legend>
<form class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get" autocomplete="off">
<div class="layui-form-item layui-inline">
<label class="layui-form-label">支付名称</label>
<label class="layui-input-inline">
<input name="name" value="{:input('name','')}" placeholder="请输入支付名称" class="layui-input">
</label>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">支付通道</label>
<div class="layui-input-inline">
<select class="layui-select" name="type">
<option value="">-- 全部 --</option>
{foreach $types as $k=>$v}
{if $k eq input('type')}
<option selected value="{$k}">{$v}</option>
{else}
<option value="{$k}">{$v}</option>
{/if}{/foreach}
</select>
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">使用状态</label>
<div class="layui-input-inline">
<select class="layui-select" name="status">
{foreach [''=>'-- 全部 --','0'=>'已禁用的记录','1'=>'已激活的记录'] as $k=>$v}
{if $k.'' eq input('status')}
<option selected value="{$k}">{$v}</option>
{else}
<option value="{$k}">{$v}</option>
{/if}{/foreach}
</select>
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">创建时间</label>
<label class="layui-input-inline">
<input data-date-range name="create_at" value="{:input('create_at','')}" placeholder="请选择创建时间" class="layui-input">
</label>
</div>
<div class="layui-form-item layui-inline">
<button class="layui-btn layui-btn-primary"><i class="layui-icon">&#xe615;</i> 搜 索</button>
</div>
</form>
</fieldset>
<script>window.form.render()</script>