PoC en Java con Spring Boot, arquitectura hexagonal, DDD y Neo4j para modelar un caso de payment processing basado en grafos.
El caso de uso sí aplica a Neo4j porque en pagos es útil analizar relaciones entre clientes, comercios, instrumentos de pago y transacciones. Neo4j permite detectar patrones como tarjetas compartidas por varios clientes, pagos rechazados recurrentes, comercios relacionados a pagos riesgosos y redes transaccionales sospechosas.
src/main/java/com/edgarrt/poc/paymentprocessing
├── domain
│ ├── model # Entidades y value objects del dominio
│ └── service # Política de riesgo del dominio
├── application
│ ├── port/in # Casos de uso
│ ├── port/out # Puertos de persistencia
│ └── service # Orquestación de casos de uso
└── infrastructure
├── adapter/in/rest # API REST
├── out/neo4j # Adaptador Neo4j con Cypher
└── config # Configuración de beans
graph TD
C[Customer] -->|OWNS| PI[Payment Instrument]
C -->|INITIATES| P[Payment]
P -->|USES| PI
P -->|PAID_TO| M[Merchant]
M -->|HAS_CATEGORY| MC[Merchant Category]
P -->|HAS_RISK_ANALYSIS| R[Risk Analysis]
- JDK 25
- Maven 3.9+
- Docker y Docker Compose
- IntelliJ IDEA
cd infraestructura
docker compose up -dConsola Neo4j:
- URL: http://localhost:7474
- User:
neo4j - Password:
paymentspoc123
Ejecutar constraints y datos iniciales:
docker exec -i neo4j-payment-processing cypher-shell -u neo4j -p paymentspoc123 < neo4j/init.cypherDesde la raíz del proyecto:
mvn spring-boot:runHealth check:
curl http://localhost:8080/actuator/healthLa aplicación usa src/main/resources/properties.yml, importado desde application.yml.
spring:
neo4j:
uri: bolt://localhost:7687
authentication:
username: neo4j
password: paymentspoc123POST /payments/v1/customers
Content-Type: application/json
{
"customerId": "CUS-100",
"fullName": "Edgar Rodriguez",
"documentNumber": "12345678",
"segment": "PREMIUM"
}POST /payments/v1/merchants
Content-Type: application/json
{
"merchantId": "MER-100",
"legalName": "Payment Processing Store SAC",
"mcc": "5732",
"country": "PE"
}POST /payments/v1/instruments
Content-Type: application/json
{
"instrumentId": "CARD-100",
"type": "CARD",
"fingerprint": "fp-card-100",
"brand": "VISA",
"last4": "4242"
}POST /payments/v1/payments/authorize
Content-Type: application/json
{
"paymentId": "PAY-100",
"customerId": "CUS-100",
"merchantId": "MER-100",
"instrumentId": "CARD-100",
"amount": 250.50,
"currency": "PEN",
"channel": "MOBILE_APP"
}Response esperado:
{
"code": "OK",
"message": "Operation completed",
"data": {
"paymentId": "PAY-100",
"customerId": "CUS-100",
"merchantId": "MER-100",
"instrumentId": "CARD-100",
"amount": 250.50,
"currency": "PEN",
"channel": "MOBILE_APP",
"status": "AUTHORIZED",
"riskLevel": "LOW",
"riskReason": "No relevant graph risk signals found"
}
}GET /payments/v1/payments/PAY-100GET /payments/v1/payments/PAY-100/risk-analysisGET /payments/v1/customers/CUS-100/risk-networkSe incluye:
infraestructura/http/payment-processing.http
Puedes abrirlo en IntelliJ IDEA y ejecutar cada request directamente.
MATCH (c:Customer)-[:INITIATED]->(p:Payment)-[:PAID_TO]->(m:Merchant)
MATCH (p)-[:USED_INSTRUMENT]->(i:PaymentInstrument)
RETURN c,p,m,i;MATCH (c1:Customer)-[:OWNS_OR_USES]->(i:PaymentInstrument)<-[:OWNS_OR_USES]-(c2:Customer)
WHERE c1.customerId <> c2.customerId
RETURN c1.customerId, i.instrumentId, c2.customerId;- Descomprime el ZIP.
- Abre IntelliJ IDEA.
- Selecciona
Open. - Elige la carpeta
neo4j-payment-processing-poc. - IntelliJ detectará el proyecto Maven.
- Configura SDK Java 25.
- Levanta Neo4j con Docker Compose.
- Ejecuta
PaymentProcessingApplication.