Overview
The Fulfillment service is responsible for generating tickets after successful payment. It creates ticket records, generates PDF tickets with QR codes, stores them locally, and publishes events to trigger notification delivery. Port: 50004 (external), 5004 (internal)Database Schema:
bc_fulfillmentDependencies: PostgreSQL, Kafka, Ordering Service
Responsibilities
- Generate tickets after successful payment
- Create PDF tickets with QR codes for venue entry
- Store ticket PDFs in local file storage
- Track ticket status (pending, generated, failed, delivered)
- Publish
ticket-issuedevents to Kafka - Serve ticket PDFs via HTTP endpoints
- Enrich ticket data by querying Ordering service
API Endpoints
Get Ticket PDF
Retrieves the PDF file for a specific ticket by ID.
The ticket ID (GUID).
.pdf extension is optional.~/workspace/source/services/fulfillment/src/Api/Controllers/TicketsController.cs
- 400 Bad Request: Invalid GUID format
- 404 Not Found: Ticket not found in database or PDF file missing
Domain Models
Ticket
Represents a generated ticket for an event.Unique ticket identifier
Reference to the order
Customer email address
Name of the event
Seat identifier (e.g., “Section A, Row 5, Seat 12”)
Ticket price
Currency code (default: “USD”)
Ticket status enum:
Pending, Generated, Failed, or DeliveredQR code data for ticket validation at venue
Local file path to the generated PDF
When the ticket was generated
When the ticket record was created
When the ticket was last updated
~/workspace/source/services/fulfillment/src/Domain/Entities/Ticket.cs
Configuration
Database Connection
appsettings.json
Kafka Configuration
File Storage
Ticket PDFs are stored locally in:fulfillment-data) to persist across container restarts.
Ticket Generation Flow
- Listen for payment-succeeded event: Kafka consumer receives event from Payment service
- Extract order details: Parse OrderId from the event payload
- Enrich ticket data: Query Ordering service for order details (customer, event, seat)
- Generate QR code: Create QR code data for ticket validation
- Create ticket record: Insert ticket into database with
Pendingstatus - Generate PDF: Create PDF ticket with event details, seat info, and QR code
- Save PDF: Store PDF in local file storage (
/app/data/tickets/) - Update ticket status: Mark ticket as
Generated - Publish event: Send
ticket-issuedevent to Kafka with ticket details - Notification triggered: Notification service consumes event and sends email
Kafka Integration
Consumed Events:- payment-succeeded: Triggers ticket generation flow
- Payload:
{ OrderId, CustomerId, Amount, ... }
- Payload:
- ticket-issued: Published after successful ticket generation
- Payload:
{ TicketId, OrderId, CustomerEmail, TicketPdfUrl, QrCodeData, ... } - Consumed by Notification service to send tickets via email
- Payload:
PDF Generation
The service uses a PDF library to generate ticket PDFs with:- Event name and details
- Customer information
- Seat information (section, row, number)
- Purchase price
- QR code for venue scanning
- Ticket ID and order reference
- Generation timestamp
File Storage
Tickets are stored in a local directory:- Development:
/app/data/tickets/ - Docker: Mounted volume
fulfillment-data:/app/data/tickets - Filename format:
{ticketId}.pdf
Architecture Notes
- Uses MediatR for CQRS-style command/query handling
- Infrastructure services registered via
AddInfrastructure()extension method - Listens to Kafka for
payment-succeededevents - Queries Ordering service via HTTP for order enrichment
- Stores PDFs locally (could be extended to use S3, Azure Blob, etc.)
- Publishes
ticket-issuedevents for downstream notification delivery
Error Handling
- If ticket generation fails, status is set to
Failed - Failed tickets can be retried via background job
- Missing PDF files return 404 but ticket record may still exist
- Idempotency: Re-processing same OrderId won’t create duplicate tickets
