diff --git a/app/Http/Controllers/Api/Client/ClientController.php b/app/Http/Controllers/Api/Client/ClientController.php index 26c1e8b..88fcbf0 100644 --- a/app/Http/Controllers/Api/Client/ClientController.php +++ b/app/Http/Controllers/Api/Client/ClientController.php @@ -81,7 +81,7 @@ class ClientController extends Controller */ public function me() { - return new ClientResource(auth('sanctum')->user()); + return new ClientResource(auth('client')->user()); } /** @@ -201,7 +201,7 @@ class ClientController extends Controller */ public function logout() { - auth('sanctum')->user()->currentAccessToken()->delete(); + auth('client')->logout(); return response()->json([ 'error' => false, diff --git a/app/Http/Controllers/Api/Transaction/TransactionController.php b/app/Http/Controllers/Api/Transaction/TransactionController.php index ac97688..a4cdbfd 100644 --- a/app/Http/Controllers/Api/Transaction/TransactionController.php +++ b/app/Http/Controllers/Api/Transaction/TransactionController.php @@ -11,6 +11,7 @@ use App\Models\Log; use App\Models\Transaction; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log as FacadesLog; class TransactionController extends Controller { @@ -55,6 +56,12 @@ class TransactionController extends Controller $vnp_TxnRef = $data['vnp_TxnRef'] ?? null; $vnp_Amount = $data['vnp_Amount'] ?? 0; + FacadesLog::info('VNPay callback received', [ + 'vnp_TxnRef' => $vnp_TxnRef, + 'vnp_Amount' => $vnp_Amount, + 'user' => $request->user() ? $request->user()->id : 'not authenticated', + ]); + $transaction = Transaction::where('trans', 'DEP' . $vnp_TxnRef)->first(); if (!$transaction) { @@ -100,6 +107,12 @@ class TransactionController extends Controller $verify = $this->vnpayService->verifyPayment($data); + FacadesLog::info('VNPay callback debug', [ + 'isValid' => $verify['isValid'], + 'isSuccess' => $verify['isSuccess'] ?? false, + 'responseCode' => $data['vnp_ResponseCode'] ?? 'N/A', + ]); + if (!$verify['isValid']) { return response()->json([ 'error' => true, @@ -137,10 +150,24 @@ class TransactionController extends Controller $transaction->update(['status' => TransactionStatus::COMPLETED->value]); $customer = Customer::find($transaction->customer_id); + + FacadesLog::info('Customer update debug', [ + 'customer_id' => $transaction->customer_id, + 'customer_found' => $customer ? true : false, + 'transaction_amount' => $transaction->amount, + 'current_total' => $customer->total ?? 'N/A', + 'current_credit' => $customer->credit ?? 'N/A', + ]); + $customer->total += $transaction->amount; $customer->credit += $transaction->amount / 100; $customer->save(); + FacadesLog::info('Customer after update', [ + 'new_total' => $customer->total, + 'new_credit' => $customer->credit, + ]); + Log::create([ 'agent' => 'api', 'client_ip' => $request->ip(), @@ -206,4 +233,39 @@ class TransactionController extends Controller 'data' => $transaction, ]); } + + public function verifyPayment(Request $request) + { + $transRef = $request->query('vnp_TxnRef'); + + if (!$transRef) { + return response()->json([ + 'error' => true, + 'message' => 'Thiếu tham số vnp_TxnRef', + ], 400); + } + + $transaction = Transaction::where('trans', 'DEP' . $transRef)->first(); + + if (!$transaction) { + return response()->json([ + 'error' => true, + 'message' => 'Giao dịch không tồn tại', + ], 404); + } + + return response()->json([ + 'error' => false, + 'message' => 'Lấy thông tin giao dịch thành công', + 'data' => [ + 'trans' => $transaction->trans, + 'amount' => $transaction->amount, + 'amount_vnp' => $transaction->amount * 100, + 'status' => $transaction->status, + 'status_label' => TransactionStatus::from($transaction->status)->label(), + 'created_at' => $transaction->created_at, + 'updated_at' => $transaction->updated_at, + ], + ]); + } } \ No newline at end of file diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 2fc5c3d..3560712 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -40,7 +40,6 @@ class Kernel extends HttpKernel ], 'api' => [ - \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], diff --git a/app/Http/Middleware/ApiAuthCheck.php b/app/Http/Middleware/ApiAuthCheck.php index df9a1ed..1baef2f 100644 --- a/app/Http/Middleware/ApiAuthCheck.php +++ b/app/Http/Middleware/ApiAuthCheck.php @@ -17,7 +17,7 @@ class ApiAuthCheck */ public function handle(Request $request, Closure $next, $guard = null) { - $checkGuard = $guard ?: 'sanctum'; + $checkGuard = $guard ?: 'client'; if (!Auth::guard($checkGuard)->check()) { return response()->json([ diff --git a/app/Http/Services/VNPayService.php b/app/Http/Services/VNPayService.php index 6188cd9..8fccd82 100644 --- a/app/Http/Services/VNPayService.php +++ b/app/Http/Services/VNPayService.php @@ -26,7 +26,7 @@ class VNPayService $vnp_BankCode = $data['bankCode'] ?? ''; $vnp_IpAddr = request()->ip(); - $user = Auth::guard('sanctum')->user() ?? Auth::guard('users')->user(); + $user = Auth::guard('client')->user() ?? Auth::guard('users')->user(); $userName = $user ? $user->fullname : 'Khách'; $isDeposit = isset($data['transaction_ref']); diff --git a/app/Models/Customer.php b/app/Models/Customer.php index d7fe73d..6c35446 100644 --- a/app/Models/Customer.php +++ b/app/Models/Customer.php @@ -7,8 +7,9 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Foundation\Auth\User as Authenticatable; use Laravel\Sanctum\HasApiTokens; +use Tymon\JWTAuth\Contracts\JWTSubject; -class Customer extends Authenticatable +class Customer extends Authenticatable implements JWTSubject { use HasFactory, HasApiTokens, HasUuids, SoftDeletes; @@ -228,4 +229,14 @@ class Customer extends Authenticatable { return $this->gender?->label() ?? 'Khác'; } + + public function getJWTIdentifier() + { + return $this->getKey(); + } + + public function getJWTCustomClaims() + { + return []; + } } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index b8fa873..0ba6606 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -39,7 +39,7 @@ class RouteServiceProvider extends ServiceProvider $this->routes(function () { // 1. Agency API (Domain riêng, dùng routes/client.php) - Route::domain('api-agency.tgs.com.vn.test') + Route::domain('api-agency.test') ->middleware(['api', 'json.response']) ->namespace($this->namespace) ->group(base_path('routes/client.php')); diff --git a/app/Services/Api/Client/ClientAuthService.php b/app/Services/Api/Client/ClientAuthService.php index ac761f1..52ff5b5 100644 --- a/app/Services/Api/Client/ClientAuthService.php +++ b/app/Services/Api/Client/ClientAuthService.php @@ -5,6 +5,7 @@ namespace App\Services\Api\Client; use App\Repositories\Api\Client\ClientRepositoryInterface; use Illuminate\Support\Facades\Auth; use Illuminate\Validation\ValidationException; +use Tymon\JWTAuth\Facades\JWTAuth; class ClientAuthService { @@ -20,14 +21,13 @@ class ClientAuthService */ public function authenticateClient(array $credentials): array { - if (!Auth::guard('client')->attempt($credentials)) { + if (!$token = Auth::guard('client')->attempt($credentials)) { throw ValidationException::withMessages([ 'email' => ['Thông tin đăng nhập không chính xác.'], ]); } $client = Auth::guard('client')->user(); - $token = $client->createToken('client-token')->plainTextToken; return [ 'client' => $client, @@ -47,7 +47,7 @@ class ClientAuthService 'password' => bcrypt($data['password']), ]); - $token = $client->createToken('client-token')->plainTextToken; + $token = JWTAuth::fromUser($client); return [ 'client' => $client, diff --git a/composer.json b/composer.json index cca7785..13d236e 100644 --- a/composer.json +++ b/composer.json @@ -30,6 +30,7 @@ "pusher/pusher-php-server": "^7.2", "spatie/laravel-permission": "^6.3", "spatie/laravel-sluggable": "^3.7", + "tymon/jwt-auth": "^2.0", "yajra/laravel-datatables": "^10.0", "yajra/laravel-datatables-oracle": "^10.3.1" }, diff --git a/composer.lock b/composer.lock index 53cadb8..d0da793 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5d2f1f843f26a0e49fde4a891d311eb7", + "content-hash": "e8e3d079473d0f39c2ea9336da6e56cc", "packages": [ { "name": "aws/aws-crt-php", @@ -2254,16 +2254,16 @@ }, { "name": "laravel/framework", - "version": "v10.50.0", + "version": "10.50.2", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "fc41c8ceb4d4a55b23d4030ef4ed86383e4b2bc3" + "reference": "3ff39b7a9b83e633383ec9b019827ed54b6d38bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/fc41c8ceb4d4a55b23d4030ef4ed86383e4b2bc3", - "reference": "fc41c8ceb4d4a55b23d4030ef4ed86383e4b2bc3", + "url": "https://api.github.com/repos/laravel/framework/zipball/3ff39b7a9b83e633383ec9b019827ed54b6d38bc", + "reference": "3ff39b7a9b83e633383ec9b019827ed54b6d38bc", "shasum": "" }, "require": { @@ -2458,7 +2458,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-11-28T18:20:42+00:00" + "time": "2026-02-15T14:12:07+00:00" }, { "name": "laravel/horizon", @@ -2932,38 +2932,39 @@ }, { "name": "lcobucci/jwt", - "version": "5.6.0", + "version": "4.3.0", "source": { "type": "git", "url": "https://github.com/lcobucci/jwt.git", - "reference": "bb3e9f21e4196e8afc41def81ef649c164bca25e" + "reference": "4d7de2fe0d51a96418c0d04004986e410e87f6b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/jwt/zipball/bb3e9f21e4196e8afc41def81ef649c164bca25e", - "reference": "bb3e9f21e4196e8afc41def81ef649c164bca25e", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/4d7de2fe0d51a96418c0d04004986e410e87f6b4", + "reference": "4d7de2fe0d51a96418c0d04004986e410e87f6b4", "shasum": "" }, "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-mbstring": "*", "ext-openssl": "*", "ext-sodium": "*", - "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", - "psr/clock": "^1.0" + "lcobucci/clock": "^2.0 || ^3.0", + "php": "^7.4 || ^8.0" }, "require-dev": { - "infection/infection": "^0.29", - "lcobucci/clock": "^3.2", - "lcobucci/coding-standard": "^11.0", + "infection/infection": "^0.21", + "lcobucci/coding-standard": "^6.0", + "mikey179/vfsstream": "^1.6.7", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.2", - "phpstan/phpstan": "^1.10.7", - "phpstan/phpstan-deprecation-rules": "^1.1.3", - "phpstan/phpstan-phpunit": "^1.3.10", - "phpstan/phpstan-strict-rules": "^1.5.0", - "phpunit/phpunit": "^11.1" - }, - "suggest": { - "lcobucci/clock": ">= 3.2" + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/php-invoker": "^3.1", + "phpunit/phpunit": "^9.5" }, "type": "library", "autoload": { @@ -2989,7 +2990,7 @@ ], "support": { "issues": "https://github.com/lcobucci/jwt/issues", - "source": "https://github.com/lcobucci/jwt/tree/5.6.0" + "source": "https://github.com/lcobucci/jwt/tree/4.3.0" }, "funding": [ { @@ -3001,7 +3002,7 @@ "type": "patreon" } ], - "time": "2025-10-17T11:30:53+00:00" + "time": "2023-01-02T13:28:00+00:00" }, { "name": "league/commonmark", @@ -4702,16 +4703,16 @@ }, { "name": "nette/schema", - "version": "v1.3.3", + "version": "v1.3.4", "source": { "type": "git", "url": "https://github.com/nette/schema.git", - "reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004" + "reference": "086497a2f34b82fede9b5a41cc8e131d087cd8f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/2befc2f42d7c715fd9d95efc31b1081e5d765004", - "reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004", + "url": "https://api.github.com/repos/nette/schema/zipball/086497a2f34b82fede9b5a41cc8e131d087cd8f7", + "reference": "086497a2f34b82fede9b5a41cc8e131d087cd8f7", "shasum": "" }, "require": { @@ -4719,8 +4720,8 @@ "php": "8.1 - 8.5" }, "require-dev": { - "nette/tester": "^2.5.2", - "phpstan/phpstan-nette": "^2.0@stable", + "nette/tester": "^2.6", + "phpstan/phpstan": "^2.0@stable", "tracy/tracy": "^2.8" }, "type": "library", @@ -4761,22 +4762,22 @@ ], "support": { "issues": "https://github.com/nette/schema/issues", - "source": "https://github.com/nette/schema/tree/v1.3.3" + "source": "https://github.com/nette/schema/tree/v1.3.4" }, - "time": "2025-10-30T22:57:59+00:00" + "time": "2026-02-08T02:54:00+00:00" }, { "name": "nette/utils", - "version": "v4.1.1", + "version": "v4.1.3", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "c99059c0315591f1a0db7ad6002000288ab8dc72" + "reference": "bb3ea637e3d131d72acc033cfc2746ee893349fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/c99059c0315591f1a0db7ad6002000288ab8dc72", - "reference": "c99059c0315591f1a0db7ad6002000288ab8dc72", + "url": "https://api.github.com/repos/nette/utils/zipball/bb3ea637e3d131d72acc033cfc2746ee893349fe", + "reference": "bb3ea637e3d131d72acc033cfc2746ee893349fe", "shasum": "" }, "require": { @@ -4788,8 +4789,10 @@ }, "require-dev": { "jetbrains/phpstorm-attributes": "^1.2", + "nette/phpstan-rules": "^1.0", "nette/tester": "^2.5", - "phpstan/phpstan-nette": "^2.0@stable", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", "tracy/tracy": "^2.9" }, "suggest": { @@ -4850,9 +4853,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.1.1" + "source": "https://github.com/nette/utils/tree/v4.1.3" }, - "time": "2025-12-22T12:14:32+00:00" + "time": "2026-02-13T03:05:33+00:00" }, { "name": "nikic/php-parser", @@ -9625,6 +9628,90 @@ }, "time": "2025-12-02T11:56:42+00:00" }, + { + "name": "tymon/jwt-auth", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/tymondesigns/jwt-auth.git", + "reference": "42381e56db1bf887c12e5302d11901d65cc74856" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tymondesigns/jwt-auth/zipball/42381e56db1bf887c12e5302d11901d65cc74856", + "reference": "42381e56db1bf887c12e5302d11901d65cc74856", + "shasum": "" + }, + "require": { + "illuminate/auth": "^9.0|^10.0|^11.0|^12.0", + "illuminate/contracts": "^9.0|^10.0|^11.0|^12.0", + "illuminate/http": "^9.0|^10.0|^11.0|^12.0", + "illuminate/support": "^9.0|^10.0|^11.0|^12.0", + "lcobucci/jwt": "^4.0", + "nesbot/carbon": "^2.69|^3.0", + "php": "^8.0" + }, + "require-dev": { + "illuminate/console": "^9.0|^10.0|^11.0|^12.0", + "illuminate/database": "^9.0|^10.0|^11.0|^12.0", + "illuminate/routing": "^9.0|^10.0|^11.0|^12.0", + "mockery/mockery": "^1.6", + "phpunit/phpunit": "^9.4" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "JWTAuth": "Tymon\\JWTAuth\\Facades\\JWTAuth", + "JWTFactory": "Tymon\\JWTAuth\\Facades\\JWTFactory" + }, + "providers": [ + "Tymon\\JWTAuth\\Providers\\LaravelServiceProvider" + ] + }, + "branch-alias": { + "dev-2.x": "2.0-dev", + "dev-develop": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Tymon\\JWTAuth\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sean Tymon", + "email": "tymon148@gmail.com", + "homepage": "https://tymon.xyz", + "role": "Developer" + } + ], + "description": "JSON Web Token Authentication for Laravel and Lumen", + "homepage": "https://github.com/tymondesigns/jwt-auth", + "keywords": [ + "Authentication", + "JSON Web Token", + "auth", + "jwt", + "laravel" + ], + "support": { + "issues": "https://github.com/tymondesigns/jwt-auth/issues", + "source": "https://github.com/tymondesigns/jwt-auth" + }, + "funding": [ + { + "url": "https://www.patreon.com/seantymon", + "type": "patreon" + } + ], + "time": "2025-04-16T22:22:54+00:00" + }, { "name": "vlucas/phpdotenv", "version": "v5.6.3", diff --git a/config/auth.php b/config/auth.php index 486a6b8..1bd0765 100644 --- a/config/auth.php +++ b/config/auth.php @@ -53,7 +53,15 @@ return [ 'provider' => 'users', ], 'client' => [ - 'driver' => 'session', + 'driver' => 'jwt', + 'provider' => 'users', + ], + 'client-api' => [ + 'driver' => 'jwt', + 'provider' => 'users', + ], + 'client-sanctum' => [ + 'driver' => 'sanctum', 'provider' => 'users', ], ], diff --git a/config/cors.php b/config/cors.php index d8e09b8..403ed4b 100644 --- a/config/cors.php +++ b/config/cors.php @@ -15,11 +15,11 @@ return [ | */ - 'paths' => ['api/*', 'sanctum/csrf-cookie'], + 'paths' => ['api/*', 'sanctum/csrf-cookie', 'v1/*'], 'allowed_methods' => ['*'], - 'allowed_origins' => ['*', 'http://localhost:5173', 'http://localhost:3000', 'http://localhost:3001'], + 'allowed_origins' => ['*', 'http://localhost:5173/', 'http://localhost:3000/', 'http://localhost:3001/', 'https://127.0.0.1/'], 'allowed_origins_patterns' => [], diff --git a/config/jwt.php b/config/jwt.php new file mode 100644 index 0000000..f83234d --- /dev/null +++ b/config/jwt.php @@ -0,0 +1,301 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +return [ + + /* + |-------------------------------------------------------------------------- + | JWT Authentication Secret + |-------------------------------------------------------------------------- + | + | Don't forget to set this in your .env file, as it will be used to sign + | your tokens. A helper command is provided for this: + | `php artisan jwt:secret` + | + | Note: This will be used for Symmetric algorithms only (HMAC), + | since RSA and ECDSA use a private/public key combo (See below). + | + */ + + 'secret' => env('JWT_SECRET'), + + /* + |-------------------------------------------------------------------------- + | JWT Authentication Keys + |-------------------------------------------------------------------------- + | + | The algorithm you are using, will determine whether your tokens are + | signed with a random string (defined in `JWT_SECRET`) or using the + | following public & private keys. + | + | Symmetric Algorithms: + | HS256, HS384 & HS512 will use `JWT_SECRET`. + | + | Asymmetric Algorithms: + | RS256, RS384 & RS512 / ES256, ES384 & ES512 will use the keys below. + | + */ + + 'keys' => [ + + /* + |-------------------------------------------------------------------------- + | Public Key + |-------------------------------------------------------------------------- + | + | A path or resource to your public key. + | + | E.g. 'file://path/to/public/key' + | + */ + + 'public' => env('JWT_PUBLIC_KEY'), + + /* + |-------------------------------------------------------------------------- + | Private Key + |-------------------------------------------------------------------------- + | + | A path or resource to your private key. + | + | E.g. 'file://path/to/private/key' + | + */ + + 'private' => env('JWT_PRIVATE_KEY'), + + /* + |-------------------------------------------------------------------------- + | Passphrase + |-------------------------------------------------------------------------- + | + | The passphrase for your private key. Can be null if none set. + | + */ + + 'passphrase' => env('JWT_PASSPHRASE'), + + ], + + /* + |-------------------------------------------------------------------------- + | JWT time to live + |-------------------------------------------------------------------------- + | + | Specify the length of time (in minutes) that the token will be valid for. + | Defaults to 1 hour. + | + | You can also set this to null, to yield a never expiring token. + | Some people may want this behaviour for e.g. a mobile app. + | This is not particularly recommended, so make sure you have appropriate + | systems in place to revoke the token if necessary. + | Notice: If you set this to null you should remove 'exp' element from 'required_claims' list. + | + */ + + 'ttl' => env('JWT_TTL', 60), + + /* + |-------------------------------------------------------------------------- + | Refresh time to live + |-------------------------------------------------------------------------- + | + | Specify the length of time (in minutes) that the token can be refreshed + | within. I.E. The user can refresh their token within a 2 week window of + | the original token being created until they must re-authenticate. + | Defaults to 2 weeks. + | + | You can also set this to null, to yield an infinite refresh time. + | Some may want this instead of never expiring tokens for e.g. a mobile app. + | This is not particularly recommended, so make sure you have appropriate + | systems in place to revoke the token if necessary. + | + */ + + 'refresh_ttl' => env('JWT_REFRESH_TTL', 20160), + + /* + |-------------------------------------------------------------------------- + | JWT hashing algorithm + |-------------------------------------------------------------------------- + | + | Specify the hashing algorithm that will be used to sign the token. + | + */ + + 'algo' => env('JWT_ALGO', Tymon\JWTAuth\Providers\JWT\Provider::ALGO_HS256), + + /* + |-------------------------------------------------------------------------- + | Required Claims + |-------------------------------------------------------------------------- + | + | Specify the required claims that must exist in any token. + | A TokenInvalidException will be thrown if any of these claims are not + | present in the payload. + | + */ + + 'required_claims' => [ + 'iss', + 'iat', + 'exp', + 'nbf', + 'sub', + 'jti', + ], + + /* + |-------------------------------------------------------------------------- + | Persistent Claims + |-------------------------------------------------------------------------- + | + | Specify the claim keys to be persisted when refreshing a token. + | `sub` and `iat` will automatically be persisted, in + | addition to the these claims. + | + | Note: If a claim does not exist then it will be ignored. + | + */ + + 'persistent_claims' => [ + // 'foo', + // 'bar', + ], + + /* + |-------------------------------------------------------------------------- + | Lock Subject + |-------------------------------------------------------------------------- + | + | This will determine whether a `prv` claim is automatically added to + | the token. The purpose of this is to ensure that if you have multiple + | authentication models e.g. `App\User` & `App\OtherPerson`, then we + | should prevent one authentication request from impersonating another, + | if 2 tokens happen to have the same id across the 2 different models. + | + | Under specific circumstances, you may want to disable this behaviour + | e.g. if you only have one authentication model, then you would save + | a little on token size. + | + */ + + 'lock_subject' => true, + + /* + |-------------------------------------------------------------------------- + | Leeway + |-------------------------------------------------------------------------- + | + | This property gives the jwt timestamp claims some "leeway". + | Meaning that if you have any unavoidable slight clock skew on + | any of your servers then this will afford you some level of cushioning. + | + | This applies to the claims `iat`, `nbf` and `exp`. + | + | Specify in seconds - only if you know you need it. + | + */ + + 'leeway' => env('JWT_LEEWAY', 0), + + /* + |-------------------------------------------------------------------------- + | Blacklist Enabled + |-------------------------------------------------------------------------- + | + | In order to invalidate tokens, you must have the blacklist enabled. + | If you do not want or need this functionality, then set this to false. + | + */ + + 'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true), + + /* + | ------------------------------------------------------------------------- + | Blacklist Grace Period + | ------------------------------------------------------------------------- + | + | When multiple concurrent requests are made with the same JWT, + | it is possible that some of them fail, due to token regeneration + | on every request. + | + | Set grace period in seconds to prevent parallel request failure. + | + */ + + 'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0), + + /* + |-------------------------------------------------------------------------- + | Cookies encryption + |-------------------------------------------------------------------------- + | + | By default Laravel encrypt cookies for security reason. + | If you decide to not decrypt cookies, you will have to configure Laravel + | to not encrypt your cookie token by adding its name into the $except + | array available in the middleware "EncryptCookies" provided by Laravel. + | see https://laravel.com/docs/master/responses#cookies-and-encryption + | for details. + | + | Set it to true if you want to decrypt cookies. + | + */ + + 'decrypt_cookies' => false, + + /* + |-------------------------------------------------------------------------- + | Providers + |-------------------------------------------------------------------------- + | + | Specify the various providers used throughout the package. + | + */ + + 'providers' => [ + + /* + |-------------------------------------------------------------------------- + | JWT Provider + |-------------------------------------------------------------------------- + | + | Specify the provider that is used to create and decode the tokens. + | + */ + + 'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class, + + /* + |-------------------------------------------------------------------------- + | Authentication Provider + |-------------------------------------------------------------------------- + | + | Specify the provider that is used to authenticate users. + | + */ + + 'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class, + + /* + |-------------------------------------------------------------------------- + | Storage Provider + |-------------------------------------------------------------------------- + | + | Specify the provider that is used to store tokens in the blacklist. + | + */ + + 'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class, + + ], + +]; diff --git a/routes/client.php b/routes/client.php index eb80576..e5466b4 100644 --- a/routes/client.php +++ b/routes/client.php @@ -59,6 +59,7 @@ Route::prefix('v1')->as('api.')->group(function () { Route::controller(TransactionController::class)->group(function () { Route::get('get-list', 'getTransactions')->name('getList'); Route::post('pay', 'handle')->name('pay'); + Route::get('verify', 'verifyPayment')->name('verify'); Route::get('return', 'returnCallback')->name('return'); Route::get('{transaction:slug}', 'getDetailTransaction')->name('detail'); }); diff --git a/routes/web.php b/routes/web.php index 8800b89..4f7aa60 100644 --- a/routes/web.php +++ b/routes/web.php @@ -2,6 +2,7 @@ use App\Models\Customer; use App\Models\User; +use Illuminate\Support\Facades\Route; use Yajra\DataTables\DataTables; /* @@ -16,7 +17,7 @@ use Yajra\DataTables\DataTables; */ -Route::domain('admin.tgs.com.vn.test')->group(function () { +Route::domain('admin.portal.test')->group(function () { include __DIR__ . '/admin.php'; });