初始上传
This commit is contained in:
134
addon/wechatpay/api/controller/Transfer.php
Executable file
134
addon/wechatpay/api/controller/Transfer.php
Executable file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\api\controller;
|
||||
|
||||
use addon\memberwithdraw\model\Withdraw as WithdrawModel;
|
||||
use addon\wechat\model\Config as WechatConfig;
|
||||
use addon\wechatpay\model\Config;
|
||||
use addon\wechatpay\model\Pay;
|
||||
use addon\wechatpay\model\TransferConfig;
|
||||
use app\exception\ApiException;
|
||||
use app\model\system\PayTransfer;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Log;
|
||||
use app\api\controller\BaseApi;
|
||||
use addon\weapp\model\Config as WeaAppConfig;
|
||||
class Transfer extends BaseApi
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 微信转账v3用户主动收款回调
|
||||
*/
|
||||
public function notify(){
|
||||
$pay = new Pay();
|
||||
$pay->transferNotify();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发起收款
|
||||
*/
|
||||
|
||||
public function transfer(){
|
||||
|
||||
$id = $this->params['id'] ?? ''; //提现单id
|
||||
$transfer_type = $this->params['transfer_type'] ?? ''; //提现来源
|
||||
|
||||
$token = $this->checkToken();
|
||||
if ($token[ 'code' ] < 0 && $transfer_type != 'store_withdraw') return $this->response($token);
|
||||
if (empty($id)) {
|
||||
return $this->response($this->error('', 'REQUEST_ID'));
|
||||
}
|
||||
|
||||
$cache = Cache::get('transfer:' . $id);
|
||||
if(!empty($cache)){
|
||||
return $this->response($this->error('', '系统处理中,请务重复提交'));
|
||||
}
|
||||
|
||||
try{
|
||||
Cache::set("transfer:".$id,1,10);
|
||||
|
||||
//判断是公众号还是小程序
|
||||
if($transfer_type != 'store_withdraw'){
|
||||
$member_model = new \app\model\member\Member();
|
||||
$member_info = $member_model->getMemberInfo([['member_id', '=', $this->member_id]], 'wx_openid,weapp_openid')['data'];
|
||||
(new PayTransfer())->editTransfer([
|
||||
'is_weapp'=>$this->params['app_type'] == 'weapp' ? 1 : 0,
|
||||
'account_number'=>$this->params['app_type'] == 'weapp' ? $member_info['weapp_openid'] : $member_info['wx_openid'],
|
||||
],[['relate_tag','=',$id],['from_type','=',$transfer_type]]);
|
||||
}
|
||||
|
||||
$transfer_model = new \app\model\system\PayTransfer();
|
||||
$result = $transfer_model->transfer($transfer_type, $id, true);
|
||||
|
||||
Cache::delete('transfer:' . $id);
|
||||
return $this->response($result);
|
||||
}catch (ApiException $errorException){
|
||||
Cache::delete('transfer:' . $id);
|
||||
Log::write('发起收款接口异常,原因'.$errorException->getMessage());
|
||||
return $this->response($this->error([],'系统异常,请稍后再试'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤销转账
|
||||
*/
|
||||
|
||||
public function cancel(){
|
||||
$out_trade_no = $this->params['out_trade_no'] ?? '';
|
||||
if (empty($out_trade_no)) {
|
||||
return $this->response($this->error('', '商户单号有误'));
|
||||
}
|
||||
$pay = new Pay();
|
||||
$result = $pay->transferCancel($out_trade_no);
|
||||
return $this->response($result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取转账配置
|
||||
*/
|
||||
public function getWithdrawConfig(){
|
||||
$config_model = new Config();
|
||||
$config = $config_model->getPayConfig($this->site_id)[ 'data' ][ 'value' ];
|
||||
$wechat_config = (new WechatConfig())->getWechatConfig($this->site_id);
|
||||
$weapp_config_result = (new WeaAppConfig())->getWeappConfig($this->site_id);
|
||||
$data = [
|
||||
'transfer_type'=>$config['transfer_type'] == 'v3' && $config['transfer_v3_type'] == $config_model::TRANSFER_V3_TYPE_USER ? 1 : 0,
|
||||
'mch_id'=>$config['mch_id'] ?? '',
|
||||
'wechat_appid'=>$wechat_config['data']['value']['appid'] ?? '',
|
||||
'weapp_appid'=>$weapp_config_result['data']['value']['appid'] ?? '',
|
||||
];
|
||||
return $this->response($this->success($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更改状态为转账中
|
||||
*/
|
||||
public function inProcess()
|
||||
{
|
||||
$relate_tag = $this->params['relate_tag'] ?? '';
|
||||
$from_type = $this->params['from_type'] ?? '';
|
||||
|
||||
$transfer_model = new \app\model\system\PayTransfer();
|
||||
$transfer_info = $transfer_model->getTransferInfo([['from_type', '=', $from_type], ['relate_tag', '=', $relate_tag]])['data'];
|
||||
$res = $transfer_model->updateStatus(['status' => $transfer_model::STATUS_IN_PROCESS], $transfer_info['id'] ?? 0);
|
||||
|
||||
return $this->response($res);
|
||||
}
|
||||
}
|
||||
38
addon/wechatpay/config/diy_view.php
Executable file
38
addon/wechatpay/config/diy_view.php
Executable file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
return [
|
||||
|
||||
// 自定义模板页面类型,格式:[ 'title' => '页面类型名称', 'name' => '页面标识', 'path' => '页面路径', 'value' => '页面数据,json格式' ]
|
||||
'template' => [],
|
||||
|
||||
// 后台自定义组件——装修
|
||||
'util' => [],
|
||||
|
||||
// 自定义页面路径
|
||||
'link' => [],
|
||||
|
||||
// 自定义图标库
|
||||
'icon_library' => [],
|
||||
|
||||
// uni-app 组件,格式:[ 'name' => '组件名称/文件夹名称', 'path' => '文件路径/目录路径' ],多个逗号隔开,自定义组件名称前缀必须是diy-,也可以引用第三方组件
|
||||
'component' => [],
|
||||
|
||||
// uni-app 页面,多个逗号隔开
|
||||
'pages' => [],
|
||||
|
||||
// 模板信息,格式:'title' => '模板名称', 'name' => '模板标识', 'cover' => '模板封面图', 'preview' => '模板预览图', 'desc' => '模板描述'
|
||||
'info' => [],
|
||||
|
||||
// 主题风格配色,格式可以自由定义扩展,【在uni-app中通过:this.themeStyle... 获取定义的颜色字段,例如:this.themeStyle.main_color】
|
||||
'theme' => [],
|
||||
|
||||
// 自定义页面数据,格式:[ 'title' => '页面名称', 'name' => "页面标识", 'value' => [页面数据,json格式] ]
|
||||
'data' => []
|
||||
];
|
||||
47
addon/wechatpay/config/event.php
Executable file
47
addon/wechatpay/config/event.php
Executable file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
// 事件定义文件
|
||||
return [
|
||||
'bind' => [
|
||||
|
||||
],
|
||||
|
||||
'listen' => [
|
||||
//支付异步回调
|
||||
'PayNotify' => [
|
||||
'addon\wechatpay\event\PayNotify'
|
||||
],
|
||||
//支付方式,后台查询
|
||||
'PayType' => [
|
||||
'addon\wechatpay\event\PayType'
|
||||
],
|
||||
//支付,前台应用
|
||||
'Pay' => [
|
||||
'addon\wechatpay\event\Pay'
|
||||
],
|
||||
'PayClose' => [
|
||||
'addon\wechatpay\event\PayClose'
|
||||
],
|
||||
'PayRefund' => [
|
||||
'addon\wechatpay\event\PayRefund'
|
||||
],
|
||||
'PayTransfer' => [
|
||||
'addon\wechatpay\event\PayTransfer'
|
||||
],
|
||||
'TransferType' => [
|
||||
'addon\wechatpay\event\TransferType'
|
||||
],
|
||||
'PayTransferResult' => [
|
||||
'addon\wechatpay\event\PayTransferResult'
|
||||
],
|
||||
//付款码支付异步回调
|
||||
'AuthcodePay' => [
|
||||
'addon\wechatpay\event\AuthcodePay'
|
||||
],
|
||||
'PayOrderQuery' => [
|
||||
'addon\wechatpay\event\PayOrderQuery'
|
||||
],
|
||||
],
|
||||
|
||||
'subscribe' => [
|
||||
],
|
||||
];
|
||||
20
addon/wechatpay/config/info.php
Executable file
20
addon/wechatpay/config/info.php
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
return [
|
||||
'name' => 'wechatpay',
|
||||
'title' => '微信支付',
|
||||
'description' => '微信支付功能',
|
||||
'type' => 'system', //插件类型 system :系统插件(自动安装), business:业务插件 promotion:扩展营销插件 tool:工具插件
|
||||
'status' => 1,
|
||||
'author' => '',
|
||||
'version' => '5.5.3',
|
||||
'version_no' => '553250709001',
|
||||
'content' => '',
|
||||
];
|
||||
18
addon/wechatpay/config/menu_shop.php
Executable file
18
addon/wechatpay/config/menu_shop.php
Executable file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 平台端菜单设置
|
||||
// +----------------------------------------------------------------------
|
||||
return [
|
||||
[
|
||||
'name' => 'WECHAT_PAY_CONFIG',
|
||||
'title' => '微信支付编辑',
|
||||
'url' => 'wechatpay://shop/pay/config',
|
||||
'parent' => 'CONFIG_PAY',
|
||||
'is_show' => 0,
|
||||
'is_control' => 1,
|
||||
'is_icon' => 0,
|
||||
'picture' => '',
|
||||
'picture_select' => '',
|
||||
'sort' => 1,
|
||||
],
|
||||
];
|
||||
48
addon/wechatpay/event/AuthcodePay.php
Executable file
48
addon/wechatpay/event/AuthcodePay.php
Executable file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
// +---------------------------------------------------------------------+
|
||||
// | NiuCloud | [ WE CAN DO IT JUST NiuCloud ] |
|
||||
// +---------------------------------------------------------------------+
|
||||
// | Copy right 2019-2029 www.niucloud.com |
|
||||
// +---------------------------------------------------------------------+
|
||||
// | Author | NiuCloud <niucloud@outlook.com> |
|
||||
// +---------------------------------------------------------------------+
|
||||
// | Repository | https://github.com/niucloud/framework.git |
|
||||
// +---------------------------------------------------------------------+
|
||||
|
||||
namespace addon\wechatpay\event;
|
||||
|
||||
use addon\wechatpay\model\Pay as PayModel;
|
||||
use app\model\system\Pay as PayCommon;
|
||||
|
||||
/**
|
||||
* 支付回调
|
||||
*/
|
||||
class AuthcodePay
|
||||
{
|
||||
/**
|
||||
* 支付方式及配置
|
||||
*/
|
||||
public function handle($params)
|
||||
{
|
||||
$out_trade_no = $params[ 'out_trade_no' ] ?? '';
|
||||
$auth_code_array = [ 10, 11, 12, 13, 14, 15 ];
|
||||
if (!empty($out_trade_no)) {
|
||||
$auth_code = $params[ 'auth_code' ];
|
||||
$sub_str = substr($auth_code, 0, 2);
|
||||
if (in_array($sub_str, $auth_code_array)) {
|
||||
$pay = new PayCommon();
|
||||
$pay_info = $pay->getPayInfo($out_trade_no)[ 'data' ] ?? [];
|
||||
if (!empty($pay_info)) {
|
||||
$site_id = $pay_info[ 'site_id' ] ?? 0;
|
||||
$pay_model = new PayModel(0, $site_id);
|
||||
|
||||
$result = $pay_model->micropay(array_merge($params, $pay_info));
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
25
addon/wechatpay/event/Install.php
Executable file
25
addon/wechatpay/event/Install.php
Executable file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\event;
|
||||
|
||||
/**
|
||||
* 应用安装
|
||||
*/
|
||||
class Install
|
||||
{
|
||||
/**
|
||||
* 执行安装
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
return success();
|
||||
}
|
||||
}
|
||||
56
addon/wechatpay/event/Pay.php
Executable file
56
addon/wechatpay/event/Pay.php
Executable file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\event;
|
||||
|
||||
use addon\wechatpay\model\Pay as PayModel;
|
||||
|
||||
/**
|
||||
* 生成支付
|
||||
*/
|
||||
class Pay
|
||||
{
|
||||
/**
|
||||
* 支付
|
||||
*/
|
||||
public function handle($params)
|
||||
{
|
||||
if ($params[ "pay_type" ] == "wechatpay") {
|
||||
|
||||
$app_type = $params[ 'app_type' ];
|
||||
$is_weapp = 0;
|
||||
switch ( $app_type ) {
|
||||
case 'h5' :
|
||||
$trade_type = "MWEB";
|
||||
break;
|
||||
case 'wechat' :
|
||||
$trade_type = "JSAPI";
|
||||
break;
|
||||
case 'weapp' :
|
||||
$is_weapp = 1;
|
||||
$trade_type = "APPLET";
|
||||
break;
|
||||
case 'app' :
|
||||
$trade_type = "APP";
|
||||
break;
|
||||
case 'pc' :
|
||||
$trade_type = "NATIVE";
|
||||
break;
|
||||
case 'cashier':
|
||||
$trade_type = "NATIVE";
|
||||
break;
|
||||
}
|
||||
$params[ "trade_type" ] = $trade_type;
|
||||
$pay_model = new PayModel($is_weapp, $params[ 'site_id' ]);
|
||||
$result = $pay_model->pay($params);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
42
addon/wechatpay/event/PayClose.php
Executable file
42
addon/wechatpay/event/PayClose.php
Executable file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\event;
|
||||
|
||||
use addon\wechatpay\model\Pay as PayModel;
|
||||
|
||||
/**
|
||||
* 关闭支付
|
||||
*/
|
||||
class PayClose
|
||||
{
|
||||
/**
|
||||
* 关闭支付
|
||||
* @param $params
|
||||
* @return array
|
||||
*/
|
||||
public function handle($params)
|
||||
{
|
||||
$mch_info = json_decode($params['mch_info'], true);
|
||||
$pay_type = $mch_info['pay_type'] ?? '';
|
||||
$is_weapp = $mch_info['is_weapp'] ?? 0;
|
||||
if($pay_type == 'wechatpay'){
|
||||
try {
|
||||
$pay_model = new PayModel($is_weapp, $params[ 'site_id' ]);
|
||||
$result = $pay_model->close($params);
|
||||
return $result;
|
||||
} catch (\Exception $e) {
|
||||
return error(-1, $e->getMessage());
|
||||
} catch (\Throwable $e) {
|
||||
return error(-1, $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
31
addon/wechatpay/event/PayNotify.php
Executable file
31
addon/wechatpay/event/PayNotify.php
Executable file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\event;
|
||||
|
||||
use addon\wechatpay\model\Pay as PayModel;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 支付回调
|
||||
*/
|
||||
class PayNotify
|
||||
{
|
||||
/**
|
||||
* 支付方式及配置
|
||||
*/
|
||||
public function handle($param)
|
||||
{
|
||||
$reqData = empty($GLOBALS[ 'HTTP_RAW_POST_DATA' ]) ? file_get_contents('php://input') : $GLOBALS[ 'HTTP_RAW_POST_DATA' ];
|
||||
Log::write('微信支付回调数据');
|
||||
Log::write($reqData);
|
||||
return ( new PayModel() )->payNotify();
|
||||
}
|
||||
}
|
||||
47
addon/wechatpay/event/PayOrderQuery.php
Executable file
47
addon/wechatpay/event/PayOrderQuery.php
Executable file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\event;
|
||||
|
||||
use addon\wechat\model\Config as WechatConfig;
|
||||
use addon\wechatpay\model\Config;
|
||||
use addon\wechatpay\model\Pay as PayModel;
|
||||
use addon\wechatpay\model\V2;
|
||||
use app\model\system\Pay;
|
||||
|
||||
/**
|
||||
* 查询支付结果
|
||||
*/
|
||||
class PayOrderQuery
|
||||
{
|
||||
public function handle(array $params)
|
||||
{
|
||||
try {
|
||||
$res = success();
|
||||
$pay_info = ( new Pay() )->getInfo([ [ 'id', '=', $params[ 'relate_id' ] ]])[ 'data' ];
|
||||
if (!empty($pay_info) && $pay_info['is_delete'] == 0) {
|
||||
$mch_info = json_decode($pay_info['mch_info'], true);
|
||||
$pay_type = $mch_info['pay_type'] ?? 'wechatpay';
|
||||
if($pay_type == 'wechatpay'){
|
||||
$pay_config = ( new Config() )->getPayConfig($pay_info[ 'site_id' ])[ 'data' ][ 'value' ];
|
||||
$wechat_config = ( new WechatConfig() )->getWechatConfig($pay_info[ 'site_id' ])[ 'data' ][ 'value' ];
|
||||
$pay_config[ 'appid' ] = $wechat_config[ 'appid' ] ?? '';
|
||||
if (!empty($pay_config) && $pay_config[ 'pay_status' ] == 1) {
|
||||
$res = ( new V2($pay_config) )->orderQuery($pay_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}catch (\Throwable $e) {
|
||||
return error(-1, $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
47
addon/wechatpay/event/PayRefund.php
Executable file
47
addon/wechatpay/event/PayRefund.php
Executable file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\event;
|
||||
|
||||
use addon\wechatpay\model\Pay as PayModel;
|
||||
use addon\shopcomponent\model\Weapp;
|
||||
|
||||
/**
|
||||
* 原路退款
|
||||
*/
|
||||
class PayRefund
|
||||
{
|
||||
/**
|
||||
* 原路退款
|
||||
*/
|
||||
public function handle($params)
|
||||
{
|
||||
if ($params[ "pay_info" ][ "pay_type" ] == "wechatpay") {
|
||||
|
||||
if ($params[ 'is_video_number' ] == 1) {
|
||||
$weapp_model = new Weapp($params[ 'site_id' ]);
|
||||
$refund_params = [
|
||||
"out_aftersale_id" => $params[ 'out_aftersale_id' ]
|
||||
];
|
||||
$info = $weapp_model->getAftersale($refund_params);
|
||||
if ($info[ 'code' ] == 0 && !empty($info[ 'data' ])) {
|
||||
$result = $weapp_model->orderRefund($refund_params);
|
||||
} else {
|
||||
$pay_model = new PayModel(0, $params[ 'site_id' ]);
|
||||
$result = $pay_model->refund($params);
|
||||
}
|
||||
} else {
|
||||
$pay_model = new PayModel(0, $params[ 'site_id' ]);
|
||||
$result = $pay_model->refund($params);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
33
addon/wechatpay/event/PayTransfer.php
Executable file
33
addon/wechatpay/event/PayTransfer.php
Executable file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\event;
|
||||
|
||||
use addon\wechatpay\model\Pay;
|
||||
|
||||
class PayTransfer
|
||||
{
|
||||
public function handle(array $params)
|
||||
{
|
||||
if ($params[ 'transfer_type' ] == 'wechatpay') {
|
||||
//TODO 本地测试流程
|
||||
// if(request()->ip() == '127.0.0.1'){
|
||||
// $pay_transfer_model = new \app\model\system\PayTransfer();
|
||||
// return $pay_transfer_model->success([
|
||||
// 'status' => $pay_transfer_model::STATUS_IN_PROCESS,
|
||||
// ]);
|
||||
// }
|
||||
$is_weapp = $params[ 'is_weapp' ] ?? 0;
|
||||
$pay = new Pay($is_weapp, $params[ 'site_id' ]);
|
||||
$res = $pay->transfer($params);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
31
addon/wechatpay/event/PayTransferResult.php
Executable file
31
addon/wechatpay/event/PayTransferResult.php
Executable file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace addon\wechatpay\event;
|
||||
|
||||
use addon\wechatpay\model\Config;
|
||||
use addon\wechatpay\model\V3;
|
||||
use app\model\member\Withdraw;
|
||||
|
||||
class PayTransferResult
|
||||
{
|
||||
public function handle($params)
|
||||
{
|
||||
//TODO 本地测试流程
|
||||
// if(request()->ip() == '127.0.0.1'){
|
||||
// $pay_transfer_model = new \app\model\system\PayTransfer();
|
||||
// /*return $pay_transfer_model->success([
|
||||
// 'status' => $pay_transfer_model::STATUS_SUCCESS,
|
||||
// ]);*/
|
||||
// /*return $pay_transfer_model->success([
|
||||
// 'status' => $pay_transfer_model::STATUS_FAIL,
|
||||
// 'fail_reason' => '用户姓名校验失败',
|
||||
// 'fail_code' => 'NAME_NOT_CORRECT',
|
||||
// ]);*/
|
||||
// }
|
||||
$pay_config = (new Config())->getPayConfig($params['site_id'])['data']['value'];
|
||||
$pay_config['site_id'] = $params['site_id'];
|
||||
if (!empty($pay_config) && $pay_config['transfer_v3_type'] == Config::TRANSFER_V3_TYPE_SHOP) {
|
||||
return (new V3($pay_config))->getTransferResult($params);
|
||||
}
|
||||
return (new V3($pay_config))->success();
|
||||
}
|
||||
}
|
||||
52
addon/wechatpay/event/PayType.php
Executable file
52
addon/wechatpay/event/PayType.php
Executable file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\event;
|
||||
|
||||
use addon\wechatpay\model\Config;
|
||||
|
||||
/**
|
||||
* 支付方式 (前后台调用)
|
||||
*/
|
||||
class PayType
|
||||
{
|
||||
/**
|
||||
* 支付方式及配置
|
||||
*/
|
||||
public function handle($params)
|
||||
{
|
||||
$config_model = new Config();
|
||||
$config_result = $config_model->getPayConfig($params[ 'site_id' ] ?? 1);
|
||||
$config = $config_result[ "data" ][ "value" ] ?? [];
|
||||
$pay_status = $config[ "pay_status" ] ?? 0;
|
||||
|
||||
$app_type = $params['app_type'] ?? '';
|
||||
if (!empty($app_type)) {
|
||||
$app_type_array = [ 'h5', 'wechat', 'weapp', 'pc' ];
|
||||
if (!in_array($app_type, $app_type_array)) {
|
||||
return '';
|
||||
}
|
||||
if ($pay_status == 0) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
$info = array (
|
||||
"pay_type" => "wechatpay",
|
||||
"pay_type_name" => "微信支付",
|
||||
"edit_url" => "wechatpay://shop/pay/config",
|
||||
"shop_url" => "wechatpay://shop/pay/config",
|
||||
"logo" => "addon/wechatpay/icon.png",
|
||||
"desc" => "微信支付,用户通过扫描二维码、微信内打开商品页面购买等多种方式调起微信支付模块完成支付。",
|
||||
"pay_status" => $pay_status,
|
||||
);
|
||||
return $info;
|
||||
|
||||
}
|
||||
}
|
||||
43
addon/wechatpay/event/TransferType.php
Executable file
43
addon/wechatpay/event/TransferType.php
Executable file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\event;
|
||||
|
||||
use addon\wechatpay\model\Config;
|
||||
|
||||
/**
|
||||
* 转账方式 (前后台调用)
|
||||
*/
|
||||
class TransferType
|
||||
{
|
||||
public function handle($params)
|
||||
{
|
||||
$app_type = $params['app_type'] ?? '';
|
||||
if (!empty($app_type)) {
|
||||
$config_model = new Config();
|
||||
$app_type_array = $config_model->app_type;
|
||||
if (!in_array($app_type, $app_type_array)) {
|
||||
return '';
|
||||
}
|
||||
$config_result = $config_model->getPayConfig($params[ 'site_id' ]);
|
||||
$config = $config_result[ "data" ][ "value" ] ?? [];
|
||||
$transfer_status = $config[ "transfer_status" ] ?? 0;
|
||||
if ($transfer_status == 0) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
$info = array (
|
||||
"type" => "wechatpay",
|
||||
"type_name" => "微信零钱",
|
||||
);
|
||||
return $info;
|
||||
|
||||
}
|
||||
}
|
||||
25
addon/wechatpay/event/UnInstall.php
Executable file
25
addon/wechatpay/event/UnInstall.php
Executable file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\event;
|
||||
|
||||
/**
|
||||
* 应用卸载
|
||||
*/
|
||||
class UnInstall
|
||||
{
|
||||
/**
|
||||
* 执行卸载
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
return success();
|
||||
}
|
||||
}
|
||||
BIN
addon/wechatpay/icon.png
Executable file
BIN
addon/wechatpay/icon.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
340
addon/wechatpay/model/Config.php
Executable file
340
addon/wechatpay/model/Config.php
Executable file
@@ -0,0 +1,340 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\model;
|
||||
|
||||
use app\model\system\Config as ConfigModel;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 微信支付配置
|
||||
* 版本 1.0.4
|
||||
*/
|
||||
class Config extends BaseModel
|
||||
{
|
||||
|
||||
private $encrypt = '******';
|
||||
|
||||
/**
|
||||
* 设置支付配置
|
||||
* @param $data
|
||||
* @param int $site_id
|
||||
* @param string $app_module
|
||||
* @return array
|
||||
*/
|
||||
public function setPayConfig($data, $site_id = 0, $app_module = 'shop')
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
|
||||
// 未加密前的数据
|
||||
$original_config = $this->getPayConfig($site_id)['data']['value'];
|
||||
|
||||
// 检测数据是否发生变化,如果没有变化,则保持未加密前的数据
|
||||
if (!empty($data['pay_signkey']) && $data['pay_signkey'] == $this->encrypt) {
|
||||
$data['pay_signkey'] = $original_config['pay_signkey']; // APIv2密钥
|
||||
}
|
||||
if (!empty($data['apiclient_cert']) && $data['apiclient_cert'] == $this->encrypt) {
|
||||
$data['apiclient_cert'] = $original_config['apiclient_cert']; // 支付证书cert
|
||||
}
|
||||
if (!empty($data['apiclient_key']) && $data['apiclient_key'] == $this->encrypt) {
|
||||
$data['apiclient_key'] = $original_config['apiclient_key']; // 支付证书key
|
||||
}
|
||||
if (!empty($data['plateform_cert']) && $data['plateform_cert'] == $this->encrypt) {
|
||||
$data['plateform_cert'] = $original_config['plateform_cert']; // 平台证书 生成的
|
||||
}
|
||||
if (!empty($data['plateform_certificate']) && $data['plateform_certificate'] == $this->encrypt) {
|
||||
$data['plateform_certificate'] = $original_config['plateform_certificate']; // 平台证书 主动上传的
|
||||
}
|
||||
if (!empty($data['plateform_certificate_serial']) && $data['plateform_certificate_serial'] == $this->encrypt) {
|
||||
$data['plateform_certificate_serial'] = $original_config['plateform_certificate_serial']; // 平台证书序列号
|
||||
}
|
||||
if (!empty($data['v3_pay_signkey']) && $data['v3_pay_signkey'] == $this->encrypt) {
|
||||
$data['v3_pay_signkey'] = $original_config['v3_pay_signkey']; // APIv3密钥
|
||||
}
|
||||
|
||||
if(!($data['transfer_status'] == 1 && $data['transfer_type'] == 'v3' && $data['transfer_v3_type'] == self::TRANSFER_V3_TYPE_USER)){
|
||||
$data['member_transfer_scene'] = '';
|
||||
$data['store_transfer_scene'] = '';
|
||||
$data['fenxiao_transfer_scene'] = '';
|
||||
$data['member_transfer_code'] = '';
|
||||
$data['store_transfer_code'] = '';
|
||||
$data['fenxiao_transfer_code'] = '';
|
||||
$data['member_transfer_info'] = [];
|
||||
$data['fenxiao_transfer_info'] = [];
|
||||
$data['store_transfer_info'] = [];
|
||||
$data['member_transfer_recv'] = '';
|
||||
$data['store_transfer_recv'] = '';
|
||||
$data['fenxiao_transfer_recv'] = '';
|
||||
}
|
||||
|
||||
$res = $config->setConfig($data, '微信支付配置', 1, [['site_id', '=', $site_id], ['app_module', '=', $app_module], ['config_key', '=', 'WECHAT_PAY_CONFIG']]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付配置
|
||||
* @param int $site_id
|
||||
* @param string $app_module
|
||||
* @param bool $need_encrypt 是否需要加密数据,true:加密、false:不加密
|
||||
* @return array
|
||||
*/
|
||||
public function getPayConfig($site_id = 0, $app_module = 'shop', $need_encrypt = false)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->getConfig([['site_id', '=', $site_id], ['app_module', '=', $app_module], ['config_key', '=', 'WECHAT_PAY_CONFIG']]);
|
||||
|
||||
//旧定义字段变为新定义字段
|
||||
$res['data']['value'] = json_encode($res['data']['value']);
|
||||
$res['data']['value'] = str_replace('member_transfer', 'member_withdraw', $res['data']['value']);
|
||||
$res['data']['value'] = str_replace('store_transfer', 'store_withdraw', $res['data']['value']);
|
||||
$res['data']['value'] = str_replace('fenxiao_transfer', 'fenxiao_withdraw', $res['data']['value']);
|
||||
$res['data']['value'] = json_decode($res['data']['value'], true);
|
||||
|
||||
$res['data']['value'] = array_merge([
|
||||
"appid" => '',
|
||||
"mch_id" => '',
|
||||
"pay_signkey" => '',
|
||||
"apiclient_cert" => '',
|
||||
"apiclient_key" => '',
|
||||
"refund_status" => 0,
|
||||
"pay_status" => 0,
|
||||
"transfer_status" => 0,
|
||||
'transfer_type' => 'v2',
|
||||
'plateform_cert' => '',
|
||||
'plateform_certificate' => '',
|
||||
'plateform_certificate_serial' => '',
|
||||
'api_type' => 'v2',
|
||||
'v3_pay_signkey' => '',
|
||||
'transfer_v3_type'=>'1',//旧版1 新版2
|
||||
'member_withdraw_scene'=>'',
|
||||
'store_withdraw_scene'=>'',
|
||||
'fenxiao_withdraw_scene'=>'',
|
||||
'member_withdraw_code'=>'',
|
||||
'store_withdraw_code'=>'',
|
||||
'fenxiao_withdraw_code'=>'',
|
||||
'member_withdraw_info' => [],
|
||||
'fenxiao_withdraw_info'=> [],
|
||||
'store_withdraw_info' => [],
|
||||
'member_withdraw_recv'=>'',
|
||||
'store_withdraw_recv'=>'',
|
||||
'fenxiao_withdraw_recv'=>'',
|
||||
], $res['data']['value']);
|
||||
|
||||
// 加密敏感信息
|
||||
if (!empty($res['data']['value']) && $need_encrypt) {
|
||||
|
||||
if (!empty($res['data']['value']['pay_signkey'])) {
|
||||
$res['data']['value']['pay_signkey'] = $this->encrypt; // APIv2密钥
|
||||
}
|
||||
if (!empty($res['data']['value']['apiclient_cert'])) {
|
||||
$res['data']['value']['apiclient_cert'] = $this->encrypt; // 支付证书cert
|
||||
}
|
||||
if (!empty($res['data']['value']['apiclient_key'])) {
|
||||
$res['data']['value']['apiclient_key'] = $this->encrypt; // 支付证书key
|
||||
}
|
||||
if (!empty($res['data']['value']['plateform_cert'])) {
|
||||
$res['data']['value']['plateform_cert'] = $this->encrypt; // 平台证书 通过接口获取和生成的
|
||||
}
|
||||
if (!empty($res['data']['value']['plateform_certificate'])) {
|
||||
$res['data']['value']['plateform_certificate'] = $this->encrypt; // 平台证书,直接上传的
|
||||
}
|
||||
if (!empty($res['data']['value']['plateform_certificate_serial'])) {
|
||||
$res['data']['value']['plateform_certificate_serial'] = $this->encrypt; // 平台证书ID
|
||||
}
|
||||
if (!empty($res['data']['value']['v3_pay_signkey'])) {
|
||||
$res['data']['value']['v3_pay_signkey'] = $this->encrypt; // APIv3密钥
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
CONST TRANSFER_V3_TYPE_SHOP = 1; //商户转账
|
||||
CONST TRANSFER_V3_TYPE_USER = 2; //会员收款
|
||||
|
||||
public function getTransferSceneConfig()
|
||||
{
|
||||
$config = [
|
||||
[
|
||||
'num'=>1,
|
||||
'title' => '现金营销',
|
||||
'infos' => [
|
||||
[
|
||||
'info_type' => '活动名称',
|
||||
'info_content' => ''
|
||||
],
|
||||
[
|
||||
'info_type' => '奖励说明',
|
||||
'info_content' => '',
|
||||
],
|
||||
],
|
||||
'user_recv'=>[
|
||||
'活动奖励',
|
||||
'现金奖励'
|
||||
]
|
||||
],
|
||||
[
|
||||
'num'=>2,
|
||||
'title' => '企业赔付',
|
||||
'infos' => [
|
||||
[
|
||||
'info_type' => '赔付原因',
|
||||
'info_content' => ''
|
||||
],
|
||||
],
|
||||
'user_recv'=>[
|
||||
'退款',
|
||||
'商家赔付'
|
||||
]
|
||||
],
|
||||
[
|
||||
'num'=>3,
|
||||
'title' => '佣金报酬',
|
||||
'infos' => [
|
||||
[
|
||||
'info_type' => '岗位类型',
|
||||
'info_content' => ''
|
||||
],
|
||||
[
|
||||
'info_type' => '报酬说明',
|
||||
'info_content' => '',
|
||||
],
|
||||
],
|
||||
'user_recv'=>[
|
||||
'劳务报酬',
|
||||
'报销款',
|
||||
'企业补贴',
|
||||
'开工利是',
|
||||
]
|
||||
],
|
||||
[
|
||||
'num'=>4,
|
||||
'title' => '采购货款',
|
||||
'infos' => [
|
||||
[
|
||||
'info_type' => '采购商品名称',
|
||||
'info_content' => ''
|
||||
],
|
||||
],
|
||||
'user_recv'=>[
|
||||
'货款',
|
||||
]
|
||||
],
|
||||
[
|
||||
'num'=>5,
|
||||
'title' => '二手回收',
|
||||
'infos' => [
|
||||
[
|
||||
'info_type' => '回收商品名称',
|
||||
'info_content' => ''
|
||||
],
|
||||
],
|
||||
'user_recv'=>[
|
||||
'二手回收货款',
|
||||
]
|
||||
],
|
||||
[
|
||||
'num'=>6,
|
||||
'title' => '公益补助',
|
||||
'infos' => [
|
||||
[
|
||||
'info_type' => '公益活动名称',
|
||||
'info_content' => ''
|
||||
],
|
||||
[
|
||||
'info_type' => '公益活动备案编号',
|
||||
'info_content' => ''
|
||||
],
|
||||
],
|
||||
'user_recv'=>[
|
||||
'公益补助金',
|
||||
]
|
||||
],
|
||||
[
|
||||
'num'=>7,
|
||||
'title' => '行政补贴',
|
||||
'infos' => [
|
||||
[
|
||||
'info_type' => '补贴类型',
|
||||
'info_content' => ''
|
||||
],
|
||||
],
|
||||
'user_recv'=>[
|
||||
'行政补贴',
|
||||
'行政奖励',
|
||||
]
|
||||
],
|
||||
[
|
||||
'num'=>8,
|
||||
'title' => '保险理赔',
|
||||
'infos' => [
|
||||
[
|
||||
'info_type' => '保险产品备案编号',
|
||||
'info_content' => ''
|
||||
],
|
||||
[
|
||||
'info_type' => '保险名称',
|
||||
'info_content' => ''
|
||||
],
|
||||
[
|
||||
'info_type' => '保险操作单号',
|
||||
'info_content' => ''
|
||||
],
|
||||
],
|
||||
'user_recv'=>[
|
||||
'保险理赔款',
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$data = [];
|
||||
foreach ($config as $k=>$v){
|
||||
$data[$v['num']] = $v;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function getTransferSceneInfo($param){
|
||||
|
||||
$data = [
|
||||
'member_withdraw_info'=>[],
|
||||
'fenxiao_withdraw_info'=>[],
|
||||
'store_withdraw_info'=>[]
|
||||
];
|
||||
if(!isset($param['transfer_v3_type']) || $param['transfer_v3_type'] !=2){
|
||||
return $data;
|
||||
}
|
||||
$config = $this->getTransferSceneConfig();
|
||||
//会员提现场景
|
||||
if(!empty($param['member_withdraw_scene'])){
|
||||
foreach($config[$param['member_withdraw_scene']]['infos'] as $k=>$v){
|
||||
$v['info_content'] = $param['member_withdraw_'.$k] ?? '';
|
||||
$data['member_withdraw_info'][$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
//分销提现场景
|
||||
if(!empty($param['fenxiao_withdraw_scene'])){
|
||||
foreach($config[$param['fenxiao_withdraw_scene']]['infos'] as $k=>$v){
|
||||
$v['info_content'] = $param['fenxiao_withdraw_'.$k] ?? '';
|
||||
$data['fenxiao_withdraw_info'][$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
//店铺提现场景
|
||||
if(!empty($param['store_withdraw_scene'])){
|
||||
foreach($config[$param['store_withdraw_scene']]['infos'] as $k=>$v){
|
||||
$v['info_content'] = $param['store_withdraw_'.$k] ?? '';
|
||||
$data['store_withdraw_info'][$k] = $v;
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
388
addon/wechatpay/model/Pay.php
Executable file
388
addon/wechatpay/model/Pay.php
Executable file
@@ -0,0 +1,388 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\model;
|
||||
|
||||
use addon\shopcomponent\model\Weapp;
|
||||
use app\exception\ApiException;
|
||||
use app\model\order\OrderMessage;
|
||||
use app\model\system\Cron;
|
||||
use app\model\BaseModel;
|
||||
use addon\weapp\model\Config as WeappConfig;
|
||||
use addon\wechat\model\Config as WechatConfig;
|
||||
use app\model\system\Pay as PayModel;
|
||||
use think\facade\Log;
|
||||
use addon\wechatpay\model\Config as WechatPayConfig;
|
||||
/**
|
||||
* 微信支付配置
|
||||
* 版本 1.0.4
|
||||
*/
|
||||
class Pay extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 支付接口实例
|
||||
* @var
|
||||
*/
|
||||
private $app;
|
||||
|
||||
/**
|
||||
* 是否是小程序端
|
||||
* @var int
|
||||
*/
|
||||
private $is_weapp = 0;
|
||||
|
||||
/**
|
||||
* 支付配置
|
||||
* @var array|mixed
|
||||
*/
|
||||
private $config = [];
|
||||
|
||||
/**
|
||||
* 微信支付接口版本
|
||||
* @var string
|
||||
*/
|
||||
private $api = 'v2';
|
||||
|
||||
/**
|
||||
* 站点id
|
||||
* @var
|
||||
*/
|
||||
private $site_id;
|
||||
|
||||
public function __construct($is_weapp = 0, $site_id = 1)
|
||||
{
|
||||
$this->is_weapp = $is_weapp;
|
||||
$this->site_id = $site_id;
|
||||
|
||||
// 支付配置
|
||||
$config_model = new Config();
|
||||
$this->config = $config_model->getPayConfig($site_id)[ 'data' ][ 'value' ];
|
||||
if (empty($this->config)) throw new ApiException(-1, "平台未配置微信支付");
|
||||
|
||||
$this->api = $this->config[ 'api_type' ];
|
||||
$this->config[ 'site_id' ] = $site_id;
|
||||
|
||||
if ($is_weapp == 0) {
|
||||
$wechat_config = ( new WechatConfig() )->getWechatConfig($this->site_id)[ 'data' ][ 'value' ];
|
||||
$this->config[ 'appid' ] = $wechat_config[ 'appid' ] ?? '';
|
||||
} else {
|
||||
$weapp_config = ( new WeappConfig() )->getWeappConfig($this->site_id)[ 'data' ][ 'value' ];
|
||||
$this->config[ 'appid' ] = $weapp_config[ 'appid' ] ?? '';
|
||||
}
|
||||
|
||||
$this->factory();
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例化支付接口
|
||||
*/
|
||||
public function factory()
|
||||
{
|
||||
$class = 'addon\\wechatpay\\model\\' . ucfirst($this->api);
|
||||
if (!class_exists($class)) throw new ApiException(-1, "Class '{$class}' not found");
|
||||
|
||||
try {
|
||||
$this->app = new $class($this->config);
|
||||
} catch (\Exception $e) {
|
||||
Log::write('微信支付配置错误:' . $e->getMessage() . $e->getFile() . $e->getLine());
|
||||
throw new ApiException(-1, $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 生成支付
|
||||
* @param $param
|
||||
*/
|
||||
public function pay($param)
|
||||
{
|
||||
if (!$this->config[ 'pay_status' ]) return $this->error([], '平台未启用微信支付');
|
||||
|
||||
//清除绑定支付数据
|
||||
$pay_model = new PayModel();
|
||||
$clear_res = $pay_model->clearMchPay($param[ "out_trade_no" ], 'wechatpay');
|
||||
if($clear_res['code'] < 0) return $clear_res;
|
||||
|
||||
if ($param[ 'trade_type' ] == 'JSAPI' || $param[ 'trade_type' ] == 'APPLET') {
|
||||
$member_info = model('member')->getInfo([ [ "member_id", "=", $param[ "member_id" ] ] ], 'weapp_openid,wx_openid');
|
||||
if (empty($member_info)) return $this->error(-1, '未获取到会员信息');
|
||||
$param[ 'openid' ] = $this->is_weapp ? $member_info[ 'weapp_openid' ] : $member_info[ 'wx_openid' ];
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $this->app->pay($param);
|
||||
|
||||
//绑定支付数据
|
||||
if($result['code'] >= 0){
|
||||
$pay_model->bindMchPay($param[ "out_trade_no" ], [
|
||||
"pay_type" => 'wechatpay',
|
||||
"is_weapp" => $this->is_weapp,
|
||||
"app_id" => $this->config[ "appid" ],
|
||||
]);
|
||||
}
|
||||
|
||||
// 对视频号订单做处理
|
||||
if ($result[ 'code' ] == 0 && in_array($param[ 'scene' ], [ 1175, 1176, 1177, 1191, 1195 ])) {
|
||||
$weapp_model = new Weapp($param[ 'site_id' ]);
|
||||
$prepay_id = str_replace('prepay_id=', '', $result[ 'data' ][ 'data' ][ 'package' ]);
|
||||
$order_info = $this->getOrderInfo($param[ "out_trade_no" ], $param[ 'openid' ], $prepay_id, $param[ 'scene' ]);
|
||||
$res = $weapp_model->createOrder($order_info);
|
||||
if ($res[ 'code' ] >= 0) {
|
||||
$order_params = [
|
||||
"order_id" => $res[ 'data' ][ 'data' ][ 'order_id' ],
|
||||
"out_order_id" => $res[ 'data' ][ 'data' ][ 'out_order_id' ],
|
||||
"openid" => $param[ "openid" ]
|
||||
];
|
||||
$config = $weapp_model->getPaymentParams($order_params);
|
||||
$result = $this->success([
|
||||
'type' => 'jsapi',
|
||||
'data' => $config[ 'data' ][ 'payment_params' ]
|
||||
]);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
} catch (\Exception $e) {
|
||||
Log::write('微信支付接口调用失败,请求参数:' . json_encode($param) . ' 错误原因:' . $e->getMessage() . $e->getFile() . $e->getLine());
|
||||
return $this->error([], '微信支付接口调用失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付异步通知
|
||||
* @return mixed
|
||||
*/
|
||||
public function payNotify()
|
||||
{
|
||||
return $this->app->payNotify();
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭支付
|
||||
* @param $param
|
||||
* @return array
|
||||
*/
|
||||
public function close($param)
|
||||
{
|
||||
try {
|
||||
return $this->app->payClose($param);
|
||||
} catch (\Exception $e) {
|
||||
Log::write('微信订单关闭失败,请求参数:' . json_encode($param) . ' 错误原因:' . $e->getMessage() . $e->getFile() . $e->getLine());
|
||||
return $this->error([], '微信订单关闭失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信原路退款
|
||||
* @param $param
|
||||
* @return array
|
||||
*/
|
||||
public function refund($param)
|
||||
{
|
||||
if (!$this->config[ 'refund_status' ]) return $this->error([], '平台未启用微信退款');
|
||||
|
||||
try {
|
||||
$mch_info = empty($param[ "pay_info" ][ 'mch_info' ]) ? [] : json_decode($param[ "pay_info" ][ 'mch_info' ], true);
|
||||
$this->config[ "appid" ] = $mch_info[ "app_id" ] ?? $this->config[ "appid" ];//替换为商户自己的appid
|
||||
$this->factory();
|
||||
|
||||
return $this->app->refund($param);
|
||||
} catch (\Exception $e) {
|
||||
Log::write('微信退款失败,请求参数:' . json_encode($param) . ' 错误原因:' . $e->getMessage() . $e->getFile() . $e->getLine());
|
||||
return $this->error(['file' => $e->getFile(),'line'=>$e->getLine(),'message'=>$e->getMessage()], '微信退款失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信转账到零钱
|
||||
* @param array $param
|
||||
* @return array
|
||||
* @throws ApiException
|
||||
*/
|
||||
public function transfer(array $param)
|
||||
{
|
||||
if (!$this->config[ 'transfer_status' ]) return $this->error([], '平台未启用微信转账');
|
||||
if ($this->api != $this->config[ 'transfer_type' ]) {
|
||||
$this->api = $this->config[ 'transfer_type' ];
|
||||
$this->factory();
|
||||
}
|
||||
try {
|
||||
$result = $this->app->transfer($param);
|
||||
return $result;
|
||||
} catch (\Exception $e) {
|
||||
Log::write('微信转账接口调用失败,错误原因:' . $e->getMessage() . $e->getFile() . $e->getLine());
|
||||
return $this->error([], '微信转账接口调用失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付所需订单信息
|
||||
* @param $out_trade_no
|
||||
* @param $openid
|
||||
* @param $prepay_id
|
||||
* @param int $scene
|
||||
* @return array
|
||||
*/
|
||||
private function getOrderInfo($out_trade_no, $openid, $prepay_id, $scene = 0)
|
||||
{
|
||||
$order_info = model('order')->getInfo([ [ 'out_trade_no', '=', $out_trade_no ] ], 'site_id,create_time,order_id,order_type,member_id,order_money,delivery_money,name,full_address,mobile,delivery_store_info,delivery_store_name');
|
||||
$data = [
|
||||
'create_time' => date("Y-m-d H:i:s", $order_info[ 'create_time' ]),
|
||||
'out_order_id' => $order_info[ 'order_id' ],
|
||||
'openid' => $openid,
|
||||
'path' => ( new OrderMessage() )->handleUrl($order_info[ 'order_type' ], $order_info[ 'order_id' ]),
|
||||
'out_user_id' => $order_info[ 'member_id' ],
|
||||
'order_detail' => [
|
||||
'product_infos' => [],
|
||||
'pay_info' => [
|
||||
'pay_method' => '微信支付',
|
||||
'prepay_id' => $prepay_id,
|
||||
'prepay_time' => date('Y-m-d H:i:s', time())
|
||||
],
|
||||
'price_info' => [
|
||||
'order_price' => $order_info[ 'order_money' ] * 100,
|
||||
'freight' => $order_info[ 'delivery_money' ] * 100,
|
||||
'discounted_price' => 0,
|
||||
'additional_price' => 0
|
||||
]
|
||||
],
|
||||
'delivery_detail' => [],
|
||||
'fund_type' => 1,
|
||||
'expire_time' => time() + 3600
|
||||
];
|
||||
// 配送方式
|
||||
switch ( $order_info[ 'order_type' ] ) {
|
||||
case 2:
|
||||
$delivery_store_info = json_decode($order_info[ 'delivery_store_info' ], true);
|
||||
$data[ 'delivery_detail' ][ 'delivery_type' ] = 4; //用户自提
|
||||
$data[ 'address_info' ] = [
|
||||
'receiver_name' => $order_info[ 'delivery_store_name' ],
|
||||
'detailed_address' => $delivery_store_info[ 'full_address' ],
|
||||
'tel_number' => $delivery_store_info[ 'telphone' ]
|
||||
];
|
||||
break;
|
||||
case 3:
|
||||
$data[ 'delivery_detail' ][ 'delivery_type' ] = 3; //线下配送
|
||||
break;
|
||||
case 4:
|
||||
$data[ 'delivery_detail' ][ 'delivery_type' ] = 2; //无需快递
|
||||
break;
|
||||
default:
|
||||
$data[ 'delivery_detail' ][ 'delivery_type' ] = 1; //正常快递
|
||||
$data[ 'address_info' ] = [
|
||||
'receiver_name' => $order_info[ 'name' ],
|
||||
'detailed_address' => $order_info[ 'full_address' ],
|
||||
'tel_number' => $order_info[ 'mobile' ]
|
||||
];
|
||||
break;
|
||||
}
|
||||
$order_goods = model('order_goods')->getList([ [ 'order_id', '=', $order_info[ 'order_id' ] ] ], 'goods_id,sku_id,num,price,sku_name,sku_image');
|
||||
foreach ($order_goods as $goods) {
|
||||
$data['order_detail']['product_infos'][] = [
|
||||
'out_product_id' => $goods['goods_id'],
|
||||
'out_sku_id' => $goods['sku_id'],
|
||||
'product_cnt' => numberFormat($goods['num']),
|
||||
'sale_price' => $goods['price'] * 100,
|
||||
'path' => 'pages/goods/detail?sku_id=' . $goods['sku_id'],
|
||||
'title' => $goods['sku_name'],
|
||||
'head_img' => img($goods['sku_image']),
|
||||
'sku_real_price' => $goods['price'] * 100
|
||||
];
|
||||
}
|
||||
$video_number_scene = [ 1175, 1176, 1177, 1191, 1195 ]; // 视频号场景值
|
||||
if (in_array($scene, $video_number_scene)) model('order')->update([ 'is_video_number' => 1 ], [ [ 'order_id', '=', $order_info[ 'order_id' ] ] ]);
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 付款码支付
|
||||
* @param $param
|
||||
* @return array|mixed|void
|
||||
* @throws ApiException
|
||||
*/
|
||||
public function micropay($param)
|
||||
{
|
||||
if (!$this->config[ 'pay_status' ]) return $this->error([], '平台未启用微信支付');
|
||||
|
||||
if ($this->api != 'v2') {
|
||||
$this->api = 'v2';
|
||||
$this->factory();
|
||||
}
|
||||
|
||||
try {
|
||||
$pay_model = new PayModel();
|
||||
|
||||
//清空绑定支付数据
|
||||
$clear_res = $pay_model->clearMchPay($param[ "out_trade_no" ], 'wechatpay');
|
||||
if($clear_res['code'] < 0) return $clear_res;
|
||||
//绑定支付数据
|
||||
$pay_model->bindMchPay($param[ "out_trade_no" ], [
|
||||
"pay_type" => 'wechatpay',
|
||||
"app_id" => $this->config[ "appid" ],
|
||||
]);
|
||||
|
||||
$res = $this->app->micropay($param);
|
||||
if ($res[ 'code' ] != 0) {
|
||||
if (isset($res['data']['err_code'])) {
|
||||
if ($res['data']['err_code'] == 'TRADE_ERROR'){
|
||||
(new PayModel())->edit(['pay_status' => PayModel::PAY_STATUS_CANCEL], ['out_trade_no' => $param[ "out_trade_no" ] ]);
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
$res = $pay_model->onlinePay($param[ 'out_trade_no' ], 'wechatpay', $res[ 'data' ][ 'transaction_id' ], 'wechatpay');
|
||||
return $res;
|
||||
} catch (\Exception $e) {
|
||||
Log::write('微信付款码支付失败,请求参数:' . json_encode($param) . ' 错误原因:' . $e->getMessage() . $e->getFile() . $e->getLine());
|
||||
return $this->error([], '微信付款码支付失败');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 微信转账到零钱新版本回调
|
||||
*/
|
||||
public function transferNotify()
|
||||
{
|
||||
if (!$this->config[ 'transfer_status' ]) return $this->error([], '平台未启用微信转账');
|
||||
if ($this->api != $this->config[ 'transfer_type' ]) {
|
||||
$this->api = $this->config[ 'transfer_type' ];
|
||||
$this->factory();
|
||||
}
|
||||
try {
|
||||
return $this->app->transferNotify();
|
||||
} catch (\Exception $e) {
|
||||
Log::write('微信转账接口回调处理失败,错误原因:' . $e->getMessage() . $e->getFile() . $e->getLine());
|
||||
return $this->error([], '微信转账接口回调处理失败');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 撤销微信转账
|
||||
* @param $out_bill_no 商户单号
|
||||
* @return array
|
||||
*/
|
||||
|
||||
public function transferCancel($out_bill_no){
|
||||
|
||||
if (!$this->config[ 'transfer_status' ]) return $this->error([], '平台未启用微信转账');
|
||||
if ($this->api != $this->config[ 'transfer_type' ]) {
|
||||
$this->api = $this->config[ 'transfer_type' ];
|
||||
$this->factory();
|
||||
}
|
||||
try {
|
||||
return $this->app->transferCancel($out_bill_no);
|
||||
} catch (\Exception $e) {
|
||||
Log::write('微信转账接口回调处理失败,错误原因:' . $e->getMessage() . $e->getFile() . $e->getLine());
|
||||
return $this->error([], '微信转账接口回调处理失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
280
addon/wechatpay/model/V2.php
Executable file
280
addon/wechatpay/model/V2.php
Executable file
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use app\model\system\Cron;
|
||||
use app\model\system\Pay as PayCommon;
|
||||
use app\model\upload\Upload;
|
||||
use EasyWeChat\Factory;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 微信支付v2支付
|
||||
* 版本 1.0.4
|
||||
*/
|
||||
class V2 extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 微信支付配置
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* 支付实例
|
||||
* @var
|
||||
*/
|
||||
private $app;
|
||||
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
|
||||
$this->app = Factory::payment([
|
||||
'app_id' => $config[ 'appid' ], //应用id
|
||||
'mch_id' => $config[ "mch_id" ] ?? '', //商户号
|
||||
'key' => $config[ "pay_signkey" ] ?? '', // API 密钥
|
||||
// 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
|
||||
'cert_path' => realpath($config[ "apiclient_cert" ]) ?? '', // apiclient_cert.pem XXX: 绝对路径!!!!
|
||||
'key_path' => realpath($config[ "apiclient_key" ]) ?? '', // apiclient_key.pem XXX: 绝对路径!!!!
|
||||
'notify_url' => '',// 你也可以在下单时单独设置来想覆盖它
|
||||
'response_type' => 'array',
|
||||
'log' => [
|
||||
'level' => 'debug',
|
||||
'permission' => 0777,
|
||||
'file' => 'runtime/log/wechat/easywechat.logs',
|
||||
],
|
||||
'sandbox' => false, // 设置为 false 或注释则关闭沙箱模式
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付
|
||||
* @param array $param
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function pay(array $param)
|
||||
{
|
||||
$data = [
|
||||
'body' => str_sub($param[ "pay_body" ], 15),
|
||||
'out_trade_no' => $param[ "out_trade_no" ],
|
||||
'total_fee' => $param[ "pay_money" ] * 100,
|
||||
'notify_url' => $param[ "notify_url" ],
|
||||
'trade_type' => $param[ "trade_type" ] == 'APPLET' ? 'JSAPI' : $param[ "trade_type" ]
|
||||
];
|
||||
if ($param[ 'trade_type' ] == 'JSAPI' || $param[ 'trade_type' ] == 'APPLET') $data[ 'openid' ] = $param[ 'openid' ];
|
||||
$result = $this->app->order->unify($data);
|
||||
|
||||
if ($result[ "return_code" ] == 'FAIL') return $this->error([], $result[ "return_msg" ]);
|
||||
if ($result[ "result_code" ] == 'FAIL') return $this->error([], $result[ "err_code_des" ]);
|
||||
|
||||
$return = [];
|
||||
switch ( $param[ "trade_type" ] ) {
|
||||
case 'JSAPI' ://微信支付 或小程序支付
|
||||
$return = [
|
||||
"type" => "jsapi",
|
||||
"data" => $this->app->jssdk->sdkConfig($result[ 'prepay_id' ], false)
|
||||
];
|
||||
break;
|
||||
case 'APPLET' ://微信支付 或小程序支付
|
||||
$return = [
|
||||
"type" => "jsapi",
|
||||
"data" => $this->app->jssdk->bridgeConfig($result[ 'prepay_id' ], false)
|
||||
];
|
||||
break;
|
||||
case 'NATIVE' :
|
||||
$upload_model = new Upload($param[ 'site_id' ]);
|
||||
$qrcode_result = $upload_model->qrcode($result[ 'code_url' ]);
|
||||
$return = [
|
||||
"type" => "qrcode",
|
||||
"qrcode" => $qrcode_result[ 'data' ] ?? ''
|
||||
];
|
||||
break;
|
||||
case 'MWEB' ://H5支付
|
||||
$return = [
|
||||
"type" => "url",
|
||||
"url" => $result[ 'mweb_url' ]
|
||||
];
|
||||
break;
|
||||
case 'APP' :
|
||||
$config = $this->app->jssdk->appConfig($result[ 'prepay_id' ]);
|
||||
$return = [
|
||||
"type" => "app",
|
||||
"data" => $config
|
||||
];
|
||||
break;
|
||||
}
|
||||
return $this->success($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步回调
|
||||
*/
|
||||
public function payNotify()
|
||||
{
|
||||
$response = $this->app->handlePaidNotify(function($message, $fail) {
|
||||
$pay_common = new PayCommon();
|
||||
if ($message[ 'return_code' ] === 'SUCCESS') {
|
||||
// return_code 表示通信状态,不代表支付状态
|
||||
if ($message[ 'result_code' ] === 'SUCCESS') {
|
||||
// 判断支付金额是否等于支付单据的金额
|
||||
$pay_info = $pay_common->getPayInfo($message[ 'out_trade_no' ])[ 'data' ];
|
||||
if (empty($pay_info)) return $fail('通信失败,请稍后再通知我');
|
||||
if ($message[ 'total_fee' ] != round($pay_info[ 'pay_money' ] * 100)) return;
|
||||
// 用户是否支付成功
|
||||
$pay_common->onlinePay($message[ 'out_trade_no' ], "wechatpay", $message[ "transaction_id" ], "wechatpay");
|
||||
}
|
||||
} else {
|
||||
return $fail('通信失败,请稍后再通知我');
|
||||
}
|
||||
return true;
|
||||
});
|
||||
$response->send();
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭支付单据
|
||||
* @param array $param
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function payClose(array $param)
|
||||
{
|
||||
$query_result = $this->app->order->queryByOutTradeNumber($param[ "out_trade_no" ]);
|
||||
if($query_result['return_code'] == 'SUCCESS' && $query_result['result_code'] == 'SUCCESS' && $query_result['trade_state'] != 'CLOSED'){
|
||||
if($query_result['trade_state'] == 'SUCCESS'){
|
||||
return $this->error([ 'is_paid' => 1, 'pay_type' => 'wechatpay'], '微信已支付不可关闭');
|
||||
}
|
||||
$close_result = $this->app->order->close($param[ "out_trade_no" ]);
|
||||
if($close_result['return_code'] != 'SUCCESS' || $close_result['result_code'] != 'SUCCESS'){
|
||||
return $this->error($close_result, $close_result[ 'return_msg' ]);
|
||||
}
|
||||
}
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款
|
||||
* @param array $param
|
||||
*/
|
||||
public function refund(array $param)
|
||||
{
|
||||
$pay_info = $param[ "pay_info" ];
|
||||
$refund_no = $param[ "refund_no" ];
|
||||
$total_fee = round($pay_info[ "pay_money" ] * 100);
|
||||
$refund_fee = round($param[ "refund_fee" ] * 100);
|
||||
|
||||
$result = $this->app->refund->byOutTradeNumber($pay_info[ "out_trade_no" ], $refund_no, $total_fee, $refund_fee, []);
|
||||
//调用失败
|
||||
if ($result[ "return_code" ] == 'FAIL') return $this->error([], $result[ "return_msg" ]);
|
||||
if ($result[ "result_code" ] == 'FAIL') return $this->error([], $result[ "err_code_des" ]);
|
||||
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转账
|
||||
* @param array $param
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function transfer(array $param)
|
||||
{
|
||||
$data = [
|
||||
'partner_trade_no' => $param[ 'out_trade_no' ], // 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号)
|
||||
'openid' => $param[ 'account_number' ],
|
||||
'check_name' => 'FORCE_CHECK', // NO_CHECK:不校验真实姓名, FORCE_CHECK:强校验真实姓名
|
||||
're_user_name' => $param[ 'real_name' ], // 如果 check_name 设置为FORCE_CHECK,则必填用户真实姓名
|
||||
'amount' => round($param[ 'amount' ] * 100, 2), // 转账金额
|
||||
'desc' => $param[ 'desc' ]
|
||||
];
|
||||
$res = $this->app->transfer->toBalance($data);
|
||||
if ($res[ 'return_code' ] == 'SUCCESS') {
|
||||
if ($res[ 'result_code' ] == 'SUCCESS') {
|
||||
return $this->success([
|
||||
'out_trade_no' => $res[ 'partner_trade_no' ], // 商户交易号
|
||||
'payment_no' => $res[ 'payment_no' ], // 微信付款单号
|
||||
'payment_time' => $res[ 'payment_time' ] // 付款成功时间
|
||||
]);
|
||||
} else {
|
||||
return $this->error([], $res[ 'err_code_des' ]);
|
||||
}
|
||||
} else {
|
||||
return $this->error([], $res[ 'return_msg' ]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 付款码支付
|
||||
* @param array $param
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function micropay(array $param)
|
||||
{
|
||||
$data = [
|
||||
'body' => str_sub($param[ "pay_body" ], 15),
|
||||
'out_trade_no' => $param[ "out_trade_no" ],
|
||||
'total_fee' => $param[ "pay_money" ] * 100,
|
||||
'auth_code' => $param[ "auth_code" ]
|
||||
];
|
||||
$result = $this->app->base->pay($data);
|
||||
if ($result[ 'return_code' ] == 'FAIL') {
|
||||
return $this->error([], $result[ 'return_msg' ]);
|
||||
}
|
||||
if ($result[ 'result_code' ] == 'FAIL') {
|
||||
if ($result[ 'err_code' ] != 'USERPAYING') {
|
||||
( new Cron() )->addCron(1, 0, "查询付款码支付结果", "PayOrderQuery", time() + 3, $param[ 'id' ]);
|
||||
}
|
||||
return $this->error($result, $result[ 'err_code_des' ]);
|
||||
}
|
||||
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单支付结果
|
||||
* @param $pay_info
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
*/
|
||||
public function orderQuery($pay_info)
|
||||
{
|
||||
$result = $this->app->order->queryByOutTradeNumber($pay_info[ 'out_trade_no' ]);
|
||||
Log::write('查询微信支付订单' . json_encode($result));
|
||||
if ($result[ 'return_code' ] == 'FAIL') {
|
||||
return $this->error([], $result[ 'return_msg' ]);
|
||||
}
|
||||
if ($result[ 'result_code' ] == 'SUCCESS') {
|
||||
if ($result[ 'trade_state' ] == 'SUCCESS') {
|
||||
( new PayCommon() )->onlinePay($pay_info[ 'out_trade_no' ], 'wechatpay', $result[ 'transaction_id' ], 'wechatpay');
|
||||
} else if (in_array($result[ 'trade_state' ], [ 'NOTPAY', 'USERPAYING', 'ACCEPT' ])) {
|
||||
$cron_model = new Cron();
|
||||
$cron_model->deleteCron([ [ 'event', '=', 'PayOrderQuery' ], [ 'relate_id', '=', $pay_info[ 'id' ] ] ]);
|
||||
$cron_model->addCron(1, 0, "查询付款码支付结果", "PayOrderQuery", time() + 3, $pay_info[ 'id' ]);
|
||||
}else if($result[ 'trade_state' ] == 'PAYERROR'){
|
||||
(new PayCommon())->edit(['pay_status' => PayCommon::PAY_STATUS_CANCEL], ['out_trade_no' => $pay_info[ "out_trade_no" ] ]);
|
||||
}
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
}
|
||||
849
addon/wechatpay/model/V3.php
Executable file
849
addon/wechatpay/model/V3.php
Executable file
@@ -0,0 +1,849 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\model;
|
||||
|
||||
use app\exception\ApiException;
|
||||
use app\model\BaseModel;
|
||||
use app\model\system\Cron;
|
||||
use app\model\system\Pay as PayCommon;
|
||||
use app\model\system\PayTransfer;
|
||||
use app\model\upload\Upload;
|
||||
use think\exception\HttpException;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Log;
|
||||
use WeChatPay\Builder;
|
||||
use WeChatPay\ClientDecoratorInterface;
|
||||
use WeChatPay\Crypto\AesGcm;
|
||||
use WeChatPay\Crypto\Rsa;
|
||||
use WeChatPay\Formatter;
|
||||
use WeChatPay\Util\PemUtil;
|
||||
use GuzzleHttp\Middleware;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use addon\wechatpay\model\Config as WechatPayConfig;
|
||||
|
||||
/**
|
||||
* 微信支付v3支付
|
||||
* 版本 1.0.4
|
||||
*/
|
||||
class V3 extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 应用实例
|
||||
* @var \WeChatPay\BuilderChainable
|
||||
*/
|
||||
private $app;
|
||||
|
||||
// 平台证书实例
|
||||
private $plateform_certificate_instance;
|
||||
|
||||
// 平台证书序列号
|
||||
private $plateform_certificate_serial;
|
||||
|
||||
/**
|
||||
* 微信支付配置
|
||||
*/
|
||||
private $config;
|
||||
|
||||
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
|
||||
$merchant_certificate_instance = PemUtil::loadCertificate(realpath($config['apiclient_cert']));
|
||||
// 证书序列号
|
||||
$merchant_certificate_serial = PemUtil::parseCertificateSerialNo($merchant_certificate_instance);
|
||||
// var_dump($this->config);
|
||||
//平台证书和序列号处理
|
||||
//plateform_cert 是系统自动生成的 plateform_certificate 是直接上传的
|
||||
if (empty($this->config['plateform_certificate_serial'])) {
|
||||
// 检测平台证书是否存在
|
||||
if (empty($config['plateform_cert']) || !is_file($config['plateform_cert'])) {
|
||||
$create_res = $this->certificates();
|
||||
if ($create_res['code'] != 0) throw new ApiException(-1, $create_res['message'] ?? "微信支付配置错误");
|
||||
// 保存平台证书
|
||||
$this->config['plateform_cert'] = $create_res['data']['cert_path'];
|
||||
(new Config())->setPayConfig($this->config, $this->config['site_id']);
|
||||
}
|
||||
// 加载平台证书
|
||||
$this->plateform_certificate_instance = PemUtil::loadCertificate(realpath($this->config['plateform_cert']));
|
||||
// 平台证书序列号
|
||||
$this->plateform_certificate_serial = PemUtil::parseCertificateSerialNo($this->plateform_certificate_instance);
|
||||
} else {
|
||||
// 加载平台证书
|
||||
$this->plateform_certificate_instance = file_get_contents(realpath($this->config['plateform_certificate']));
|
||||
// 平台证书序列号
|
||||
$this->plateform_certificate_serial = $this->config['plateform_certificate_serial'];
|
||||
// 具体业务有很多需要用这个字段,值与新字段保持相同
|
||||
$this->config[ 'plateform_cert' ] = $this->config[ 'plateform_certificate' ];
|
||||
}
|
||||
|
||||
$this->app = Builder::factory([
|
||||
// 商户号
|
||||
'mchid' => $config['mch_id'],
|
||||
// 商户证书序列号
|
||||
'serial' => $merchant_certificate_serial,
|
||||
// 商户API私钥
|
||||
'privateKey' => PemUtil::loadPrivateKey(realpath($config['apiclient_key'])),
|
||||
'certs' => [
|
||||
$this->plateform_certificate_serial => $this->plateform_certificate_instance
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成平台证书
|
||||
*/
|
||||
private function certificates()
|
||||
{
|
||||
try {
|
||||
$merchant_certificate_instance = PemUtil::loadCertificate(realpath($this->config['apiclient_cert']));
|
||||
// 证书序列号
|
||||
$merchant_certificate_serial = PemUtil::parseCertificateSerialNo($merchant_certificate_instance);
|
||||
|
||||
$certs = ['any' => null];
|
||||
$app = Builder::factory([
|
||||
// 商户号
|
||||
'mchid' => $this->config['mch_id'],
|
||||
// 商户证书序列号
|
||||
'serial' => $merchant_certificate_serial,
|
||||
// 商户API私钥
|
||||
'privateKey' => PemUtil::loadPrivateKey(realpath($this->config['apiclient_key'])),
|
||||
'certs' => &$certs
|
||||
]);
|
||||
|
||||
$stack = $app->getDriver()->select(ClientDecoratorInterface::JSON_BASED)->getConfig('handler');
|
||||
$stack->after('verifier', Middleware::mapResponse(self::certsInjector($this->config['v3_pay_signkey'], $certs)), 'injector');
|
||||
$stack->before('verifier', Middleware::mapResponse(self::certsRecorder((string)dirname($this->config['apiclient_key']), $certs)), 'recorder');
|
||||
|
||||
$param = [
|
||||
'url' => '/v3/certificates',
|
||||
'timestamp' => (string)Formatter::timestamp(),
|
||||
'noncestr' => uniqid()
|
||||
];
|
||||
$resp = $app->chain("v3/certificates")
|
||||
->get([
|
||||
'headers' => [
|
||||
'Authorization' => Rsa::sign(
|
||||
Formatter::joinedByLineFeed(...array_values($param)),
|
||||
Rsa::from('file://' . realpath($this->config['apiclient_key']))
|
||||
)
|
||||
]
|
||||
]);
|
||||
$result = json_decode($resp->getBody()->getContents(), true);
|
||||
$file_path = dirname($this->config['apiclient_key']) . '/plateform_cert.pem';
|
||||
return $this->success(['cert_path' => $file_path]);
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||||
$result = json_decode($e->getResponse()->getBody()->getContents(), true);
|
||||
return $this->error($result, $result['message']);
|
||||
} else {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function certsInjector(string $apiv3Key, array &$certs): callable
|
||||
{
|
||||
return static function (ResponseInterface $response) use ($apiv3Key, &$certs): ResponseInterface {
|
||||
$body = (string)$response->getBody();
|
||||
/** @var object{data:array<object{encrypt_certificate:object{serial_no:string,nonce:string,associated_data:string}}>} $json */
|
||||
$json = \json_decode($body);
|
||||
$data = \is_object($json) && isset($json->data) && \is_array($json->data) ? $json->data : [];
|
||||
\array_map(static function ($row) use ($apiv3Key, &$certs) {
|
||||
$cert = $row->encrypt_certificate;
|
||||
$certs[$row->serial_no] = AesGcm::decrypt($cert->ciphertext, $apiv3Key, $cert->nonce, $cert->associated_data);
|
||||
}, $data);
|
||||
|
||||
return $response;
|
||||
};
|
||||
}
|
||||
|
||||
private static function certsRecorder(string $outputDir, array &$certs): callable
|
||||
{
|
||||
return static function (ResponseInterface $response) use ($outputDir, &$certs): ResponseInterface {
|
||||
$body = (string)$response->getBody();
|
||||
/** @var object{data:array<object{effective_time:string,expire_time:string:serial_no:string}>} $json */
|
||||
$json = \json_decode($body);
|
||||
$data = \is_object($json) && isset($json->data) && \is_array($json->data) ? $json->data : [];
|
||||
\array_walk($data, static function ($row, $index, $certs) use ($outputDir) {
|
||||
$serialNo = $row->serial_no;
|
||||
$outpath = $outputDir . \DIRECTORY_SEPARATOR . 'plateform_cert.pem';
|
||||
\file_put_contents($outpath, $certs[$serialNo]);
|
||||
}, $certs);
|
||||
|
||||
return $response;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付
|
||||
* @param array $param
|
||||
* @return array
|
||||
*/
|
||||
public function pay(array $param)
|
||||
{
|
||||
$self = $this;
|
||||
$site_id = $param['site_id'];
|
||||
$data = [
|
||||
'json' => [
|
||||
'appid' => $this->config['appid'],
|
||||
'mchid' => $this->config['mch_id'],
|
||||
'description' => str_sub($param["pay_body"], 15),
|
||||
'out_trade_no' => $param["out_trade_no"],
|
||||
'notify_url' => $param["notify_url"],
|
||||
'amount' => [
|
||||
'total' => round($param["pay_money"] * 100)
|
||||
]
|
||||
]
|
||||
];
|
||||
switch ($param["trade_type"]) {
|
||||
case 'JSAPI':
|
||||
$data['json']['payer'] = ['openid' => $param['openid']];
|
||||
$data['trade_type'] = 'jsapi';
|
||||
$data['callback'] = function ($result) use ($self) {
|
||||
return success(0, '', [
|
||||
"type" => "jsapi",
|
||||
"data" => $self->jsskdConfig($result['prepay_id'])
|
||||
]);
|
||||
};
|
||||
break;
|
||||
case 'APPLET':
|
||||
$data['json']['payer'] = ['openid' => $param['openid']];
|
||||
$data['trade_type'] = 'jsapi';
|
||||
$data['callback'] = function ($result) use ($self) {
|
||||
return success(0, '', [
|
||||
"type" => "jsapi",
|
||||
"data" => $self->jsskdConfig($result['prepay_id'])
|
||||
]);
|
||||
};
|
||||
break;
|
||||
case 'NATIVE':
|
||||
$data['trade_type'] = 'native';
|
||||
$data['callback'] = function ($result) use ($site_id) {
|
||||
$upload_model = new Upload($site_id);
|
||||
$qrcode_result = $upload_model->qrcode($result['code_url']);
|
||||
return success(0, '', [
|
||||
"type" => "qrcode",
|
||||
"qrcode" => $qrcode_result['data'] ?? ''
|
||||
]);
|
||||
};
|
||||
break;
|
||||
case 'MWEB':
|
||||
$data['trade_type'] = 'h5';
|
||||
$data['json']['scene_info'] = [
|
||||
'payer_client_ip' => request()->ip(),
|
||||
'h5_info' => [
|
||||
'type' => 'Wap'
|
||||
]
|
||||
];
|
||||
$data['callback'] = function ($result) {
|
||||
return success(0, '', [
|
||||
"type" => "url",
|
||||
"url" => $result['h5_url']
|
||||
]);
|
||||
};
|
||||
break;
|
||||
case 'APP':
|
||||
$data['trade_type'] = 'app';
|
||||
$data['callback'] = function ($result) use ($self) {
|
||||
return success(0, '', [
|
||||
"type" => "app",
|
||||
"data" => $self->appConfig($result['prepay_id'])
|
||||
]);
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
$result = $this->unify($data);
|
||||
if ($result['code'] != 0) return $result;
|
||||
|
||||
$result = $data['callback']($result['data']);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一下单接口
|
||||
* @param array $param
|
||||
*/
|
||||
public function unify(array $param)
|
||||
{
|
||||
try {
|
||||
$resp = $this->app->chain('v3/pay/transactions/' . $param['trade_type'])->post([
|
||||
'json' => $param['json'],
|
||||
'headers' => [
|
||||
'Wechatpay-Serial' => $this->plateform_certificate_serial
|
||||
]
|
||||
]);
|
||||
$result = json_decode($resp->getBody()->getContents(), true);
|
||||
return $this->success($result);
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||||
$result = json_decode($e->getResponse()->getBody()->getContents(), true);
|
||||
$result = json_decode($e->getMessage(), true);
|
||||
return $this->error($result, $result['message']);
|
||||
} else {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成支付配置
|
||||
* @param string $prepay_id
|
||||
* @return array
|
||||
*/
|
||||
private function jsskdConfig(string $prepay_id)
|
||||
{
|
||||
$param = [
|
||||
'appId' => $this->config['appid'],
|
||||
'timeStamp' => (string)Formatter::timestamp(),
|
||||
'nonceStr' => uniqid(),
|
||||
'package' => "prepay_id=$prepay_id"
|
||||
];
|
||||
$param += ['paySign' => Rsa::sign(
|
||||
Formatter::joinedByLineFeed(...array_values($param)),
|
||||
Rsa::from('file://' . realpath($this->config['apiclient_key']))
|
||||
), 'signType' => 'RSA'];
|
||||
return $param;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成支付配置
|
||||
* @param string $prepay_id
|
||||
* @return array
|
||||
*/
|
||||
private function appConfig(string $prepay_id)
|
||||
{
|
||||
$param = [
|
||||
'appid' => $this->config['appid'],
|
||||
'timestamp' => (string)Formatter::timestamp(),
|
||||
'noncestr' => uniqid(),
|
||||
'prepayid' => $prepay_id
|
||||
];
|
||||
$param += [
|
||||
'sign' => Rsa::sign(
|
||||
Formatter::joinedByLineFeed(...array_values($param)),
|
||||
Rsa::from('file://' . realpath($this->config['apiclient_key']))
|
||||
),
|
||||
'package' => 'Sign=WXPay',
|
||||
'partnerid' => $this->config['mch_id']
|
||||
];
|
||||
return $param;
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步回调
|
||||
*/
|
||||
public function payNotify()
|
||||
{
|
||||
$inWechatpaySignature = request()->header('Wechatpay-Signature'); // 从请求头中拿到 签名
|
||||
$inWechatpayTimestamp = request()->header('Wechatpay-Timestamp'); // 从请求头中拿到 时间戳
|
||||
$inWechatpaySerial = request()->header('Wechatpay-Serial'); // 从请求头中拿到 时间戳
|
||||
$inWechatpayNonce = request()->header('Wechatpay-Nonce'); // 从请求头中拿到 时间戳
|
||||
$inBody = file_get_contents('php://input');
|
||||
|
||||
$platformPublicKeyInstance = Rsa::from('file://' . realpath($this->config['plateform_cert']), Rsa::KEY_TYPE_PUBLIC);
|
||||
|
||||
$timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
|
||||
$verifiedStatus = Rsa::verify(
|
||||
// 构造验签名串
|
||||
Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, file_get_contents('php://input')),
|
||||
$inWechatpaySignature,
|
||||
$platformPublicKeyInstance
|
||||
);
|
||||
if ($timeOffsetStatus && $verifiedStatus) {
|
||||
// 转换通知的JSON文本消息为PHP Array数组
|
||||
$inBodyArray = (array)json_decode($inBody, true);
|
||||
// 使用PHP7的数据解构语法,从Array中解构并赋值变量
|
||||
['resource' => [
|
||||
'ciphertext' => $ciphertext,
|
||||
'nonce' => $nonce,
|
||||
'associated_data' => $aad
|
||||
]] = $inBodyArray;
|
||||
// 加密文本消息解密
|
||||
$inBodyResource = AesGcm::decrypt($ciphertext, $this->config['v3_pay_signkey'], $nonce, $aad);
|
||||
// 把解密后的文本转换为PHP Array数组
|
||||
$message = json_decode($inBodyResource, true);
|
||||
Log::write('message' . $inBodyResource);
|
||||
// 交易状态为成功
|
||||
if (isset($message['trade_state']) && $message['trade_state'] == 'SUCCESS') {
|
||||
if (isset($message['out_trade_no'])) {
|
||||
$pay_common = new PayCommon();
|
||||
$pay_info = $pay_common->getPayInfo($message['out_trade_no'])['data'];
|
||||
if (empty($pay_info)) return;
|
||||
if ($message['amount']['total'] != round($pay_info['pay_money'] * 100)) return;
|
||||
// 用户是否支付成功
|
||||
$pay_common->onlinePay($message['out_trade_no'], "wechatpay", $message["transaction_id"], "wechatpay");
|
||||
header('', '', 200);
|
||||
}
|
||||
} else {
|
||||
$this->payNotifyFail(501, 'FAIL', '没有trade_state字段或不是SUCCESS');
|
||||
}
|
||||
} else {
|
||||
$this->payNotifyFail(401, 'FAIL', '验签失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付回调失败处理
|
||||
* @param $response_code
|
||||
* @param $code
|
||||
* @param $message
|
||||
*/
|
||||
protected function payNotifyFail($response_code, $code, $message)
|
||||
{
|
||||
//记录日志
|
||||
Log::write('V3支付回调失败');
|
||||
Log::write(['response_code' => $response_code, 'code' => $code, 'message' => $message]);
|
||||
|
||||
// 设置HTTP响应头
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
http_response_code($response_code); // 或400等适当的状态码
|
||||
// 构造错误响应
|
||||
$errorResponse = [
|
||||
'code' => $code,
|
||||
'message' => $message
|
||||
];
|
||||
// 输出JSON响应
|
||||
echo json_encode($errorResponse, JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付单据关闭
|
||||
* @param array $param
|
||||
* @return array
|
||||
*/
|
||||
public function payClose(array $param)
|
||||
{
|
||||
$get_res = $this->get($param['out_trade_no']);
|
||||
if ($get_res['code'] >= 0 && $get_res['data']['trade_state'] != 'CLOSED') {
|
||||
if ($get_res['data']['trade_state'] == 'SUCCESS') {
|
||||
return $this->error(['is_paid' => 1, 'pay_type' => 'wechatpay'], '微信已支付不可关闭');
|
||||
}
|
||||
try {
|
||||
$resp = $this->app->chain("v3/pay/transactions/out-trade-no/{$param['out_trade_no']}/close")->post([
|
||||
'json' => [
|
||||
'mchid' => $this->config['mch_id']
|
||||
]
|
||||
]);
|
||||
$result = json_decode($resp->getBody()->getContents(), true);
|
||||
return $this->success($result);
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||||
$result = json_decode($e->getResponse()->getBody()->getContents(), true);
|
||||
return $this->error($result, $result['message']);
|
||||
}
|
||||
return $this->error(['file' => $e->getFile(), 'line' => $e->getLine(), 'message' => $e->getMessage()], $e->getMessage());
|
||||
}
|
||||
}
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款
|
||||
* @param array $param
|
||||
* @return array
|
||||
*/
|
||||
public function refund(array $param)
|
||||
{
|
||||
$pay_info = $param["pay_info"];
|
||||
|
||||
try {
|
||||
$resp = $this->app->chain("v3/refund/domestic/refunds")->post([
|
||||
'json' => [
|
||||
'out_trade_no' => $pay_info['out_trade_no'],
|
||||
'out_refund_no' => $param['refund_no'],
|
||||
'notify_url' => addon_url("pay/pay/refundnotify"),
|
||||
'amount' => [
|
||||
'refund' => round($param['refund_fee'] * 100),
|
||||
'total' => round($pay_info['pay_money'] * 100),
|
||||
'currency' => $param['currency'] ?? 'CNY'
|
||||
]
|
||||
]
|
||||
]);
|
||||
$result = json_decode($resp->getBody()->getContents(), true);
|
||||
if (isset($result['status']) && ($result['status'] == 'SUCCESS' || $result['status'] == 'PROCESSING'))
|
||||
return $this->success($result);
|
||||
else return $this->success($result, '退款异常');
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||||
$result = json_decode($e->getResponse()->getBody()->getContents(), true);
|
||||
return $this->error($result, $result['message']);
|
||||
} else {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 转账
|
||||
* @param array $param
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function transfer(array $param)
|
||||
{
|
||||
if($this->config['transfer_v3_type'] == WechatPayConfig::TRANSFER_V3_TYPE_SHOP){
|
||||
return $this->transferByShop($param);
|
||||
}else{
|
||||
return $this->transferByUser($param);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 商户直接转账
|
||||
* @param array $param
|
||||
* @return mixed
|
||||
*/
|
||||
public function transferByShop(array $param)
|
||||
{
|
||||
$data = [
|
||||
'appid' => $this->config['appid'],
|
||||
'out_batch_no' => $param['out_trade_no'],
|
||||
'batch_name' => '客户提现转账',
|
||||
'batch_remark' => '客户提现转账提现交易号' . $param['out_trade_no'],
|
||||
'total_amount' => round($param['amount'] * 100),
|
||||
'total_num' => 1,
|
||||
'transfer_detail_list' => [
|
||||
[
|
||||
'out_detail_no' => $param['out_trade_no'],
|
||||
'transfer_amount' => round($param['amount'] * 100, 2),
|
||||
'transfer_remark' => $param['desc'],
|
||||
'openid' => $param['account_number'],
|
||||
'user_name' => $this->encryptor($param['real_name'])
|
||||
]
|
||||
]
|
||||
];
|
||||
\think\facade\Log::write('转账发起数据');
|
||||
\think\facade\Log::write($data);
|
||||
$this->app->chain('v3/transfer/batches')
|
||||
->postAsync([
|
||||
'json' => $data,
|
||||
'headers' => [
|
||||
'Wechatpay-Serial' => $this->plateform_certificate_serial
|
||||
]
|
||||
])->then(static function ($response) use (&$result) {
|
||||
$pay_transfer_model = new PayTransfer();
|
||||
$result = json_decode($response->getBody()->getContents(), true);
|
||||
\think\facade\Log::write('转账成功返回');
|
||||
\think\facade\Log::write($result);
|
||||
$result = $pay_transfer_model->success([
|
||||
'status' => $pay_transfer_model::STATUS_IN_PROCESS,
|
||||
]);
|
||||
})->otherwise(static function ($exception) use (&$result) {
|
||||
if ($exception instanceof \GuzzleHttp\Exception\RequestException && $exception->hasResponse()) {
|
||||
$result = json_decode($exception->getResponse()->getBody()->getContents(), true);
|
||||
\think\facade\Log::write('转账其他返回');
|
||||
\think\facade\Log::write($result);
|
||||
$pay_transfer_model = new PayTransfer();
|
||||
if (isset($result['batch_status'])) {
|
||||
if (in_array($result['batch_status'], ['ACCEPTED', 'PROCESSING'])) {
|
||||
$result = $pay_transfer_model->success([
|
||||
'status' => $pay_transfer_model::STATUS_IN_PROCESS,
|
||||
]);
|
||||
} else if ($result['batch_status'] == 'FINISHED') {
|
||||
$result = $pay_transfer_model->success([
|
||||
'status' => $pay_transfer_model::STATUS_SUCCESS,
|
||||
]);
|
||||
} else {
|
||||
$result = $pay_transfer_model->error($result, '转账失败');
|
||||
}
|
||||
} else {
|
||||
$result = error(-1, '转账错误:' . $result['message'] ?? '未知错误', $result);
|
||||
}
|
||||
} else {
|
||||
$result = error(-1, '转账报错:' . $exception->getMessage());
|
||||
}
|
||||
})->wait();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询转账明细
|
||||
* @param string $out_batch_no
|
||||
* @param string $out_detail_no
|
||||
* @return array
|
||||
*/
|
||||
public function transferDetail(string $out_batch_no, string $out_detail_no): array
|
||||
{
|
||||
try {
|
||||
$resp = $this->app->chain("v3/transfer/batches/out-batch-no/{$out_batch_no}/details/out-detail-no/{$out_detail_no}")
|
||||
->get();
|
||||
$result = json_decode($resp->getBody()->getContents(), true);
|
||||
\think\facade\Log::write('转账查询正常返回');
|
||||
\think\facade\Log::write($result);
|
||||
return $this->success($result);
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||||
$result = json_decode($e->getResponse()->getBody()->getContents(), true);
|
||||
\think\facade\Log::write('转账查询其他返回');
|
||||
\think\facade\Log::write($result);
|
||||
if (isset($result['detail_status'])) {
|
||||
return $this->success($result);
|
||||
} else {
|
||||
return $this->error($result, $result['message'] ?? '未知错误');
|
||||
}
|
||||
} else {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密数据
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public function encryptor(string $str)
|
||||
{
|
||||
$publicKey = $this->plateform_certificate_instance;
|
||||
// 加密方法
|
||||
$encryptor = function ($msg) use ($publicKey) {
|
||||
return Rsa::encrypt($msg, $publicKey);
|
||||
};
|
||||
return $encryptor($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取转账结果
|
||||
* @param $withdraw_info
|
||||
* @return array
|
||||
*/
|
||||
public function getTransferResult($withdraw_info)
|
||||
{
|
||||
$pay_transfer_model = new PayTransfer();
|
||||
$result = $this->transferDetail($withdraw_info['out_trade_no'], $withdraw_info['out_trade_no']);
|
||||
if ($result['code'] == 0) {
|
||||
switch ($result['data']['detail_status']) {
|
||||
case 'SUCCESS':
|
||||
$status = $pay_transfer_model::STATUS_SUCCESS;
|
||||
break;
|
||||
case 'FAIL':
|
||||
$status = $pay_transfer_model::STATUS_FAIL;
|
||||
$reason_config = [
|
||||
'ACCOUNT_FROZEN' => '账户冻结',
|
||||
'REAL_NAME_CHECK_FAIL' => '用户未实名',
|
||||
'NAME_NOT_CORRECT' => '用户姓名校验失败',
|
||||
'OPENID_INVALID' => 'Openid校验失败',
|
||||
'TRANSFER_QUOTA_EXCEED' => '超过用户单笔收款额度',
|
||||
'DAY_RECEIVED_QUOTA_EXCEED' => '超过用户单日收款额度',
|
||||
'MONTH_RECEIVED_QUOTA_EXCEED' => '超过用户单月收款额度',
|
||||
'DAY_RECEIVED_COUNT_EXCEED' => '超过用户单日收款次数',
|
||||
'PRODUCT_AUTH_CHECK_FAIL' => '产品权限校验失败',
|
||||
'OVERDUE_CLOSE' => '转账关闭',
|
||||
'ID_CARD_NOT_CORRECT' => '用户身份证校验失败',
|
||||
'ACCOUNT_NOT_EXIST' => '用户账户不存在',
|
||||
'TRANSFER_RISK' => '转账存在风险',
|
||||
'REALNAME_ACCOUNT_RECEIVED_QUOTA_EXCEED' => '用户账户收款受限,请引导用户在微信支付查看详情',
|
||||
'RECEIVE_ACCOUNT_NOT_PERMMIT' => '未配置该用户为转账收款人',
|
||||
'PAYER_ACCOUNT_ABNORMAL' => '商户账户付款受限,可前往商户平台-违约记录获取解除功能限制指引',
|
||||
'PAYEE_ACCOUNT_ABNORMAL' => '用户账户收款异常,请引导用户完善其在微信支付的身份信息以继续收款',
|
||||
'MERCHANT_REJECT' => '商家拒绝',
|
||||
];
|
||||
$reason_code = $result['data']['fail_reason'] ?? '';
|
||||
$fail_reason = $reason_config[$reason_code] ?? $reason_code;
|
||||
break;
|
||||
default:
|
||||
$status = $pay_transfer_model::STATUS_IN_PROCESS;
|
||||
}
|
||||
return $this->success([
|
||||
'status' => $status,
|
||||
'fail_reason' => $fail_reason ?? '',
|
||||
'reason_code' => $reason_code ?? '',
|
||||
]);
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单信息
|
||||
* @param $out_trade_no
|
||||
* @return array
|
||||
*/
|
||||
public function get($out_trade_no)
|
||||
{
|
||||
try {
|
||||
$resp = $this->app->chain("/v3/pay/transactions/out-trade-no/{$out_trade_no}")->get();
|
||||
$result = json_decode($resp->getBody()->getContents(), true);
|
||||
return $this->success($result);
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||||
$result = json_decode($e->getResponse()->getBody()->getContents(), true);
|
||||
return $this->error($result, $result['message']);
|
||||
} else {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 会员转账下单
|
||||
* @param array $param
|
||||
*/
|
||||
|
||||
public function transferByUser(array $param)
|
||||
{
|
||||
$data = [
|
||||
'appid' => $this->config['appid'],
|
||||
'out_bill_no' => $param['out_trade_no'],
|
||||
'transfer_scene_id' => $this->config[$param['from_type'].'_code'],
|
||||
'openid' => $param['account_number'],
|
||||
'user_name' => $param['amount'] >= 2000 ? $this->encryptor($param['real_name']) : '',
|
||||
'transfer_amount' => round($param['amount'] * 100),
|
||||
'transfer_remark' => '客户提现转账',
|
||||
'notify_url' => addon_url("wechatpay://api/transfer/notify"),
|
||||
'user_recv_perception'=> $this->config[$param['from_type'].'_recv'] ?? '',
|
||||
'transfer_scene_report_infos' => $this->config[$param['from_type'].'_info'],
|
||||
];
|
||||
|
||||
Log::write('会员发起转账数据');
|
||||
Log::write($data);
|
||||
|
||||
try {
|
||||
$resp = $this->app
|
||||
->chain('/v3/fund-app/mch-transfer/transfer-bills')
|
||||
->postAsync([
|
||||
'json' => $data,
|
||||
'headers' => [
|
||||
'Wechatpay-Serial' => $this->plateform_certificate_serial
|
||||
]
|
||||
])->then(static function ($response) use (&$result) {
|
||||
|
||||
$result = json_decode($response->getBody()->getContents(), true);
|
||||
\think\facade\Log::write('申请转账返回');
|
||||
\think\facade\Log::write($result);
|
||||
|
||||
})->otherwise(static function ($exception) use (&$result) {
|
||||
if ($exception instanceof \GuzzleHttp\Exception\RequestException && $exception->hasResponse()) {
|
||||
$result = json_decode($exception->getResponse()->getBody()->getContents(), true);
|
||||
\think\facade\Log::write('申请转账返回异常');
|
||||
\think\facade\Log::write($result);
|
||||
$result = error(-1, '转账异常:' .$result['message'] ?? '');
|
||||
} else {
|
||||
$result = error(-1, '转账异常:' . $exception->getMessage());
|
||||
}
|
||||
})->wait();
|
||||
|
||||
if(isset($result['code']) && $result['code'] != 0){
|
||||
return $result;
|
||||
}
|
||||
//状态为待转账
|
||||
$result['status'] = PayTransfer::STATUS_WAIT;
|
||||
return $this->success($result);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\think\facade\Log::write('会员提现转账失败,原因'.$e->getMessage());
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤销转账
|
||||
* @param $out_bill_no
|
||||
*/
|
||||
public function transferCancel($out_bill_no){
|
||||
|
||||
Log::write('会员撤销转账');
|
||||
Log::write($out_bill_no);
|
||||
|
||||
try {
|
||||
$resp = $this->app
|
||||
->chain('/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/'.$out_bill_no.'/cancel')
|
||||
->postAsync()
|
||||
->then(static function ($response) use (&$result) {
|
||||
$result = json_decode($response->getBody()->getContents(), true);
|
||||
Log::write('会员撤销转账数据返回');
|
||||
Log::write($result);
|
||||
})->otherwise(static function ($exception) use (&$result) {
|
||||
if ($exception instanceof \GuzzleHttp\Exception\RequestException && $exception->hasResponse()) {
|
||||
$result = json_decode($exception->getResponse()->getBody()->getContents(), true);
|
||||
Log::write('撤销转账返回异常');
|
||||
Log::write($result);
|
||||
} else {
|
||||
$result = error(-1, '撤销转账报错:' . $exception->getMessage());
|
||||
}
|
||||
})->wait();
|
||||
|
||||
return $this->success($result);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::write('会员撤销转账失败,原因'.$e->getMessage());
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 会员提现回调
|
||||
* @throws \Exception
|
||||
*/
|
||||
|
||||
public function transferNotify(){
|
||||
|
||||
$inWechatpaySignature = request()->header('Wechatpay-Signature'); // 从请求头中拿到 签名
|
||||
$inWechatpayTimestamp = request()->header('Wechatpay-Timestamp'); // 从请求头中拿到 时间戳
|
||||
$inWechatpaySerial = request()->header('Wechatpay-Serial'); // 从请求头中拿到 时间戳
|
||||
$inWechatpayNonce = request()->header('Wechatpay-Nonce'); // 从请求头中拿到 时间戳
|
||||
$inBody = file_get_contents('php://input');
|
||||
|
||||
Log::write('transferNotifyHeader'.json_encode(request()->header()));
|
||||
Log::write('transferNotifyBody' . $inBody);
|
||||
|
||||
$platformPublicKeyInstance = Rsa::from('file://' . realpath($this->config['plateform_cert']), Rsa::KEY_TYPE_PUBLIC);
|
||||
|
||||
$timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
|
||||
$verifiedStatus = Rsa::verify(
|
||||
// 构造验签名串
|
||||
Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, file_get_contents('php://input')),
|
||||
$inWechatpaySignature,
|
||||
$platformPublicKeyInstance
|
||||
);
|
||||
if ($timeOffsetStatus && $verifiedStatus) {
|
||||
// 转换通知的JSON文本消息为PHP Array数组
|
||||
$inBodyArray = (array)json_decode($inBody, true);
|
||||
// 使用PHP7的数据解构语法,从Array中解构并赋值变量
|
||||
['resource' => [
|
||||
'ciphertext' => $ciphertext,
|
||||
'nonce' => $nonce,
|
||||
'associated_data' => $aad
|
||||
]] = $inBodyArray;
|
||||
// 加密文本消息解密
|
||||
$inBodyResource = AesGcm::decrypt($ciphertext, $this->config['v3_pay_signkey'], $nonce, $aad);
|
||||
// 把解密后的文本转换为PHP Array数组
|
||||
$message = json_decode($inBodyResource, true);
|
||||
Log::write('transferNotifyMessage' . $inBodyResource);
|
||||
// 交易状态为成功
|
||||
|
||||
$pay_transfer_model = new PayTransfer();
|
||||
if (isset($message['state']) && $message['state'] == 'SUCCESS') {
|
||||
if (isset($message['out_bill_no'])) {
|
||||
$transfer_info = $pay_transfer_model->getTransferInfo([['out_trade_no', '=', $message['out_bill_no']]],'id')['data'];
|
||||
$update_result = $pay_transfer_model->updateStatus(['status' => PayTransfer::STATUS_SUCCESS, 'result' => $message], $transfer_info['id']);
|
||||
Log::write('transferNotify' . json_encode(['transfer_info'=>$transfer_info,'update_result'=>$update_result]));
|
||||
header('', '', 200);
|
||||
}
|
||||
} else {
|
||||
if (isset($message['out_bill_no'])) {
|
||||
$transfer_info = $pay_transfer_model->getTransferInfo([['out_trade_no', '=', $message['out_bill_no']]],'id')['data'];
|
||||
$update_result = $pay_transfer_model->updateStatus(['status' => PayTransfer::STATUS_FAIL, 'result' => $message], $transfer_info['id']);
|
||||
Log::write('transferNotify' . json_encode(['transfer_info'=>$transfer_info,'update_result'=>$update_result]));
|
||||
}
|
||||
|
||||
throw new HttpException(500, '失败', null, [], 'FAIL');
|
||||
}
|
||||
} else {
|
||||
throw new HttpException(500, '失败', null, [], 'FAIL');
|
||||
}
|
||||
}
|
||||
}
|
||||
116
addon/wechatpay/shop/controller/Pay.php
Executable file
116
addon/wechatpay/shop/controller/Pay.php
Executable file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\wechatpay\shop\controller;
|
||||
|
||||
use addon\wechatpay\model\Config as ConfigModel;
|
||||
use app\model\upload\Upload;
|
||||
use app\shop\controller\BaseShop;
|
||||
use think\facade\Config;
|
||||
|
||||
/**
|
||||
* 支付 控制器
|
||||
*/
|
||||
class Pay extends BaseShop
|
||||
{
|
||||
public function config()
|
||||
{
|
||||
$config_model = new ConfigModel();
|
||||
if (request()->isJson()) {
|
||||
$appid = input("appid", "");//公众账号ID
|
||||
$mch_id = input("mch_id", "");//商户号
|
||||
$pay_signkey = input("pay_signkey", "");//支付签名串API密钥
|
||||
$apiclient_cert = input("apiclient_cert", "");//支付证书cert
|
||||
$apiclient_key = input("apiclient_key", "");//支付证书key
|
||||
$pay_status = input("pay_status", 0);//支付启用状态
|
||||
$refund_status = input("refund_status", 0);//退款启用状态
|
||||
$transfer_status = input("transfer_status", 0);//转账启用状态
|
||||
$transfer_type = input("transfer_type", 'v2');
|
||||
$api_type = input("api_type", 'v2');
|
||||
$v3_pay_signkey = input('v3_pay_signkey', '');
|
||||
$plateform_certificate_serial = input('plateform_certificate_serial', '');
|
||||
$plateform_certificate = input('plateform_certificate', '');
|
||||
$transfer_v3_type = input('transfer_v3_type','');
|
||||
|
||||
$member_withdraw_scene = input('member_withdraw_scene',''); //转账场景编号
|
||||
$store_withdraw_scene = input('store_withdraw_scene','');
|
||||
$fenxiao_withdraw_scene = input('fenxiao_withdraw_scene','');
|
||||
|
||||
$member_withdraw_code = input('member_withdraw_code',''); //转账场景ID
|
||||
$store_withdraw_code= input('store_withdraw_code','');
|
||||
$fenxiao_withdraw_code = input('fenxiao_withdraw_code','');
|
||||
|
||||
$member_withdraw_recv = input('member_withdraw_recv',''); //转账场景说明
|
||||
$store_withdraw_recv= input('store_withdraw_recv','');
|
||||
$fenxiao_withdraw_recv = input('fenxiao_withdraw_recv','');
|
||||
|
||||
$transfer_info = $config_model->getTransferSceneInfo(request()->all());
|
||||
|
||||
$data = array (
|
||||
"appid" => $appid,
|
||||
"mch_id" => $mch_id,
|
||||
"pay_signkey" => $pay_signkey,
|
||||
"apiclient_cert" => $apiclient_cert,
|
||||
"apiclient_key" => $apiclient_key,
|
||||
"refund_status" => $refund_status,
|
||||
"pay_status" => $pay_status,
|
||||
"transfer_status" => $transfer_status,
|
||||
'transfer_type' => $transfer_type,
|
||||
'plateform_cert' => '',
|
||||
'plateform_certificate' => $plateform_certificate,
|
||||
'plateform_certificate_serial' => $plateform_certificate_serial,
|
||||
'api_type' => $api_type,
|
||||
'v3_pay_signkey' => $v3_pay_signkey,
|
||||
'transfer_v3_type'=>$transfer_v3_type,
|
||||
'member_withdraw_scene'=>$member_withdraw_scene,
|
||||
'store_withdraw_scene'=>$store_withdraw_scene,
|
||||
'fenxiao_withdraw_scene'=>$fenxiao_withdraw_scene,
|
||||
'member_withdraw_code'=>$member_withdraw_code,
|
||||
'store_withdraw_code'=>$store_withdraw_code,
|
||||
'fenxiao_withdraw_code'=>$fenxiao_withdraw_code,
|
||||
'member_withdraw_info' => $transfer_info['member_withdraw_info'],
|
||||
'fenxiao_withdraw_info'=> $transfer_info['fenxiao_withdraw_info'],
|
||||
'store_withdraw_info' => $transfer_info['store_withdraw_info'],
|
||||
'member_withdraw_recv'=>$member_withdraw_recv,
|
||||
'store_withdraw_recv'=>$store_withdraw_recv,
|
||||
'fenxiao_withdraw_recv'=>$fenxiao_withdraw_recv,
|
||||
);
|
||||
|
||||
$result = $config_model->setPayConfig($data, $this->site_id, $this->app_module);
|
||||
return $result;
|
||||
} else {
|
||||
$info = $config_model->getPayConfig($this->site_id, $this->app_module, true)[ 'data' ][ 'value' ];
|
||||
|
||||
$this->assign("info", $info);
|
||||
$this->assign("scene_config",$config_model->getTransferSceneConfig());
|
||||
|
||||
return $this->fetch("pay/config");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传微信支付证书
|
||||
*/
|
||||
public function uploadWechatCert()
|
||||
{
|
||||
$upload_model = new Upload();
|
||||
$site_id = request()->siteid();
|
||||
$name = input("name", "");
|
||||
$extend_type = [ 'pem' ];
|
||||
$param = array (
|
||||
"name" => "file",
|
||||
"extend_type" => $extend_type
|
||||
);
|
||||
|
||||
$site_id = max($site_id, 0);
|
||||
$result = $upload_model->setPath("common/wechat/cert/" . $site_id . "/")->file($param);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
525
addon/wechatpay/shop/view/pay/config.html
Executable file
525
addon/wechatpay/shop/view/pay/config.html
Executable file
@@ -0,0 +1,525 @@
|
||||
<style>
|
||||
.input-text span{margin-right: 15px;}
|
||||
.file-upload {display: inline-block; margin-right: 5px;}
|
||||
.api-type-config, .transfer-type {display: none;}
|
||||
.scene-config-content{
|
||||
border: 1px dashed #ccc;
|
||||
padding-top:15px;
|
||||
margin-bottom: 15px;
|
||||
width: 50%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="layui-form form-wrap">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商户号:</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="mch_id" type="text" value="{$info.mch_id ?? ''}" class="layui-input len-long" lay-verify="required">
|
||||
</div>
|
||||
<div class="word-aux"><span>[MCHID]</span>微信支付商户号</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">支付接口类型:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" title="v2" name="api_type" lay-filter="api_type" value="v2" {if !$info || ($info && $info.api_type eq 'v2')}checked{/if}>
|
||||
<input type="radio" title="v3" name="api_type" lay-filter="api_type" value="v3" {if $info && $info.api_type eq 'v3'}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item api-type-config v2-config" {if empty($info) || ( ($info.api_type eq 'v2') || ($info.transfer_status == 1 && $info.transfer_type eq 'v2') ) }style="display:block"{/if}>
|
||||
<label class="layui-form-label"><span class="required">*</span>APIv2密钥 :</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="pay_signkey" lay-verify="pay_signkey" type="text" value="{$info.pay_signkey ?? ''}" class="layui-input len-long">
|
||||
</div>
|
||||
<div class="word-aux">微信商户APIv2密钥 <a href="https://kf.qq.com/faq/180830UVRZR7180830Ij6ZZz.html" class="text-color" target="_blank">查看指引</a></div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item api-type-config v3-config v3-transfer-type" {if !empty($info) && ( ($info.api_type eq 'v3') || ($info.transfer_status == 1 && $info.transfer_type eq 'v3') ) }style="display:block"{/if}>
|
||||
<label class="layui-form-label"><span class="required">*</span>APIv3密钥 :</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="v3_pay_signkey" lay-verify="v3_pay_signkey" type="text" value="{$info.v3_pay_signkey ?? ''}" class="layui-input len-long">
|
||||
</div>
|
||||
<div class="word-aux">微信商户APIv3密钥 <a href="https://kf.qq.com/faq/180830E36vyQ180830AZFZvu.html" class="text-color" target="_blank">查看指引</a></div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item api-type-config v3-config v3-transfer-type" {if !empty($info) && ( ($info.api_type eq 'v3') || ($info.transfer_status == 1 && $info.transfer_type eq 'v3') ) }style="display:block"{/if}>
|
||||
<label class="layui-form-label">支付公钥ID :</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="plateform_certificate_serial" lay-verify="plateform_certificate_serial" type="text" value="{$info.plateform_certificate_serial ?? ''}" class="layui-input len-long">
|
||||
</div>
|
||||
<div class="word-aux">微信支付公钥ID,没有可以不填 <a href="https://kf.qq.com/faq/180830E36vyQ180830AZFZvu.html" class="text-color" target="_blank">查看指引</a></div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="required">*</span>支付证书cert:</label>
|
||||
<div class="layui-input-block">
|
||||
{notempty name="$info.apiclient_cert"}
|
||||
<p class="file-upload">已上传</p>
|
||||
{else/}
|
||||
<p class="file-upload">未上传</p>
|
||||
{/notempty}
|
||||
<button type="button" class="layui-btn" id="cert_upload">
|
||||
<i class="layui-icon"></i>上传文件
|
||||
</button>
|
||||
<input type="hidden" name="apiclient_cert" class="layui-input len-long" value="{$info.apiclient_cert ?? ''}" lay-verify="apiclient_cert">
|
||||
</div>
|
||||
<div class="word-aux">上传apiclient_cert.pem文件</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="required">*</span>支付证书key:</label>
|
||||
<div class="layui-input-block">
|
||||
{notempty name="$info.apiclient_key"}
|
||||
<p class="file-upload">已上传</p>
|
||||
{else/}
|
||||
<p class="file-upload">未上传</p>
|
||||
{/notempty}
|
||||
<button type="button" class="layui-btn" id="key_upload">
|
||||
<i class="layui-icon"></i>上传文件
|
||||
</button>
|
||||
<input type="hidden" name="apiclient_key" class="layui-input len-long" value="{$info.apiclient_key ?? ''}" lay-verify="apiclient_key">
|
||||
</div>
|
||||
<div class="word-aux">上传apiclient_key.pem文件</div>
|
||||
<div class="word-aux">微信商户API证书 <a href="https://kf.qq.com/faq/161222NneAJf161222U7fARv.html" class="text-color" target="_blank">查看指引</a></div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">支付公钥:</label>
|
||||
<div class="layui-input-block">
|
||||
{notempty name="$info.plateform_certificate"}
|
||||
<p class="file-upload">已上传</p>
|
||||
{else/}
|
||||
<p class="file-upload">未上传</p>
|
||||
{/notempty}
|
||||
<button type="button" class="layui-btn" id="plateform_certificate_upload">
|
||||
<i class="layui-icon"></i>上传文件
|
||||
</button>
|
||||
<input type="hidden" name="plateform_certificate" class="layui-input len-long" value="{$info.plateform_certificate ?? ''}" lay-verify="plateform_certificate">
|
||||
</div>
|
||||
<div class="word-aux">上传pub_key.pem文件</div>
|
||||
<div class="word-aux">微信支付公钥,没有可以不传 <a href="https://kf.qq.com/faq/161222NneAJf161222U7fARv.html" class="text-color" target="_blank">查看指引</a></div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">是否启用支付:</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="checkbox" name="pay_status" value="1" lay-skin="switch" {if condition="$info && $info.pay_status == 1"} checked {/if} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">是否启用退款:</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="checkbox" name="refund_status" value="1" lay-skin="switch" {if condition="$info && $info.refund_status == 1"} checked {/if} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">是否启用转账:</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="checkbox" name="transfer_status" value="1" lay-skin="switch" {if condition="$info && $info.transfer_status == 1"} checked {/if} lay-filter="transfer_status"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="transfer-config" {if condition="!$info || $info.transfer_status != 1"}style="display:none;"{/if}>
|
||||
<div class="layui-form-item api-type-config v2-api-type" {if !$info || ($info && $info.api_type eq 'v2')}style="display:block;"{/if}>
|
||||
<label class="layui-form-label">转账使用产品:</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" title="企业付款到零钱" name="transfer_type" lay-filter="transfer_type" value="v2" {if !$info || ($info && $info.transfer_type eq 'v2')}checked{/if}>
|
||||
<input type="radio" title="商家转账到零钱" name="transfer_type" lay-filter="transfer_type" value="v3" {if $info && $info.transfer_type eq 'v3'}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item api-type-config v3-api-type" {if condition="$info && $info.api_type == 'v3'"} style="display:block;"{/if}>
|
||||
<label class="layui-form-label">转账使用产品:</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" title="商家转账到零钱" name="transfer_type" lay-filter="transfer_type" value="v3" {if $info.api_type eq 'v3' && $info.transfer_type eq 'v3'}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="api-type-config v3-config v3-transfer-type" {if condition="$info && $info.transfer_type == 'v3'"}style="display:block;"{/if}>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">V3商家转账版本:</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" title="旧版接口(商家发起转账)" name="transfer_v3_type" lay-filter="transfer_v3_type" value="1" {if !$info || ($info && $info.transfer_v3_type eq '1')}checked{/if}>
|
||||
<input type="radio" title="新版接口(用户确认收款)" name="transfer_v3_type" lay-filter="transfer_v3_type" value="2" {if $info && $info.transfer_v3_type eq '2'}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="scene-config" {if $info && $info['transfer_v3_type'] == 2} style="display:block"{else/}style="display:none;"{/if}>
|
||||
{if addon_is_exit('memberwithdraw') == 1 }
|
||||
<div class="scene-config-content" data-scene="member_withdraw">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">会员提现场景:</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="member_withdraw_scene" lay-filter="transfer_scene" class="transfer_select" lay-verify="required">
|
||||
<option value="">选择场景</option>
|
||||
{foreach $scene_config as $group_list_k => $group_list_v}
|
||||
<option value="{$group_list_v.num}" {if $info && $info['member_withdraw_scene'] == $group_list_v.num} selected{/if}>{$group_list_v.title}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="scene-config">
|
||||
{if $info && !empty($info['member_withdraw_code'])}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">收款提示:</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="member_withdraw_recv" lay-verify="required">
|
||||
{foreach $scene_config[$info['member_withdraw_scene']]['user_recv'] as $group_list_k => $group_list_v}
|
||||
<option value="{$group_list_v}" {if $info && $info['member_withdraw_recv'] == $group_list_v} selected{/if}>{$group_list_v}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">转账场景ID:</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="member_withdraw_code" type="text" value="{$info.member_withdraw_code ?? ''}" class="layui-input len-long" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{foreach $info['member_withdraw_info'] as $group_list_k => $group_list_v}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{$group_list_v['info_type']}:</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="member_withdraw_{$group_list_k}" type="text" value="{$group_list_v['info_content'] ?? ''}" class="layui-input len-long" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if addon_is_exit('store') == 1 }
|
||||
<div class="scene-config-content" data-scene="store_withdraw">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">门店提现场景:</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="store_withdraw_scene" lay-filter="transfer_scene" lay-verify="required">
|
||||
<option value="">选择场景</option>
|
||||
{foreach $scene_config as $group_list_k => $group_list_v}
|
||||
<option value="{$group_list_v.num}" {if $info && $info['store_withdraw_scene'] == $group_list_v.num} selected{/if}>{$group_list_v.title}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scene-config">
|
||||
{if $info && !empty($info['store_withdraw_code'])}
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">收款提示:</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="store_withdraw_recv" lay-verify="required">
|
||||
{foreach $scene_config[$info['store_withdraw_scene']]['user_recv'] as $group_list_k => $group_list_v}
|
||||
<option value="{$group_list_v}" {if $info && $info['store_withdraw_recv'] == $group_list_v} selected{/if}>{$group_list_v}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">转账场景ID:</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="store_withdraw_code" type="text" value="{$info.store_withdraw_code ?? ''}" class="layui-input len-long" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{foreach $info['store_withdraw_info'] as $group_list_k => $group_list_v}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{$group_list_v['info_type']}:</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="store_withdraw_{$group_list_k}" type="text" value="{$group_list_v['info_content'] ?? ''}" class="layui-input len-long" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if addon_is_exit('fenxiao') == 1 }
|
||||
<div class="scene-config-content" data-scene="fenxiao_withdraw">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分销提现场景:</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="fenxiao_withdraw_scene" lay-filter="transfer_scene" lay-verify="required">
|
||||
<option value="">选择场景</option>
|
||||
{foreach $scene_config as $group_list_k => $group_list_v}
|
||||
<option value="{$group_list_v.num}" {if $info && $info['fenxiao_withdraw_scene'] == $group_list_v.num} selected{/if}>{$group_list_v.title}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scene-config">
|
||||
{if $info && !empty($info['fenxiao_withdraw_code'])}
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">收款提示:</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="fenxiao_withdraw_recv">
|
||||
{foreach $scene_config[$info['fenxiao_withdraw_scene']]['user_recv'] as $group_list_k => $group_list_v}
|
||||
<option value="{$group_list_v}" {if $info && $info['fenxiao_withdraw_recv'] == $group_list_v} selected{/if}>{$group_list_v}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">转账场景ID:</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="fenxiao_withdraw_code" type="text" value="{$info.fenxiao_withdraw_code ?? ''}" class="layui-input len-long" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{foreach $info['fenxiao_withdraw_info'] as $group_list_k => $group_list_v}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{$group_list_v['info_type']}:</label>
|
||||
<div class="layui-input-block">
|
||||
<input name="fenxiao_withdraw_{$group_list_k}" type="text" value="{$group_list_v['info_content'] ?? ''}" class="layui-input len-long" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-row">
|
||||
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
|
||||
<button class="layui-btn layui-btn-primary" onclick="backPayConfig()">返回</button>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
var old_transfer_type = "{$info.transfer_type ?? 'v2'}"
|
||||
function refreshPage() {
|
||||
let api_type = $("input[name='api_type']:checked").val();//支付接口类型 v2,v3
|
||||
let transfer_status = parseInt($("input[name='transfer_status']:checked").val()) //是否启用转账 1启用
|
||||
let transfer_type = $("input[name='transfer_type']:checked").val() //转账使用产品 v2企业付款到零钱 v3商家转账到零钱
|
||||
let transfer_v3_type = parseInt($("input[name='transfer_v3_type']:checked").val()) //v3转账版本 1旧版接口 2新版接口
|
||||
|
||||
$('.api-type-config').hide();
|
||||
$('.' + api_type + '-config').show();
|
||||
$('.' + api_type + '-api-type').show();
|
||||
|
||||
if (transfer_status === 1) {
|
||||
$('.transfer-config').show()
|
||||
|
||||
if(api_type === 'v3'){
|
||||
$('.v3-api-type input[name="transfer_type"][value="v3"]').prop('checked', true);
|
||||
}else{
|
||||
$('.v2-api-type input[name="transfer_type"][value="'+old_transfer_type+'"]').prop('checked', true);
|
||||
}
|
||||
|
||||
if(transfer_type === 'v3'){
|
||||
$(".transfer-type").hide()
|
||||
$('.v3-transfer-type').show()
|
||||
if(transfer_v3_type === 2){
|
||||
$(".scene-config").show()
|
||||
}else{
|
||||
$(".scene-config").hide()
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$('.transfer-config').hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var scene_config = '{:json_encode($scene_config)}';
|
||||
layui.use(['form'], function() {
|
||||
var form = layui.form,
|
||||
repeat_flag = false; //防重复标识
|
||||
|
||||
refreshTransferRequired();
|
||||
form.render();
|
||||
|
||||
form.on('switch(transfer_status)', function (data) {
|
||||
refreshPage()
|
||||
refreshTransferRequired();
|
||||
form.render();
|
||||
})
|
||||
|
||||
form.on('radio(api_type)', function (data) {
|
||||
refreshPage();
|
||||
refreshTransferRequired();
|
||||
form.render();
|
||||
})
|
||||
|
||||
|
||||
form.on('radio(transfer_type)', function (data) {
|
||||
old_transfer_type = data.value;
|
||||
refreshPage()
|
||||
refreshTransferRequired();
|
||||
form.render();
|
||||
})
|
||||
|
||||
form.on('radio(transfer_v3_type)', function (data) {
|
||||
refreshPage()
|
||||
refreshTransferRequired()
|
||||
form.render();
|
||||
})
|
||||
|
||||
|
||||
function refreshTransferRequired(){
|
||||
var transfer_v3_type = $("input[name='transfer_v3_type']:checked").val()
|
||||
var transfer_type = $("input[name='transfer_type']:checked").val()
|
||||
var transfer_status = $("input[name='transfer_status']:checked").val()
|
||||
if(transfer_type === 'v3' && transfer_v3_type == 2 && transfer_status==1){
|
||||
$(".scene-config select,.scene-config input").attr('lay-verify', 'required');
|
||||
}else{
|
||||
$(".scene-config select,.scene-config input").removeAttr('lay-verify')
|
||||
}
|
||||
}
|
||||
|
||||
form.on('select(transfer_scene)', function(data){
|
||||
|
||||
var res = JSON.parse(scene_config)[data.value];
|
||||
if (typeof res === "undefined") {
|
||||
$(this).parents('.scene-config-content').children(".scene-config").empty()
|
||||
return
|
||||
}
|
||||
var scene = $(this).parents('.scene-config-content').data("scene");
|
||||
|
||||
console.log(scene)
|
||||
var recv_name = scene + '_recv';
|
||||
var recv_html = "<div class='layui-form-item'>"+
|
||||
"<label class='layui-form-label'>收款提示:</label>"+
|
||||
"<div class='layui-input-inline'>"+
|
||||
"<select name="+recv_name+" lay-verify=\"required\" >";
|
||||
|
||||
|
||||
for (let i = 0; i < res.user_recv.length; i++) {
|
||||
var item = res.user_recv[i];
|
||||
recv_html += "<option value="+item+">"+item+"</option>"
|
||||
}
|
||||
|
||||
recv_html += "</select></div></div>"
|
||||
|
||||
|
||||
console.log(recv_html)
|
||||
|
||||
var code_name = scene+'_code'
|
||||
var html = recv_html + "<div class='layui-form-item'> " +
|
||||
"<label class='layui-form-label'>转账场景ID:</label> " +
|
||||
"<div class='layui-input-block'>"+
|
||||
"<input name="+code_name+" type='text' value='' class='layui-input len-long' lay-verify='required'>"+
|
||||
"</div>"+
|
||||
"</div>"
|
||||
|
||||
for (let i = 0; i < res.infos.length; i++) {
|
||||
// 遍历数组,对每个元素进行操作
|
||||
var item = res.infos[i];
|
||||
var name = scene+"_"+i;
|
||||
html += "<div class='layui-form-item'> " +
|
||||
"<label class='layui-form-label'>"+item.info_type+":</label> " +
|
||||
"<div class='layui-input-block'>"+
|
||||
"<input name="+name+" type='text' value='' class='layui-input len-long' lay-verify='required'>"+
|
||||
"</div>"+
|
||||
"</div>"
|
||||
}
|
||||
$(this).parents('.scene-config-content').children(".scene-config").empty().append(html)
|
||||
form.render();
|
||||
});
|
||||
|
||||
new Upload({
|
||||
elem: '#cert_upload',
|
||||
url: ns.url("wechatpay://shop/pay/uploadwechatcert"),
|
||||
accept: 'file',
|
||||
callback:function (res) {
|
||||
if (res.code >= 0) {
|
||||
$("input[name='apiclient_cert']").val(res.data.path);
|
||||
$("input[name='apiclient_cert']").siblings(".file-upload").text("已上传");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new Upload({
|
||||
elem: '#key_upload',
|
||||
url: ns.url("wechatpay://shop/pay/uploadwechatcert"),
|
||||
accept: 'file',
|
||||
callback:function (res) {
|
||||
if (res.code >= 0) {
|
||||
$("input[name='apiclient_key']").val(res.data.path);
|
||||
$("input[name='apiclient_key']").siblings(".file-upload").text("已上传");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new Upload({
|
||||
elem: '#plateform_certificate_upload',
|
||||
url: ns.url("wechatpay://shop/pay/uploadwechatcert"),
|
||||
accept: 'file',
|
||||
callback:function (res) {
|
||||
if (res.code >= 0) {
|
||||
$("input[name='plateform_certificate']").val(res.data.path);
|
||||
$("input[name='plateform_certificate']").siblings(".file-upload").text("已上传");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
form.verify({
|
||||
pay_signkey: function(value){
|
||||
if (!$('.v2-config').is(':hidden') && !/[\S]+/.test(value)) return '请设置微信APIv2密钥';
|
||||
},
|
||||
v3_pay_signkey: function(value){
|
||||
if (!$('.v3-config').is(':hidden') && !/[\S]+/.test(value)) return '请设置微信APIv3密钥';
|
||||
},
|
||||
apiclient_cert: function(value){
|
||||
if (!/[\S]+/.test(value)) return '请上传apiclient_cert.pem文件';
|
||||
},
|
||||
apiclient_key: function(value){
|
||||
if (!/[\S]+/.test(value)) return '请上传apiclient_key.pem文件';
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 监听提交
|
||||
*/
|
||||
form.on('submit(save)', function(data) {
|
||||
if (repeat_flag) return false;
|
||||
repeat_flag = true;
|
||||
|
||||
$.ajax({
|
||||
url: ns.url("wechatpay://shop/pay/config"),
|
||||
data: data.field,
|
||||
dataType: 'JSON',
|
||||
type: 'POST',
|
||||
success: function(res) {
|
||||
repeat_flag = false;
|
||||
|
||||
if (res.code == 0) {
|
||||
layer.confirm('编辑成功', {
|
||||
title:'操作提示',
|
||||
btn: ['返回列表', '继续操作'],
|
||||
yes: function(index, layero){
|
||||
location.hash = ns.hash("shop/config/pay");
|
||||
layer.close(index);
|
||||
},
|
||||
btn2: function(index, layero) {
|
||||
layer.close(index);
|
||||
}
|
||||
});
|
||||
}else{
|
||||
layer.msg(res.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function backPayConfig() {
|
||||
location.hash = ns.hash("shop/config/pay");
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user