WechatPay.php 14.0 KB
<?php

namespace app\index\controller;

use app\common\controller\HomeBase;
use app\index\model\OrderDetail;
use app\index\model\OrderInfo;
use app\index\model\Store;
use app\index\model\Viporder;
use EasyWeChat\Foundation\Application;
//use EasyWeChat\Payment\Order;
use think\Db;
use think\Log;

/**
 * 微信支付,退款,提现
 * @ApiInternal
 */
class WechatPay extends HomeBase
{
    protected $options;

    function _initialize()
    {
        $this->options = config('wechat');
    }
    /**
     * 微信支付(购买会员)
     * @param $data
     * @return mixed
     */
    public function index($data)
    {
        $attributes = [
            'trade_type' => 'NATIVE',
            'body' => '工企邦',
            'detail' => '购买会员',
            'out_trade_no' => $data['num'],
            'total_fee' => $data['money'] * 100, // 单位:分
            'notify_url' => url('wechat_pay/notify', '', '', true), // 支付结果通知网址,如果不设置则会使用配置里的默认地址
            'openid' => '', // trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识,
        ];
        $order = new \EasyWeChat\Payment\Order($attributes);

        $app = new Application($this->options);
        $payment = $app->payment;
        $result = $payment->prepare($order);
        if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS') {
            return $result->code_url;
        } else {
            $this->error('支付参数错误', '', $result);
        }
    }

    /**
     * 微信支付(购买商品)
     * @param $data
     * @return mixed
     */
    public function index2($data){
        $attributes = [
            'trade_type' => 'NATIVE',
            'body' => '工企邦',
            'detail' => '购买商品',
            'out_trade_no' => $data['num'],
            'total_fee' => 1,//$data['pay_total'] * 100, // 单位:分
            'notify_url' => url('wechat_pay/notify2', '', '', true), // 支付结果通知网址,如果不设置则会使用配置里的默认地址
            'openid' => '', // trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识,
        ];
        $order = new \EasyWeChat\Payment\Order($attributes);

        $app = new Application($this->options);
        $payment = $app->payment;
        $result = $payment->prepare($order);
        if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS') {
            return $result->code_url;
        } 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;
            $vipOrderModel = new Viporder();
            $data = $vipOrderModel->findData(['num'=>$out_trade_no]);
            if (empty($data)) { // 如果订单不存在
                return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
            }
            // 如果订单存在
            // 检查订单是否已经更新过支付状态
            if (!empty($data['paytime'])) {
                return true;
            }
            $userModel = new \app\index\model\User();
            $user = $userModel->findData(['id'=>$data['user_id']]);
            $storeModel = new Store();
            $store = $storeModel->findData(['user_id'=>$data['user_id']]);
            // 用户是否支付成功
            if($successful){
                if($data['vip_type'] == '1'){
                    //普通会员
                    /*if($user['is_vip'] == '1'){
                        $vip_passtime = $user['vip_passtime'] + 365*24*60*60;
                    }else{
                        $vip_passtime = time() + 365*24*60*60;
                    }*/
                    $arr1['user_id'] = $data['user_id'];
                    if(!empty($store)){
                        $arr1['store_id'] = $store['id'];
                    }
                    $province_ids = explode(',',$data['province_ids']);
                    foreach($province_ids as $key => $province_id){
                        $arr1['province_id'] = $province_id;
                        $arr1['createtime'] = time();
                        $arr1['paytime'] = time();
                        $arr1['expiration_time'] = time() + 365*24*60*60;
                        $user_province = Db::name('user_province')->where(['user_id'=>$data['user_id'],'province_id'=>$province_id])->find();
                        if(!empty($user_province)){
                            if($user_province['expiration_time'] > time()){
                                $arr1['expiration_time'] = $user_province['expiration_time'] + (365*24*60*60);
                            }
                            Db::name('user_province')->where(['id'=>$user_province['id']])->update($arr1);
                        }else{
                            Db::name('user_province')->insert($arr1);
                        }
                    }
                    /*$userModel->updateData(['id'=>$user['id']],['vip_passtime'=>$vip_passtime,'province_ids'=>",".$data['province_ids'].","]);
                    if(!empty($store)){
                        $storeModel->updateData(['id'=>$user['id']],['vip_passtime'=>$vip_passtime,'province_ids'=>",".$data['province_ids'].","]);
                    }*/
                }else if($data['vip_type'] == '2'){
                    //清空普通vip记录
                    Db::name('user_province')->where(['user_id'=>$data['user_id']])->delete();
                    //超级会员
                    if($user['is_svip'] == '1'){
                        $svip_passtime = $user['svip_passtime'] + 365*24*60*60;
                    }else{
                        $svip_passtime = time() + 365*24*60*60;
                    }
                    $userModel->updateData(['id'=>$user['id']],['svip_passtime'=>$svip_passtime]);
                    if(!empty($store)){
                        $storeModel->updateData(['id'=>$store['id']],['svip_passtime'=>$svip_passtime,'viptype'=>2]);
                    }
                }
                $arr['status'] = "2";
                $arr['paytime'] = time();
            }else{
                $arr['status'] = "1";
            }
            $vipOrderModel->updateData(['id'=>$data['id']],$arr);
            return true; // 返回处理完成
        });
        $response->send();
    }

    public function demo(){
        dump(cache('a'));
        dump(cache('b'));
        dump(cache('c'));
        dump(cache('d'));
        dump(cache('e'));
//        dump(cache('f'));
//        dump(cache('g'));
//        dump(cache('h'));
    }

    /**
     * 支付回调(购买商品)
     * @throws \EasyWeChat\Core\Exceptions\FaultException
     */
    public function notify2()
    {
        $app = new Application($this->options);
        $response = $app->payment->handleNotify(function ($notify, $successful) {
            // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
            $out_trade_no=$notify->out_trade_no;
            $identification = substr($out_trade_no, -1);
            $orderModel = new \app\index\model\Order();
            $orderDetailModel = new OrderDetail();
            $orderInfoModel = new OrderInfo();
            if($identification == 1){
                $data = $orderModel->findData(['num'=>$out_trade_no]);
            }else{
                $data = $orderDetailModel->findData(['num'=>$out_trade_no]);
            }
            if (empty($data)) { // 如果订单不存在
                return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
            }
            // 如果订单存在
            // 检查订单是否已经更新过支付状态
            if (!empty($data['paytime'])) {
                return true;
            }
            // 用户是否支付成功
            if($successful){
                if($identification == 1){
                    $orderModel->updateData(['id'=>$data['id']],['paytime'=>time(),'status'=>'2']);
                    $orderDetailModel->updateData(['order_id'=>$data['id']],['paytime'=>time(),'status'=>'2']);
                    $order_info = $orderInfoModel->selectData(['order_id'=>$data['id']]);
                }else{
                    $orderDetailModel->updateData(['id'=>$data['id']],['paytime'=>time(),'status'=>'2']);
                    $order_detail_status1_count = $orderDetailModel->findData(['order_id'=>$data['order_id'],'status'=>'1']);
                    if($order_detail_status1_count == 0){
                        $orderModel->updateData(['id'=>$data['order_id']],['paytime'=>time(),'status'=>'2']);
                    }
                    $order_info = $orderInfoModel->selectData(['order_detail_id'=>$data['id']]);
                }
                $goodsModel = new \app\index\model\Goods();
                //扣除库存、增销量
                foreach($order_info as $key => $o_i){
//                    $goods = $goodsModel->findData(['g.id'=>$o_i['goods_id']]);
                    $goodsModel->where(['id'=>$o_i['goods_id']])->setDec('inventory',$o_i['number']);
                    $goodsModel->where(['id'=>$o_i['goods_id']])->setInc('sale',$o_i['number']);
                }
            }
            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 = 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;
    }


}