fix: Corregir autenticación API, bypass de pago y relaciones de modelos
- Corregir middleware Authenticate para retornar JSON 401 en rutas API - Agregar método unauthenticated() en Handler para respuestas JSON - Implementar bypass de pago en ContractController - Corregir relaciones belongsToMany en Postulations y Suppliers - Corregir concatenación de strings en NoHomeController Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ namespace App\Exceptions;
|
||||
|
||||
use Throwable;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
@@ -48,4 +49,21 @@ class Handler extends ExceptionHandler
|
||||
{
|
||||
return parent::render($request, $exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an authentication exception into a response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Illuminate\Auth\AuthenticationException $exception
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
protected function unauthenticated($request, AuthenticationException $exception)
|
||||
{
|
||||
// Para rutas API, siempre retornar JSON
|
||||
if ($request->is('api/*') || $request->expectsJson()) {
|
||||
return response()->json(['message' => 'Unauthenticated.'], 401);
|
||||
}
|
||||
|
||||
return redirect()->guest(route('login'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +159,19 @@ class ContractController extends Controller
|
||||
|
||||
public function create(Request $request) {
|
||||
|
||||
// Si el bypass está activo, usar reglas relajadas
|
||||
$paymentBypass = env('PAYMENT_BYPASS', false);
|
||||
|
||||
if ($paymentBypass) {
|
||||
$rules = [
|
||||
'postulation_id' => 'required|numeric',
|
||||
'supplier_id' => 'required|numeric',
|
||||
'card_id' => 'required|string',
|
||||
'code' => 'required|string',
|
||||
'device_id' => 'required|string',
|
||||
'coupon' => 'nullable|string',
|
||||
];
|
||||
} else {
|
||||
$rules = [
|
||||
'postulation_id' => 'required|numeric',
|
||||
'supplier_id' => 'required|numeric',
|
||||
@@ -167,20 +180,29 @@ class ContractController extends Controller
|
||||
'device_id' => 'required|string|regex:/(^[A-Za-z0-9 ]+$)+/',
|
||||
'coupon' => 'nullable|string|regex:/(^[A-Za-z0-9 ]+$)+/',
|
||||
];
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), $rules);
|
||||
if ($validator->fails()) {
|
||||
// Para rutas API, retornar JSON en lugar de redirect
|
||||
if ($request->is('api/*') || $request->expectsJson()) {
|
||||
return response()->json(['type' => 'error', 'message' => $validator->errors()->first()], 422);
|
||||
}
|
||||
return redirect()->back()->withInput($request->all())->withErrors($validator);
|
||||
} else {
|
||||
|
||||
$user = Auth::user();
|
||||
$postulation = Postulations::where('id', $request->postulation_id)->first();
|
||||
$coupon = Coupon::where('name', $request->coupon)->first();
|
||||
|
||||
if (!$paymentBypass) {
|
||||
Openpay::setProductionMode(true);
|
||||
}
|
||||
|
||||
if ($user->id == $postulation->user_id) {
|
||||
|
||||
if ($request->card_id) {
|
||||
$card = null;
|
||||
if (!$paymentBypass && $request->card_id) {
|
||||
$card = Cards::where('id', $request->card_id)->first();
|
||||
}
|
||||
$supplier = Suppliers::where('id', $request->supplier_id)->first();
|
||||
@@ -191,7 +213,8 @@ class ContractController extends Controller
|
||||
$ichambafee = iChambaParameter::where('parameter', 'ichamba_fee')->first();
|
||||
$category = Categories::where('id', $postulation->category_id)->first();
|
||||
|
||||
if ($card->user_id == $user->id) {
|
||||
// En modo bypass, saltar la validación de tarjeta
|
||||
if ($paymentBypass || ($card && $card->user_id == $user->id)) {
|
||||
|
||||
$contract = new CurrentContracts();
|
||||
$contract->user_id = $postulation->user_id;
|
||||
@@ -232,6 +255,8 @@ class ContractController extends Controller
|
||||
$discount = (($fee*(($coupon->percentage = null ? 0 : $coupon->percentage)/100))+($coupon->amount = null ? 0 : $coupon->amount));
|
||||
|
||||
$contract->coupon_id = $coupon->id;
|
||||
// Solo crear chargeData si no estamos en bypass mode
|
||||
if (!$paymentBypass && $card) {
|
||||
$chargeData = array(
|
||||
'source_id' => $card->token,
|
||||
'method' => 'card',
|
||||
@@ -242,12 +267,15 @@ class ContractController extends Controller
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
$fee = ($supplier->minimun_fee < 150 ? 150 : $supplier->minimun_fee);
|
||||
$discount = 0;
|
||||
|
||||
$contract->coupon_id = null;
|
||||
// Solo crear chargeData si no estamos en bypass mode
|
||||
if (!$paymentBypass && $card) {
|
||||
$chargeData = array(
|
||||
'source_id' => $card->token,
|
||||
'method' => 'card',
|
||||
@@ -257,9 +285,14 @@ class ContractController extends Controller
|
||||
'cvv2' => $request->code
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!empty($request->card_id) && !empty($request->device_id) && !empty($request->code) && $fee > $discount) {
|
||||
// Bypass de pago para pruebas
|
||||
if (env('PAYMENT_BYPASS', false)) {
|
||||
$contract->transaction_id = 'BYPASS_' . uniqid();
|
||||
} else {
|
||||
try {
|
||||
$openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));
|
||||
|
||||
@@ -302,6 +335,7 @@ class ContractController extends Controller
|
||||
}
|
||||
|
||||
$contract->transaction_id = $charge->id;
|
||||
}
|
||||
|
||||
} else if ($coupon) {
|
||||
if ($coupon->limit > 0 && $discount >= $fee) {
|
||||
|
||||
@@ -146,7 +146,7 @@ class NoHomeController extends Controller
|
||||
$data = null,
|
||||
$buttons = null,
|
||||
$schedule = null,
|
||||
$headings = $client->name + ", tu proveedor del servicio ha llegado"
|
||||
$headings = $client->name . ", tu proveedor del servicio ha llegado"
|
||||
);
|
||||
return response()->json([
|
||||
//'message' => 'Por favor espere a los 10 minutos de tolerancia de la hora acordada'
|
||||
|
||||
@@ -14,6 +14,10 @@ class Authenticate extends Middleware
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
// Para rutas API, nunca redirigir - dejar que lance excepción 401
|
||||
if ($request->is('api/*')) {
|
||||
return null;
|
||||
}
|
||||
if (! $request->expectsJson()) {
|
||||
return route('login');
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class Postulations extends Model
|
||||
|
||||
public function suppliers()
|
||||
{
|
||||
return $this->hasMany(Suppliers::class);
|
||||
return $this->belongsToMany(Suppliers::class, 'postulations_suppliers', 'postulations_id', 'suppliers_id')->withTimestamps();
|
||||
}
|
||||
|
||||
public function status()
|
||||
|
||||
@@ -55,7 +55,7 @@ class Suppliers extends Model
|
||||
|
||||
public function postulations()
|
||||
{
|
||||
return $this->belongsToMany(Postulations::class)->withTimestamps();
|
||||
return $this->belongsToMany(Postulations::class, 'postulations_suppliers', 'suppliers_id', 'postulations_id')->withTimestamps();
|
||||
}
|
||||
|
||||
public function payments()
|
||||
|
||||
Reference in New Issue
Block a user