feat: Implement JWT authentication for client API and add transaction verification endpoint.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,6 @@ class Kernel extends HttpKernel
|
||||
],
|
||||
|
||||
'api' => [
|
||||
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
'throttle:api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
@@ -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([
|
||||
|
||||
@@ -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']);
|
||||
|
||||
+12
-1
@@ -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 [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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'));
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user