<?php namespace app\portal\controller; use cmf\controller\HomeBaseController; use EasyWeChat\Foundation\Application; use EasyWeChat\Payment\Order; use think\Db; /** * 微信支付,退款,提现DEMO * Class PayController * @package app\portal\controller */ class PayController extends HomeBaseController { protected $options; function _initialize() { parent::_initialize(); $this->options = [ 'app_id' => config('wechat_config.app_id'), 'secret' => config('wechat_config.secret'), 'payment' => config('wechat_config.payment'), ]; } /** * 微信支付 */ public function index(){ $id = $this->request->param('id',0,'intval'); if(empty($id)){ $this->error('缺少必要参数','','',''); } $data = Db::name('indent')->where('id',$id)->find(); if(empty($data)){ $this->error('查询为空','','',''); } if($data['state'] != 4){ $this->error('订单不是待支付状态','','',''); } $attributes = [ 'trade_type' => 'JSAPI', 'body' => '百荣科技', 'detail' => '以客户为中心 以奋斗者文本', 'out_trade_no' => $data['order_number'], 'total_fee' => $data['money']*100, // 单位:分 '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); $out_trade_no=$notify->out_trade_no; //查询订单信息 $order = Db::name('indent')->where('order_number',$out_trade_no)->find(); if($successful){ $update['state'] = 2; //更新订单状态为待发货 Db::name('indent')->where('order_number',$out_trade_no)->update($update); $uid = cmf_get_current_user_id(); //查询当前用户身份 $data_user = Db::name('my_user')->where('uid',$uid)->find(); if($order['indent_type'] == 1){ //如果是平台商品 学生购买 if($data_user['status'] == 4){ //查询平台商品老师和业务员所占的佣金比例 $money_ratio = Db::name('money_ratio') -> where('id',1) -> find(); //查询这条订单下的所有商品 $data_indent_goods = Db::name('indent_goods') -> where('indent_id',$order['id']) -> select(); $money_salesman = 0; //查询老师的uid $teacher = Db::name('my_user') -> where('id',$data_user['pid']) -> find(); //查询业务员的uid $salesman = Db::name('my_user') -> where('id',$teacher['pid']) -> find(); foreach ($data_indent_goods as $key => $val){ $money_salesman += $val['price']*$val['number']*$money_ratio['salesman_ratio']; $data_money_income_salesman['create_time'] = time(); $data_money_income_salesman['money'] = $money_salesman; $data_money_income_salesman['type'] = 1; $data_money_income_salesman['book_name'] = $val['book_name']; $data_money_income_salesman['book_thumbnail'] = $val['thumbnail']; $data_money_income_salesman['book_num'] = $val['number']; $data_money_income_salesman['uid'] = $salesman['uid']; Db::name('money_income') -> insert($data_money_income_salesman); } Db::name('my_user') -> where('uid',$salesman['uid']) -> setInc('balance',$money_salesman); $money_teacher = 0; foreach ($data_indent_goods as $key => $val){ $money_teacher += $val['price']*$val['number']*$money_ratio['teacher_ratio']; $data_money_income_teacher['create_time'] = time(); $data_money_income_teacher['money'] = $money_teacher; $data_money_income_teacher['type'] = 1; $data_money_income_teacher['book_name'] = $val['book_name']; $data_money_income_teacher['book_thumbnail'] = $val['thumbnail']; $data_money_income_teacher['book_num'] = $val['number']; $data_money_income_teacher['uid'] = $teacher['uid']; Db::name('money_income') -> insert($data_money_income_teacher); } Db::name('my_user') -> where('uid',$teacher['uid']) -> setInc('balance',$money_salesman); } //如果是平台商品 老师购买 if($data_user['status'] == 3){ //查询平台商品老师和业务员所占的佣金比例 $money_ratio = Db::name('money_ratio') -> where('id',1) -> find(); //查询这条订单下的所有商品 $data_indent_goods = Db::name('indent_goods') -> where('indent_id',$order['id']) -> select(); $money_salesman = 0; //查询老师的uid /* $teacher = Db::name('my_user') -> where('id',$data_user['pid']) -> find();*/ //查询业务员的uid $salesman = Db::name('my_user') -> where('id',$data_user['pid']) -> find(); foreach ($data_indent_goods as $key => $val){ $money_salesman += $val['price']*$val['number']*$money_ratio['salesman_ratio']; $data_money_income_salesman['create_time'] = time(); $data_money_income_salesman['money'] = $money_salesman; $data_money_income_salesman['type'] = 1; $data_money_income_salesman['book_name'] = $val['book_name']; $data_money_income_salesman['book_thumbnail'] = $val['thumbnail']; $data_money_income_salesman['book_num'] = $val['number']; $data_money_income_salesman['uid'] = $salesman['uid']; Db::name('money_income') -> insert($data_money_income_salesman); } Db::name('my_user') -> where('uid',$salesman['uid']) -> setInc('balance',$money_salesman); $money_teacher = 0; foreach ($data_indent_goods as $key => $val){ $money_teacher += $val['price']*$val['number']*$money_ratio['teacher_ratio']; $data_money_income_teacher['create_time'] = time(); $data_money_income_teacher['money'] = $money_teacher; $data_money_income_teacher['type'] = 1; $data_money_income_teacher['book_name'] = $val['book_name']; $data_money_income_teacher['book_thumbnail'] = $val['thumbnail']; $data_money_income_teacher['book_num'] = $val['number']; $data_money_income_teacher['uid'] = $data_user['uid']; Db::name('money_income') -> insert($data_money_income_teacher); } Db::name('my_user') -> where('uid',$data_user['uid']) -> setInc('balance',$money_salesman); } }else if($order['indent_type'] == 2){ //如果是业务员订单 //查询平台商品老师和业务员所占的佣金比例 $money_ratio = Db::name('money_ratio') -> where('id',1) -> find(); //查询这条订单下的所有商品 $data_indent_goods = Db::name('indent_goods') -> where('indent_id',$order['id']) -> select(); //业务员商品学生购买 if($data_user['status'] == 4){ $teacher = Db::name('my_user') -> where('id',$data_user['pid']) -> find(); $money = 0; foreach ($data_indent_goods as $key => $val){ $money += $val['commission']*$val['number']; $money_income_teacher['create_time'] = time(); $money_income_teacher['money'] = $money; $money_income_teacher['type'] = 2; $money_income_teacher['book_name'] = $val['book_name']; $money_income_teacher['book_thumbnail'] = $val['thumbnail']; $money_income_teacher['book_num'] = $val['number']; $money_income_teacher['uid'] = $teacher['uid']; Db::name('money_income') -> insert($money_income_teacher); } //增加老师余额 Db::name('my_user') -> where('uid',$teacher['uid']) -> setInc('balance',$money); //计算业务员这条订单的收入 $balance_salesman = $order['money'] - $order['money']*$money_ratio['platform_ratio'] - $money; //增加业务员的余额 Db::name('my_user') -> where('uid',$order['salesman_uid']) -> setInc('balance',$balance_salesman); //添加业务员的收入记录 $money_income_salesman_indent['create_time'] = time(); $money_income_salesman_indent['uid'] = $order['salesman_uid']; $money_income_salesman_indent['money'] = $balance_salesman; $money_income_salesman_indent['type'] = 2; $money_income_salesman_indent['indent_id'] = $order['id']; Db::name('money_income') -> insert($money_income_salesman_indent); } //业务员商品老师购买 if ($data_user['status'] == 3){ $teacher = $data_user['uid']; $money = 0; foreach ($data_indent_goods as $key => $val){ $money += $val['commission']*$val['number']; $money_income_teacher['create_time'] = time(); $money_income_teacher['money'] = $money; $money_income_teacher['type'] = 2; $money_income_teacher['book_name'] = $val['book_name']; $money_income_teacher['book_thumbnail'] = $val['thumbnail']; $money_income_teacher['book_num'] = $val['number']; $money_income_teacher['uid'] = $teacher; Db::name('money_income') -> insert($money_income_teacher); } //增加老师余额 Db::name('my_user') -> where('uid',$teacher) -> setInc('balance',$money); //计算业务员这条订单的收入 $balance_salesman = $order['money'] - $order['money']*$money_ratio['platform_ratio'] - $money; //增加业务员的余额 Db::name('my_user') -> where('uid',$order['salesman_uid']) -> setInc('balance',$balance_salesman); //添加业务员的收入记录 $money_income_salesman_indent['create_time'] = time(); $money_income_salesman_indent['uid'] = $order['salesman_uid']; $money_income_salesman_indent['money'] = $balance_salesman; $money_income_salesman_indent['type'] = 2; $money_income_salesman_indent['indent_id'] = $order['id']; Db::name('money_income') -> insert($money_income_salesman_indent); } } } return true; // 返回处理完成 }); $response->send(); } /** * 查询订单 */ public function checkOrder(){ $app = new Application($this->options); $payment = $app->payment; $orderNo = "2018080397545210";//商户系统内部的订单号(out_trade_no) $result=$payment->query($orderNo); var_dump($result); } /** * 退款 */ public function refund(){ //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('签名验证失败'); }*/ $app = new Application($this->options); $payment = $app->payment; //使用商户订单号退款 PS.其他形式参考文档 $orderNo = "2018080397100101";//商户系统内部的订单号(out_trade_no) $refundNo = cmf_get_order_sn();//退款单号 $result = $payment->refund($orderNo, $refundNo, 1, 1); // 总金额 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 refundNotify() { cache('test',123123); $app = new Application($this->options); $response = $app->payment->handleRefundNotify(function ($message, $reqInfo) { cache('message',$message); cache('reqInfo',$reqInfo); // 其中 $message['req_info'] 获取到的是加密信息 // $reqInfo 为 message['req_info'] 解密后的信息 // 你的业务逻辑... return true; // 返回 true 告诉微信“我已处理完成” // 或返回错误原因 $fail('参数格式校验错误'); }); $response->send(); } /** * 红包 */ public function luckyMoney(){ //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('签名验证失败'); }*/ $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; } }