Wxpay.php 8.8 KB
<?php

namespace app\api\controller;

use app\common\controller\Api;
use addons\epay\library\Service;
use app\admin\model\Porder;
use think\Db;
use Yansongda\Pay\Pay;
use app\admin\model\Account;
use app\admin\model\User;
use app\admin\model\Message;
use app\admin\model\off\Line;
use think\Log;
use fast\Http;
use think\Validate;
use Exception;
/**
 * 支付接口**
 */
class Wxpay extends Api
{
    protected  $noNeedLogin = ['notify','notifyCharge'];
    protected $noNeedRight = ['notify','notifyCharge'];
    protected $user_id = '';//token存贮user_id
    protected $order_status = [];//订单状态
    public function _initialize()
    {
        parent::_initialize();
        $this->user_id = $this->auth->getUserId();
        $this->order_status = config('site.order_status');
    }

    /**
     * @ApiTitle    (支付订单)
     * @ApiSummary  (支付订单)
     * @ApiMethod   (POST)
     * @ApiRoute    (/api/wxpay/pay)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     * @ApiParams   (name="openid", type="string", required=true, description="小程序openid")
     * @ApiParams   (name="pay_order_sn", type="string", required=true, description="支付订单号")
     * @ApiParams   (name="share_uid", type="integer", required=false, description="分享用户id")
     * @ApiReturn ({code: 0, msg: "无效的订单", time: "1554176100", data: null})
     */
    public function pay(){
        if($this->request->isPost()){
            //创建支付对象
            $pay = Pay::wechat(Service::getConfig('wechat'));
            $openid = $this->request->post('openid');//小程序传递openid
            $pay_order_sn = $this->request->post('pay_order_sn');//支付订单号
            $share_uid = $this->request->post('share_uid');//分享用户uid
            if(empty($openid) && empty($pay_order_sn)){
                $this->error('无效的参数');
            }
            //查询订单是否已支付
            $is_pay = Db::table('gc_porder')
                ->where(['pay_order_sn' => $pay_order_sn, 'uid' => $this->user_id])
                ->where('status','>',0)
                ->select();
            if ($is_pay) {
                $this->error('该订单已支付过了');
            }
            //是否有此订单
            $exist = Db::table('gc_porder')
                ->where(['pay_order_sn' => $pay_order_sn, 'uid' => $this->user_id, 'status' => $this->order_status[0]])
                ->select();
            if (!$exist) {
                $this->error('无效的订单');
            }
            //计算总价格
            $total_price = 0;
            foreach ($exist as $value) {
                $total_price += $value['total_price'];
            }
            //构建订单信息
            $order = [
                'out_trade_no' => $pay_order_sn,//支付订单号
                'body' => '广西小纸皮再生资源回收有限公司',
//                'total_fee' => 1,
                'total_fee' => floatval($total_price)*100,//单位:分
                'openid' => $openid,
            ];
            if(!empty($share_uid)){
                $order['notify_url'] = url('api/Wxpay/notify/share_uid/'.$share_uid,'','',true);
            }else{
                $order['notify_url'] = url('api/Wxpay/notify','','',true);
            }
            //跳转或输出
            $this->success('成功',$pay->miniapp($order));

        }else{
            $this->error('请求方式错误');
        }
    }

    /**
     * @ApiTitle    (商品订单去付款)
     * @ApiSummary  (商品订单去付款)
     * @ApiMethod   (POST)
     * @ApiRoute    (/api/wxpay/toPay)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     * @ApiParams   (name="o_id", type="integer", required=true, description="订单id")
     * @ApiReturn ({
            "code": 1,
            "msg": "成功",
            "time": "1554184134",
            "data": {
                "pay_order_sn": "155418413436253500503"
            }
            })
     */
    public function toPay(){
        if($this->request->isGet()){
            $o_id = $this->request->get('o_id');//订单id
            $pay = $this->auth->genPayOrderSn();//支付订单号
            $rule = config('site.orders');
            $validate = new Validate($rule['rule'],$rule['msg']);
            if (!$validate->check(['o_id'=>$o_id])) {
                $this->error($validate->getError());
            }
            $p_order = new Porder();
            $res = $p_order->where(['id'=>$o_id,'uid'=>$this->user_id])->update(['pay_order_sn'=>$pay]);
            if($res){
                $this->success('成功',['pay_order_sn'=>$pay]);
            }else{
                $this->error('失败');
            }
        }else{
            $this->error('请求方式错误');
        }
    }

    /**
     * 微信异步通知
     */
    public function notify(){
        $pay = Pay::wechat(Service::getConfig('wechat'));
        $share_uid = $this->request->param('share_uid');
        try {
            $data = $pay->verify();
            if($data['result_code'] == 'SUCCESS' && $data['return_code'] == 'SUCCESS'){
                $porderModel = new Porder();
                $porderModel->where(['pay_order_sn'=>$data['out_trade_no']])->update(['status'=>$this->order_status[1]]);

                //如果携带分享uid,则按照积分增加
                if(!empty($share_uid)){
                    $score = config('site.share_purchase');
                    //给分享用户增加积分
                    $user = new User();
                    $user->where(['id'=>$share_uid,'status'=>'normal'])->setInc('score', $score);
                    //成为分享用户的下线
                    $offlineModel = new Line();
                    $offlineModel->create(['uid'=>$share_uid,'s_score'=>$score,'off_uid'=>$this->user_id]);
                }
            }
        } catch (Exception $e) {
            echo "验签失败";
            return;
        }
        return $pay->success()->send();
    }

    /**
     * @ApiTitle    (充值)
     * @ApiSummary  (充值)
     * @ApiMethod   (POST)
     * @ApiRoute    (/api/wxpay/toPay)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     * @ApiParams   (name="o_id", type="integer", required=true, description="订单id")
     * @ApiReturn ({
        "code": 1,
        "msg": "成功",
        "time": "1554184134",
        "data": null
    })
     */
    public function payCharge(){
        if($this->request->isPost()){
            $amount = $this->request->post('amount');
            $openid = $this->request->post('openid');//小程序传递openid
            if(empty($openid)){
                $this->error("openid必填");
            }
            $pay = Pay::wechat(Service::getConfig('wechat'));
            if (!$amount || $amount < 0) {
                $this->error("充值金额必须大于0");
            }
            $pay_order_sn = $this->auth->genPayOrderSn();//支付订单号
            //构建订单信息
            $order = [
                'out_trade_no' => $pay_order_sn,//支付订单号
                'body' => '广西小纸皮再生资源回收有限公司',
                'total_fee' => floatval($amount)*100,//单位:分
                'openid' => $openid,
                'notify_url'   => url('api/Wxpay/notifyCharge','','',true),
            ];
            //跳转或输出
            $this->success('成功',$pay->miniapp($order));
        }else{
            $this->error('请求方式错误');
        }
    }

    /**
     * 微信异步通知
     */
    public function notifyCharge(){
        $pay = Pay::wechat(Service::getConfig('wechat'));
        try {
            $data = $pay->verify();
            //你可以在这里你的业务处理逻辑,比如处理你的订单状态、给会员加余额等等功能
            if($data['result_code'] == 'SUCCESS' && $data['return_code'] == 'SUCCESS'){
                $money = $data['total_fee'] / 100;
                $userModel = new User();
                $user = $userModel->where(['openid' => $data['openid']])->find();
                //给用户增加充值金额
                $userModel->where(['openid' => $data['openid']])->setInc('money',$money);

                //充值记录
                $accountModel = new Account();
                $account = $accountModel::create(['uid' => $user['id'], 'money' => $money]);

                //系统充值消息
                $messageModel = new Message();
                $messageModel::create(['account_id' => $account->id, 'title' => config('site.message')]);
                Log::info('执行一次');
            }
        } catch (Exception $e) {
            echo "验签失败";
            return;
        }
        //下面这句必须要执行,且在此之前不能有任何输出
        return $pay->success()->send();
    }

}