mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-13 08:58:48 +00:00
terminado pagos
This commit is contained in:
@ -11,6 +11,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@ -276,7 +277,8 @@ public class PaymentController {
|
||||
+ messageSource.getMessage("pagos.table.finalizar", null, locale) + "</span> ";
|
||||
|
||||
}
|
||||
if ((pago.getAmountCents() - p.getAmountRefundedCents() > 0) && pago.getStatus() == PaymentTransactionStatus.succeeded) {
|
||||
if ((pago.getAmountCents() - p.getAmountRefundedCents() > 0)
|
||||
&& pago.getStatus() == PaymentTransactionStatus.succeeded) {
|
||||
actions += "<span class=\'badge bg-secondary btn-transfer-refund \' data-dsOrderId=\'"
|
||||
+ p.getGatewayOrderId()
|
||||
+ "\' data-transactionId=\'" + pago.getPayment().getId()
|
||||
@ -309,4 +311,21 @@ public class PaymentController {
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value = "/transfer/refund/{id}", produces = "application/json")
|
||||
public ResponseEntity<Map<String, Object>> refundTransfer(@PathVariable Long id,
|
||||
@RequestParam("amountCents") Long amountCents) {
|
||||
|
||||
Map<String, Object> response;
|
||||
try {
|
||||
paymentService.refundBankTransfer(id, amountCents);
|
||||
response = Map.of("success", true);
|
||||
return ResponseEntity.ok(response);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
response = Map.of("success", false);
|
||||
response.put("error", e.getMessage());
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,7 +312,7 @@ public class PaymentService {
|
||||
tx.setCurrency(currency);
|
||||
// tx.setProcessedAt(null); // la dejas nula hasta que se confirme
|
||||
txRepo.save(tx);
|
||||
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -358,6 +358,84 @@ public class PaymentService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve (total o parcialmente) un pago hecho por transferencia bancaria.
|
||||
* - Solo permite gateway = "bank_transfer".
|
||||
* - Crea un Refund + PaymentTransaction de tipo REFUND.
|
||||
* - Actualiza amountRefundedCents y el estado del Payment.
|
||||
*/
|
||||
@Transactional
|
||||
public Refund refundBankTransfer(Long paymentId, long amountCents) {
|
||||
Payment p = payRepo.findById(paymentId)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Payment no encontrado: " + paymentId));
|
||||
|
||||
if (!"bank_transfer".equals(p.getGateway())) {
|
||||
throw new IllegalStateException("El Payment " + paymentId + " no es de tipo bank_transfer");
|
||||
}
|
||||
|
||||
if (amountCents <= 0) {
|
||||
throw new IllegalArgumentException("El importe de devolución debe ser > 0");
|
||||
}
|
||||
|
||||
// Solo tiene sentido devolver si está capturado o ya parcialmente devuelto
|
||||
if (p.getStatus() != PaymentStatus.captured
|
||||
&& p.getStatus() != PaymentStatus.partially_refunded) {
|
||||
throw new IllegalStateException(
|
||||
"El Payment " + paymentId + " no está capturado; estado actual: " + p.getStatus());
|
||||
}
|
||||
|
||||
long maxRefundable = p.getAmountCapturedCents() - p.getAmountRefundedCents();
|
||||
if (amountCents > maxRefundable) {
|
||||
throw new IllegalStateException(
|
||||
"Importe de devolución supera lo todavía reembolsable. " +
|
||||
"maxRefundable=" + maxRefundable + " requested=" + amountCents);
|
||||
}
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
// 1) Crear Refund (para transferencias lo marcamos como SUCCEEDED directamente)
|
||||
Refund refund = new Refund();
|
||||
refund.setPayment(p);
|
||||
refund.setAmountCents(amountCents);
|
||||
// reason usa el valor por defecto (customer_request); si quieres otro, cámbialo
|
||||
// aquí
|
||||
refund.setStatus(RefundStatus.succeeded);
|
||||
refund.setRequestedAt(now);
|
||||
refund.setProcessedAt(now);
|
||||
// requestedByUserId, notes, metadata -> opcionales, déjalos en null si no los
|
||||
// usas
|
||||
refund = refundRepo.save(refund);
|
||||
|
||||
// 2) Crear transacción de tipo REFUND
|
||||
PaymentTransaction tx = new PaymentTransaction();
|
||||
tx.setPayment(p);
|
||||
tx.setType(PaymentTransactionType.REFUND);
|
||||
tx.setStatus(PaymentTransactionStatus.succeeded);
|
||||
tx.setAmountCents(amountCents);
|
||||
tx.setCurrency(p.getCurrency());
|
||||
tx.setProcessedAt(now);
|
||||
// gatewayTransactionId lo dejamos null → el índice UNIQUE permite múltiples
|
||||
// NULL
|
||||
tx = txRepo.save(tx);
|
||||
|
||||
// Vincular el Refund con la transacción
|
||||
refund.setTransaction(tx);
|
||||
refundRepo.save(refund);
|
||||
|
||||
// 3) Actualizar Payment: total devuelto y estado
|
||||
p.setAmountRefundedCents(p.getAmountRefundedCents() + amountCents);
|
||||
|
||||
if (p.getAmountRefundedCents().equals(p.getAmountCapturedCents())) {
|
||||
p.setStatus(PaymentStatus.refunded);
|
||||
} else {
|
||||
p.setStatus(PaymentStatus.partially_refunded);
|
||||
}
|
||||
|
||||
payRepo.save(p);
|
||||
|
||||
return refund;
|
||||
}
|
||||
|
||||
private boolean isRedsysAuthorized(RedsysService.RedsysNotification notif) {
|
||||
if (notif.response == null) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user