haciendo pagos pendientes

This commit is contained in:
2025-12-22 20:41:21 +01:00
parent 4cc47b4249
commit d4120bb486
18 changed files with 1312 additions and 572 deletions

View File

@ -1,10 +1,15 @@
package com.imprimelibros.erp.redsys;
import com.imprimelibros.erp.cart.Cart;
import com.imprimelibros.erp.common.Utils;
import com.imprimelibros.erp.payments.PaymentService;
import com.imprimelibros.erp.payments.model.Payment;
import com.imprimelibros.erp.payments.repo.PaymentTransactionRepository;
import com.imprimelibros.erp.pedidos.Pedido;
import com.imprimelibros.erp.pedidos.PedidoService;
import com.imprimelibros.erp.redsys.RedsysService.FormPayload;
import groovy.util.logging.Log;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@ -27,6 +32,7 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
@Controller
@ -37,13 +43,16 @@ public class RedsysController {
private final MessageSource messageSource;
private final SpringTemplateEngine templateEngine;
private final ServletContext servletContext;
private final PedidoService pedidoService;
public RedsysController(PaymentService paymentService, MessageSource messageSource,
SpringTemplateEngine templateEngine, ServletContext servletContext) {
SpringTemplateEngine templateEngine, ServletContext servletContext,
PedidoService pedidoService) {
this.paymentService = paymentService;
this.messageSource = messageSource;
this.templateEngine = templateEngine;
this.servletContext = servletContext;
this.pedidoService = pedidoService;
}
@PostMapping(value = "/crear", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@ -55,9 +64,15 @@ public class RedsysController {
HttpServletResponse response, Locale locale)
throws Exception {
// Creamos el pedido inteno
Pedido order = pedidoService.crearPedido(cartId, dirFactId, null, null);
if ("bank-transfer".equalsIgnoreCase(method)) {
// 1) Creamos el Payment interno SIN orderId (null)
Payment p = paymentService.createBankTransferPayment(cartId, dirFactId, amountCents, "EUR");
Payment p = paymentService.createBankTransferPayment(cartId, dirFactId, amountCents, "EUR", locale, order.getId());
pedidoService.markPedidoAsProcesingPayment(order.getId());
// 1⃣ Crear la "aplicación" web de Thymeleaf (Jakarta)
JakartaServletWebApplication app = JakartaServletWebApplication.buildApplication(servletContext);
@ -89,7 +104,102 @@ public class RedsysController {
}
// Tarjeta o Bizum (Redsys)
FormPayload form = paymentService.createRedsysPayment(cartId, dirFactId, amountCents, "EUR", method);
FormPayload form = paymentService.createRedsysPayment(cartId, dirFactId, amountCents, "EUR", method, order.getId());
String html = """
<html><head><meta charset="utf-8"><title>Redirigiendo a Redsys…</title></head>
<body onload="document.forms[0].submit()">
<form action="%s" method="post">
<input type="hidden" name="Ds_SignatureVersion" value="%s"/>
<input type="hidden" name="Ds_MerchantParameters" value="%s"/>
<input type="hidden" name="Ds_Signature" value="%s"/>
<input type="hidden" name="cartId" value="%d"/>
<noscript>
<p>Haz clic en pagar para continuar</p>
<button type="submit">Pagar</button>
</noscript>
</form>
</body></html>
""".formatted(
form.action(),
form.signatureVersion(),
form.merchantParameters(),
form.signature(), cartId);
byte[] body = html.getBytes(StandardCharsets.UTF_8);
return ResponseEntity.ok()
.contentType(MediaType.TEXT_HTML)
.body(body);
}
@PostMapping(value = "/reintentar", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@ResponseBody
public ResponseEntity<byte[]> reintentarPago(@RequestParam("amountCents") Long amountCents,
@RequestParam("method") String method, @RequestParam("orderId") Long orderId,
HttpServletRequest request,
HttpServletResponse response, Locale locale)
throws Exception {
// Creamos el pedido inteno
Pedido order = pedidoService.findById(orderId);
// Find the payment with orderId = order.getId() and status = failed
Payment failedPayment = paymentService.findFailedPaymentByOrderId(order.getId());
if (failedPayment == null) {
throw new Exception("No se encontró un pago fallido para el pedido " + order.getId());
}
Long cartId = null;
Long dirFactId = null;
// Find payment transaction details from failedPayment if needed
try{
Map<String, Long> transactionDetails = paymentService.getPaymentTransactionData(failedPayment.getId());
cartId = transactionDetails.get("cartId");
dirFactId = transactionDetails.get("dirFactId");
} catch (Exception e) {
throw new Exception("No se pudieron obtener los detalles de la transacción para el pago " + failedPayment.getId());
}
if ("bank-transfer".equalsIgnoreCase(method)) {
// 1) Creamos el Payment interno SIN orderId (null)
Payment p = paymentService.createBankTransferPayment(cartId, dirFactId, amountCents, "EUR", locale, order.getId());
pedidoService.markPedidoAsProcesingPayment(order.getId());
// 1⃣ Crear la "aplicación" web de Thymeleaf (Jakarta)
JakartaServletWebApplication app = JakartaServletWebApplication.buildApplication(servletContext);
// 2⃣ Construir el intercambio web desde request/response
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
IWebExchange exchange = app.buildExchange(request, response);
// 3⃣ Crear el contexto WebContext con Locale
WebContext ctx = new WebContext(exchange, locale);
String importeFormateado = Utils.formatCurrency(amountCents / 100.0, locale);
ctx.setVariable("importe", importeFormateado);
ctx.setVariable("concepto", "TRANSF-" + p.getOrderId());
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
boolean isAuth = auth != null
&& auth.isAuthenticated()
&& !(auth instanceof AnonymousAuthenticationToken);
ctx.setVariable("isAuth", isAuth);
// 3) Renderizamos la plantilla a HTML
String html = templateEngine.process("imprimelibros/pagos/transfer", ctx);
byte[] body = html.getBytes(StandardCharsets.UTF_8);
return ResponseEntity.ok()
.contentType(MediaType.TEXT_HTML)
.body(body);
}
// Tarjeta o Bizum (Redsys)
FormPayload form = paymentService.createRedsysPayment(cartId, dirFactId, amountCents, "EUR", method, order.getId());
String html = """
<html><head><meta charset="utf-8"><title>Redirigiendo a Redsys…</title></head>