All backend components are complete and ready to run:
- β Stripe Integration: Java SDK v24.9.0 configured
- β Payment Models: PaymentModel, PaymentStatusEnum (PENDING, REQUIRES_CONFIRMATION, SUCCEEDED, FAILED)
- β Repository Layer: PaymentRepository with JPA + Specifications
- β Service Layer: PaymentService, PaymentProcessingService with Stripe API calls
- β REST API: PaymentController with /process and /webhook endpoints
- β Event-Driven: RabbitMQ integration (listens to payment-request, publishes payment-success)
- β Configuration: Stripe keys, database, service discovery all configured
-
PostgreSQL running on
localhost:5432- Database:
db-payment - Username:
postgres - Password:
mysecretpassword
- Database:
-
Consul running on
localhost:8500(service discovery) -
RabbitMQ running on
localhost:5672(event messaging) -
Environment Variables configured (see below)
The Payment service reads Stripe credentials from environment variables. You have two options:
The .env file already contains:
STRIPE_SECRET_KEY=sk_test_51SYuUWRzGsmN2IxdQKjXO5Odsr4xVR9KLe0yCcwkaSTIaAUOw5EKO4ioim5pj75XQn4DoBp2MFJ84nac7ZZUM8Qq00JSZBCjzK
STRIPE_WEBHOOK_SECRET=whsec_661b1cccb7ca673417e10f38c798ea1841d6449a716f268d89890d71db5bcb8dIn PowerShell:
# Load .env file (run from Payment directory)
Get-Content .env | ForEach-Object {
if ($_ -match '^([^=]+)=(.*)$') {
[System.Environment]::SetEnvironmentVariable($matches[1], $matches[2], "Process")
}
}Or set manually:
$env:STRIPE_SECRET_KEY="sk_test_51SYuUWRzGsmN2IxdQKjXO5Odsr4xVR9KLe0yCcwkaSTIaAUOw5EKO4ioim5pj75XQn4DoBp2MFJ84nac7ZZUM8Qq00JSZBCjzK"
$env:STRIPE_WEBHOOK_SECRET="whsec_661b1cccb7ca673417e10f38c798ea1841d6449a716f268d89890d71db5bcb8d"Add to Run Configuration β Environment Variables:
STRIPE_SECRET_KEY=sk_test_51SYuUWRzGsmN2IxdQKjXO5Odsr4xVR9KLe0yCcwkaSTIaAUOw5EKO4ioim5pj75XQn4DoBp2MFJ84nac7ZZUM8Qq00JSZBCjzK
STRIPE_WEBHOOK_SECRET=whsec_661b1cccb7ca673417e10f38c798ea1841d6449a716f268d89890d71db5bcb8d
# From Payment directory
./mvnw clean install -DskipTests./mvnw spring-boot:run- Run
PaymentApplication.javamain class - Ensure environment variables are set in Run Configuration
java -jar target/payment-0.0.1-SNAPSHOT.jar-
Check Consul: http://localhost:8500/ui/
- Service
paymentshould appear
- Service
-
Check Actuator Health: http://localhost:8087/actuator/health
{ "status": "UP" } -
Check Logs for:
π§ Stripe API initialized πΎ Database connection established π‘ Consul registration successful π° RabbitMQ connection established π Payment service started on port 8087
Creates/retrieves a Stripe PaymentIntent for a ticket purchase.
Request:
POST /payments/process
Content-Type: application/json
{
"ticketRequestId": "ticket-uuid-here"
}Response:
{
"paymentIntentId": "pi_xxx",
"clientSecret": "pi_xxx_secret_xxx",
"amount": 150.0,
"currency": "MAD"
}Receives events from Stripe when payments succeed/fail.
Request:
POST /payments/webhook
Content-Type: application/json
Stripe-Signature: t=xxx,v1=xxx
{...stripe event payload...}Response:
"Success"Event: payment-request (from Ticket service)
Queue: payment-process
Payload:
{
"userId": "user-uuid",
"routeId": "route-uuid",
"amount": 150.0,
"currency": "MAD",
"ticketRequestId": "ticket-uuid"
}Action:
- Creates
PaymentModelwith statusPENDING - Creates Stripe
PaymentIntent - Updates status to
REQUIRES_CONFIRMATION - Stores
stripePaymentIntentId
Event: payment-success (to Ticket service)
Exchange: payment.success.exchange
Payload:
{
"paymentId": "payment-uuid",
"ticketRequestId": "ticket-uuid",
"routeId": "route-uuid",
"userId": "user-uuid",
"amount": 150.0,
"currency": "MAD"
}Triggered By: Stripe webhook payment_intent.succeeded
Table: N_PAYMENT
| Column | Type | Description |
|---|---|---|
| id | VARCHAR | Primary key (UUID) |
| user_id | VARCHAR | User who initiated payment |
| amount | DOUBLE | Payment amount |
| currency | VARCHAR(3) | Currency code (MAD) |
| status | VARCHAR | PENDING, REQUIRES_CONFIRMATION, SUCCEEDED, FAILED |
| stripe_payment_intent_id | VARCHAR | Stripe PaymentIntent ID |
| stripe_charge_id | VARCHAR | Stripe Charge ID (after success) |
| description | VARCHAR | Optional description |
| ticket_request_id | VARCHAR | Reference to ticket being purchased |
| ticket_id | VARCHAR | Final ticket ID (after success) |
| subscription_id | VARCHAR | For future subscription support |
| created_at | TIMESTAMP | Creation timestamp |
| updated_at | TIMESTAMP | Last update timestamp |
# Start PostgreSQL, Consul, RabbitMQ
cd platform-local-env
docker-compose up -dcd Payment
./mvnw spring-boot:runUse RabbitMQ Management UI (http://localhost:15672) or code to publish to payment-process queue:
{
"userId": "test-user-123",
"routeId": "route-456",
"amount": 150.0,
"currency": "MAD",
"ticketRequestId": "ticket-789"
}Query database:
SELECT * FROM n_payment WHERE ticket_request_id = 'ticket-789';Should show:
- status:
REQUIRES_CONFIRMATION - stripe_payment_intent_id:
pi_xxx
curl http://localhost:8087/payments/process `
-H "Content-Type: application/json" `
-d '{"ticketRequestId":"ticket-789"}'Should return:
{
"paymentIntentId": "pi_xxx",
"clientSecret": "pi_xxx_secret_xxx",
"amount": 150.0,
"currency": "MAD"
}Use Stripe CLI or send webhook manually:
stripe trigger payment_intent.succeededCheck logs for:
π Stripe PaymentIntent succeeded: pi_xxx
β
Payment SUCCESS updated
π€ payment-success event published
Symptom: Error about missing environment variables
Could not resolve placeholder 'STRIPE_SECRET_KEY'
Solution: Ensure environment variables are set:
echo $env:STRIPE_SECRET_KEY
echo $env:STRIPE_WEBHOOK_SECRETIf empty, run:
Get-Content .env | ForEach-Object {
if ($_ -match '^([^=]+)=(.*)$') {
[System.Environment]::SetEnvironmentVariable($matches[1], $matches[2], "Process")
}
}Symptom: Connection to localhost:5432 refused
Solution:
-
Check PostgreSQL is running:
docker ps | Select-String postgres
-
Create database if missing:
CREATE DATABASE "db-payment"; -
Verify credentials in
application-dev.yml
Symptom: Could not locate Consul agent
Solution:
# Start Consul
docker run -d -p 8500:8500 consul agent -devSymptom: Connection refused: localhost:5672
Solution:
# Check RabbitMQ
docker ps | Select-String rabbitmq
# If not running:
docker run -d -p 5672:5672 -p 15672:15672 rabbitmq:managementSymptom: No API key provided
Solution:
-
Verify Stripe key is set:
echo $env:STRIPE_SECRET_KEY -
Check key starts with
sk_test_ -
Test key in Stripe Dashboard: https://dashboard.stripe.com/test/apikeys
- PostgreSQL running with
db-paymentdatabase - Consul running on port 8500
- RabbitMQ running on port 5672
- Environment variables set (
STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET) - Project built:
./mvnw clean install - Service running:
./mvnw spring-boot:run - Health check passes: http://localhost:8087/actuator/health
- Service registered in Consul: http://localhost:8500/ui/
The Gateway should route /paymentMgtApi/** to Payment service:
# Gateway application.yml
spring:
cloud:
gateway:
routes:
- id: payment-service
uri: lb://payment
predicates:
- Path=/paymentMgtApi/**
filters:
- StripPrefix=1See frontend todo list for:
- Installing Stripe.js packages
- Creating paymentService.ts
- Creating PaymentPage component
- Updating BuyTicketPage flow
- Stripe Java Docs: https://stripe.com/docs/api?lang=java
- Spring Cloud Stream: https://spring.io/projects/spring-cloud-stream
- RabbitMQ Management: http://localhost:15672 (guest/guest)
- Consul UI: http://localhost:8500/ui/
- Actuator Endpoints: http://localhost:8087/actuator
The backend is COMPLETE. Next, implement the frontend:
- Install Stripe.js packages in FrontEnd
- Create
paymentService.tsAPI client - Create
PaymentPage.tsxwith Stripe Elements - Modify
BuyTicketPage.tsxto redirect to payment - Add payment route to router
- Configure Stripe publishable key in frontend .env
See updated todo list for detailed frontend tasks.
change this by your path to set the env variables
"""
cd C:\Users\ZACKWEB\Desktop\OurBusWay\Payment; Get-Content .env | ForEach-Object { if (
"""
C:\Users\ZACKWEB\Desktop\OurBusWay\strip_133\stripe.exe listen --forward-to localhost:8087/paymentMgtApi/webhook