Преглед изворни кода

添加当面付接口/公私钥输入时自动去除空格和换行

yiheyang пре 7 година
родитељ
комит
be59753784

+ 23 - 3
app/Http/Controllers/AdminController.php

@@ -2033,20 +2033,40 @@ EOF;
             $value = intval($value) / 100;
         }
 
-        // 用有赞云支付不可用AliPay
+        // 用有赞云支付不可用AliPay和当面付
         if (in_array($name, ['is_youzan']) && $name) {
             $is_alipay = Config::query()->where('name', 'is_alipay')->first();
             if ($is_alipay->value) {
-                return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【AliPay支付】']);
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【支付宝国际支付】']);
+            }
+            $is_f2fpay = Config::query()->where('name', 'is_f2fpay')->first();
+            if ($is_f2fpay->value) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【支付宝当面付】']);
             }
         }
 
-        // 用AliPay支付不可用有赞云支付
+        // 用AliPay支付不可用有赞云支付和当面付
         if (in_array($name, ['is_alipay']) && $name) {
             $is_youzan = Config::query()->where('name', 'is_youzan')->first();
             if ($is_youzan->value) {
                 return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【有赞云支付】']);
             }
+            $is_f2fpay = Config::query()->where('name', 'is_f2fpay')->first();
+            if ($is_f2fpay->value) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【支付宝当面付】']);
+            }
+        }
+
+        // 用当面不可用有赞云支付和Alipay支付
+        if (in_array($name, ['is_f2fpay']) && $name) {
+            $is_youzan = Config::query()->where('name', 'is_youzan')->first();
+            if ($is_youzan->value) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【有赞云支付】']);
+            }
+            $is_alipay = Config::query()->where('name', 'is_alipay')->first();
+            if ($is_alipay->value) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【支付宝国际支付】']);
+            }
         }
 
         // 更新配置

+ 283 - 0
app/Http/Controllers/Api/F2fpayController.php

@@ -0,0 +1,283 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Components\Helpers;
+use App\Components\AlipayNotify;
+use App\Http\Controllers\Controller;
+use App\Http\Models\Goods;
+use App\Http\Models\GoodsLabel;
+use App\Http\Models\Order;
+use App\Http\Models\Payment;
+use App\Http\Models\SsNode;
+use App\Http\Models\SsNodeLabel;
+use App\Http\Models\User;
+use App\Http\Models\UserLabel;
+use App\Mail\sendUserInfo;
+use Illuminate\Http\Request;
+use Log;
+use DB;
+use Mail;
+use Hash;
+
+/**
+ * Class AlipayController
+ *
+ * @author  wz812180
+ *
+ * @package App\Http\Controllers\Api
+ */
+class F2fpayController extends Controller
+{
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    // 接收GET请求
+    public function index(Request $request)
+    {
+        \Log::info("【AliPay】回调接口[GET]:" . var_export($request->all(), true) . '[' . getClientIp() . ']');
+        exit("【AliPay】接口正常");
+    }
+
+    // 接收POST请求
+    public function store(Request $request)
+    {
+        \Log::info("【AliPay】回调接口[POST]:" . var_export($request->all(), true));
+
+        $result = "fail";
+        $alipayNotify = new AlipayNotify(self::$systemConfig['alipay_sign_type'], self::$systemConfig['alipay_partner'], self::$systemConfig['alipay_key'], self::$systemConfig['alipay_private_key'], self::$systemConfig['alipay_public_key'], self::$systemConfig['alipay_transport']);
+
+        // 验证支付宝交易
+        $verify_result = $alipayNotify->verifyNotify();
+        if ($verify_result) { // 验证成功
+            $result = "success";
+            if ($_POST['trade_status'] == 'TRADE_FINISHED' || $_POST['trade_status'] == 'TRADE_SUCCESS') {
+                // 商户订单号
+                $data = [];
+                $data['out_trade_no'] = $request->get('out_trade_no');
+                // 支付宝交易号
+                $data['trade_no'] = $request->get('trade_no');
+                // 交易状态
+                $data['trade_status'] = $request->get('trade_status');
+                // 交易金额(这里是按照结算货币汇率的金额,和rmb_fee不相等)
+                $data['total_fee'] = $request->get('total_fee');
+
+                $this->tradePaid($data);
+            } else {
+                Log::info('AliPay-POST:交易失败[' . getClientIp() . ']');
+            }
+        } else {
+            Log::info('AliPay-POST:验证失败[' . getClientIp() . ']');
+        }
+
+        // 返回验证结果
+        exit($result);
+    }
+
+    // 交易支付
+    private function tradePaid($msg)
+    {
+        Log::info('【Alipay】回调交易支付');
+
+        // 获取未完成状态的订单防止重复增加时间
+        $payment = Payment::query()->with(['order', 'order.goods'])->where('status', 0)->where('order_sn', $msg['out_trade_no'])->first();
+        if (!$payment) {
+            Log::info('【Alipay】回调订单不存在');
+            return;
+        }
+
+        // 处理订单
+        DB::beginTransaction();
+        try {
+            // 如果支付单中没有用户信息则创建一个用户
+            if (!$payment->user_id) {
+                // 生成一个可用端口
+                $port = self::$systemConfig['is_rand_port'] ? Helpers::getRandPort() : Helpers::getOnlyPort();
+
+                $user = new User();
+                $user->username = '自动生成-' . $payment->order->email;
+                $user->password = Hash::make(makeRandStr());
+                $user->port = $port;
+                $user->passwd = makeRandStr();
+                $user->vmess_id = createGuid();
+                $user->enable = 1;
+                $user->method = Helpers::getDefaultMethod();
+                $user->protocol = Helpers::getDefaultProtocol();
+                $user->obfs = Helpers::getDefaultObfs();
+                $user->usage = 1;
+                $user->transfer_enable = 1; // 新创建的账号给1,防止定时任务执行时发现u + d >= transfer_enable被判为流量超限而封禁
+                $user->enable_time = date('Y-m-d');
+                $user->expire_time = date('Y-m-d', strtotime("+" . $payment->order->goods->days . " days"));
+                $user->reg_ip = getClientIp();
+                $user->referral_uid = 0;
+                $user->traffic_reset_day = 0;
+                $user->status = 1;
+                $user->save();
+
+                if ($user->id) {
+                    Order::query()->where('oid', $payment->oid)->update(['user_id' => $user->id]);
+                }
+            }
+
+            // 更新支付单
+            $payment->pay_way = 2; // 1-微信、2-支付宝
+            $payment->status = 1;
+            $payment->save();
+
+            // 更新订单
+            $order = Order::query()->with(['user'])->where('oid', $payment->oid)->first();
+            $order->status = 2;
+            $order->save();
+
+            $goods = Goods::query()->where('id', $order->goods_id)->first();
+
+            // 商品为流量或者套餐
+            if ($goods->type <= 2) {
+                // 如果买的是套餐,则先将之前购买的所有套餐置都无效,并扣掉之前所有套餐的流量,重置用户已用流量为0
+                if ($goods->type == 2) {
+                    $existOrderList = Order::query()
+                        ->with(['goods'])
+                        ->whereHas('goods', function ($q) {
+                            $q->where('type', 2);
+                        })
+                        ->where('user_id', $order->user_id)
+                        ->where('oid', '<>', $order->oid)
+                        ->where('is_expire', 0)
+                        ->where('status', 2)
+                        ->get();
+
+                    foreach ($existOrderList as $vo) {
+                        Order::query()->where('oid', $vo->oid)->update(['is_expire' => 1]);
+
+                        // 先判断,防止手动扣减过流量的用户流量被扣成负数
+                        if ($order->user->transfer_enable - $vo->goods->traffic * 1048576 <= 0) {
+                            // 写入用户流量变动记录
+                            Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, 0, 0, '[在线支付]用户购买套餐,先扣减之前套餐的流量(扣完)');
+
+                            User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0, 'transfer_enable' => 0]);
+                        } else {
+                            // 写入用户流量变动记录
+                            $user = User::query()->where('id', $order->user_id)->first(); // 重新取出user信息
+                            Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, $user->transfer_enable, ($user->transfer_enable - $vo->goods->traffic * 1048576), '[在线支付]用户购买套餐,先扣减之前套餐的流量(未扣完)');
+
+                            User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0]);
+                            User::query()->where('id', $order->user_id)->decrement('transfer_enable', $vo->goods->traffic * 1048576);
+                        }
+                    }
+                }
+
+                // 写入用户流量变动记录
+                $user = User::query()->where('id', $order->user_id)->first(); // 重新取出user信息
+                Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, $user->transfer_enable, ($user->transfer_enable + $goods->traffic * 1048576), '[在线支付]用户购买商品,加上流量');
+
+                // 把商品的流量加到账号上
+                User::query()->where('id', $order->user_id)->increment('transfer_enable', $goods->traffic * 1048576);
+
+                // 计算账号过期时间
+                if ($order->user->expire_time < date('Y-m-d', strtotime("+" . $goods->days . " days"))) {
+                    $expireTime = date('Y-m-d', strtotime("+" . $goods->days . " days"));
+                } else {
+                    $expireTime = $order->user->expire_time;
+                }
+
+                // 套餐就改流量重置日,流量包不改
+                if ($goods->type == 2) {
+                    if (date('m') == 2 && date('d') == 29) {
+                        $traffic_reset_day = 28;
+                    } else {
+                        $traffic_reset_day = date('d') == 31 ? 30 : abs(date('d'));
+                    }
+                    User::query()->where('id', $order->user_id)->update(['traffic_reset_day' => $traffic_reset_day, 'expire_time' => $expireTime, 'enable' => 1]);
+                } else {
+                    User::query()->where('id', $order->user_id)->update(['expire_time' => $expireTime, 'enable' => 1]);
+                }
+
+                // 写入用户标签
+                if ($goods->label) {
+                    // 用户默认标签
+                    $defaultLabels = [];
+                    if (self::$systemConfig['initial_labels_for_user']) {
+                        $defaultLabels = explode(',', self::$systemConfig['initial_labels_for_user']);
+                    }
+
+                    // 取出现有的标签
+                    $userLabels = UserLabel::query()->where('user_id', $order->user_id)->pluck('label_id')->toArray();
+                    $goodsLabels = GoodsLabel::query()->where('goods_id', $order->goods_id)->pluck('label_id')->toArray();
+
+                    // 标签去重
+                    $newUserLabels = array_values(array_unique(array_merge($userLabels, $goodsLabels, $defaultLabels)));
+
+                    // 删除用户所有标签
+                    UserLabel::query()->where('user_id', $order->user_id)->delete();
+
+                    // 生成标签
+                    foreach ($newUserLabels as $vo) {
+                        $obj = new UserLabel();
+                        $obj->user_id = $order->user_id;
+                        $obj->label_id = $vo;
+                        $obj->save();
+                    }
+                }
+
+                // 写入返利日志
+                if ($order->user->referral_uid) {
+                    $this->addReferralLog($order->user_id, $order->user->referral_uid, $order->oid, $order->amount, $order->amount * self::$systemConfig['referral_percent']);
+                }
+
+                // 取消重复返利
+                User::query()->where('id', $order->user_id)->update(['referral_uid' => 0]);
+            } elseif ($goods->type == 3) { // 商品为在线充值
+                User::query()->where('id', $order->user_id)->increment('balance', $goods->price * 100);
+
+                // 余额变动记录日志
+                $this->addUserBalanceLog($order->user_id, $order->oid, $order->user->balance, $order->user->balance + $goods->price, $goods->price, '用户在线充值');
+            }
+
+            // 自动提号机:如果order的email值不为空
+            if ($order->email) {
+                $title = '自动发送账号信息';
+                $content = [
+                    'order_sn'      => $order->order_sn,
+                    'goods_name'    => $order->goods->name,
+                    'goods_traffic' => flowAutoShow($order->goods->traffic * 1048576),
+                    'port'          => $order->user->port,
+                    'passwd'        => $order->user->passwd,
+                    'method'        => $order->user->method,
+                    //'protocol'       => $order->user->protocol,
+                    //'protocol_param' => $order->user->protocol_param,
+                    //'obfs'           => $order->user->obfs,
+                    //'obfs_param'     => $order->user->obfs_param,
+                    'created_at'    => $order->created_at->toDateTimeString(),
+                    'expire_at'     => $order->expire_at
+                ];
+
+                // 获取可用节点列表
+                $labels = UserLabel::query()->where('user_id', $order->user_id)->get()->pluck('label_id');
+                $nodeIds = SsNodeLabel::query()->whereIn('label_id', $labels)->get()->pluck('node_id');
+                $nodeList = SsNode::query()->whereIn('id', $nodeIds)->orderBy('sort', 'desc')->orderBy('id', 'desc')->get()->toArray();
+                $content['serverList'] = $nodeList;
+
+                try {
+                    Mail::to($order->email)->send(new sendUserInfo($content));
+                    Helpers::addEmailLog($order->email, $title, json_encode($content));
+                } catch (\Exception $e) {
+                    Helpers::addEmailLog($order->email, $title, json_encode($content), 0, $e->getMessage());
+                }
+            }
+
+            DB::commit();
+        } catch (\Exception $e) {
+            DB::rollBack();
+            Log::info('【Alipay】回调更新支付单和订单异常:' . $e->getMessage());
+        }
+    }
+
+    public function show(Request $request)
+    {
+        exit('show');
+    }
+}

+ 28 - 2
app/Http/Controllers/PaymentController.php

@@ -11,6 +11,7 @@ use App\Http\Models\Order;
 use App\Http\Models\Payment;
 use App\Http\Models\PaymentCallback;
 use Illuminate\Http\Request;
+use Payment\Client\Charge;
 use Response;
 use Redirect;
 use Log;
@@ -46,7 +47,7 @@ class PaymentController extends Controller
         }
 
         // 判断是否开启有赞云支付
-        if (!self::$systemConfig['is_youzan'] && !self::$systemConfig['is_alipay']) {
+        if (!self::$systemConfig['is_youzan'] && !self::$systemConfig['is_alipay'] && !self::$systemConfig['is_f2fpay']) {
             return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:系统并未开启在线支付功能']);
         }
 
@@ -123,6 +124,8 @@ class PaymentController extends Controller
                 $pay_way = 2;
             } elseif (self::$systemConfig['is_alipay']) {
                 $pay_way = 4;
+            } elseif (self::$systemConfig['is_f2fpay']) {
+                $pay_way = 5;
             }
 
             // 生成订单
@@ -167,6 +170,23 @@ class PaymentController extends Controller
                 // 建立请求
                 $alipaySubmit = new AlipaySubmit(self::$systemConfig['alipay_sign_type'], self::$systemConfig['alipay_partner'], self::$systemConfig['alipay_key'], self::$systemConfig['alipay_private_key']);
                 $result = $alipaySubmit->buildRequestForm($parameter, "post", "确认");
+            } elseif (self::$systemConfig['is_f2fpay']) {
+                $result = Charge::run("ali_qr", [
+                    'use_sandbox'     => false,
+                    "partner"         => self::$systemConfig['f2fpay_app_id'],
+                    'app_id'          => self::$systemConfig['f2fpay_app_id'],
+                    'sign_type'       => 'RSA2',
+                    'ali_public_key'  => self::$systemConfig['f2fpay_public_key'],
+                    'rsa_private_key' => self::$systemConfig['f2fpay_private_key'],
+                    'notify_url'      => self::$systemConfig['website_url'] . "/api/f2fpay", // 异步回调接口
+                    'return_url'      => self::$systemConfig['website_url'],
+                    'return_raw'      => false
+                ], [
+                    'body'     => '',
+                    'subject'  => '充值/购买',
+                    'order_no' => $orderSn,
+                    'amount'   => $amount,
+                ]);
             }
 
             $payment = new Payment();
@@ -183,6 +203,10 @@ class PaymentController extends Controller
                 $payment->qr_local_url = $this->base64ImageSaver($result['response']['qr_code']);
             } elseif (self::$systemConfig['is_alipay']) {
                 $payment->qr_code = $result;
+            } elseif (self::$systemConfig['is_f2fpay']) {
+                $payment->qr_code = $result;
+                $payment->qr_url = 'http://qr.liantu.com/api.php?text=' . $result . '&bg=ffffff&fg=1eabfc&pt=1c73bd&m=0&w=400&el=1&inpt=1eabfc';
+                $payment->qr_local_url = $payment->qr_url;
             }
             $payment->status = 0;
             $payment->save();
@@ -198,7 +222,7 @@ class PaymentController extends Controller
             }
 
             DB::commit();
-	    
+
             if (self::$systemConfig['is_alipay']) {
                 // Alipay返回支付信息
                 return Response::json(['status' => 'success', 'data' => $result, 'message' => '创建订单成功,正在转到付款页面,请稍后']);
@@ -238,6 +262,8 @@ class PaymentController extends Controller
         $view['website_analytics'] = self::$systemConfig['website_analytics'];
         $view['website_customer_service'] = self::$systemConfig['website_customer_service'];
         $view['is_alipay'] = self::$systemConfig['is_alipay'];
+        $view['is_f2fpay'] = self::$systemConfig['is_f2fpay'];
+        $view['is_youzan'] = self::$systemConfig['is_youzan'];
 
         return Response::view('payment.detail', $view);
     }

+ 1 - 0
app/Http/Controllers/UserController.php

@@ -760,6 +760,7 @@ class UserController extends Controller
             $view['goods'] = $goods;
             $view['is_youzan'] = self::$systemConfig['is_youzan'];
             $view['is_alipay'] = self::$systemConfig['is_alipay'];
+            $view['is_f2fpay'] = self::$systemConfig['is_f2fpay'];
 
             return Response::view('user.buy', $view);
         }

+ 1 - 0
composer.json

@@ -21,6 +21,7 @@
         "phpoffice/phpspreadsheet": "^1.6",
         "predis/predis": "^1.1",
         "rap2hpoutre/laravel-log-viewer": "^1.0",
+        "riverslei/payment": "*",
         "spatie/laravel-permission": "^2.29",
         "youzan/open-sdk": "^1.0"
     },

+ 62 - 2
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "0f9a76403962ab65ed544a820f7aa986",
+    "content-hash": "548690c9d667e05f6589c9f975b31819",
     "packages": [
         {
             "name": "barryvdh/laravel-ide-helper",
@@ -3377,6 +3377,66 @@
             ],
             "time": "2019-01-02T21:10:18+00:00"
         },
+        {
+            "name": "riverslei/payment",
+            "version": "v4.1.7",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/helei112g/payment.git",
+                "reference": "94ecb0306288e3d8f60bbcc1a3a5e045c5bfa588"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/helei112g/payment/zipball/94ecb0306288e3d8f60bbcc1a3a5e045c5bfa588",
+                "reference": "94ecb0306288e3d8f60bbcc1a3a5e045c5bfa588",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://dl.laravel-china.org/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "ext-bcmath": "*",
+                "ext-mbstring": "*",
+                "guzzlehttp/guzzle": "~6.0",
+                "php": ">=5.6"
+            },
+            "require-dev": {
+                "codeception/codeception": "*",
+                "endroid/qrcode": "~1.9"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Payment\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "helei",
+                    "email": "[email protected]",
+                    "homepage": "https://helei112g.github.io/categories/payment-3/"
+                }
+            ],
+            "description": "支付宝支付、微信支付、招商一网通支付php SDK。方便快速接入,最完整的开源支付 php sdk",
+            "homepage": "https://helei112g.github.io/categories/payment-3/",
+            "keywords": [
+                "alipay",
+                "weixin",
+                "一网通",
+                "微信支付",
+                "招商一网通",
+                "支付宝支付",
+                "集成支付接口SDK"
+            ],
+            "time": "2018-05-23T12:01:20+00:00"
+        },
         {
             "name": "seld/jsonlint",
             "version": "1.7.1",
@@ -4275,7 +4335,7 @@
                 },
                 {
                     "name": "Gert de Pagter",
-                    "email": "BackEndT[email protected]"
+                    "email": "backendt[email protected]"
                 }
             ],
             "description": "Symfony polyfill for ctype functions",

Разлика између датотеке није приказан због своје велике величине
+ 424 - 137
resources/views/admin/system.blade.php


+ 1 - 1
resources/views/payment/detail.blade.php

@@ -8,7 +8,7 @@
         <div class="portlet light bordered">
             <div class="portlet-body">
                 <div class="alert alert-info" style="text-align: center;">
-                    请使用<strong style="color:red;">支付宝、微信</strong>扫描如下二维码
+                    请使用<strong style="color:red;">支付宝@if($is_youzan==1)、微信@endif</strong>扫描如下二维码
                 </div>
                 <div class="row" style="text-align: center; font-size: 1.05em;">
                     <div class="col-md-12">

+ 2 - 0
resources/views/user/buy.blade.php

@@ -79,6 +79,8 @@
                         <a class="btn btn-lg red hidden-print" onclick="onlinePay(0)"> {{trans('home.online_pay')}} </a>
                     @elseif($is_alipay)
                         <a class="btn btn-lg green hidden-print" onclick="onlinePay(4)"> 支付宝扫码 </a>
+                    @elseif($is_f2fpay)
+                        <a class="btn btn-lg green hidden-print" onclick="onlinePay(5)"> 支付宝扫码 </a>
                     @endif
                   	@if($goods->type <= 2)
                         <a class="btn btn-lg blue hidden-print uppercase" onclick="pay()"> {{trans('home.service_pay_button')}} </a>

+ 4 - 0
sql/db.sql

@@ -367,6 +367,10 @@ INSERT INTO `config` VALUES ('80', 'alipay_private_key', '');
 INSERT INTO `config` VALUES ('81', 'alipay_public_key', '');
 INSERT INTO `config` VALUES ('82', 'alipay_transport', 'http');
 INSERT INTO `config` VALUES ('83', 'alipay_currency', 'USD');
+INSERT INTO `config` values ('84', 'is_f2fpay', 0);
+INSERT INTO `config` VALUES ('85', 'f2fpay_app_id', '');
+INSERT INTO `config` VALUES ('86', 'f2fpay_private_key', '');
+INSERT INTO `config` VALUES ('87', 'f2fpay_public_key', '');
 
 -- ----------------------------
 -- Table structure for `article`

Неке датотеке нису приказане због велике количине промена