chore(docker): add root Dockerfile pinning ubi8/openjdk-21:1.21 + UID 1001 for lionsctl pipeline
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 4m2s
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 4m2s
This commit is contained in:
@@ -1,139 +0,0 @@
|
||||
package dev.lions.unionflow.server.resource;
|
||||
|
||||
import dev.lions.unionflow.server.api.payment.*;
|
||||
import dev.lions.unionflow.server.entity.SouscriptionOrganisation;
|
||||
import dev.lions.unionflow.server.payment.orchestration.PaymentOrchestrator;
|
||||
import dev.lions.unionflow.server.payment.orchestration.PaymentProviderRegistry;
|
||||
import dev.lions.unionflow.server.repository.SouscriptionOrganisationRepository;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Endpoints de paiement unifiés — abstraction multi-provider.
|
||||
* Remplace à terme les endpoints Wave-spécifiques.
|
||||
*/
|
||||
@Slf4j
|
||||
@Path("/api/paiements")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class PaiementUnifieResource {
|
||||
|
||||
@Inject
|
||||
PaymentOrchestrator orchestrator;
|
||||
|
||||
@Inject
|
||||
PaymentProviderRegistry registry;
|
||||
|
||||
@Inject
|
||||
SouscriptionOrganisationRepository souscriptionRepository;
|
||||
|
||||
/**
|
||||
* Initie un paiement via le provider demandé (ou le provider par défaut).
|
||||
*
|
||||
* <p>Exemple : {@code POST /api/paiements/initier?provider=WAVE}
|
||||
*/
|
||||
@POST
|
||||
@Path("/initier")
|
||||
@RolesAllowed({"MEMBRE_ACTIF", "ADMIN_ORGANISATION", "TRESORIER", "SUPER_ADMIN"})
|
||||
public Response initier(
|
||||
@QueryParam("provider") String provider,
|
||||
PaiementInitierRequest req) {
|
||||
try {
|
||||
// Si une souscription est fournie, utiliser le providerDefaut de sa formule
|
||||
String resolvedProvider = provider;
|
||||
if (req.souscriptionId() != null) {
|
||||
resolvedProvider = souscriptionRepository.findByIdOptional(req.souscriptionId())
|
||||
.map(SouscriptionOrganisation::getFormule)
|
||||
.map(f -> f.getProviderDefaut())
|
||||
.filter(p -> p != null && !p.isBlank())
|
||||
.orElse(provider);
|
||||
}
|
||||
|
||||
CheckoutRequest checkoutRequest = new CheckoutRequest(
|
||||
req.montant(),
|
||||
req.devise() != null ? req.devise() : "XOF",
|
||||
req.telephone(),
|
||||
req.email(),
|
||||
req.reference(),
|
||||
req.successUrl(),
|
||||
req.cancelUrl(),
|
||||
Map.of()
|
||||
);
|
||||
CheckoutSession session = orchestrator.initierPaiement(checkoutRequest, resolvedProvider);
|
||||
return Response.ok(session).build();
|
||||
} catch (PaymentException e) {
|
||||
return Response.status(e.getHttpStatus())
|
||||
.entity(Map.of("error", e.getMessage(), "provider", e.getProviderCode()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Webhook entrant d'un provider. Vérifie la signature et met à jour le statut.
|
||||
* Route : {@code POST /api/paiements/webhook/{provider}}
|
||||
*/
|
||||
@POST
|
||||
@Path("/webhook/{provider}")
|
||||
@PermitAll
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
public Response webhook(
|
||||
@PathParam("provider") String providerCode,
|
||||
String rawBody,
|
||||
@Context HttpHeaders httpHeaders) {
|
||||
try {
|
||||
PaymentProvider provider = registry.get(providerCode.toUpperCase());
|
||||
Map<String, String> headers = httpHeaders.getRequestHeaders().entrySet().stream()
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
e -> e.getValue().isEmpty() ? "" : e.getValue().get(0)
|
||||
));
|
||||
|
||||
PaymentEvent event = provider.processWebhook(rawBody, headers);
|
||||
orchestrator.handleEvent(event);
|
||||
return Response.ok().build();
|
||||
|
||||
} catch (UnsupportedOperationException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", "Provider inconnu : " + providerCode))
|
||||
.build();
|
||||
} catch (PaymentException e) {
|
||||
log.error("Webhook {} rejeté : {}", providerCode, e.getMessage());
|
||||
return Response.status(e.getHttpStatus())
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Retourne les providers de paiement disponibles. */
|
||||
@GET
|
||||
@Path("/providers")
|
||||
@RolesAllowed({"ADMIN_ORGANISATION", "SUPER_ADMIN"})
|
||||
public List<String> getProviders() {
|
||||
return registry.getAvailableCodes();
|
||||
}
|
||||
|
||||
public record PaiementInitierRequest(
|
||||
BigDecimal montant,
|
||||
String devise,
|
||||
String telephone,
|
||||
String email,
|
||||
String reference,
|
||||
String successUrl,
|
||||
String cancelUrl,
|
||||
/** Optionnel — si fourni, le providerDefaut de la formule prend le dessus sur le query param. */
|
||||
UUID souscriptionId
|
||||
) {}
|
||||
}
|
||||
Reference in New Issue
Block a user