Skip to content

Commit 5592464

Browse files
committed
base servicio mercadopago
1 parent cb46ddb commit 5592464

File tree

2 files changed

+75
-78
lines changed

2 files changed

+75
-78
lines changed
Lines changed: 70 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,89 @@
1-
package com.outfitlab.project.domain.service;
1+
package com.outfitlab.project.presentation;
22

3-
import com.mercadopago.MercadoPagoConfig;
4-
import com.mercadopago.client.payment.PaymentClient;
5-
import com.mercadopago.client.preference.PreferenceClient;
6-
import com.mercadopago.client.preference.PreferenceItemRequest;
7-
import com.mercadopago.client.preference.PreferencePayerRequest;
8-
import com.mercadopago.client.preference.PreferenceRequest;
93
import com.mercadopago.exceptions.MPApiException;
10-
import com.mercadopago.resources.payment.Payment;
11-
import com.mercadopago.resources.preference.Preference;
124
import com.mercadopago.exceptions.MPException;
13-
import org.springframework.beans.factory.annotation.Value;
14-
import org.springframework.stereotype.Service;
5+
import com.outfitlab.project.domain.service.SubscriptionService;
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.http.ResponseEntity;
8+
import org.springframework.web.bind.annotation.*;
9+
import java.util.Map;
10+
import java.util.HashMap;
1511
import java.math.BigDecimal;
16-
import java.util.ArrayList;
17-
import java.util.List;
1812

19-
@Service
20-
public class SubscriptionService {
13+
class SubscriptionRequest {
14+
private String planId;
15+
private String userEmail;
16+
private BigDecimal price;
17+
private String currency;
2118

22-
/**
23-
* Constructor para inicializar el SDK con el Access Token.
24-
* Se ejecuta al iniciar Spring Boot.
25-
*/
26-
public SubscriptionService(@Value("${mercadopago.access.token}") String accessToken) {
27-
if (accessToken == null || accessToken.trim().isEmpty() || accessToken.equals("${mercadopago.access.token}")) {
28-
throw new IllegalArgumentException("ERROR: El Access Token de Mercado Pago no está configurado. Revisa la variable de entorno MP_ACCESS_TOKEN.");
29-
}
30-
MercadoPagoConfig.setAccessToken(accessToken);
31-
System.out.println("Mercado Pago SDK de Java inicializado (desde SubscriptionService).");
32-
}
19+
public String getPlanId() { return planId; }
20+
public void setPlanId(String planId) { this.planId = planId; }
21+
public String getUserEmail() { return userEmail; }
22+
public void setUserEmail(String userEmail) { this.userEmail = userEmail; }
23+
public BigDecimal getPrice() { return price; }
24+
public void setPrice(BigDecimal price) { this.price = price; }
25+
public String getCurrency() { return currency; }
26+
public void setCurrency(String currency) { this.currency = currency; }
27+
}
3328

34-
/**
35-
* Crea una Preferencia de Pago Único (para la demo).
36-
*/
37-
public String createMercadoPagoPreference(String planId, String userEmail, BigDecimal price, String currency) throws MPException, MPApiException {
29+
@RestController
30+
@RequestMapping("/api/mp")
31+
public class SubscriptionController {
3832

39-
// 1. Definir el ítem
40-
PreferenceItemRequest itemRequest = PreferenceItemRequest.builder()
41-
.id(planId)
42-
.title("Demo Premium Outfit Lab")
43-
.description("Acceso único a funciones premium")
44-
.quantity(1)
45-
.unitPrice(price)
46-
.currencyId(currency)
47-
.build();
33+
@Autowired
34+
private SubscriptionService subscriptionService;
4835

49-
List<PreferenceItemRequest> items = new ArrayList<>();
50-
items.add(itemRequest);
36+
@PostMapping("/crear-suscripcion")
37+
@CrossOrigin(origins = "http://localhost:5173")
38+
public ResponseEntity<Map<String, String>> createPreference(@RequestBody SubscriptionRequest request) {
5139

52-
// 2. Definir el pagador (con el email de prueba)
53-
PreferencePayerRequest payer = PreferencePayerRequest.builder()
54-
.email(userEmail)
55-
.build();
40+
if (request.getPlanId() == null || request.getUserEmail() == null || request.getPrice() == null) {
41+
return ResponseEntity.badRequest().body(Map.of("error", "Faltan planId, userEmail o price."));
42+
}
5643

57-
// 3. Crear la solicitud de Preferencia
58-
PreferenceRequest request = PreferenceRequest.builder()
59-
.items(items)
60-
.payer(payer)
61-
// --- SE ELIMINAN backUrls y autoReturn ---
62-
// Esto evita el error 500 (MPApiException) al validar localhost.
63-
// Mercado Pago usará las URLs configuradas en el dashboard
64-
// o mostrará un botón simple de "Volver al sitio".
65-
.externalReference(planId)
66-
.build();
44+
try {
45+
String initPointUrl = subscriptionService.createMercadoPagoPreference(
46+
request.getPlanId(),
47+
request.getUserEmail(),
48+
request.getPrice(),
49+
request.getCurrency() != null ? request.getCurrency() : "ARS"
50+
);
6751

68-
// 4. Ejecutar la API
69-
PreferenceClient client = new PreferenceClient();
70-
Preference preference = client.create(request);
52+
Map<String, String> response = new HashMap<>();
53+
response.put("initPoint", initPointUrl);
54+
return ResponseEntity.ok(response);
7155

72-
// 5. Devolver la URL de pago
73-
return preference.getInitPoint();
56+
} catch (MPException | MPApiException e) {
57+
e.printStackTrace();
58+
System.err.println("Error de API de Mercado Pago: " + e.getMessage());
59+
return ResponseEntity.status(500).body(Map.of("error", "Error al crear la preferencia en Mercado Pago."));
60+
} catch (Exception e) {
61+
e.printStackTrace();
62+
return ResponseEntity.status(500).body(Map.of("error", "Error interno del servidor."));
63+
}
7464
}
7565

76-
/**
77-
* Procesa el Webhook para un Pago Único.
78-
*/
79-
public void processPaymentNotification(Long paymentId) throws MPException, MPApiException {
80-
PaymentClient client = new PaymentClient();
81-
Payment payment = client.get(paymentId);
82-
83-
String status = payment.getStatus();
84-
String externalReference = payment.getExternalReference();
66+
@PostMapping("/webhooks")
67+
public ResponseEntity<String> handleMercadoPagoWebhook(
68+
@RequestParam(name = "id", required = false) String id,
69+
@RequestParam(name = "topic", required = false) String topic)
70+
{
71+
if ("payment".equals(topic) && id != null) {
72+
try {
73+
Long paymentId = Long.parseLong(id);
8574

86-
System.out.printf("Procesando Webhook de PAGO. ID Pago MP: %s, ID Plan Interno: %s, Status: %s%n",
87-
paymentId, externalReference, status);
75+
subscriptionService.processPaymentNotification(paymentId);
8876

89-
if ("approved".equals(status)) {
90-
System.out.println("Pago AUTHORIZED. Activando Premium (Demo) para: " + externalReference);
91-
// TODO: Aquí iría tu lógica de base de datos para activar el servicio
92-
} else if ("rejected".equals(status) || "cancelled".equals(status)) {
93-
System.out.println("Pago REJECTED/CANCELLED para: " + externalReference);
77+
return ResponseEntity.ok("Notification processed successfully.");
78+
} catch (NumberFormatException e) {
79+
System.err.println("Error: El ID del Webhook no es un número (Long). ID: " + id);
80+
return ResponseEntity.badRequest().body("ID inválido.");
81+
} catch (MPException | MPApiException e) {
82+
System.err.println("Error procesando Webhook de Pago: " + e.getMessage());
83+
return ResponseEntity.status(500).body("Error processing notification.");
84+
}
9485
}
86+
87+
return ResponseEntity.ok("Notification received, not a relevant topic.");
9588
}
96-
}
89+
}

src/main/resources/application-cloud.properties

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,8 @@ management.health.db.enabled=true
4747

4848
# ===== API Keys =====
4949
fashion.ia.secret-key=${FASHION_IA_SECRET_KEY}
50-
tripo.api.key=tsk_IDtE_QEJ0ZCwQJDvy7HEotADi6auStMdj5dka5Z3LpV
50+
tripo.api.key=tsk_IDtE_QEJ0ZCwQJDvy7HEotADi6auStMdj5dka5Z3LpV
51+
52+
# ===== mercado pago =====
53+
mercadopago.access.token=${MP_ACCESS_TOKEN}
54+
mercadopago.urls.back=http://localhost:5173/suscripcion-finalizada

0 commit comments

Comments
 (0)