增加 API 充值
优化 Balance 代码
This commit is contained in:
parent
796fd6fce2
commit
15ecf5516a
69
app/Http/Controllers/Api/BalanceController.php
Normal file
69
app/Http/Controllers/Api/BalanceController.php
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Balance;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class BalanceController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$balances = Balance::thisUser()->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('无法支付。');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
class BalanceController extends Controller
|
class BalanceController extends Controller
|
||||||
{
|
{
|
||||||
//
|
|
||||||
|
|
||||||
public function index(Request $request): View
|
public function index(Request $request): View
|
||||||
{
|
{
|
||||||
$balance = $request->user()->balance;
|
$balance = $request->user()->balance;
|
||||||
@ -31,29 +29,16 @@ public function index(Request $request): View
|
|||||||
|
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
// 充值
|
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
'amount' => 'required|integer|min:0.1|max:10000',
|
'amount' => 'required|integer|min:0.1|max:10000',
|
||||||
'payment' => 'required|in:wechat,alipay',
|
'payment' => 'required|in:wechat,alipay',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$user = $request->user();
|
$balance = Balance::create([
|
||||||
|
'user_id' => auth('web')->id(),
|
||||||
$balance = new Balance();
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
'user_id' => $user->id,
|
|
||||||
'amount' => $request->input('amount'),
|
'amount' => $request->input('amount'),
|
||||||
'payment' => $request->input('payment'),
|
'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'));
|
return redirect()->route('balances.show', compact('balance'));
|
||||||
}
|
}
|
||||||
@ -64,7 +49,7 @@ public function store(Request $request)
|
|||||||
public function show(Request $request, Balance $balance)
|
public function show(Request $request, Balance $balance)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ($balance->paid_at !== null) {
|
if ($balance->isPaid()) {
|
||||||
if ($request->ajax()) {
|
if ($request->ajax()) {
|
||||||
return $this->success($balance);
|
return $this->success($balance);
|
||||||
}
|
}
|
||||||
@ -76,7 +61,7 @@ public function show(Request $request, Balance $balance)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($balance->isOverdue()) {
|
||||||
if (now()->diffInDays($balance->created_at) > 1) {
|
if (now()->diffInDays($balance->created_at) > 1) {
|
||||||
if ($request->ajax()) {
|
if ($request->ajax()) {
|
||||||
return $this->forbidden($balance);
|
return $this->forbidden($balance);
|
||||||
@ -84,6 +69,7 @@ public function show(Request $request, Balance $balance)
|
|||||||
|
|
||||||
return redirect()->route('index')->with('error', '订单已逾期。');
|
return redirect()->route('index')->with('error', '订单已逾期。');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$balance->load('user');
|
$balance->load('user');
|
||||||
|
|
||||||
@ -109,14 +95,16 @@ public function show(Request $request, Balance $balance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($qr_code)) {
|
if (!isset($qr_code)) {
|
||||||
abort(500, '支付方式错误');
|
return redirect()->route('index')->with('error', '支付方式错误。');
|
||||||
}
|
}
|
||||||
|
|
||||||
return view('balances.pay', compact('balance', 'qr_code'));
|
return view('balances.pay', compact('balance', 'qr_code'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function xunhu_wechat(Balance $balance, $subject = '支付')
|
private
|
||||||
{
|
function xunhu_wechat(
|
||||||
|
Balance $balance, $subject = '支付'
|
||||||
|
) {
|
||||||
$data = [
|
$data = [
|
||||||
'version' => '1.1',
|
'version' => '1.1',
|
||||||
'lang' => 'zh-cn',
|
'lang' => 'zh-cn',
|
||||||
@ -142,7 +130,7 @@ private function xunhu_wechat(Balance $balance, $subject = '支付')
|
|||||||
$response = Http::post(config('pay.xunhu.gateway'), $data);
|
$response = Http::post(config('pay.xunhu.gateway'), $data);
|
||||||
|
|
||||||
if (!$response->successful()) {
|
if (!$response->successful()) {
|
||||||
abort(500, '支付网关错误');
|
return redirect()->route('index')->with('error', '支付网关错误。');
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $response->json();
|
$response = $response->json();
|
||||||
@ -150,14 +138,16 @@ private function xunhu_wechat(Balance $balance, $subject = '支付')
|
|||||||
$hash = $this->xunhu_hash($response);
|
$hash = $this->xunhu_hash($response);
|
||||||
|
|
||||||
if (!isset($response['hash']) || $response['hash'] !== $hash) {
|
if (!isset($response['hash']) || $response['hash'] !== $hash) {
|
||||||
abort(500, '无法校验支付网关返回数据');
|
return redirect()->route('index')->with('error', '无法校验支付网关返回数据。');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function xunhu_hash(array $arr)
|
private
|
||||||
{
|
function xunhu_hash(
|
||||||
|
array $arr
|
||||||
|
) {
|
||||||
ksort($arr);
|
ksort($arr);
|
||||||
|
|
||||||
$pre = [];
|
$pre = [];
|
||||||
@ -188,10 +178,11 @@ private function xunhu_hash(array $arr)
|
|||||||
/**
|
/**
|
||||||
* @throws ValidationException
|
* @throws ValidationException
|
||||||
*/
|
*/
|
||||||
public function notify(Request $request, $payment): View|JsonResponse
|
public
|
||||||
{
|
function notify(
|
||||||
|
Request $request, $payment
|
||||||
|
): View|JsonResponse {
|
||||||
$is_paid = false;
|
$is_paid = false;
|
||||||
// $pay_amount = 0;
|
|
||||||
|
|
||||||
if ($payment === 'alipay') {
|
if ($payment === 'alipay') {
|
||||||
$out_trade_no = $request->input('out_trade_no');
|
$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'));
|
return view('balances.process', compact('balance'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 处理验证
|
// 处理验证
|
||||||
if ($payment === 'wechat') {
|
if ($payment === 'wechat') {
|
||||||
if (!($request->filled('hash') || $request->filled('trade_order_id'))) {
|
if (!($request->filled('hash') || $request->filled('trade_order_id'))) {
|
||||||
|
@ -77,12 +77,6 @@ class Balance extends Model
|
|||||||
'amount' => 'decimal:2',
|
'amount' => 'decimal:2',
|
||||||
];
|
];
|
||||||
|
|
||||||
// route key
|
|
||||||
public function getRouteKeyName(): string
|
|
||||||
{
|
|
||||||
return 'order_id';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function user(): BelongsToAlias
|
public function user(): BelongsToAlias
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
@ -92,4 +86,31 @@ public function scopeThisUser($query)
|
|||||||
{
|
{
|
||||||
return $query->where('user_id', auth()->id());
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\Api\BalanceController;
|
||||||
use App\Http\Controllers\Api\ForumController;
|
use App\Http\Controllers\Api\ForumController;
|
||||||
use App\Http\Controllers\Api\HostController;
|
use App\Http\Controllers\Api\HostController;
|
||||||
use App\Http\Controllers\Api\IndexController;
|
use App\Http\Controllers\Api\IndexController;
|
||||||
@ -17,6 +18,8 @@
|
|||||||
Route::get('user', [UserController::class, 'index']);
|
Route::get('user', [UserController::class, 'index']);
|
||||||
Route::get('users', [UserController::class, 'index']);
|
Route::get('users', [UserController::class, 'index']);
|
||||||
|
|
||||||
|
Route::resource('balances', BalanceController::class);
|
||||||
|
|
||||||
Route::get('servers', ServerController::class);
|
Route::get('servers', ServerController::class);
|
||||||
|
|
||||||
Route::get('modules', [ModuleController::class, 'index']);
|
Route::get('modules', [ModuleController::class, 'index']);
|
||||||
|
@ -23,11 +23,10 @@
|
|||||||
Route::post('newToken', [AuthController::class, 'newToken'])->name('newToken');
|
Route::post('newToken', [AuthController::class, 'newToken'])->name('newToken');
|
||||||
Route::delete('deleteAll', [AuthController::class, 'deleteAll'])->name('deleteAll');
|
Route::delete('deleteAll', [AuthController::class, 'deleteAll'])->name('deleteAll');
|
||||||
|
|
||||||
|
|
||||||
Route::get('transactions', [BalanceController::class, 'transactions'])->name('transactions');
|
Route::get('transactions', [BalanceController::class, 'transactions'])->name('transactions');
|
||||||
|
|
||||||
Route::resource('balances', BalanceController::class)->except('show');
|
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::get('transfer', [TransferController::class, 'index'])->name('transfer');
|
||||||
Route::post('transfer', [TransferController::class, 'transfer']);
|
Route::post('transfer', [TransferController::class, 'transfer']);
|
||||||
@ -37,6 +36,6 @@
|
|||||||
Route::view('contact', 'contact')->name('contact');
|
Route::view('contact', 'contact')->name('contact');
|
||||||
|
|
||||||
Route::view('not_verified', 'not_verified')->name('not_verified');
|
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');
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user