清华大学--赵志磊 商品支付模块 Ajax 前后端分离

后台:(只写接口)

商品列表:

    public static function goodsList($goodsInfo){
        try {
            $page = $goodsInfo['page']?:1;
//            $list_rows = $goodsInfo['list_rows']?:5;
            $redis = Cache::store('redis');
            $goodsList = $redis->get('goods-list-page-'.$page)?:null;
//            如果缓存内不为空就讲redis缓存数据返回前端
            if (!empty($goodsList)){
                return success(200,'商品列表',[
                    'goods'=>$goodsList,
                ]);
            }
//        如果缓存没有 我们需要先获取 然后存入redis
            $goodsList = \app\home\model\Goods::page($page,6)->select();
            $redis->set('goods-list-page'.$page,$goodsList,3600);
            return success(200,'成功',[
                'goods'=>$goodsList,
            ]);
        }catch (\Exception $exception){
            return fail(2001,$exception->getMessage(),[]);
        }
    }

商品详情:

  public static function goodsDetail($id){
        try {
            $goods = \app\home\model\Goods::find($id);
            if ($goods['goods_status'] == 0){
                throw new Exception('商品已售罄');
            }
            return success(200,'商品详情获取成功',[
                'goods'=>$goods,
            ]);
        }catch (\Exception $exception){
            return fail(2001,$exception->getMessage(),[]);
        }

    }

创建订单:

    public static function getOrder($data){
        try {
            $id = $data['id'];
            $number = $data['number'];
            $user_id = get_user_id();
            if (connection_status() != 0){
                throw new \Exception('网络中断,请检查网络');
            }
            if (!is_numeric($id)){
                throw new \Exception('商品参数id不合法');
            }
            if (!is_numeric($number)){
                throw new \Exception('商品参数购买数量不合法');
            }
            $goods = \app\home\model\Goods::find($id);
            Db::startTrans();
            $order_sn = 'pdd'.md5(time().uniqid(1000,9999));
            Order::create([
                'user_id'=>get_user_id(),
               'order_sn'=> $order_sn,
                'order_status'=>0,
                'order_freight'=>0,
                'order_consume'=>$number*$goods['goods_price'],
                'create_time'=>time(),
            ]);
            $order_id = Order::getLastInsID();
            GoodsOrder::create([
               'order_id'=>$order_id,
                'goods_id'=>$id,
                'goods_number'=>$number,
                'goods_price'=>$goods['goods_price'],
                'goods_consume'=>$number*$goods['goods_price'],
                'create_time'=>time(),
            ]);
            Db::commit();
            return success(200,'下单成功',[
                'order_sn'=> $order_sn,
                'total'=>number_format($number*$goods['goods_price'],2),
            ]);
        }catch (\Exception $exception){
            Db::rollback();
            return fail(2001,$exception->getMessage(),[]);
        }
    }

支付:

    public static function pay($data){
        try {
            $order_sn = $data['order_sn'];
            $order = Order::where('order_sn','=',$order_sn)->find();
            if (empty($order)){
                throw new \Exception('订单不存在,请重新下单');
            }
            if (time()- strtotime($order['create_time']) >= 900){
                throw new \Exception('订单超时,请重新下单');
            }
//            防止重复请求
            $is_handle = \cache('order-id-'.$order['id'])?:0;
            if ($is_handle == 1){
                throw new \Exception('订单正在处理中');
            }
//            第一次请求 存入缓存  避免重复支付
            \cache('order-id-'.$order['id'],1);
//            Cache::delete('order-id-'.$order['id']);
//            支付
            $goodsOrder = GoodsOrder::where('order_id','=',$order['id'])->find();
            $total = $goodsOrder['goods_number']*$goodsOrder['goods_price'];

            require_once public_path().'/static/home/alipay/config.php';
            require_once public_path().'/static/home/alipay/pagepay/service/AlipayTradeService.php';
            require_once public_path().'/static/home/alipay/pagepay/buildermodel/AlipayTradePagePayContentBuilder.php';

            $goods = \app\home\model\Goods::find($goodsOrder['goods_id']);
            $body = substr_replace(mb_substr($goods['goods_name'],0,10),'...',30,5);
            $subject = $order_sn;
            $total_amount = $total;
            $out_trade_no = $order_sn;
            //构造参数
//            $payRequestBuilder = new AlipayTradePagePayContentBuilder();
            $payRequestBuilder = new \AlipayTradePagePayContentBuilder();
            $payRequestBuilder->setBody($body);
            $payRequestBuilder->setSubject($subject);
            $payRequestBuilder->setTotalAmount($total_amount);
            $payRequestBuilder->setOutTradeNo($out_trade_no);

            $aop = new \AlipayTradeService($config);

            /**
             * pagePay 电脑网站支付请求
             * @param $builder 业务参数,使用buildmodel中的对象生成。
             * @param $return_url 同步跳转地址,公网可以访问
             * @param $notify_url 异步通知地址,公网可以访问
             * @return $response 支付宝返回的信息
             */
            $response = $aop->pagePay($payRequestBuilder,$config['return_url'],$config['notify_url']);
            //输出表单
            var_dump($response);



        }catch (\Exception $exception){
            return fail(2001,$exception->getMessage(),[]);
        }
    }

同步和异步回掉:

    public static function aliSync($arr)
    {
        try {
            require_once public_path() . '/static/home/alipay/pagepay/service/AlipayTradeService.php';
            $config = config('account');

            $alipaySevice = new \AlipayTradeService($config);
            $result = $alipaySevice->check($arr);
            //验证成功
            if ($result) {
                //商户订单号
                $out_trade_no = htmlspecialchars($arr['out_trade_no']);
//                支付金额
                $total_amount = $arr['total_amount'];
//               条件
                $where = [
                    ['order_sn', '=', $out_trade_no],
                    ['order_consume', '=', $total_amount],
                ];
                $order = Order::where($where)->select();
                if (!$order) {
                    throw new Exception('支付失败');
                }
                return redirect('http://www.chaishao.com/month/pay_success.html');
            }
        }catch (\Exception $exception){
            return redirect('http://www.chaishao.com/month/pay_fail.html');
        }
    }
    public static function aliAsyn($arr){
        try {
            $out_trade_no = $arr['out_trade_no'];
            $trade_status = $arr['trade_status'];
            $order = Order::where('order_sn','=',$out_trade_no)->find();
            if (!$order){
                echo 'fail';
                die();
            }
            if ($order['order_status'] == 1){
//                订单已经做过处理  防止重复提交
                echo 'success';
                die();
            }
            if ($trade_status == 'TRADE_SUCCESS'){
//                判断该笔订单是否再商户网站中做过处理
                Db::startTrans();
                Order::where('order_sn','=',$out_trade_no)->update([
                   'order_status'=>1,
                   'pay_time'=>time(),
                ]);
                PayLog::create([
                    'order_sn'=>$out_trade_no,
                    'json'=>json_encode($arr),
                    'create_time'=>time(),
                ]);
                Log::write(json_encode($arr));
                Db::commit();
                echo 'success';
                die();
            }else{
                echo 'fail';
                die();
            }
        }catch (\Exception $exception){
            Db::rollback();
            echo 'fail';
            die();
        }
    }

订单列表和订单详情:

    public static function orderList($data){
        try {
            $page = $data['page'];
            if (empty($page)){
                throw new \Exception('页码参数为空');
            }
            if (!is_numeric($page) || $page<=0){
                throw new \Exception('页码参数不正确');
            }
            $where = [];
            $where[] =['user_id','=',get_user_id()];
            if (!array_key_exists('order_status',$data)){
                throw new \Exception('订单状态参数缺少');
            }
            if ($data['order_status'] != 1 && $data['order_status'] != 0 && $data['order_status'] != ''){
                throw new \Exception('订单状态参数错误');
            }
            if ($data['order_status'] || $data['order_status'] == 0){
                $order_status = $data['order_status'];
                $where[] = ['order_status','=',"$order_status"];
            }
            $redis = Cache::store('redis');
            $order = $redis->get('order-list-page-'.$page.'-status-'.$data['order_status'])?:'';
            if ($order){
                return success(200,'列表获取成功',[
                   'order'=>json_decode($order),
                ]);
            }
            $order = \app\home\model\Order::where($where)->page($page,6)->select();
            $orderList = json_encode($order);
            $redis->set('order-list-page-'.$page.'-status-'.$data['order_status'],$orderList,3600);
            return success(200,'订单列表获取成功',[
               'order'=>$order,
            ]);
        }catch (\Exception $exception){
            return fail(2001,$exception->getMessage(),[]);
        }
    }
    public static function orderDetail($data){
        try {
            $orderId = $data['id'];
            if (!is_numeric($orderId)){
                throw new \Exception('订单id参数不合法');
            }
            $order = \app\home\model\Order::with('goodsOrder')->find($orderId);
            if (empty($order)){
                throw new \Exception('订单不存在');
            }
            return success(200,'订单详情',[
                'order_detail'=>$order,
            ]);
        }catch (\Exception $exception){
            return fail(2001,$exception->getMessage(),[]);
        }
    }

中间件验证签名和token以及时间戳:

 

    /**
     * 处理请求
     *
     * @param \think\Request $request
     * @param \Closure       $next
     * @return Response
     * 中间件验证
     */
    public function handle($request, \Closure $next)
    {
        try {
            $this->checkTime();
            $this->checkSign();
            $this->checkToken();
//            验证全部通过 方行
            return  $next($request);
        }catch (\Exception $exception){
            return fail(2001,$exception->getMessage(),[]);
        }
    }

    /**
     * @throws \Exception
     * 验证时间戳参数合法与否
     * 以及请求时长是否超时
     */
    public function checkTime(){
        $client_time = request()->get('timestamp')?:request()->post('timestamp');
        if (!is_numeric($client_time)){
            throw new \Exception('时间格式不正确');
        }
        if (time()-$client_time > 60){
            throw new \Exception('请求超时');
        }
    }

    /**
     * @throws \Exception
     * 验证签名
     */
    public function checkSign(){
        $client_sign = request()->get('sign')?:request()->all('sign');
        #判断是否有签名
        if (!$client_sign){
            throw new \Exception('签名不存在');
        }
        #判断签名是否正确
        $server_sign = $this->getSign();
        if ($server_sign != $client_sign){
            throw new \Exception('签名不正确');
        }
    }

    /**
     * @return string
     * 获取签名
     */
    public function getSign(){
        #获取所有参数
        $params = request()->all();
        #签名规则
        #第一步 参与签名的参数不包括签名本身  不包括token
        unset($params['token']);
        unset($params['sign']);
        #第二步 按照ASCLL排序
        ksort($params);
        $wait_sign = '';
        foreach($params as $key => $value){
            $wait_sign .= $key.'='.$value.'&';
        }
        $wait_sign = rtrim($wait_sign,'&');
        return md5($wait_sign);
    }

    /**
     * @throws Exception
     * token验证
     */
    public function checkToken(){
        $token = JWTAuth::token();
        if ($token == null){
            throw new Exception('token不存在-请先登录');
        }
        $token = $token->get();
        $payload = JWTAuth::auth();
        $user_id = $payload['user_id']->getValue();
        if (empty($user_id) || !is_numeric($user_id)){
            throw new \Exception('用户id参数不合法-非法请求');
        }
        $delete_token = cache('delete_token')?:[];
        if (in_array($token,$delete_token)){
            throw new \Exception('token已失效,请重新登录');
        }
    }

 支付时:如果报错 缺少记录日志的文件 则:

define("AOP_SDK_WORK_DIR", dirname(__FILE__)."/tmp/");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柔情柴少

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值