mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-12 16:38:48 +00:00
intentando meter los ficheros redsys
This commit is contained in:
35
pom.xml
35
pom.xml
@ -151,6 +151,41 @@
|
||||
<version>${liquibase.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Redsys -->
|
||||
<dependency>
|
||||
<groupId>com.redsys</groupId>
|
||||
<artifactId>apiSha512V2</artifactId>
|
||||
<version>2.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/main/resources/lib/apiSha512V2.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
<!-- Dependencias locales incluidas en el ZIP -->
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>1.47</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/main/resources/lib/bcprov-jdk15on-1.4.7.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/main/resources/lib/commons-codec-1.3.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/main/resources/lib/org.json.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
package com.imprimelibros.erp.redsys;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/pagos/redsys")
|
||||
public class RedsysController {
|
||||
|
||||
private final RedsysService service;
|
||||
public RedsysController(RedsysService service) { this.service = service; }
|
||||
|
||||
@PostMapping("/crear")
|
||||
public String crearPago(@RequestParam String order,
|
||||
@RequestParam long amountCents,
|
||||
Model model) {
|
||||
var payReq = new RedsysService.PaymentRequest(order, amountCents, "Compra en ImprimeLibros");
|
||||
var form = service.buildRedirectForm(payReq);
|
||||
model.addAttribute("action", form.action());
|
||||
model.addAttribute("signatureVersion", form.signatureVersion());
|
||||
model.addAttribute("merchantParameters", form.merchantParameters());
|
||||
model.addAttribute("signature", form.signature());
|
||||
return "payments/redsys-redirect"; // Thymeleaf
|
||||
}
|
||||
|
||||
@PostMapping("/notify")
|
||||
@ResponseBody
|
||||
public ResponseEntity<String> notifyRedsys(@RequestParam("Ds_Signature") String dsSig,
|
||||
@RequestParam("Ds_SignatureVersion") String dsSigVer,
|
||||
@RequestParam("Ds_MerchantParameters") String dsParams) throws Exception {
|
||||
var notif = service.validateAndParse(dsSig, dsSigVer, dsParams);
|
||||
|
||||
// 1) Idempotencia: marca el pedido si aún no procesado.
|
||||
// 2) Verifica importe/moneda/pedido contra tu base de datos.
|
||||
// 3) Autoriza en tu sistema si notif.authorized() == true.
|
||||
|
||||
return ResponseEntity.ok("OK");
|
||||
}
|
||||
|
||||
@GetMapping("/ok")
|
||||
public String ok() { return "payments/success"; }
|
||||
|
||||
@GetMapping("/ko")
|
||||
public String ko() { return "payments/failure"; }
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
package com.imprimelibros.erp.redsys;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class RedsysService {
|
||||
|
||||
@Value("${redsys.merchant-code}") private String merchantCode;
|
||||
@Value("${redsys.terminal}") private String terminal;
|
||||
@Value("${redsys.currency}") private String currency;
|
||||
@Value("${redsys.transaction-type}") private String txType;
|
||||
@Value("${redsys.secret-key}") private String secretKey;
|
||||
@Value("${redsys.urls.ok}") private String urlOk;
|
||||
@Value("${redsys.urls.ko}") private String urlKo;
|
||||
@Value("${redsys.urls.notify}") private String urlNotify;
|
||||
@Value("${redsys.environment}") private String env;
|
||||
|
||||
public record PaymentRequest(String order, long amountCents, String description) {}
|
||||
|
||||
public record FormPayload(String action, String signatureVersion, String merchantParameters, String signature) {}
|
||||
|
||||
public FormPayload buildRedirectForm(PaymentRequest req) {
|
||||
// RedsysAPI proviene del JAR oficial
|
||||
com.redsys.api.RedsysAPI api = new com.redsys.api.RedsysAPI();
|
||||
|
||||
Map<String, String> mp = new HashMap<>();
|
||||
mp.put("DS_MERCHANT_AMOUNT", String.valueOf(req.amountCents()));
|
||||
mp.put("DS_MERCHANT_ORDER", req.order());
|
||||
mp.put("DS_MERCHANT_MERCHANTCODE", merchantCode);
|
||||
mp.put("DS_MERCHANT_CURRENCY", currency);
|
||||
mp.put("DS_MERCHANT_TRANSACTIONTYPE", txType);
|
||||
mp.put("DS_MERCHANT_TERMINAL", terminal);
|
||||
mp.put("DS_MERCHANT_MERCHANTNAME", "Tu Comercio");
|
||||
mp.put("DS_MERCHANT_PRODUCTDESCRIPTION", req.description());
|
||||
mp.put("DS_MERCHANT_URLOK", urlOk);
|
||||
mp.put("DS_MERCHANT_URLKO", urlKo);
|
||||
mp.put("DS_MERCHANT_MERCHANTURL", urlNotify);
|
||||
|
||||
String merchantParameters = api.createMerchantParameters(mp);
|
||||
String signature = api.createMerchantSignature(secretKey);
|
||||
|
||||
String action = "test".equalsIgnoreCase(env)
|
||||
? "https://sis-t.redsys.es:25443/sis/realizarPago"
|
||||
: "https://sis.redsys.es/sis/realizarPago";
|
||||
|
||||
return new FormPayload(action, "HMAC_SHA256_V1", merchantParameters, signature);
|
||||
}
|
||||
|
||||
// Validación de la notificación on-line (webhook).
|
||||
public RedsysNotification validateAndParse(String dsSignature, String dsSignatureVersion, String dsMerchantParametersB64) {
|
||||
com.redsys.api.RedsysAPI api = new com.redsys.api.RedsysAPI();
|
||||
|
||||
// 1) Validar firma
|
||||
String calc = api.createMerchantSignatureNotif(secretKey, dsMerchantParametersB64);
|
||||
if (!Objects.equals(calc, dsSignature)) {
|
||||
throw new IllegalArgumentException("Firma Redsys no válida");
|
||||
}
|
||||
|
||||
// 2) Decodificar parámetros
|
||||
String json = api.decodeMerchantParameters(dsMerchantParametersB64);
|
||||
Map<String, Object> params = new com.fasterxml.jackson.databind.ObjectMapper()
|
||||
.readValue(json, new com.fasterxml.jackson.core.type.TypeReference<>() {});
|
||||
// Campos típicos: Ds_Order, Ds_Amount, Ds_Currency, Ds_Response, etc.
|
||||
return RedsysNotification.from(params);
|
||||
}
|
||||
|
||||
public static record RedsysNotification(String order, String dsResponse, long amountCents, String currency) {
|
||||
static RedsysNotification from(Map<String, Object> p) {
|
||||
String order = (String) p.get("Ds_Order");
|
||||
String resp = String.valueOf(p.get("Ds_Response"));
|
||||
long amount = Long.parseLong((String) p.get("Ds_Amount"));
|
||||
String curr = String.valueOf(p.get("Ds_Currency"));
|
||||
return new RedsysNotification(order, resp, amount, curr);
|
||||
}
|
||||
// Éxito si 0–99.
|
||||
public boolean authorized() {
|
||||
try {
|
||||
int r = Integer.parseInt(dsResponse);
|
||||
return r >= 0 && r <= 99;
|
||||
} catch (Exception e) { return false; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -105,3 +105,16 @@ spring.liquibase.change-log=classpath:db/changelog/master.yml
|
||||
# spring.liquibase.url=jdbc:mysql://localhost:3306/imprimelibros
|
||||
# spring.liquibase.user=tu_user
|
||||
# spring.liquibase.password=tu_pass
|
||||
|
||||
|
||||
# Redsys
|
||||
redsys.environment=test
|
||||
redsys.merchant-code=124760810
|
||||
redsys.terminal=1
|
||||
redsys.currency=978
|
||||
redsys.transaction-type=0
|
||||
redsys.secret-key=sq7HjrUOBfKmC576ILgskD5srU870gJ7
|
||||
redsys.urls.ok=https://localhost:8080/pagos/redsys/ok
|
||||
redsys.urls.ko=https://localhost:8080/pagos/redsys/ko
|
||||
redsys.urls.notify=https://localhost:8080/pagos/redsys/notify
|
||||
|
||||
|
||||
BIN
src/main/resources/lib/apiSha512V2.jar
Normal file
BIN
src/main/resources/lib/apiSha512V2.jar
Normal file
Binary file not shown.
BIN
src/main/resources/lib/bcprov-jdk15on-1.4.7.jar
Normal file
BIN
src/main/resources/lib/bcprov-jdk15on-1.4.7.jar
Normal file
Binary file not shown.
BIN
src/main/resources/lib/commons-codec-1.3.jar
Normal file
BIN
src/main/resources/lib/commons-codec-1.3.jar
Normal file
Binary file not shown.
BIN
src/main/resources/lib/org.json.jar
Normal file
BIN
src/main/resources/lib/org.json.jar
Normal file
Binary file not shown.
Reference in New Issue
Block a user