作者 魏强

授权及支付

... ... @@ -13,6 +13,12 @@ if (file_exists(CMF_ROOT . "data/conf/config.php")) {
} else {
$runtimeConfig = [];
}
if (file_exists(CMF_ROOT . "app/extra/wechat.php")) {
$wechatConfig['wechat_config'] = include CMF_ROOT . "app/extra/wechat.php";
} else {
$wechatConfig['wechat_config'] = [];
}
$configs = [
// +----------------------------------------------------------------------
// | 应用设置
... ... @@ -227,4 +233,4 @@ $configs = [
'cmf_admin_theme_path' => 'themes/',
'cmf_admin_default_theme' => 'admin_simpleboot3',
];
return array_merge($configs, $runtimeConfig);
\ No newline at end of file
return array_merge($configs, $runtimeConfig,$wechatConfig);
\ No newline at end of file
... ...
... ... @@ -12,6 +12,7 @@ use cmf\controller\HomeBaseController;
class IndexController extends HomeBaseController
{
protected $abc;
public function index()
{
return $this->fetch(':index');
... ...
... ... @@ -3,9 +3,9 @@
namespace app\portal\controller;
use cmf\controller\HomeBaseController;
use EasyWeChat\Foundation\Application;
use EasyWeChat\Payment\Order;
use think\Db;
use think\Log;
use think\Validate;
/**
* 微信支付,退款,提现DEMO
... ... @@ -14,67 +14,142 @@ use think\Validate;
*/
class PayController extends HomeBaseController
{
protected $options;
function _initialize()
{
parent::_initialize();
$this->options = [
'app_id' => config('wechat_config.app_id'), // AppID
'secret' => config('wechat_config.secret'), // AppSecret
// payment
'payment' => config('wechat_config.payment'),
];
}
/**
* 微信支付
*/
public function index(){
$attributes = [
'trade_type' => 'JSAPI',
'body' => '百荣科技',
'detail' => '以客户为中心 以奋斗者文本',
'out_trade_no' => cmf_get_order_sn(),
'total_fee' => 1, // 单位:分
'notify_url' => url('portal/pay/notify','','',true), // 支付结果通知网址,如果不设置则会使用配置里的默认地址
'openid' => cmf_get_current_user_openid(), // trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识,
];
$order = new Order($attributes);
$app = new Application($this->options);
$payment = $app->payment;
$result = $payment->prepare($order);
if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){
$prepayId = $result->prepay_id;
$jsApiParameters=$payment->configForJSSDKPayment($prepayId);
$this->assign('jsApiParameters',json_encode($jsApiParameters));
return $this->fetch();
}else{
$this->error('支付参数错误','',$result);
}
}
/**
* 支付回调
* @throws \EasyWeChat\Core\Exceptions\FaultException
*/
public function notify(){
cache('nnn',111);
$app = new Application($this->options);
$response = $app->payment->handleNotify(function($notify, $successful){
cache('notify',$notify);
cache('successful',$successful);
/*这里是支付回调逻辑处理,一下是DEMO*/
// // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
// $out_trade_no=$notify->out_trade_no;
// $order = Db::name('order')->where('order_sn',$out_trade_no)->find();
// if (!$order) { // 如果订单不存在
// return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
// }
// // 如果订单存在
// // 检查订单是否已经更新过支付状态
// if ($order['pay_time']>0) { // 假设订单字段“支付时间”不为空代表已经支付
// return true; // 已经支付成功了就不再更新了
// }
//
// // 用户是否支付成功
// if ($successful) {
// // 回填微信的订单号
// $update['transaction_id']=$notify->transaction_id;
// $update['pay_time']=time();
// // 不是已经支付状态则修改为已经支付状态
// $update['status'] = 2;
// } else { // 用户支付失败
// $update['status']=9;
// }
// Db::name('order')->where('order_sn',$out_trade_no)->update($update);
return true; // 返回处理完成
});
$response->send();
}
/**
* 查询订单
*/
public function checkOrder(){
$app = new Application($this->options);
$payment = $app->payment;
$orderNo = "2018080210097519";//商户系统内部的订单号(out_trade_no)
$result=$payment->query($orderNo);
var_dump($result);
}
/**
* 退款
* @throws \WxPayException
*/
public function refund(){
$param = $this->request->param();
//todo 退款逻辑应该加入百荣签名验证规则,避免出现被盗用
/*$param=$this->request->param();
$signature = $param['s'];
$arithmetic['timeStamp']= $param['t'];
$arithmetic['randomStr']= $param['r'];
$arithmetic['orderSn']= $param['o'];
$str = arithmetic($arithmetic);
if($str != $signature){
$this->error('签名验证失败');
}
/*微信退款*/
require_once EXTEND_PATH."WxpayAPI/lib/WxPay.Api.php";
require_once EXTEND_PATH."WxpayAPI/example/log.php";
if(isset($info["transaction_id"]) && empty($info["transaction_id"])){
$transaction_id = $info["transaction_id"];
$total_fee = $info["real_price"]*100;
$refund_fee = $info["real_price"]*100;
$input = new \WxPayRefund();
$input->SetTransaction_id($transaction_id);
$input->SetTotal_fee($total_fee);
$input->SetRefund_fee($refund_fee);
$input->SetOut_refund_no(\WxPayConfig::MCHID.date("YmdHis"));
$input->SetOp_user_id(\WxPayConfig::MCHID);
$ret=\WxPayApi::refund($input);
if($ret['result_code']=='SUCCESS'){
//todo 退款成功处理
$this->success('退款成功');
}else{
$this->error("退款失败:".$ret['err_code_des']);
}
}else{
$this->error('缺少退款标识');
}
$this->error('签名验证失败');
}*/
$app = new Application($this->options);
$payment = $app->payment;
//使用商户订单号退款 PS.其他形式参考文档
$orderNo = "2018080210097519";//商户系统内部的订单号(out_trade_no)
$refundNo = cmf_get_order_sn();//退款单号
$result = $payment->refund($orderNo, $refundNo, 100, 80); // 总金额 100, 退款 80,refundFee可选(为空时全额退款)
var_dump($result);
}
/**
* 查询退款
*/
public function checkRefund(){
$app = new Application($this->options);
$payment = $app->payment;
$outTradeNo="2018080210097519";//商户系统内部的订单号(out_trade_no)
$result = $payment->queryRefund($outTradeNo);
var_dump($result);
}
/**
* 提现
* 红包
*/
public function withdraw_cash(){
$param = $this->request->param();
public function luckyMoney(){
//todo 退款逻辑应该加入百荣签名验证规则,避免出现被盗用
/*$param=$this->request->param();
$signature = $param['s'];
$arithmetic['timeStamp']= $param['t'];
$arithmetic['randomStr']= $param['r'];
... ... @@ -82,19 +157,51 @@ class PayController extends HomeBaseController
$str = arithmetic($arithmetic);
if($str != $signature){
$this->error('签名验证失败');
}
$price=1;
$openid='';
$merch=new \MerchPay();
$trade_no = cmf_get_order_sn();
$res=$merch->pay($openid,$trade_no,$price,'提现');
if($res['result_code']=='SUCCESS'){
//todo 提现成功处理
}else{
$this->error('操作失败:'.$res['return_msg']);
}
}*/
$app = new Application($this->options);
$luckyMoney = $app->lucky_money;
$luckyMoneyData = [
'mch_billno' => 'xy123456',
'send_name' => '测试红包',
're_openid' => 'oxTWIuGaIt6gTKsQRLau2M0yL16E',
'total_num' => 1, //普通红包固定为1,裂变红包不小于3
'total_amount' => 100, //单位为分,普通红包不小于100,裂变红包不小于300
'wishing' => '祝福语',
'client_ip' => '192.168.0.1', //可不传,不传则由 SDK 取当前客户端 IP
'act_name' => '测试活动',
'remark' => '测试备注',
// ...
];
//普通红包
$result = $luckyMoney->send($luckyMoneyData, \EasyWeChat\Payment\LuckyMoney\API::TYPE_NORMAL);
var_dump($result);
}
/**
* 查询红包
*/
public function checkLuckyMoney(){
$mchBillNo = "商户系统内部的订单号(mch_billno)";
$app = new Application($this->options);
$luckyMoney = $app->lucky_money;
$luckyMoney->query($mchBillNo);
}
/**
* 生成签名DEMO
* @return string
*/
public function getSignatureDemo(){
$timeStamp = time();
$randomStr = cmf_random_string(8);
$arithmetic['timeStamp']= $timeStamp;
$arithmetic['randomStr']= $randomStr;
$signature = arithmetic($arithmetic);
$notifyParam=array('t'=>$timeStamp,'r'=>$randomStr,'s'=>$signature);
$url=url('your url 表达式',$notifyParam,true,true);
return $url;
}
}
\ No newline at end of file
... ...
... ... @@ -10,24 +10,108 @@
// +----------------------------------------------------------------------
namespace app\user\controller;
use app\user\model\UserModel;
use cmf\controller\HomeBaseController;
use think\Db;
use EasyWeChat\Foundation\Application;
use think\Log;
class IndexController extends HomeBaseController
{
public function callback(){
$config = [];
$appId=config('wechat_config.app_id');
$secret=config('wechat_config.secret');
$config = [
'app_id' => $appId,
'secret' => $secret,
];
$app = new Application($config);
$oauth = $app->oauth;
$user = $oauth->user();
$wechat_user = $user->toArray();
//todo $wechat_user与数据库对比
session('wechat_user',$wechat_user);
$target_url=session('target_url');
$targetUrl = empty($target_url) ? '/' : $target_url;
header('location:'. $targetUrl);
if(isset($wechat_user['id'])){
$openid=$wechat_user['id'];
$findThirdPartyUser = Db::name("third_party_user")
->where('openid', $openid)
->where('app_id', $appId)
->find();
$currentTime = time();
$ip = $this->request->ip(0, true);
if ($findThirdPartyUser) {
$token = cmf_generate_user_token($findThirdPartyUser['user_id'], 'public');
$userData = [
'last_login_ip' => $ip,
'last_login_time' => $currentTime,
'login_times' => ['exp', 'login_times+1']
];
$row1=Db::name("third_party_user")
->where('openid', $openid)
->where('app_id', $appId)
->update($userData);
$userInfo=Db::name("third_party_user")
->where('openid', $openid)
->where('app_id', $appId)->find();
unset($userData['login_times']);
$row2=Db::name("user")
->where('id', $userInfo['user_id'])
->update($userData);
if($row1!==false&&$row2!==false){
$userModel=new UserModel();
$user=$userModel->getUserInfo(['user_id'=>$userInfo['user_id'],'app_id'=>$appId]);
cmf_update_current_user($user);
session('token',$token);
Db::commit();
}else{
Db::rollback();
}
}else{
Db::startTrans();
$userId = Db::name("user")->insertGetId([
'create_time' => $currentTime,
'user_status' => 1,
'user_type' => 2,
'sex' => $wechat_user['original']['sex'],
'user_nickname' => $wechat_user['nickname'],
'avatar' => $wechat_user['avatar'],
'last_login_ip' => $ip,
'last_login_time' => $currentTime,
]);
$row=Db::name("third_party_user")->insert([
'openid' => $openid,
'user_id' => $userId,
'third_party' => 'public',
'nickname' => $wechat_user['nickname'],
'app_id' => $appId,
'last_login_ip' => $ip,
'union_id' => '',
'last_login_time' => $currentTime,
'create_time' => $currentTime,
'login_times' => 1,
'status' => 1,
'more' => json_encode($wechat_user)
]);
if($userId && $row){
$token = cmf_generate_user_token($userId, 'public');
$userModel=new UserModel();
$user=$userModel->getUserInfo(['user_id'=>$userId,'app_id'=>$appId]);
cmf_update_current_user($user);
session('token',$token);
Db::commit();
}else{
Db::rollback();
}
}
$target_url=session('target_url');
$targetUrl = empty($target_url) ? '/' : $target_url;
header('location:'. $targetUrl);
}else{
Log::write('获取微信用户数据失败');
$this->error('获取微信用户数据失败');
}
}
/**
... ...
... ... @@ -22,6 +22,9 @@ class TestController extends WeChatBaseController
$this->checkWeChatUserLogin();
}
public function index(){
}
}
\ No newline at end of file
... ...
... ... @@ -30,8 +30,8 @@ class UserModel extends Model
if(empty($where)){
redirect('/');
}
$user= Db::name("user_third")->alias('a')
->join('__USER__ b','a.user_id=b.id','LEFT')
$user= Db::name("third_party_user")->alias('b')
->join('__USER__ a','a.id=b.user_id','LEFT')
->field('a.*,b.openid,b.union_id')
->where($where)
->find();
... ...
... ... @@ -80,6 +80,20 @@ function cmf_get_current_user_id()
}
/**
* 获取当前登录前台用户openid
* @return int
*/
function cmf_get_current_user_openid()
{
$sessionOpenId = session('user.openid');
if (empty($sessionOpenId)) {
return 0;
}
return $sessionOpenId;
}
/**
* 返回带协议的域名
*/
function cmf_get_domain()
... ...
... ... @@ -206,17 +206,17 @@ class WeChatBaseController extends BaseController
$userId = cmf_get_current_user_id();
if (empty($userId)) {
$config = [
'app_id' => config('wechat_config.app_id'),
'secret' => config('wechat_config.secret'),
'oauth' => [
'scopes' => ['snsapi_userinfo'],
'callback' => '/oauth_callback',
'callback' => url('user/index/callback'),
],
];
$app = new Application($config);
$oauth = $app->oauth;
$target_url='http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
session('target_url',$target_url);
return $oauth->redirect();
$app->oauth->redirect()->send();
}
}
... ...
... ... @@ -244,8 +244,8 @@ class Payment
{
$config = $this->configForPayment($prepayId, false);
$config['timestamp'] = $config['timeStamp'];
unset($config['timeStamp']);
// $config['timestamp'] = $config['timeStamp'];
// unset($config['timeStamp']);
return $config;
}
... ...