<?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(){ $order_id = $this->request->param('id'); $data = Db::name('order')->where('id',$order_id)->find(); if(empty($data)){ $this->error('未查询到该订单!',''); } $attributes = [ 'trade_type' => 'JSAPI', 'body' => '橙象保单', 'detail' => '橙象', 'out_trade_no' => $data['num'], 'total_fee' => $data['total']*100,//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( array( 'jsApiParameters'=>json_encode($jsApiParameters), 'total'=>$data['total'], 'title'=>'橙象保单' ) ); return $this->fetch(); }else{ $this->error('支付参数错误','',$result); } } /** * 支付回调 * @throws \EasyWeChat\Core\Exceptions\FaultException */ public function notify(){ $app = new Application($this->options); $response = $app->payment->handleNotify(function($notify, $successful){ // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单 $out_trade_no=$notify->out_trade_no; $order = Db::name('order')->where('num',$out_trade_no)->find(); $order_info = Db::name('order_info')->where('order_id',$order['id'])->find(); $collocation = Db::name('collocation')->where('id',$order_info['collocation_id'])->find(); if (!$order) { // 如果订单不存在 return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了 } // 如果订单存在 // 检查订单是否已经更新过支付状态 if ($order['pay_time']>0) { // 假设订单字段“支付时间”不为空代表已经支付 return true; // 已经支付成功了就不再更新了 } // 用户是否支付成功 if ($successful) { Db::name('order_num')->insert(array('user_id'=>$order['user_id'],'create_time'=>time())); $data4 = []; $payment_time = $collocation['payment_time']; for($i=0;$i<$payment_time;$i++){ if($collocation['expire_time']-($i*365*24*60*60)-(30*24*60*60)>time()){ $data3['user_id'] = $order['user_id']; $data3['order_id'] = $order['id']; $data3['collocation_id'] = $collocation['id']; $data3['time'] = $collocation['expire_time']-($i*365*24*60*60)-(30*24*60*60); $data4[] = $data3; }else{ $data3['time'] = $collocation['expire_time']-(30*24*60*60); $data4[] = $data3; } } $update['pay_time']=time(); //未支付状态则修改为已经支付状态 $update['status'] = 3; $update['order_expire_time']=$collocation['expire_time']; $update['order_about_time']=$data4[count($data4)-1]['time']; $update['order_expire_time2']=time()+(365*24*60*60); cache('update',$update); //推送模板消息 $templateId = 'iZwqjrOt7NCILnI0zkayK59y4jUXmnmfmROERWq-NEw'; $data1 = array( 'first'=>"您好,您已购买成功。", 'name'=>$collocation['product_name'], 'remark'=>"您好,您已购买成功。", ); $url = ''; $user1 = Db::name('third_party_user')->where('user_id',$order['user_id'])->find(); $this->template($templateId,$data1,$url,$user1['openid']); //短信通知 $user = Db::name('user')->where('id',$order['user_id'])->find(); $data = array( 'content' => "【橙象保险】尊敬的用户您的保单即将生效,保单号为$collocation[insurance_num]。",//短信内容 'mobile' => $user['mobile'],//手机号码 'productid' => '887361',//产品id 'xh' => ''//小号 ); $result = send_sms($data); cache('result',$result); } else { // 用户支付失败 $update['status']=2; } Db::name('order')->where('num',$out_trade_no)->update($update); return true; // 返回处理完成 }); $response->send(); } public function demo(){ dump(cache('result')); dump(cache('update')); } /** * 查询订单 */ 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; } public function template($templateId,$data,$url=null,$openid){ $options=config('wechat_config'); $app = new Application($options); $notice = $app->notice; if(empty($url)){ $notice->uses($templateId)->andData($data)->andReceiver($openid)->send(); }else{ $notice->uses($templateId)->withUrl($url)->andData($data)->andReceiver($openid)->send(); } } public function note($content,$mobile){ $data = array( 'content' => $content,//短信内容 'mobile' => $mobile,//手机号码 'productid' => '887361',//产品id 'xh' => ''//小号 ); $result = send_sms($data); if(substr($result,0,strpos($result,',')) == "1"){ echo '发送成功!'; }else{ echo '接口出错!'; } } }