PayController.php 11.3 KB
<?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 '接口出错!';
        }
    }


}