arreglado problema pago bizum

A
This commit is contained in:
2025-11-14 18:35:06 +01:00
parent 3086a6de41
commit 6bd36dbe8c
3 changed files with 289 additions and 16 deletions

View File

@ -37,7 +37,7 @@ public class PaymentService {
this.payRepo = payRepo;
this.txRepo = txRepo;
this.refundRepo = refundRepo;
this.redsysService = redsysService;
this.redsysService = redsysService;
this.webhookEventRepo = webhookEventRepo;
this.cartService = cartService;
}
@ -83,7 +83,8 @@ public class PaymentService {
}
@Transactional
public void handleRedsysNotification(String dsSignature, String dsMerchantParameters, Locale locale) throws Exception {
public void handleRedsysNotification(String dsSignature, String dsMerchantParameters, Locale locale)
throws Exception {
// 0) Intentamos parsear la notificación. Si falla, registramos el webhook crudo
// y salimos.
@ -169,13 +170,20 @@ public class PaymentService {
? PaymentTransactionStatus.succeeded
: PaymentTransactionStatus.failed);
Object authCode = notif.raw.get("Ds_AuthorisationCode");
String gatewayTxId = null;
if (authCode != null) {
String trimmed = String.valueOf(authCode).trim();
// Redsys devuelve " " (espacios) cuando NO hay código de autorización.
// Eso lo consideramos "sin ID" → null, para no chocar con el índice único.
if (!trimmed.isEmpty()) {
// 1) Si es Bizum y tenemos Ds_Bizum_IdOper, úsalo como ID único
if (notif.isBizum()
&& notif.bizumIdOper != null
&& !notif.bizumIdOper.isBlank()) {
gatewayTxId = notif.bizumIdOper.trim();
// 2) Si no es Bizum, intenta usar Ds_AuthorisationCode
} else if (notif.authorisationCode != null) {
String trimmed = notif.authorisationCode.trim();
// Redsys suele mandar "000000" para Bizum; por si acaso también lo filtramos
if (!trimmed.isEmpty() && !"000000".equals(trimmed)) {
gatewayTxId = trimmed;
}
}
@ -187,7 +195,14 @@ public class PaymentService {
txRepo.save(tx);
if (authorized) {
p.setAuthorizationCode(tx.getGatewayTransactionId());
if (notif.isBizum()) {
p.setAuthorizationCode(null); // o "000000" si te interesa mostrarlo
} else if (notif.authorisationCode != null
&& !"000000".equals(notif.authorisationCode.trim())
&& !notif.authorisationCode.isBlank()) {
p.setAuthorizationCode(notif.authorisationCode.trim());
}
p.setStatus(PaymentStatus.captured);
p.setAmountCapturedCents(p.getAmountCapturedCents() + notif.amountCents);
p.setAuthorizedAt(LocalDateTime.now());
@ -459,17 +474,16 @@ public class PaymentService {
*/
@Transactional
private Boolean processOrder(Long cartId, Locale locale) {
Cart cart = this.cartService.findById(cartId);
if (cart != null) {
// Bloqueamos el carrito
this.cartService.lockCartById(cart.getId());
// Creamos el pedido
Long orderId = this.cartService.crearPedido(cart.getId(), locale);
if(orderId == null){
if (orderId == null) {
return false;
}
else{
} else {
// envio de correo de confirmacion de pedido podria ir aqui
}

View File

@ -195,6 +195,9 @@ public class RedsysService {
public final long amountCents;
public final String currency;
public final Long cartId;
public final String processedPayMethod; // Ds_ProcessedPayMethod
public final String bizumIdOper; // Ds_Bizum_IdOper
public final String authorisationCode; // Ds_AuthorisationCode
public RedsysNotification(Map<String, Object> raw) {
this.raw = raw;
@ -203,6 +206,9 @@ public class RedsysService {
this.currency = str(raw.get("Ds_Currency"));
this.amountCents = parseLongSafe(raw.get("Ds_Amount"));
this.cartId = extractCartId(raw.get("Ds_MerchantData"));
this.processedPayMethod = str(raw.get("Ds_ProcessedPayMethod"));
this.bizumIdOper = str(raw.get("Ds_Bizum_IdOper"));
this.authorisationCode = str(raw.get("Ds_AuthorisationCode"));
}
private static Long extractCartId(Object merchantDataObj) {
@ -231,6 +237,11 @@ public class RedsysService {
}
}
public boolean isBizum() {
// Redsys suele usar 68 para Bizum; ajustable si tu banco usa otro código.
return "68".equals(processedPayMethod);
}
private static String str(Object o) {
return o == null ? null : String.valueOf(o);
}
@ -245,7 +256,7 @@ public class RedsysService {
}
/**
* Solicita a Redsys una devolución (TransactionType = 3)
* Solicita a Redsys una devolución (TransactionType = 3)
*
* @param order El mismo Ds_Merchant_Order que se usó en el cobro.
* @param amountCents Importe en céntimos a devolver.
@ -308,7 +319,7 @@ public class RedsysService {
// Decodificar MerchantParameters de la respuesta
Map<String, Object> decoded = decodeMerchantParametersToMap(dsMerchantParametersResp);
String dsResponse = String.valueOf(decoded.get("Ds_Response"));
if (!"0900".equals(dsResponse)) {
throw new IllegalStateException("Devolución rechazada, Ds_Response=" + dsResponse);
@ -317,5 +328,4 @@ public class RedsysService {
return String.valueOf(decoded.getOrDefault("Ds_AuthorisationCode", order));
}
}