Closed aroldos91 closed 6 months ago
Ya está solucionado, el problema es que cuando redsys intenta enviar le da 419,
@aroldos91 puedes ser más explicito sobre la solución por si le pasa a otra persona.
Cuando redsys intenta enviar la solicitud por post
laravel intenta validar el _token
, que debe estar en todas las solicitudes post
, dando como respuesta Token Expirado (ERROR 419), por lo que es necesario configurar un paquete de rutas en el $middlewareGroups (app/http/Kernel)
donde especifiques que no utilice dicho token, Eje:
'paymennotification'=>[
'throttle:60,1',
\App\Http\Middleware\PaymennotificationApi::class
],
en el paquete middelware implementar la clase PaymennotificationApi
public function handle($request, Closure $next)
{
return $next($request);
}
en el RouteServiceProvider
especificar la ruta
protected function paymennotification()
{
Route::prefix('paymennotification')
->middleware('paymennotification')
->namespace($this->namespace)
->group(base_path('routes/paymennotification.php'));
}
Una vez echo todos los cambios, solo tienes que crear el fichero paymennotification.php
en las rutas y especificar que debe hacer
Route::post(/', 'PaymennotificationController@paymennotification')->name('paymennotification');
Muy buen aporte, a ver si lo incluyo en el README. Gracias
Y gracias a ti también,
Buenas, entonces en Laravel la url de notificaciones entrega un 419?
Buenas, entonces en Laravel la url de notificaciones entrega un 419?
Si, y el compañero comento como lo soluciono, implementando un middleware para omitir el tema de la comprobación del token.
Implemente el middleware para la omision del token, pero me sigue sin notificar. Gracias
Cuando redsys intenta enviar la solicitud por
post
laravel intenta validar el_token
, que debe estar en todas las solicitudespost
, dando como respuesta Token Expirado (ERROR 419), por lo que es necesario configurar un paquete de rutas en el$middlewareGroups (app/http/Kernel)
donde especifiques que no utilice dicho token, Eje:'paymennotification'=>[ 'throttle:60,1', \App\Http\Middleware\PaymennotificationApi::class ],
en el paquete middelware implementar la clase
PaymennotificationApi
public function handle($request, Closure $next) { return $next($request); }
en el
RouteServiceProvider
especificar la rutaprotected function paymennotification() { Route::prefix('paymennotification') ->middleware('paymennotification') ->namespace($this->namespace) ->group(base_path('routes/paymennotification.php')); }
Una vez echo todos los cambios, solo tienes que crear el fichero
paymennotification.php
en las rutas y especificar que debe hacerRoute::post(/', 'PaymennotificationController@paymennotification')->name('paymennotification');
No es necesario añadir toda esta lógica extra. Simplemente puedes añadir una excepción en tu VerifyCsrfTokenMiddleware:
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
'path/for/your/response/notification'
];
Hola, he realizado las pruebas correspondientes con el middleware y el except en el VerifyCsrfTokenMiddleware pero me sigue sin funcionar. no se ejecuta la ruta de notificación. Tengo la version de laravel 11 y estoy trabajando con inertia y vue3. Hay algun cambio o nueva configuracion con respecto a este tema?
Has probado con llamar a dicha url desde otro servidor como simulando la llamada del Banco?
Saludos @rapcest estas modificaciones eran con Laravel 6 o 7, y ya existen otras alternativas, por ejemplo lo que comento @asanzred, lo primero, estas realizando las pruebas en un entorno local o ya esta desplegado en el servidor?
en caso de realizar las pruebas en un servidor local, no te funcionara, por lo que deberás realizar otras modificaciones como publicar tu proyecto con ngrok, y en redys deberás configurarlo para autorizar ese dominio,
si ya esta publicado deberías analizar diferentes puntos:
Si estas utilizando Cloudflare o alguna otra herramienta, deberás excluir esa url del firewall ya que los webhook no deben pasar por el.
Analizar si estas trabajando asincrónica
webhook.
para poderte ayudar mejor deberías dar mas detalles de como estas haciendo las pruebas. espero que te sea de ayuda esta información
Hola, he realizado las pruebas correspondientes con el middleware y el except en el VerifyCsrfTokenMiddleware pero me sigue sin funcionar. no se ejecuta la ruta de notificación. Tengo la version de laravel 11 y estoy trabajando con inertia y vue3. Hay algun cambio o nueva configuracion con respecto a este tema?
Hola, si estoy haciendo las pruebas desde mi servidor web, tengo mi sitio web alojado en hostinger. También he realizado las pruebas enviando parámetros a la ruta y si recibe los parametros. Pero los del banco no. Soy nuevo en este tema, apenas llevo unas semanas documentándome pero he encontrado muy poca información que me ayude con mi problema.
este es el codigo de las rutas en mi archivo web.php.
Route::controller(RedsysController::class)->prefix('redsys')->group(function(){
Route::post('/comprobar', 'comprobar');
Route::get('/pago/{order}&{amount}&{des}&{metodo}/', 'index');
Route::get('/ok', 'ok');
Route::get('/ko', 'ko');
});
asi esta el codigo de mi controlador. para acceder a la plataforma
public static function index(Request $request, $order,$amount,$des=false, $metodo)
{
try{
$order = str_pad($order,12,0,STR_PAD_LEFT);
$key = config('redsys.key');
$merchantcode = config('redsys.merchantcode');
$terminal = config('redsys.terminal');
$enviroment = config('redsys.enviroment');
$urlOk = url(config('redsys.url_ok'));
$urlKo = url(config('redsys.url_ko'));
$urlNotification= url(config('redsys.url_notification'));
$tradeName = config('redsys.tradename');
$description = $des?$des:config('redsys.description');
Redsys::setAmount($amount);
Redsys::setOrder($idProducto);
Redsys::setMerchantcode($merchantcode);
Redsys::setCurrency('978');
Redsys::setTransactiontype('0');
Redsys::setTerminal($terminal);
Redsys::setMethod($metodo);
Redsys::setNotification(config('redsys.url_notification'));
Redsys::setUrlOk(config('redsys.url_ok'));
Redsys::setUrlKo(config('redsys.url_ko'));
Redsys::setVersion('HMAC_SHA256_V1');
Redsys::setTradeName($tradeName);
Redsys::setTitular($titular);
Redsys::setProductDescription($description);
Redsys::setEnviroment('test');
$signature = Redsys::generateMerchantSignature($key);
Redsys::setMerchantSignature($signature);
$formaPago = null;
Redsys::setAttributesSubmit('btn_submit', 'btn_id', 'Enviar', 'display:none');
$form = Redsys::createForm();
}
catch(Exception $e){
echo $e->getMessage();
}
$form = view('redsys', compact('form', 'amount', 'titular', 'description', 'formaPago'));
return $form;
Por el momento lo he dejado fuera del middleware Auth porque dentro también me daba problemas.
asi la funcion de comprobar:
public function comprobar(Request $request) { try{
$key = config('redsys.key');
$parameters = Redsys::getMerchantParameters($request->input('Ds_MerchantParameters'));
$DsResponse = $parameters["Ds_Response"];
$DsResponse += 0;
if (Redsys::check($key, $request->input()) && $DsResponse <=99) {
// aqui tengo el proceso de guardar en base de datos la información que no logro recibir por $_POST
} else {
return to_route('pedidos.cancelado');
}
} catch (SermepaTpvTpvException $e) {
echo $e->getMessage();
}
}
En el fronted envío la información por medio de inertia:
if(form.tipo_pago === 'tarjeta'){
router.get(
route('redsys/pago', {
order: 23232335,
amount: totalConEnvio.value,
des: 'sin descripción',
metodo: 'T'
}), {
onSuccess: (e)=>{
}
})
}
las rutas que uso:
http://tienda.thegreatcollector.es/redsys/comprobar http://tienda.thegreatcollector.es/redsys/ok http://tienda.thegreatcollector.es/redsys/ko
No se si sea relevante pero mi aplicación esta alojada en un subdominio y tiene una configuración de redirección: del dominio principal (thegreatcollector.es) se redirecciona al subdominio (tienda.thegreatcollector.es) siempre que se intente acceder al primer dominio.
realice pruebas con un archivo .php alojado en la carpeta public_html de mi servidor pero tampoco es capaz de recibir los parametros del banco pero si recibe parametros enviados por mi desde otra ruta.
Verifica que el tpv de redsys este configurado asíncrono, también puedes indicarle al tpv cuál sería la URL de respuesta, me da la ligera impresión que estás trabajando sincrónico, y no asíncrono
Primero un saludo, y darte las gracias por este gran trabajo que has realizado. Tengo laravel 6 y 7 y en ambos proyectos la url de notificación no responde nada, le tengo puesto un simple método de crear un log para ver la respuesta, el redsys lo tengo asincrónico, el pago y todo lo demás funciona bien pero no notifica, está el tpv en modo real pero estoy realizando pruebas porque quiero subir mi versión de larvel tengo php 7.2 en servidor