diff --git a/app/Http/Controllers/Api/BalanceController.php b/app/Http/Controllers/Api/BalanceController.php new file mode 100644 index 0000000..f8725ff --- /dev/null +++ b/app/Http/Controllers/Api/BalanceController.php @@ -0,0 +1,69 @@ +paginate(100); + + return $this->success($balances); + } + + /** + * Store a newly created resource in storage. + * + * @param Request $request + * + * @return JsonResponse + */ + public function store(Request $request) + { + $this->validate($request, [ + 'amount' => 'required|integer|min:0.1|max:10000', + 'payment' => 'required|in:wechat,alipay', + ]); + + $balance = Balance::create([ + 'user_id' => auth('sanctum')->id(), + 'amount' => $request->input('amount'), + 'payment' => $request->input('payment'), + ]); + + $url = route('balances.show', compact('balance')); + $balance->url = $url; + + return $this->success($balance); + } + + /** + * Display the specified resource. + * + * @param Balance $balance + * + * @return JsonResponse + */ + public function show(Balance $balance) + { + if ($balance->canPay()) { + + $url = route('balances.show', compact('balance')); + $balance->url = $url; + + return $this->success($balance); + } else { + return $this->badRequest('无法支付。'); + } + } +} diff --git a/app/Http/Controllers/Web/BalanceController.php b/app/Http/Controllers/Web/BalanceController.php index 0159fa3..ae4dffb 100644 --- a/app/Http/Controllers/Web/BalanceController.php +++ b/app/Http/Controllers/Web/BalanceController.php @@ -18,8 +18,6 @@ class BalanceController extends Controller { - // - public function index(Request $request): View { $balance = $request->user()->balance; @@ -31,29 +29,16 @@ public function index(Request $request): View public function store(Request $request) { - // 充值 $this->validate($request, [ 'amount' => 'required|integer|min:0.1|max:10000', 'payment' => 'required|in:wechat,alipay', ]); - $user = $request->user(); - - $balance = new Balance(); - - $data = [ - 'user_id' => $user->id, + $balance = Balance::create([ + 'user_id' => auth('web')->id(), 'amount' => $request->input('amount'), 'payment' => $request->input('payment'), - ]; - - $balance = $balance->create($data); - - // 生成 18 位订单号 - $order_id = date('YmdHis') . $balance->id . rand(1000, 9999); - $balance->order_id = $order_id; - - $balance->save(); + ]); return redirect()->route('balances.show', compact('balance')); } @@ -64,7 +49,7 @@ public function store(Request $request) public function show(Request $request, Balance $balance) { - if ($balance->paid_at !== null) { + if ($balance->isPaid()) { if ($request->ajax()) { return $this->success($balance); } @@ -76,13 +61,14 @@ public function show(Request $request, Balance $balance) } } + if ($balance->isOverdue()) { + if (now()->diffInDays($balance->created_at) > 1) { + if ($request->ajax()) { + return $this->forbidden($balance); + } - if (now()->diffInDays($balance->created_at) > 1) { - if ($request->ajax()) { - return $this->forbidden($balance); + return redirect()->route('index')->with('error', '订单已逾期。'); } - - return redirect()->route('index')->with('error', '订单已逾期。'); } $balance->load('user'); @@ -109,14 +95,16 @@ public function show(Request $request, Balance $balance) } if (!isset($qr_code)) { - abort(500, '支付方式错误'); + return redirect()->route('index')->with('error', '支付方式错误。'); } return view('balances.pay', compact('balance', 'qr_code')); } - private function xunhu_wechat(Balance $balance, $subject = '支付') - { + private + function xunhu_wechat( + Balance $balance, $subject = '支付' + ) { $data = [ 'version' => '1.1', 'lang' => 'zh-cn', @@ -142,7 +130,7 @@ private function xunhu_wechat(Balance $balance, $subject = '支付') $response = Http::post(config('pay.xunhu.gateway'), $data); if (!$response->successful()) { - abort(500, '支付网关错误'); + return redirect()->route('index')->with('error', '支付网关错误。'); } $response = $response->json(); @@ -150,14 +138,16 @@ private function xunhu_wechat(Balance $balance, $subject = '支付') $hash = $this->xunhu_hash($response); if (!isset($response['hash']) || $response['hash'] !== $hash) { - abort(500, '无法校验支付网关返回数据'); + return redirect()->route('index')->with('error', '无法校验支付网关返回数据。'); } return $response; } - private function xunhu_hash(array $arr) - { + private + function xunhu_hash( + array $arr + ) { ksort($arr); $pre = []; @@ -188,10 +178,11 @@ private function xunhu_hash(array $arr) /** * @throws ValidationException */ - public function notify(Request $request, $payment): View|JsonResponse - { + public + function notify( + Request $request, $payment + ): View|JsonResponse { $is_paid = false; - // $pay_amount = 0; if ($payment === 'alipay') { $out_trade_no = $request->input('out_trade_no'); @@ -216,7 +207,6 @@ public function notify(Request $request, $payment): View|JsonResponse return view('balances.process', compact('balance')); } - // 处理验证 if ($payment === 'wechat') { if (!($request->filled('hash') || $request->filled('trade_order_id'))) { diff --git a/app/Models/Balance.php b/app/Models/Balance.php index e60e17a..bde3bac 100644 --- a/app/Models/Balance.php +++ b/app/Models/Balance.php @@ -77,12 +77,6 @@ class Balance extends Model 'amount' => 'decimal:2', ]; - // route key - public function getRouteKeyName(): string - { - return 'order_id'; - } - public function user(): BelongsToAlias { return $this->belongsTo(User::class); @@ -92,4 +86,31 @@ public function scopeThisUser($query) { return $query->where('user_id', auth()->id()); } + + public function isPaid(): bool + { + return $this->paid_at !== null; + } + + public function isOverdue(): bool + { + return $this->created_at->diffInDays(now()) > 1 && !$this->isPaid(); + } + + public function canPay(): bool + { + return !$this->isPaid() && !$this->isOverdue(); + } + + protected static function boot() + { + parent::boot(); + + static::creating(function ($balance) { + // $balance->remaining_amount = $balance->amount; + $balance->remaining_amount = 0; + + $balance->order_id = date('YmdHis') . $balance->id . rand(1000, 9999); + }); + } } diff --git a/routes/api.php b/routes/api.php index 8a64ec8..b0cf2fe 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,5 +1,6 @@ name('newToken'); Route::delete('deleteAll', [AuthController::class, 'deleteAll'])->name('deleteAll'); - Route::get('transactions', [BalanceController::class, 'transactions'])->name('transactions'); Route::resource('balances', BalanceController::class)->except('show'); - Route::get('/balances/{balance}', [BalanceController::class, 'show'])->name('balances.show')->withoutMiddleware('auth'); + Route::get('/balances/{balance:order_id}', [BalanceController::class, 'show'])->name('balances.show')->withoutMiddleware('auth'); Route::get('transfer', [TransferController::class, 'index'])->name('transfer'); Route::post('transfer', [TransferController::class, 'transfer']); @@ -37,6 +36,6 @@ Route::view('contact', 'contact')->name('contact'); Route::view('not_verified', 'not_verified')->name('not_verified'); -Route::any('/balances/notify/{payment}', [BalanceController::class, 'notify'])->name('balances.notify'); +Route::match(['get', 'post'], '/balances/notify/{payment}', [BalanceController::class, 'notify'])->name('balances.notify');