增加 流量充值
This commit is contained in:
parent
8bc35a78ea
commit
c5eff6ad4e
@ -3,10 +3,94 @@
|
|||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Support\WHMCS;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
|
||||||
class TrafficController extends Controller
|
class TrafficController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public function price()
|
||||||
|
{
|
||||||
|
return $this->success([
|
||||||
|
'price_per_gb' => config('settings.price_per_gb')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providers()
|
||||||
|
{
|
||||||
|
$config = config('whmcs');
|
||||||
|
|
||||||
|
// 获取 config 的所有的 key
|
||||||
|
$providers = array_keys($config);
|
||||||
|
|
||||||
|
return $this->success($providers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function payments(Request $request, $provider)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$whmcs = new WHMCS($provider);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$payments = $whmcs->getPayments();
|
||||||
|
|
||||||
|
return $this->success($payments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$traffic = $user->traffic ?? 0;
|
||||||
|
|
||||||
|
$day = now()->day;
|
||||||
|
$last_sign_at = Cache::get('traffic_sign:' . $day . '-' . $user->id, null);
|
||||||
|
|
||||||
|
return $this->success([
|
||||||
|
'traffic' => $traffic,
|
||||||
|
'is_signed' => $last_sign_at
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function charge(Request $request, string $provider)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'payment' => 'required',
|
||||||
|
'traffic' => 'required|integer|min:1'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$price = bcmul(config('settings.price_per_gb'), $request->input('traffic'), 2);
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
$whmcs = new WHMCS($provider);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->error('提供商不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$whmcs->hasPayment($request->input('payment'))) {
|
||||||
|
return $this->notFound('支付方式不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $request->user();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$result = $whmcs->api_addTraffic($user->email, $request->input('payment'), $request->input('traffic'), $price);
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function free()
|
public function free()
|
||||||
{
|
{
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
@ -4,29 +4,30 @@
|
|||||||
|
|
||||||
use App\Http\Middleware\Admin;
|
use App\Http\Middleware\Admin;
|
||||||
use App\Http\Middleware\ApiToken;
|
use App\Http\Middleware\ApiToken;
|
||||||
use App\Http\Middleware\Authenticate;
|
use App\Http\Middleware\WHMCSApi;
|
||||||
use App\Http\Middleware\EncryptCookies;
|
|
||||||
use App\Http\Middleware\PreventRequestsDuringMaintenance;
|
|
||||||
use App\Http\Middleware\RedirectIfAuthenticated;
|
|
||||||
use App\Http\Middleware\TrimStrings;
|
use App\Http\Middleware\TrimStrings;
|
||||||
|
use App\Http\Middleware\Authenticate;
|
||||||
use App\Http\Middleware\TrustProxies;
|
use App\Http\Middleware\TrustProxies;
|
||||||
use App\Http\Middleware\ValidateSignature;
|
use App\Http\Middleware\EncryptCookies;
|
||||||
use App\Http\Middleware\VerifyCsrfToken;
|
use App\Http\Middleware\VerifyCsrfToken;
|
||||||
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
|
|
||||||
use Illuminate\Auth\Middleware\Authorize;
|
use Illuminate\Auth\Middleware\Authorize;
|
||||||
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;
|
use App\Http\Middleware\ValidateSignature;
|
||||||
use Illuminate\Auth\Middleware\RequirePassword;
|
|
||||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
|
||||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
|
||||||
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
|
|
||||||
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
|
|
||||||
use Illuminate\Http\Middleware\HandleCors;
|
use Illuminate\Http\Middleware\HandleCors;
|
||||||
|
use Illuminate\Auth\Middleware\RequirePassword;
|
||||||
use Illuminate\Http\Middleware\SetCacheHeaders;
|
use Illuminate\Http\Middleware\SetCacheHeaders;
|
||||||
use Illuminate\Routing\Middleware\SubstituteBindings;
|
|
||||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
|
||||||
use Illuminate\Session\Middleware\AuthenticateSession;
|
|
||||||
use Illuminate\Session\Middleware\StartSession;
|
use Illuminate\Session\Middleware\StartSession;
|
||||||
|
use App\Http\Middleware\RedirectIfAuthenticated;
|
||||||
|
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||||
|
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||||
|
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;
|
||||||
|
use Illuminate\Routing\Middleware\SubstituteBindings;
|
||||||
|
use Illuminate\Session\Middleware\AuthenticateSession;
|
||||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||||
|
use App\Http\Middleware\PreventRequestsDuringMaintenance;
|
||||||
|
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
|
||||||
|
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
|
||||||
|
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||||
|
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
|
||||||
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
|
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
|
||||||
|
|
||||||
class Kernel extends HttpKernel
|
class Kernel extends HttpKernel
|
||||||
@ -89,5 +90,6 @@ class Kernel extends HttpKernel
|
|||||||
'throttle' => ThrottleRequests::class,
|
'throttle' => ThrottleRequests::class,
|
||||||
'verified' => EnsureEmailIsVerified::class,
|
'verified' => EnsureEmailIsVerified::class,
|
||||||
'api_token' => ApiToken::class,
|
'api_token' => ApiToken::class,
|
||||||
|
'whmcs_api' => WHMCSApi::class,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
76
app/Http/Middleware/WHMCSApi.php
Normal file
76
app/Http/Middleware/WHMCSApi.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
|
|
||||||
|
class WHMCSApi
|
||||||
|
{
|
||||||
|
public function handle(Request $request, Closure $next)
|
||||||
|
{
|
||||||
|
// add json header
|
||||||
|
$request->headers->set('Accept', 'application/json');
|
||||||
|
|
||||||
|
// bearer token
|
||||||
|
if (!$request->hasHeader('Authorization')) {
|
||||||
|
return $this->unauthorized('No Authorization header found.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$tokens = $request->bearerToken();
|
||||||
|
$tokens = explode('|', $tokens);
|
||||||
|
|
||||||
|
if (count($tokens) !== 2) {
|
||||||
|
return $this->unauthorized('Invalid Authorization header.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$whmcs_id = $tokens[0];
|
||||||
|
$token = $tokens[1];
|
||||||
|
|
||||||
|
$whmcs = config('whmcs.' . $whmcs_id);
|
||||||
|
|
||||||
|
if (is_null($whmcs)) {
|
||||||
|
return $this->unauthorized('Invalid WHMCS ID.');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$config_token = config('whmcs.' . $whmcs_id . '.api_token');
|
||||||
|
|
||||||
|
if ($config_token == null) {
|
||||||
|
return $this->unauthorized('Token not allowed.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($token !== $config_token) {
|
||||||
|
return $this->unauthorized('Invalid token.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->user_id) {
|
||||||
|
$user = User::where('id', $request->user_id)->first();
|
||||||
|
// if user null
|
||||||
|
if (!$user) {
|
||||||
|
$http = Http::remote('remote')->asForm();
|
||||||
|
$user = $http->get('/users/' . $request->user_id)->json();
|
||||||
|
|
||||||
|
$user = User::create([
|
||||||
|
'id' => $user['id'],
|
||||||
|
'name' => $user['name'],
|
||||||
|
'email' => $user['email'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Auth::guard('user')->login($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unauthorized($message = 'Unauthorized.')
|
||||||
|
{
|
||||||
|
return response()->json([
|
||||||
|
'message' => $message,
|
||||||
|
], 401);
|
||||||
|
}
|
||||||
|
}
|
140
app/Support/WHMCS.php
Normal file
140
app/Support/WHMCS.php
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Support;
|
||||||
|
|
||||||
|
class WHMCS
|
||||||
|
{
|
||||||
|
private string $url;
|
||||||
|
private string $username;
|
||||||
|
private string $password;
|
||||||
|
private string $api_token;
|
||||||
|
public int|string $platform;
|
||||||
|
public array $payments = [];
|
||||||
|
|
||||||
|
private string $config_key = '';
|
||||||
|
private array $config = [];
|
||||||
|
|
||||||
|
public function __construct(int|string $whmcs_id)
|
||||||
|
{
|
||||||
|
$this->config_key = 'whmcs.' . $whmcs_id;
|
||||||
|
$whmcs = config($this->config_key);
|
||||||
|
$this->config = $whmcs;
|
||||||
|
|
||||||
|
$this->platform = $whmcs_id;
|
||||||
|
|
||||||
|
if (is_null($whmcs)) {
|
||||||
|
throw new \Exception('WHMCS config not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->url = $whmcs['url'];
|
||||||
|
$this->username = $whmcs['username'] ?? '';
|
||||||
|
$this->password = md5($whmcs['password'] ?? '');
|
||||||
|
$this->api_token = $whmcs['api_token'];
|
||||||
|
$this->payments = $whmcs['payments'] ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasPayment(string $payment): bool
|
||||||
|
{
|
||||||
|
return in_array($payment, array_keys($this->payments));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPayments(): array
|
||||||
|
{
|
||||||
|
$results = [];
|
||||||
|
|
||||||
|
// 获取 config 的所有的 key
|
||||||
|
$payments = array_keys($this->config['payments'] ?? []);
|
||||||
|
|
||||||
|
foreach ($payments as $payment) {
|
||||||
|
$results[] = [
|
||||||
|
'name' => $payment,
|
||||||
|
'title' => $this->config['payments'][$payment]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function request($action, $params = []): ?array
|
||||||
|
{
|
||||||
|
$params = array_merge([
|
||||||
|
'action' => $action,
|
||||||
|
'username' => $this->username,
|
||||||
|
'password' => md5($this->password),
|
||||||
|
'responsetype' => 'json',
|
||||||
|
], $params);
|
||||||
|
|
||||||
|
|
||||||
|
$ch = curl_init();
|
||||||
|
curl_setopt($ch, CURLOPT_URL, $this->url . '/includes/api.php');
|
||||||
|
curl_setopt($ch, CURLOPT_POST, 1);
|
||||||
|
curl_setopt(
|
||||||
|
$ch,
|
||||||
|
CURLOPT_POSTFIELDS,
|
||||||
|
http_build_query($params)
|
||||||
|
);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
$json = json_decode($response, true);
|
||||||
|
|
||||||
|
throw_if(
|
||||||
|
is_null($json),
|
||||||
|
new \Exception('WHMCS response is not valid JSON')
|
||||||
|
);
|
||||||
|
|
||||||
|
throw_if(
|
||||||
|
isset($json['result']) && $json['result'] !== 'success',
|
||||||
|
new \Exception($json['message'])
|
||||||
|
);
|
||||||
|
|
||||||
|
return $json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function api($action, $params = []): ?array
|
||||||
|
{
|
||||||
|
$params = array_merge([
|
||||||
|
'api_token' => $this->api_token
|
||||||
|
], $params);
|
||||||
|
|
||||||
|
|
||||||
|
$ch = curl_init();
|
||||||
|
curl_setopt($ch, CURLOPT_URL, $this->url . '/modules/addons/PortIOInvoice/api/' . $action . '.php');
|
||||||
|
curl_setopt($ch, CURLOPT_POST, 1);
|
||||||
|
curl_setopt(
|
||||||
|
$ch,
|
||||||
|
CURLOPT_POSTFIELDS,
|
||||||
|
http_build_query($params)
|
||||||
|
);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
$json = json_decode($response, true);
|
||||||
|
|
||||||
|
throw_if(
|
||||||
|
is_null($json),
|
||||||
|
new \Exception('WHMCS response is not valid JSON')
|
||||||
|
);
|
||||||
|
|
||||||
|
throw_if(
|
||||||
|
isset($json['status']) && $json['status'] !== true,
|
||||||
|
new \Exception($json['message'] ?? '未知错误')
|
||||||
|
);
|
||||||
|
|
||||||
|
return $json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function api_addTraffic(string $email, string $payment, int|float $traffic, int|float|string $price)
|
||||||
|
{
|
||||||
|
return $this->api('addTraffic', [
|
||||||
|
'email' => $email,
|
||||||
|
'traffic' => $traffic,
|
||||||
|
'price' => $price,
|
||||||
|
'platform' => $this->platform,
|
||||||
|
'payment' => $payment
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,5 +4,6 @@
|
|||||||
'sign' => [
|
'sign' => [
|
||||||
'max' => 10,
|
'max' => 10,
|
||||||
'min' => 1,
|
'min' => 1,
|
||||||
]
|
],
|
||||||
|
'price_per_gb' => "0.01",
|
||||||
];
|
];
|
||||||
|
12
config/whmcs.php
Normal file
12
config/whmcs.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'test' => [
|
||||||
|
'url' => 'http://whmcs.test',
|
||||||
|
'api_token' => 'abc123456',
|
||||||
|
'payments' => [
|
||||||
|
'laeFastPay' => '莱云 快捷支付',
|
||||||
|
'mailin' => '邮入',
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
@ -37,17 +37,22 @@ const items = ref([
|
|||||||
route: "index",
|
route: "index",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "签到",
|
name: "穿透隧道",
|
||||||
route: "sign",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "隧道",
|
|
||||||
route: "tunnels",
|
route: "tunnels",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "创建隧道",
|
name: "创建隧道",
|
||||||
route: "tunnels.create",
|
route: "tunnels.create",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "签到",
|
||||||
|
route: "sign",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "充值",
|
||||||
|
route: "charge",
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: "客户端下载",
|
name: "客户端下载",
|
||||||
route: "downloads",
|
route: "downloads",
|
||||||
|
@ -51,6 +51,14 @@ const routes = [
|
|||||||
title: "签到",
|
title: "签到",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/charge",
|
||||||
|
name: "charge",
|
||||||
|
component: () => import("../views/Charge.vue"),
|
||||||
|
meta: {
|
||||||
|
title: "流量充值",
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
155
resources/js/views/Charge.vue
Normal file
155
resources/js/views/Charge.vue
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h3>流量充值</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h5>您要充值多少元的流量?</h5>
|
||||||
|
<p>
|
||||||
|
每 GB 价格: <span>{{ price_per_gb }}</span> 元。
|
||||||
|
</p>
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<input
|
||||||
|
autofocus
|
||||||
|
type="number"
|
||||||
|
class="form-control"
|
||||||
|
placeholder="输入您要的流量 (单位: GB)"
|
||||||
|
v-model="amount"
|
||||||
|
/>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<span class="input-group-text">GB</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="amount">
|
||||||
|
<p>大约 <span v-text="amount * price_per_gb"></span> 元。</p>
|
||||||
|
|
||||||
|
<div v-if="providers">
|
||||||
|
<h5 class="mt-3">您将要使用哪个平台充值?</h5>
|
||||||
|
<p>如果您在选中的平台没有账号,我们将会帮您自动创建一个。</p>
|
||||||
|
<template v-for="p in providers">
|
||||||
|
<div class="form-group form-check">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
class="form-check-input"
|
||||||
|
name="provider"
|
||||||
|
:id="'providers_' + p"
|
||||||
|
:value="p"
|
||||||
|
v-model.value="provider"
|
||||||
|
@change="getPayments"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
v-text="p"
|
||||||
|
class="form-check-label"
|
||||||
|
:for="'providers_' + p"
|
||||||
|
></label>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<h5 class="mt-3">暂时没有可用的</h5>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="payments">
|
||||||
|
<h5 class="mt-3">让我们来选择支付方式。</h5>
|
||||||
|
<p>在支付后,您的流量大概需要数秒钟到账。</p>
|
||||||
|
<template v-for="py in payments">
|
||||||
|
<div class="form-group form-check">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
class="form-check-input"
|
||||||
|
name="payment"
|
||||||
|
:id="'payments_' + py.name"
|
||||||
|
v-model="payment"
|
||||||
|
:value="py.name"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
v-text="py.title"
|
||||||
|
class="form-check-label"
|
||||||
|
:for="'payments_' + py.name"
|
||||||
|
></label>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="payment">
|
||||||
|
<button
|
||||||
|
class="btn btn-primary mt-3"
|
||||||
|
@click="pay"
|
||||||
|
v-text="loading ? '请稍后' : '立即支付'"
|
||||||
|
:disabled="loading"
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p v-if="loading">正在创建订单...</p>
|
||||||
|
|
||||||
|
<div v-if="link" class="mt-3">
|
||||||
|
<h5>完成</h5>
|
||||||
|
<p>如果您浏览器没有打开新的创建,请点击以下链接来打开。</p>
|
||||||
|
<a :href="link" class="link" target="_blank">支付</a>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
import http from "../plugins/http";
|
||||||
|
|
||||||
|
const price_per_gb = ref(0);
|
||||||
|
|
||||||
|
const providers = ref([]);
|
||||||
|
const provider = ref("");
|
||||||
|
|
||||||
|
const payments = ref({});
|
||||||
|
const payment = ref("");
|
||||||
|
|
||||||
|
const amount = ref(10);
|
||||||
|
|
||||||
|
const link = ref("");
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
http.get("price").then((res) => {
|
||||||
|
price_per_gb.value = res.data.price_per_gb;
|
||||||
|
});
|
||||||
|
|
||||||
|
http.get("providers").then((res) => {
|
||||||
|
providers.value = res.data;
|
||||||
|
|
||||||
|
// 选择第一个(如果有)
|
||||||
|
if (providers.value.length > 0) {
|
||||||
|
provider.value = providers.value[0];
|
||||||
|
getPayments();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function getPayments() {
|
||||||
|
http.get("providers/" + provider.value + "/payments").then((res) => {
|
||||||
|
payments.value = res.data;
|
||||||
|
|
||||||
|
// 选择第一个(如果有)
|
||||||
|
if (payments.value.length > 0) {
|
||||||
|
payment.value = payments.value[0].name;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function pay() {
|
||||||
|
loading.value = true;
|
||||||
|
http.post("providers/" + provider.value + "/charge", {
|
||||||
|
payment: payment.value,
|
||||||
|
traffic: amount.value,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
link.value = res.data.redirect_url;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
window.open(link.value, "_blank");
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
@ -23,9 +23,13 @@
|
|||||||
Route::get('traffic', [TrafficController::class, 'free']);
|
Route::get('traffic', [TrafficController::class, 'free']);
|
||||||
Route::post('traffic', [TrafficController::class, 'sign']);
|
Route::post('traffic', [TrafficController::class, 'sign']);
|
||||||
|
|
||||||
|
Route::get('price', [TrafficController::class, 'price']);
|
||||||
|
Route::get('providers', [TrafficController::class, 'providers']);
|
||||||
|
Route::get('providers/{provider}/payments', [TrafficController::class, 'payments']);
|
||||||
|
Route::post('providers/{provider}/charge', [TrafficController::class, 'charge']);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::prefix('application')->name('application.')->middleware('api_token')->group(function () {
|
Route::prefix('application')->name('application.')->middleware('whmcs_api')->group(function () {
|
||||||
Route::post('users/{user:email}/traffic', [ApplicationUserController::class, 'addTraffic']);
|
Route::post('users/{user:email}/traffic', [ApplicationUserController::class, 'addTraffic']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user