mirror of
				https://github.com/v2board/v2board.git
				synced 2025-10-31 01:11:46 +08:00 
			
		
		
		
	rewrite: payment
This commit is contained in:
		| @@ -2,6 +2,7 @@ | |||||||
|  |  | ||||||
| namespace App\Console\Commands; | namespace App\Console\Commands; | ||||||
|  |  | ||||||
|  | use App\Services\PaymentService; | ||||||
| use Illuminate\Console\Command; | use Illuminate\Console\Command; | ||||||
|  |  | ||||||
| class Test extends Command | class Test extends Command | ||||||
| @@ -37,5 +38,7 @@ class Test extends Command | |||||||
|      */ |      */ | ||||||
|     public function handle() |     public function handle() | ||||||
|     { |     { | ||||||
|  |         $paymentService = new PaymentService('MGate'); | ||||||
|  |         var_dump($paymentService->form()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										63
									
								
								app/Http/Controllers/Admin/PaymentController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								app/Http/Controllers/Admin/PaymentController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace App\Http\Controllers\Admin; | ||||||
|  |  | ||||||
|  | use App\Services\PaymentService; | ||||||
|  | use Illuminate\Http\Request; | ||||||
|  | use App\Http\Controllers\Controller; | ||||||
|  | use App\Models\Payment; | ||||||
|  |  | ||||||
|  | class PaymentController extends Controller | ||||||
|  | { | ||||||
|  |     public function getPaymentMethods() | ||||||
|  |     { | ||||||
|  |         $methods = []; | ||||||
|  |         foreach (glob(base_path('app//Payments') . '/*.php') as $file) { | ||||||
|  |             array_push($methods, pathinfo($file)['filename']); | ||||||
|  |         } | ||||||
|  |         return response([ | ||||||
|  |             'data' => $methods | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function fetch() | ||||||
|  |     { | ||||||
|  |         return response([ | ||||||
|  |             'data' => Payment::all() | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function getPaymentForm(Request $request) | ||||||
|  |     { | ||||||
|  |         $paymentService = new PaymentService($request->input('payment'), $request->input('id')); | ||||||
|  |         return response([ | ||||||
|  |             'data' => $paymentService->form() | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function save(Request $request) | ||||||
|  |     { | ||||||
|  |         if ($request->input('id')) { | ||||||
|  |             $payment = Payment::find($request->input('id')); | ||||||
|  |             if (!$payment) abort(500, '支付方式不存在'); | ||||||
|  |             try { | ||||||
|  |                 $payment->update($request->input()); | ||||||
|  |             } catch (\Exception $e) { | ||||||
|  |                 abort(500, '更新失败'); | ||||||
|  |             } | ||||||
|  |             return response([ | ||||||
|  |                 'data' => true | ||||||
|  |             ]); | ||||||
|  |         } | ||||||
|  |         if (!Payment::create([ | ||||||
|  |             'name' => $request->input('name'), | ||||||
|  |             'payment' => $request->input('payment'), | ||||||
|  |             'config' => $request->input('config') | ||||||
|  |         ])) { | ||||||
|  |             abort(500, '保存失败'); | ||||||
|  |         } | ||||||
|  |         return response([ | ||||||
|  |             'data' => true | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								app/Http/Controllers/Guest/PaymentController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								app/Http/Controllers/Guest/PaymentController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace App\Http\Controllers\Guest; | ||||||
|  |  | ||||||
|  | use App\Models\Order; | ||||||
|  | use App\Services\OrderService; | ||||||
|  | use App\Services\PaymentService; | ||||||
|  | use App\Services\TelegramService; | ||||||
|  | use Illuminate\Http\Request; | ||||||
|  | use App\Http\Controllers\Controller; | ||||||
|  |  | ||||||
|  | class PaymentController extends Controller | ||||||
|  | { | ||||||
|  |     public function notify($method, Request $request) | ||||||
|  |     { | ||||||
|  |         $paymentService = new PaymentService($method); | ||||||
|  |         $verify = $paymentService->notify($request->input()); | ||||||
|  |         if ($verify) abort(500, 'verify error'); | ||||||
|  |         if (!$this->handle($verify['trade_no'], $verify['callback_no'])) { | ||||||
|  |             abort(500, 'handle error'); | ||||||
|  |         } | ||||||
|  |         die('success'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private function handle($tradeNo, $callbackNo) | ||||||
|  |     { | ||||||
|  |         $order = Order::where('trade_no', $tradeNo)->first(); | ||||||
|  |         if ($order->status === 1) return true; | ||||||
|  |         if (!$order) { | ||||||
|  |             abort(500, 'order is not found'); | ||||||
|  |         } | ||||||
|  |         $orderService = new OrderService($order); | ||||||
|  |         if (!$orderService->success($callbackNo)) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         $telegramService = new TelegramService(); | ||||||
|  |         $message = sprintf( | ||||||
|  |             "💰成功收款%s元\n———————————————\n订单号:%s", | ||||||
|  |             $order->total_amount / 100, | ||||||
|  |             $order->trade_no | ||||||
|  |         ); | ||||||
|  |         $telegramService->sendMessageWithAdmin($message); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -2,6 +2,7 @@ | |||||||
|  |  | ||||||
| namespace App\Http\Controllers\User; | namespace App\Http\Controllers\User; | ||||||
|  |  | ||||||
|  | use App\Models\Payment; | ||||||
| use App\Utils\Dict; | use App\Utils\Dict; | ||||||
| use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||||
| use App\Http\Controllers\Controller; | use App\Http\Controllers\Controller; | ||||||
| @@ -19,4 +20,16 @@ class CommController extends Controller | |||||||
|             ] |             ] | ||||||
|         ]); |         ]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function getStripePublicKey(Request $request) | ||||||
|  |     { | ||||||
|  |         $payment = Payment::where('id', $request->input('id')) | ||||||
|  |             ->where('payment', 'StripeCredit') | ||||||
|  |             ->first(); | ||||||
|  |         if (!$payment) abort(500, 'payment is not found'); | ||||||
|  |         $config = json_decode($payment->config, true); | ||||||
|  |         return response([ | ||||||
|  |             'data' => $config['stripe_pk_live'] | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,8 +4,10 @@ namespace App\Http\Controllers\User; | |||||||
|  |  | ||||||
| use App\Http\Controllers\Controller; | use App\Http\Controllers\Controller; | ||||||
| use App\Http\Requests\User\OrderSave; | use App\Http\Requests\User\OrderSave; | ||||||
|  | use App\Models\Payment; | ||||||
| use App\Services\CouponService; | use App\Services\CouponService; | ||||||
| use App\Services\OrderService; | use App\Services\OrderService; | ||||||
|  | use App\Services\PaymentService; | ||||||
| use App\Services\UserService; | use App\Services\UserService; | ||||||
| use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||||
| use Illuminate\Support\Facades\Cache; | use Illuminate\Support\Facades\Cache; | ||||||
| @@ -175,71 +177,20 @@ class OrderController extends Controller | |||||||
|                 'data' => true |                 'data' => true | ||||||
|             ]); |             ]); | ||||||
|         } |         } | ||||||
|         switch ($method) { |         $payment = Payment::find($method); | ||||||
|             // return type => 0: QRCode / 1: URL / 2: No action |         if (!$payment || $payment->enable !== 1) abort(500, __('user.order.checkout.pay_method_not_use')); | ||||||
|             case 0: |         $paymentService = new PaymentService($payment->payment, $payment->id); | ||||||
|                 // alipayF2F |         $result = $paymentService->pay([ | ||||||
|                 if (!(int)config('v2board.alipay_enable')) { |             'trade_no' => $tradeNo, | ||||||
|                     abort(500, __('user.order.checkout.pay_method_not_use')); |             'total_amount' => $order->total_amount, | ||||||
|                 } |             'user_id' => $order->user_id, | ||||||
|                 return response([ |             'stripe_token' => $request->input('token') | ||||||
|                     'type' => 0, |  | ||||||
|                     'data' => $this->alipayF2F($tradeNo, $order->total_amount) |  | ||||||
|         ]); |         ]); | ||||||
|             case 2: |         $order->update(['payment_id' => $method]); | ||||||
|                 // stripeAlipay |  | ||||||
|                 if (!(int)config('v2board.stripe_alipay_enable')) { |  | ||||||
|                     abort(500, __('user.order.checkout.pay_method_not_use')); |  | ||||||
|                 } |  | ||||||
|         return response([ |         return response([ | ||||||
|                     'type' => 1, |             'type' => $result['type'], | ||||||
|                     'data' => $this->stripeAlipay($order) |             'data' => $result['data'] | ||||||
|         ]); |         ]); | ||||||
|             case 3: |  | ||||||
|                 // stripeWepay |  | ||||||
|                 if (!(int)config('v2board.stripe_wepay_enable')) { |  | ||||||
|                     abort(500, __('user.order.checkout.pay_method_not_use')); |  | ||||||
|                 } |  | ||||||
|                 return response([ |  | ||||||
|                     'type' => 0, |  | ||||||
|                     'data' => $this->stripeWepay($order) |  | ||||||
|                 ]); |  | ||||||
|             case 4: |  | ||||||
|                 // bitpayX |  | ||||||
|                 if (!(int)config('v2board.bitpayx_enable')) { |  | ||||||
|                     abort(500, __('user.order.checkout.pay_method_not_use')); |  | ||||||
|                 } |  | ||||||
|                 return response([ |  | ||||||
|                     'type' => 1, |  | ||||||
|                     'data' => $this->bitpayX($order) |  | ||||||
|                 ]); |  | ||||||
|             case 5: |  | ||||||
|                 if (!(int)config('v2board.mgate_enable')) { |  | ||||||
|                     abort(500, __('user.order.checkout.pay_method_not_use')); |  | ||||||
|                 } |  | ||||||
|                 return response([ |  | ||||||
|                     'type' => 1, |  | ||||||
|                     'data' => $this->mgate($order) |  | ||||||
|                 ]); |  | ||||||
|             case 6: |  | ||||||
|                 if (!(int)config('v2board.stripe_card_enable')) { |  | ||||||
|                     abort(500, __('user.order.checkout.pay_method_not_use')); |  | ||||||
|                 } |  | ||||||
|                 return response([ |  | ||||||
|                     'type' => 2, |  | ||||||
|                     'data' => $this->stripeCard($order, $request->input('token')) |  | ||||||
|                 ]); |  | ||||||
|             case 7: |  | ||||||
|                 if (!(int)config('v2board.epay_enable')) { |  | ||||||
|                     abort(500, __('user.order.checkout.pay_method_not_use')); |  | ||||||
|                 } |  | ||||||
|                 return response([ |  | ||||||
|                     'type' => 1, |  | ||||||
|                     'data' => $this->epay($order) |  | ||||||
|                 ]); |  | ||||||
|             default: |  | ||||||
|                 abort(500, __('user.order.checkout.pay_method_not_use')); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function check(Request $request) |     public function check(Request $request) | ||||||
| @@ -258,65 +209,15 @@ class OrderController extends Controller | |||||||
|  |  | ||||||
|     public function getPaymentMethod() |     public function getPaymentMethod() | ||||||
|     { |     { | ||||||
|         $data = []; |         $methods = Payment::select([ | ||||||
|         if ((int)config('v2board.alipay_enable')) { |             'id', | ||||||
|             $alipayF2F = new \StdClass(); |             'name', | ||||||
|             $alipayF2F->name = '支付宝'; |             'payment' | ||||||
|             $alipayF2F->method = 0; |         ]) | ||||||
|             $alipayF2F->icon = 'alipay'; |             ->where('enable', 1)->get(); | ||||||
|             array_push($data, $alipayF2F); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if ((int)config('v2board.stripe_alipay_enable')) { |  | ||||||
|             $stripeAlipay = new \StdClass(); |  | ||||||
|             $stripeAlipay->name = '支付宝'; |  | ||||||
|             $stripeAlipay->method = 2; |  | ||||||
|             $stripeAlipay->icon = 'alipay'; |  | ||||||
|             array_push($data, $stripeAlipay); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if ((int)config('v2board.stripe_wepay_enable')) { |  | ||||||
|             $stripeWepay = new \StdClass(); |  | ||||||
|             $stripeWepay->name = '微信'; |  | ||||||
|             $stripeWepay->method = 3; |  | ||||||
|             $stripeWepay->icon = 'wechat'; |  | ||||||
|             array_push($data, $stripeWepay); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if ((int)config('v2board.bitpayx_enable')) { |  | ||||||
|             $bitpayX = new \StdClass(); |  | ||||||
|             $bitpayX->name = config('v2board.bitpayx_name', '在线支付'); |  | ||||||
|             $bitpayX->method = 4; |  | ||||||
|             $bitpayX->icon = 'wallet'; |  | ||||||
|             array_push($data, $bitpayX); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if ((int)config('v2board.mgate_enable')) { |  | ||||||
|             $obj = new \StdClass(); |  | ||||||
|             $obj->name = config('v2board.mgate_name', '在线支付'); |  | ||||||
|             $obj->method = 5; |  | ||||||
|             $obj->icon = 'wallet'; |  | ||||||
|             array_push($data, $obj); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if ((int)config('v2board.stripe_card_enable')) { |  | ||||||
|             $obj = new \StdClass(); |  | ||||||
|             $obj->name = '信用卡'; |  | ||||||
|             $obj->method = 6; |  | ||||||
|             $obj->icon = 'card'; |  | ||||||
|             array_push($data, $obj); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if ((int)config('v2board.epay_enable')) { |  | ||||||
|             $obj = new \StdClass(); |  | ||||||
|             $obj->name = config('v2board.epay_name', '在线支付'); |  | ||||||
|             $obj->method = 7; |  | ||||||
|             $obj->icon = 'wallet'; |  | ||||||
|             array_push($data, $obj); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return response([ |         return response([ | ||||||
|             'data' => $data |             'data' => $methods | ||||||
|         ]); |         ]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -99,6 +99,11 @@ class AdminRoute | |||||||
|             $router->post('/knowledge/show', 'Admin\\KnowledgeController@show'); |             $router->post('/knowledge/show', 'Admin\\KnowledgeController@show'); | ||||||
|             $router->post('/knowledge/drop', 'Admin\\KnowledgeController@drop'); |             $router->post('/knowledge/drop', 'Admin\\KnowledgeController@drop'); | ||||||
|             $router->post('/knowledge/sort', 'Admin\\KnowledgeController@sort'); |             $router->post('/knowledge/sort', 'Admin\\KnowledgeController@sort'); | ||||||
|  |             // Payment | ||||||
|  |             $router->get ('/payment/fetch', 'Admin\\PaymentController@fetch'); | ||||||
|  |             $router->get ('/payment/getPaymentMethods', 'Admin\\PaymentController@getPaymentMethods'); | ||||||
|  |             $router->post('/payment/getPaymentForm', 'Admin\\PaymentController@getPaymentForm'); | ||||||
|  |             $router->post('/payment/save', 'Admin\\PaymentController@save'); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,6 +20,8 @@ class GuestRoute | |||||||
|             $router->post('/order/epayNotify', 'Guest\\OrderController@epayNotify'); |             $router->post('/order/epayNotify', 'Guest\\OrderController@epayNotify'); | ||||||
|             // Telegram |             // Telegram | ||||||
|             $router->post('/telegram/webhook', 'Guest\\TelegramController@webhook'); |             $router->post('/telegram/webhook', 'Guest\\TelegramController@webhook'); | ||||||
|  |             // Payment | ||||||
|  |             $router->match(['get', 'post'], '/payment/{method}', 'Guest\\PaymentController@notify'); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -51,6 +51,7 @@ class UserRoute | |||||||
|             $router->get ('/telegram/getBotInfo', 'User\\TelegramController@getBotInfo'); |             $router->get ('/telegram/getBotInfo', 'User\\TelegramController@getBotInfo'); | ||||||
|             // Comm |             // Comm | ||||||
|             $router->get ('/comm/config', 'User\\CommController@config'); |             $router->get ('/comm/config', 'User\\CommController@config'); | ||||||
|  |             $router->Post('/comm/getStripePublicKey', 'User\\CommController@getStripePublicKey'); | ||||||
|             // Knowledge |             // Knowledge | ||||||
|             $router->get ('/knowledge/fetch', 'User\\KnowledgeController@fetch'); |             $router->get ('/knowledge/fetch', 'User\\KnowledgeController@fetch'); | ||||||
|             $router->get ('/knowledge/getCategory', 'User\\KnowledgeController@getCategory'); |             $router->get ('/knowledge/getCategory', 'User\\KnowledgeController@getCategory'); | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								app/Models/Payment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/Models/Payment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace App\Models; | ||||||
|  |  | ||||||
|  | use Illuminate\Database\Eloquent\Model; | ||||||
|  |  | ||||||
|  | class Payment extends Model | ||||||
|  | { | ||||||
|  |     protected $table = 'v2_payment'; | ||||||
|  |     protected $dateFormat = 'U'; | ||||||
|  |     protected $guarded = ['id']; | ||||||
|  | } | ||||||
							
								
								
									
										90
									
								
								app/Payments/MGate.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								app/Payments/MGate.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 自己写别抄,抄NMB抄 | ||||||
|  |  */ | ||||||
|  | namespace App\Payments; | ||||||
|  |  | ||||||
|  | use \Curl\Curl; | ||||||
|  |  | ||||||
|  | class MGate { | ||||||
|  |     public function __construct($config) | ||||||
|  |     { | ||||||
|  |         $this->config = $config; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function form() | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'mgate_url' => [ | ||||||
|  |                 'label' => 'API地址', | ||||||
|  |                 'description' => '', | ||||||
|  |                 'type' => 'input', | ||||||
|  |             ], | ||||||
|  |             'mgate_app_id' => [ | ||||||
|  |                 'label' => 'APPID', | ||||||
|  |                 'description' => '', | ||||||
|  |                 'type' => 'input', | ||||||
|  |             ], | ||||||
|  |             'mgate_app_secret' => [ | ||||||
|  |                 'label' => 'AppSecret', | ||||||
|  |                 'description' => '', | ||||||
|  |                 'type' => 'input', | ||||||
|  |             ] | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function pay($order) | ||||||
|  |     { | ||||||
|  |         $params = [ | ||||||
|  |             'out_trade_no' => $order['trade_no'], | ||||||
|  |             'total_amount' => $order['total_amount'], | ||||||
|  |             'notify_url' => $order['notify_url'], | ||||||
|  |             'return_url' => $order['return_url'] | ||||||
|  |         ]; | ||||||
|  |         $params['app_id'] = $this->config['mgate_app_id']; | ||||||
|  |         ksort($params); | ||||||
|  |         $str = http_build_query($params) . $this->config['mgate_app_secret']; | ||||||
|  |         $params['sign'] = md5($str); | ||||||
|  |         $curl = new Curl(); | ||||||
|  |         $curl->post($this->config['mgate_url'] . '/v1/gateway/fetch', http_build_query($params)); | ||||||
|  |         $result = $curl->response; | ||||||
|  |         if (!$result) { | ||||||
|  |             abort(500, '网络异常'); | ||||||
|  |         } | ||||||
|  |         if ($curl->error) { | ||||||
|  |             if (isset($result->errors)) { | ||||||
|  |                 $errors = (array)$result->errors; | ||||||
|  |                 abort(500, $errors[array_keys($errors)[0]][0]); | ||||||
|  |             } | ||||||
|  |             if (isset($result->message)) { | ||||||
|  |                 abort(500, $result->message); | ||||||
|  |             } | ||||||
|  |             abort(500, '未知错误'); | ||||||
|  |         } | ||||||
|  |         $curl->close(); | ||||||
|  |         if (!isset($result->data->trade_no)) { | ||||||
|  |             abort(500, '接口请求失败'); | ||||||
|  |         } | ||||||
|  |         return [ | ||||||
|  |             'type' => 1, // 0:qrcode 1:url | ||||||
|  |             'data' => $result->data->pay_url | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function notify($params) | ||||||
|  |     { | ||||||
|  |         $sign = $params['sign']; | ||||||
|  |         unset($params['sign']); | ||||||
|  |         ksort($params); | ||||||
|  |         reset($params); | ||||||
|  |         $str = http_build_query($params) . $this->config['mgate_app_secret']; | ||||||
|  |         if ($sign !== md5($str)) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         return [ | ||||||
|  |             'trade_no' => $params['out_trade_no'], | ||||||
|  |             'callback_no' => $params['trade_no'] | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										113
									
								
								app/Payments/StripeAlipay.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								app/Payments/StripeAlipay.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 自己写别抄,抄NMB抄 | ||||||
|  |  */ | ||||||
|  | namespace App\Payments; | ||||||
|  |  | ||||||
|  | use Stripe\Source; | ||||||
|  | use Stripe\Stripe; | ||||||
|  |  | ||||||
|  | class StripeAlipay { | ||||||
|  |     public function __construct($config) | ||||||
|  |     { | ||||||
|  |         $this->config = $config; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function form() | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'currency' => [ | ||||||
|  |                 'label' => '货币单位', | ||||||
|  |                 'description' => '', | ||||||
|  |                 'type' => 'input', | ||||||
|  |             ], | ||||||
|  |             'stripe_sk_live' => [ | ||||||
|  |                 'label' => 'SK_LIVE', | ||||||
|  |                 'description' => '', | ||||||
|  |                 'type' => 'input', | ||||||
|  |             ], | ||||||
|  |             'stripe_webhook_key' => [ | ||||||
|  |                 'label' => 'WebHook密钥签名', | ||||||
|  |                 'description' => '', | ||||||
|  |                 'type' => 'input', | ||||||
|  |             ] | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function pay($order) | ||||||
|  |     { | ||||||
|  |         $currency = $this->config['currency']; | ||||||
|  |         $exchange = $this->exchange('CNY', strtoupper($currency)); | ||||||
|  |         if (!$exchange) { | ||||||
|  |             abort(500, __('user.order.stripeAlipay.currency_convert_timeout')); | ||||||
|  |         } | ||||||
|  |         Stripe::setApiKey($this->config['stripe_sk_live']); | ||||||
|  |         $source = Source::create([ | ||||||
|  |             'amount' => floor($order['total_amount'] * $exchange), | ||||||
|  |             'currency' => $currency, | ||||||
|  |             'type' => 'alipay', | ||||||
|  |             'statement_descriptor' => $order['trade_no'], | ||||||
|  |             'metadata' => [ | ||||||
|  |                 'user_id' => $order['user_id'], | ||||||
|  |                 'out_trade_no' => $order['trade_no'], | ||||||
|  |                 'identifier' => '' | ||||||
|  |             ], | ||||||
|  |             'redirect' => [ | ||||||
|  |                 'return_url' => $order['return_url'] | ||||||
|  |             ] | ||||||
|  |         ]); | ||||||
|  |         if (!$source['redirect']['url']) { | ||||||
|  |             abort(500, __('user.order.stripeAlipay.gateway_request_failed')); | ||||||
|  |         } | ||||||
|  |         return [ | ||||||
|  |             'type' => 1, | ||||||
|  |             'data' => $source['redirect']['url'] | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function notify($params) | ||||||
|  |     { | ||||||
|  |         \Stripe\Stripe::setApiKey($this->config['stripe_sk_live']); | ||||||
|  |         try { | ||||||
|  |             $event = \Stripe\Webhook::constructEvent( | ||||||
|  |                 file_get_contents('php://input'), | ||||||
|  |                 $_SERVER['HTTP_STRIPE_SIGNATURE'], | ||||||
|  |                 $this->config['stripe_webhook_key'] | ||||||
|  |             ); | ||||||
|  |         } catch (\Stripe\Error\SignatureVerification $e) { | ||||||
|  |             abort(400); | ||||||
|  |         } | ||||||
|  |         switch ($event->type) { | ||||||
|  |             case 'source.chargeable': | ||||||
|  |                 $object = $event->data->object; | ||||||
|  |                 \Stripe\Charge::create([ | ||||||
|  |                     'amount' => $object->amount, | ||||||
|  |                     'currency' => $object->currency, | ||||||
|  |                     'source' => $object->id, | ||||||
|  |                     'metadata' => json_decode($object->metadata, true) | ||||||
|  |                 ]); | ||||||
|  |                 break; | ||||||
|  |             case 'charge.succeeded': | ||||||
|  |                 $object = $event->data->object; | ||||||
|  |                 if ($object->status === 'succeeded') { | ||||||
|  |                     $metaData = isset($object->metadata->out_trade_no) ? $object->metadata : $object->source->metadata; | ||||||
|  |                     $tradeNo = $metaData->out_trade_no; | ||||||
|  |                     return [ | ||||||
|  |                         'trade_no' => $tradeNo, | ||||||
|  |                         'callback_no' => $object->balance_transaction | ||||||
|  |                     ]; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 abort(500, 'event is not support'); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private function exchange($from, $to) | ||||||
|  |     { | ||||||
|  |         $result = file_get_contents('https://api.exchangerate.host/latest?symbols=' . $to . '&base=' . $from); | ||||||
|  |         $result = json_decode($result, true); | ||||||
|  |         return $result['rates'][$to]; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										120
									
								
								app/Payments/StripeCredit.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								app/Payments/StripeCredit.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 自己写别抄,抄NMB抄 | ||||||
|  |  */ | ||||||
|  | namespace App\Payments; | ||||||
|  |  | ||||||
|  | use Stripe\Source; | ||||||
|  | use Stripe\Stripe; | ||||||
|  |  | ||||||
|  | class StripeCredit { | ||||||
|  |     public function __construct($config) | ||||||
|  |     { | ||||||
|  |         $this->config = $config; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function form() | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'currency' => [ | ||||||
|  |                 'label' => '货币单位', | ||||||
|  |                 'description' => '', | ||||||
|  |                 'type' => 'input', | ||||||
|  |             ], | ||||||
|  |             'stripe_sk_live' => [ | ||||||
|  |                 'label' => 'SK_LIVE', | ||||||
|  |                 'description' => '', | ||||||
|  |                 'type' => 'input', | ||||||
|  |             ], | ||||||
|  |             'stripe_pk_live' => [ | ||||||
|  |                 'label' => 'PK_LIVE', | ||||||
|  |                 'description' => '', | ||||||
|  |                 'type' => 'input', | ||||||
|  |             ], | ||||||
|  |             'stripe_webhook_key' => [ | ||||||
|  |                 'label' => 'WebHook密钥签名', | ||||||
|  |                 'description' => '', | ||||||
|  |                 'type' => 'input', | ||||||
|  |             ] | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function pay($order) | ||||||
|  |     { | ||||||
|  |         info($order); | ||||||
|  |         $currency = $this->config['currency']; | ||||||
|  |         $exchange = $this->exchange('CNY', strtoupper($currency)); | ||||||
|  |         if (!$exchange) { | ||||||
|  |             abort(500, __('user.order.stripeCard.currency_convert_timeout')); | ||||||
|  |         } | ||||||
|  |         Stripe::setApiKey($this->config['stripe_sk_live']); | ||||||
|  |         try { | ||||||
|  |             $charge = \Stripe\Charge::create([ | ||||||
|  |                 'amount' => floor($order['total_amount'] * $exchange), | ||||||
|  |                 'currency' => $currency, | ||||||
|  |                 'source' => $order['stripe_token'], | ||||||
|  |                 'metadata' => [ | ||||||
|  |                     'user_id' => $order['user_id'], | ||||||
|  |                     'out_trade_no' => $order['trade_no'], | ||||||
|  |                     'identifier' => '' | ||||||
|  |                 ] | ||||||
|  |             ]); | ||||||
|  |         } catch (\Exception $e) { | ||||||
|  |             info($e); | ||||||
|  |             abort(500, __('user.order.stripeCard.was_problem')); | ||||||
|  |         } | ||||||
|  |         if (!$charge->paid) { | ||||||
|  |             abort(500, __('user.order.stripeCard.deduction_failed')); | ||||||
|  |         } | ||||||
|  |         return [ | ||||||
|  |             'type' => 2, | ||||||
|  |             'data' => $charge->paid | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function notify($params) | ||||||
|  |     { | ||||||
|  |         \Stripe\Stripe::setApiKey($this->config['stripe_sk_live']); | ||||||
|  |         try { | ||||||
|  |             $event = \Stripe\Webhook::constructEvent( | ||||||
|  |                 file_get_contents('php://input'), | ||||||
|  |                 $_SERVER['HTTP_STRIPE_SIGNATURE'], | ||||||
|  |                 $this->config['stripe_webhook_key'] | ||||||
|  |             ); | ||||||
|  |         } catch (\Stripe\Error\SignatureVerification $e) { | ||||||
|  |             abort(400); | ||||||
|  |         } | ||||||
|  |         switch ($event->type) { | ||||||
|  |             case 'source.chargeable': | ||||||
|  |                 $object = $event->data->object; | ||||||
|  |                 \Stripe\Charge::create([ | ||||||
|  |                     'amount' => $object->amount, | ||||||
|  |                     'currency' => $object->currency, | ||||||
|  |                     'source' => $object->id, | ||||||
|  |                     'metadata' => json_decode($object->metadata, true) | ||||||
|  |                 ]); | ||||||
|  |                 break; | ||||||
|  |             case 'charge.succeeded': | ||||||
|  |                 $object = $event->data->object; | ||||||
|  |                 if ($object->status === 'succeeded') { | ||||||
|  |                     $metaData = isset($object->metadata->out_trade_no) ? $object->metadata : $object->source->metadata; | ||||||
|  |                     $tradeNo = $metaData->out_trade_no; | ||||||
|  |                     return [ | ||||||
|  |                         'trade_no' => $tradeNo, | ||||||
|  |                         'callback_no' => $object->balance_transaction | ||||||
|  |                     ]; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 abort(500, 'event is not support'); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private function exchange($from, $to) | ||||||
|  |     { | ||||||
|  |         $result = file_get_contents('https://api.exchangerate.host/latest?symbols=' . $to . '&base=' . $from); | ||||||
|  |         $result = json_decode($result, true); | ||||||
|  |         return $result['rates'][$to]; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								app/Services/PaymentService.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								app/Services/PaymentService.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace App\Services; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | use App\Models\Payment; | ||||||
|  |  | ||||||
|  | class PaymentService | ||||||
|  | { | ||||||
|  |     public function __construct($method, $id = NULL) | ||||||
|  |     { | ||||||
|  |         $this->method = $method; | ||||||
|  |         $this->class = '\\App\\Payments\\' . $this->method; | ||||||
|  |         if (!class_exists($this->class)) abort(500, 'gate is not found'); | ||||||
|  |         if ($id) $payment = Payment::find($id)->toArray(); | ||||||
|  |         $this->config = []; | ||||||
|  |         if (isset($payment) && $payment['config']) $this->config = json_decode($payment['config'], true); | ||||||
|  |         $this->payment = new $this->class($this->config); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function notify($params) | ||||||
|  |     { | ||||||
|  |         if (!$this->config['enable']) abort(500, 'gate is not enable'); | ||||||
|  |         return $this->payment->notify($params); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function pay($order) | ||||||
|  |     { | ||||||
|  |         return $this->payment->pay([ | ||||||
|  |             'notify_url' => url('/api/v1/guest/payment/notify/' . $this->method), | ||||||
|  |             'return_url' => config('v2board.app_url', env('APP_URL')) . '/#/order', | ||||||
|  |             'trade_no' => $order['trade_no'], | ||||||
|  |             'total_amount' => $order['total_amount'], | ||||||
|  |             'user_id' => $order['user_id'], | ||||||
|  |             'stripe_token' => $order['stripe_token'] | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function form() | ||||||
|  |     { | ||||||
|  |         $form = $this->payment->form(); | ||||||
|  |         $keys = array_keys($form); | ||||||
|  |         foreach ($keys as $key) { | ||||||
|  |             if (isset($this->config[$key])) $form[$key]['value'] = $this->config[$key]; | ||||||
|  |         } | ||||||
|  |         return $form; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| -- Adminer 4.7.8 MySQL dump | -- Adminer 4.8.0 MySQL 5.7.29 dump | ||||||
|  |  | ||||||
| SET NAMES utf8; | SET NAMES utf8; | ||||||
| SET time_zone = '+00:00'; | SET time_zone = '+00:00'; | ||||||
| @@ -14,7 +14,7 @@ CREATE TABLE `failed_jobs` ( | |||||||
|                                `queue` text COLLATE utf8mb4_unicode_ci NOT NULL, |                                `queue` text COLLATE utf8mb4_unicode_ci NOT NULL, | ||||||
|                                `payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL, |                                `payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL, | ||||||
|                                `exception` longtext COLLATE utf8mb4_unicode_ci NOT NULL, |                                `exception` longtext COLLATE utf8mb4_unicode_ci NOT NULL, | ||||||
|                                `failed_at` timestamp NOT NULL DEFAULT current_timestamp(), |                                `failed_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||||||
|                                PRIMARY KEY (`id`) |                                PRIMARY KEY (`id`) | ||||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; | ||||||
|  |  | ||||||
| @@ -41,8 +41,8 @@ CREATE TABLE `v2_invite_code` ( | |||||||
|                                   `id` int(11) NOT NULL AUTO_INCREMENT, |                                   `id` int(11) NOT NULL AUTO_INCREMENT, | ||||||
|                                   `user_id` int(11) NOT NULL, |                                   `user_id` int(11) NOT NULL, | ||||||
|                                   `code` char(32) NOT NULL, |                                   `code` char(32) NOT NULL, | ||||||
|                                   `status` tinyint(1) NOT NULL DEFAULT 0, |                                   `status` tinyint(1) NOT NULL DEFAULT '0', | ||||||
|                                   `pv` int(11) NOT NULL DEFAULT 0, |                                   `pv` int(11) NOT NULL DEFAULT '0', | ||||||
|                                   `created_at` int(11) NOT NULL, |                                   `created_at` int(11) NOT NULL, | ||||||
|                                   `updated_at` int(11) NOT NULL, |                                   `updated_at` int(11) NOT NULL, | ||||||
|                                   PRIMARY KEY (`id`) |                                   PRIMARY KEY (`id`) | ||||||
| @@ -57,7 +57,7 @@ CREATE TABLE `v2_knowledge` ( | |||||||
|                                 `title` varchar(255) NOT NULL COMMENT '標題', |                                 `title` varchar(255) NOT NULL COMMENT '標題', | ||||||
|                                 `body` text NOT NULL COMMENT '內容', |                                 `body` text NOT NULL COMMENT '內容', | ||||||
|                                 `sort` int(11) DEFAULT NULL COMMENT '排序', |                                 `sort` int(11) DEFAULT NULL COMMENT '排序', | ||||||
|                                 `show` tinyint(1) NOT NULL DEFAULT 0 COMMENT '顯示', |                                 `show` tinyint(1) NOT NULL DEFAULT '0' COMMENT '顯示', | ||||||
|                                 `created_at` int(11) NOT NULL COMMENT '創建時間', |                                 `created_at` int(11) NOT NULL COMMENT '創建時間', | ||||||
|                                 `updated_at` int(11) NOT NULL COMMENT '更新時間', |                                 `updated_at` int(11) NOT NULL COMMENT '更新時間', | ||||||
|                                 PRIMARY KEY (`id`) |                                 PRIMARY KEY (`id`) | ||||||
| @@ -70,7 +70,7 @@ CREATE TABLE `v2_mail_log` ( | |||||||
|                                `email` varchar(64) NOT NULL, |                                `email` varchar(64) NOT NULL, | ||||||
|                                `subject` varchar(255) NOT NULL, |                                `subject` varchar(255) NOT NULL, | ||||||
|                                `template_name` varchar(255) NOT NULL, |                                `template_name` varchar(255) NOT NULL, | ||||||
|                                `error` text DEFAULT NULL, |                                `error` text, | ||||||
|                                `created_at` int(11) NOT NULL, |                                `created_at` int(11) NOT NULL, | ||||||
|                                `updated_at` int(11) NOT NULL, |                                `updated_at` int(11) NOT NULL, | ||||||
|                                PRIMARY KEY (`id`) |                                PRIMARY KEY (`id`) | ||||||
| @@ -96,6 +96,7 @@ CREATE TABLE `v2_order` ( | |||||||
|                             `user_id` int(11) NOT NULL, |                             `user_id` int(11) NOT NULL, | ||||||
|                             `plan_id` int(11) NOT NULL, |                             `plan_id` int(11) NOT NULL, | ||||||
|                             `coupon_id` int(11) DEFAULT NULL, |                             `coupon_id` int(11) DEFAULT NULL, | ||||||
|  |                             `payment_id` int(11) DEFAULT NULL, | ||||||
|                             `type` int(11) NOT NULL COMMENT '1新购2续费3升级', |                             `type` int(11) NOT NULL COMMENT '1新购2续费3升级', | ||||||
|                             `cycle` varchar(255) NOT NULL, |                             `cycle` varchar(255) NOT NULL, | ||||||
|                             `trade_no` varchar(36) NOT NULL, |                             `trade_no` varchar(36) NOT NULL, | ||||||
| @@ -105,26 +106,40 @@ CREATE TABLE `v2_order` ( | |||||||
|                             `surplus_amount` int(11) DEFAULT NULL COMMENT '剩余价值', |                             `surplus_amount` int(11) DEFAULT NULL COMMENT '剩余价值', | ||||||
|                             `refund_amount` int(11) DEFAULT NULL COMMENT '退款金额', |                             `refund_amount` int(11) DEFAULT NULL COMMENT '退款金额', | ||||||
|                             `balance_amount` int(11) DEFAULT NULL COMMENT '使用余额', |                             `balance_amount` int(11) DEFAULT NULL COMMENT '使用余额', | ||||||
|                             `surplus_order_ids` text DEFAULT NULL COMMENT '折抵订单', |                             `surplus_order_ids` text COMMENT '折抵订单', | ||||||
|                             `status` tinyint(1) NOT NULL DEFAULT 0 COMMENT '0待支付1开通中2已取消3已完成4已折抵', |                             `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0待支付1开通中2已取消3已完成4已折抵', | ||||||
|                             `commission_status` tinyint(1) NOT NULL DEFAULT 0 COMMENT '0待确认1发放中2有效3无效', |                             `commission_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0待确认1发放中2有效3无效', | ||||||
|                             `commission_balance` int(11) NOT NULL DEFAULT 0, |                             `commission_balance` int(11) NOT NULL DEFAULT '0', | ||||||
|                             `created_at` int(11) NOT NULL, |                             `created_at` int(11) NOT NULL, | ||||||
|                             `updated_at` int(11) NOT NULL, |                             `updated_at` int(11) NOT NULL, | ||||||
|                             PRIMARY KEY (`id`) |                             PRIMARY KEY (`id`) | ||||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | DROP TABLE IF EXISTS `v2_payment`; | ||||||
|  | CREATE TABLE `v2_payment` ( | ||||||
|  |                               `id` int(11) NOT NULL AUTO_INCREMENT, | ||||||
|  |                               `payment` varchar(16) NOT NULL, | ||||||
|  |                               `name` varchar(255) NOT NULL, | ||||||
|  |                               `config` text NOT NULL, | ||||||
|  |                               `enable` tinyint(1) NOT NULL DEFAULT '0', | ||||||
|  |                               `sort` int(11) DEFAULT NULL, | ||||||
|  |                               `created_at` int(11) NOT NULL, | ||||||
|  |                               `updated_at` int(11) NOT NULL, | ||||||
|  |                               PRIMARY KEY (`id`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; | ||||||
|  |  | ||||||
|  |  | ||||||
| DROP TABLE IF EXISTS `v2_plan`; | DROP TABLE IF EXISTS `v2_plan`; | ||||||
| CREATE TABLE `v2_plan` ( | CREATE TABLE `v2_plan` ( | ||||||
|                            `id` int(11) NOT NULL AUTO_INCREMENT, |                            `id` int(11) NOT NULL AUTO_INCREMENT, | ||||||
|                            `group_id` int(11) NOT NULL, |                            `group_id` int(11) NOT NULL, | ||||||
|                            `transfer_enable` int(11) NOT NULL, |                            `transfer_enable` int(11) NOT NULL, | ||||||
|                            `name` varchar(255) NOT NULL, |                            `name` varchar(255) NOT NULL, | ||||||
|                            `show` tinyint(1) NOT NULL DEFAULT 0, |                            `show` tinyint(1) NOT NULL DEFAULT '0', | ||||||
|                            `sort` int(11) DEFAULT NULL, |                            `sort` int(11) DEFAULT NULL, | ||||||
|                            `renew` tinyint(1) NOT NULL DEFAULT 1, |                            `renew` tinyint(1) NOT NULL DEFAULT '1', | ||||||
|                            `content` text DEFAULT NULL, |                            `content` text, | ||||||
|                            `month_price` int(11) DEFAULT NULL, |                            `month_price` int(11) DEFAULT NULL, | ||||||
|                            `quarter_price` int(11) DEFAULT NULL, |                            `quarter_price` int(11) DEFAULT NULL, | ||||||
|                            `half_year_price` int(11) DEFAULT NULL, |                            `half_year_price` int(11) DEFAULT NULL, | ||||||
| @@ -148,18 +163,18 @@ CREATE TABLE `v2_server` ( | |||||||
|                              `host` varchar(255) NOT NULL, |                              `host` varchar(255) NOT NULL, | ||||||
|                              `port` int(11) NOT NULL, |                              `port` int(11) NOT NULL, | ||||||
|                              `server_port` int(11) NOT NULL, |                              `server_port` int(11) NOT NULL, | ||||||
|                              `tls` tinyint(4) NOT NULL DEFAULT 0, |                              `tls` tinyint(4) NOT NULL DEFAULT '0', | ||||||
|                              `tags` varchar(255) DEFAULT NULL, |                              `tags` varchar(255) DEFAULT NULL, | ||||||
|                              `rate` varchar(11) NOT NULL, |                              `rate` varchar(11) NOT NULL, | ||||||
|                              `network` text NOT NULL, |                              `network` text NOT NULL, | ||||||
|                              `alter_id` int(11) NOT NULL DEFAULT 1, |                              `alter_id` int(11) NOT NULL DEFAULT '1', | ||||||
|                              `settings` text DEFAULT NULL, |                              `settings` text, | ||||||
|                              `rules` text DEFAULT NULL, |                              `rules` text, | ||||||
|                              `networkSettings` text DEFAULT NULL, |                              `networkSettings` text, | ||||||
|                              `tlsSettings` text DEFAULT NULL, |                              `tlsSettings` text, | ||||||
|                              `ruleSettings` text DEFAULT NULL, |                              `ruleSettings` text, | ||||||
|                              `dnsSettings` text DEFAULT NULL, |                              `dnsSettings` text, | ||||||
|                              `show` tinyint(1) NOT NULL DEFAULT 0, |                              `show` tinyint(1) NOT NULL DEFAULT '0', | ||||||
|                              `sort` int(11) DEFAULT NULL, |                              `sort` int(11) DEFAULT NULL, | ||||||
|                              `created_at` int(11) NOT NULL, |                              `created_at` int(11) NOT NULL, | ||||||
|                              `updated_at` int(11) NOT NULL, |                              `updated_at` int(11) NOT NULL, | ||||||
| @@ -206,7 +221,7 @@ CREATE TABLE `v2_server_shadowsocks` ( | |||||||
|                                          `port` int(11) NOT NULL, |                                          `port` int(11) NOT NULL, | ||||||
|                                          `server_port` int(11) NOT NULL, |                                          `server_port` int(11) NOT NULL, | ||||||
|                                          `cipher` varchar(255) NOT NULL, |                                          `cipher` varchar(255) NOT NULL, | ||||||
|                                          `show` tinyint(4) NOT NULL DEFAULT 0, |                                          `show` tinyint(4) NOT NULL DEFAULT '0', | ||||||
|                                          `sort` int(11) DEFAULT NULL, |                                          `sort` int(11) DEFAULT NULL, | ||||||
|                                          `created_at` int(11) NOT NULL, |                                          `created_at` int(11) NOT NULL, | ||||||
|                                          `updated_at` int(11) NOT NULL, |                                          `updated_at` int(11) NOT NULL, | ||||||
| @@ -225,9 +240,9 @@ CREATE TABLE `v2_server_trojan` ( | |||||||
|                                     `host` varchar(255) NOT NULL COMMENT '主机名', |                                     `host` varchar(255) NOT NULL COMMENT '主机名', | ||||||
|                                     `port` int(11) NOT NULL COMMENT '连接端口', |                                     `port` int(11) NOT NULL COMMENT '连接端口', | ||||||
|                                     `server_port` int(11) NOT NULL COMMENT '服务端口', |                                     `server_port` int(11) NOT NULL COMMENT '服务端口', | ||||||
|                                     `allow_insecure` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否允许不安全', |                                     `allow_insecure` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否允许不安全', | ||||||
|                                     `server_name` varchar(255) DEFAULT NULL, |                                     `server_name` varchar(255) DEFAULT NULL, | ||||||
|                                     `show` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否显示', |                                     `show` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否显示', | ||||||
|                                     `sort` int(11) DEFAULT NULL, |                                     `sort` int(11) DEFAULT NULL, | ||||||
|                                     `created_at` int(11) NOT NULL, |                                     `created_at` int(11) NOT NULL, | ||||||
|                                     `updated_at` int(11) NOT NULL, |                                     `updated_at` int(11) NOT NULL, | ||||||
| @@ -276,7 +291,7 @@ CREATE TABLE `v2_ticket` ( | |||||||
|                              `last_reply_user_id` int(11) NOT NULL, |                              `last_reply_user_id` int(11) NOT NULL, | ||||||
|                              `subject` varchar(255) NOT NULL, |                              `subject` varchar(255) NOT NULL, | ||||||
|                              `level` tinyint(1) NOT NULL, |                              `level` tinyint(1) NOT NULL, | ||||||
|                              `status` tinyint(1) NOT NULL DEFAULT 0 COMMENT '0:已开启 1:已关闭', |                              `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0:已开启 1:已关闭', | ||||||
|                              `created_at` int(11) NOT NULL, |                              `created_at` int(11) NOT NULL, | ||||||
|                              `updated_at` int(11) NOT NULL, |                              `updated_at` int(11) NOT NULL, | ||||||
|                              PRIMARY KEY (`id`) |                              PRIMARY KEY (`id`) | ||||||
| @@ -303,27 +318,27 @@ CREATE TABLE `v2_user` ( | |||||||
|                            `email` varchar(64) NOT NULL, |                            `email` varchar(64) NOT NULL, | ||||||
|                            `password` varchar(64) NOT NULL, |                            `password` varchar(64) NOT NULL, | ||||||
|                            `password_algo` char(10) DEFAULT NULL, |                            `password_algo` char(10) DEFAULT NULL, | ||||||
|                            `balance` int(11) NOT NULL DEFAULT 0, |                            `balance` int(11) NOT NULL DEFAULT '0', | ||||||
|                            `discount` int(11) DEFAULT NULL, |                            `discount` int(11) DEFAULT NULL, | ||||||
|                            `commission_rate` int(11) DEFAULT NULL, |                            `commission_rate` int(11) DEFAULT NULL, | ||||||
|                            `commission_balance` int(11) NOT NULL DEFAULT 0, |                            `commission_balance` int(11) NOT NULL DEFAULT '0', | ||||||
|                            `t` int(11) NOT NULL DEFAULT 0, |                            `t` int(11) NOT NULL DEFAULT '0', | ||||||
|                            `u` bigint(20) NOT NULL DEFAULT 0, |                            `u` bigint(20) NOT NULL DEFAULT '0', | ||||||
|                            `d` bigint(20) NOT NULL DEFAULT 0, |                            `d` bigint(20) NOT NULL DEFAULT '0', | ||||||
|                            `transfer_enable` bigint(20) NOT NULL DEFAULT 0, |                            `transfer_enable` bigint(20) NOT NULL DEFAULT '0', | ||||||
|                            `banned` tinyint(1) NOT NULL DEFAULT 0, |                            `banned` tinyint(1) NOT NULL DEFAULT '0', | ||||||
|                            `is_admin` tinyint(1) NOT NULL DEFAULT 0, |                            `is_admin` tinyint(1) NOT NULL DEFAULT '0', | ||||||
|                            `is_staff` tinyint(1) NOT NULL DEFAULT 0, |                            `is_staff` tinyint(1) NOT NULL DEFAULT '0', | ||||||
|                            `last_login_at` int(11) DEFAULT NULL, |                            `last_login_at` int(11) DEFAULT NULL, | ||||||
|                            `last_login_ip` int(11) DEFAULT NULL, |                            `last_login_ip` int(11) DEFAULT NULL, | ||||||
|                            `uuid` varchar(36) NOT NULL, |                            `uuid` varchar(36) NOT NULL, | ||||||
|                            `group_id` int(11) DEFAULT NULL, |                            `group_id` int(11) DEFAULT NULL, | ||||||
|                            `plan_id` int(11) DEFAULT NULL, |                            `plan_id` int(11) DEFAULT NULL, | ||||||
|                            `remind_expire` tinyint(4) DEFAULT 1, |                            `remind_expire` tinyint(4) DEFAULT '1', | ||||||
|                            `remind_traffic` tinyint(4) DEFAULT 1, |                            `remind_traffic` tinyint(4) DEFAULT '1', | ||||||
|                            `token` char(32) NOT NULL, |                            `token` char(32) NOT NULL, | ||||||
|                            `remarks` text DEFAULT NULL, |                            `remarks` text, | ||||||
|                            `expired_at` bigint(20) DEFAULT 0, |                            `expired_at` bigint(20) DEFAULT '0', | ||||||
|                            `created_at` int(11) NOT NULL, |                            `created_at` int(11) NOT NULL, | ||||||
|                            `updated_at` int(11) NOT NULL, |                            `updated_at` int(11) NOT NULL, | ||||||
|                            PRIMARY KEY (`id`), |                            PRIMARY KEY (`id`), | ||||||
| @@ -331,4 +346,4 @@ CREATE TABLE `v2_user` ( | |||||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||||||
|  |  | ||||||
|  |  | ||||||
| -- 2021-01-21 14:25:17 | -- 2021-04-28 08:53:45 | ||||||
|   | |||||||
| @@ -394,3 +394,17 @@ DROP `enable`; | |||||||
|  |  | ||||||
| ALTER TABLE `v2_user` | ALTER TABLE `v2_user` | ||||||
|     ADD `remarks` text COLLATE 'utf8_general_ci' NULL AFTER `token`; |     ADD `remarks` text COLLATE 'utf8_general_ci' NULL AFTER `token`; | ||||||
|  |  | ||||||
|  | CREATE TABLE `v2_payment` ( | ||||||
|  |                               `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY, | ||||||
|  |                               `payment` varchar(16) NOT NULL, | ||||||
|  |                               `name` varchar(255) NOT NULL, | ||||||
|  |                               `config` text NOT NULL, | ||||||
|  |                               `enable` tinyint(1) NOT NULL DEFAULT '0', | ||||||
|  |                               `sort` int(11) DEFAULT NULL, | ||||||
|  |                               `created_at` int(11) NOT NULL, | ||||||
|  |                               `updated_at` int(11) NOT NULL | ||||||
|  | ) COLLATE 'utf8mb4_general_ci'; | ||||||
|  |  | ||||||
|  | ALTER TABLE `v2_order` | ||||||
|  |     ADD `payment_id` int(11) NULL AFTER `coupon_id`; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user