mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-12 16:38:48 +00:00
165 lines
7.1 KiB
Java
165 lines
7.1 KiB
Java
package com.imprimelibros.erp.redsys;
|
|
|
|
import com.imprimelibros.erp.payments.PaymentService;
|
|
import com.imprimelibros.erp.payments.model.Payment;
|
|
import com.imprimelibros.erp.redsys.RedsysService.FormPayload;
|
|
|
|
import org.springframework.http.MediaType;
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.stereotype.Controller;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.UUID;
|
|
|
|
@Controller
|
|
@RequestMapping("/pagos/redsys")
|
|
public class RedsysController {
|
|
|
|
private final PaymentService paymentService;
|
|
|
|
public RedsysController(PaymentService paymentService) {
|
|
this.paymentService = paymentService;
|
|
}
|
|
|
|
@PostMapping(value = "/crear", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
|
@ResponseBody
|
|
public ResponseEntity<byte[]> crearPago(@RequestParam("amountCents") Long amountCents,
|
|
@RequestParam("method") String method) throws Exception {
|
|
|
|
if ("bank-transfer".equalsIgnoreCase(method)) {
|
|
// 1) Creamos el Payment interno SIN orderId (null)
|
|
Payment p = paymentService.createBankTransferPayment(null, amountCents, "EUR");
|
|
|
|
// 2) Mostramos instrucciones de transferencia
|
|
String html = """
|
|
<html><head><meta charset="utf-8"><title>Pago por transferencia</title></head>
|
|
<body>
|
|
<h2>Pago por transferencia bancaria</h2>
|
|
<p>Hemos registrado tu intención de pedido.</p>
|
|
<p><strong>Importe:</strong> %s €</p>
|
|
<p><strong>IBAN:</strong> ES00 1234 5678 9012 3456 7890</p>
|
|
<p><strong>Concepto:</strong> TRANSF-%d</p>
|
|
<p>En cuanto recibamos la transferencia, procesaremos tu pedido.</p>
|
|
<p><a href="/checkout/resumen">Volver al resumen</a></p>
|
|
</body></html>
|
|
""".formatted(
|
|
String.format("%.2f", amountCents / 100.0),
|
|
p.getId() // usamos el ID del Payment como referencia
|
|
);
|
|
|
|
byte[] body = html.getBytes(StandardCharsets.UTF_8);
|
|
return ResponseEntity.ok()
|
|
.contentType(MediaType.TEXT_HTML)
|
|
.body(body);
|
|
}
|
|
|
|
// Tarjeta o Bizum (Redsys)
|
|
FormPayload form = paymentService.createRedsysPayment(null, amountCents, "EUR", method);
|
|
|
|
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"/>
|
|
<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());
|
|
|
|
byte[] body = html.getBytes(StandardCharsets.UTF_8);
|
|
return ResponseEntity.ok()
|
|
.contentType(MediaType.TEXT_HTML)
|
|
.body(body);
|
|
}
|
|
|
|
// GET: cuando el usuario cae aquí sin parámetros, o Redsys redirige por GET
|
|
@GetMapping("/ok")
|
|
@ResponseBody
|
|
public ResponseEntity<String> okGet() {
|
|
String html = """
|
|
<h2>Pago procesado</h2>
|
|
<p>Si el pago ha sido autorizado, verás el pedido en tu área de usuario o recibirás un email de confirmación.</p>
|
|
<p><a href="/cart">Volver a la tienda</a></p>
|
|
""";
|
|
return ResponseEntity.ok(html);
|
|
}
|
|
|
|
// POST: si Redsys envía Ds_Signature y Ds_MerchantParameters (muchas
|
|
// integraciones ni lo usan)
|
|
@PostMapping(value = "/ok", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
|
@ResponseBody
|
|
public ResponseEntity<String> okPost(@RequestParam("Ds_Signature") String signature,
|
|
@RequestParam("Ds_MerchantParameters") String merchantParameters) {
|
|
try {
|
|
// opcional: idempotente, si /notify ya ha hecho el trabajo no pasa nada
|
|
paymentService.handleRedsysNotification(signature, merchantParameters);
|
|
return ResponseEntity.ok("<h2>Pago realizado correctamente</h2><a href=\"/cart\">Volver</a>");
|
|
} catch (Exception e) {
|
|
return ResponseEntity.badRequest()
|
|
.body("<h2>Error validando pago</h2><pre>" + e.getMessage() + "</pre>");
|
|
}
|
|
}
|
|
|
|
@GetMapping("/ko")
|
|
@ResponseBody
|
|
public ResponseEntity<String> koGet() {
|
|
return ResponseEntity.ok("<h2>Pago cancelado o rechazado</h2><a href=\"/checkout\">Volver</a>");
|
|
}
|
|
|
|
@PostMapping(value = "/ko", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
|
@ResponseBody
|
|
public ResponseEntity<String> koPost(
|
|
@RequestParam("Ds_Signature") String signature,
|
|
@RequestParam("Ds_MerchantParameters") String merchantParameters) {
|
|
|
|
try {
|
|
// Procesamos la notificación IGUAL que en /ok y /notify
|
|
paymentService.handleRedsysNotification(signature, merchantParameters);
|
|
|
|
// Mensaje para el usuario (pago cancelado/rechazado)
|
|
String html = "<h2>Pago cancelado o rechazado</h2><a href=\"/checkout\">Volver</a>";
|
|
return ResponseEntity.ok(html);
|
|
} catch (Exception e) {
|
|
// Si algo falla al validar/procesar, lo mostramos (útil en entorno de pruebas)
|
|
String html = "<h2>Error procesando notificación KO</h2><pre>" + e.getMessage() + "</pre>";
|
|
return ResponseEntity.badRequest().body(html);
|
|
}
|
|
}
|
|
|
|
@PostMapping(value = "/notify", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
|
@ResponseBody
|
|
public String notifyRedsys(@RequestParam("Ds_Signature") String signature,
|
|
@RequestParam("Ds_MerchantParameters") String merchantParameters) {
|
|
try {
|
|
paymentService.handleRedsysNotification(signature, merchantParameters);
|
|
return "OK";
|
|
} catch (Exception e) {
|
|
e.printStackTrace(); // 👈 para ver el motivo del 500 en logs
|
|
return "ERROR";
|
|
}
|
|
}
|
|
|
|
@PostMapping(value = "/refund/{paymentId}", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
|
@ResponseBody
|
|
public ResponseEntity<String> refund(@PathVariable Long paymentId,
|
|
@RequestParam("amountCents") Long amountCents) {
|
|
try {
|
|
String idem = "refund-" + paymentId + "-" + amountCents + "-" + UUID.randomUUID();
|
|
paymentService.refundViaRedsys(paymentId, amountCents, idem);
|
|
return ResponseEntity.ok("Refund solicitado");
|
|
} catch (Exception e) {
|
|
return ResponseEntity.badRequest().body("Error refund: " + e.getMessage());
|
|
}
|
|
}
|
|
}
|