High-level overview
Paper Channel follows a classic three-tier reactive architecture:
Inbound HTTP requests
│
▼
┌───────────────────────────────────┐
│ REST Layer │ Spring WebFlux controllers
│ (PaperMessagesRestV1Controller, │
│ PaperChannelRestV1Controller, │
│ …) │
└────────────────┬──────────────────┘
│
reactive Mono / Flux
│
▼
┌───────────────────────────────────┐
│ Service Layer │ Business logic, prepare/send
│ (QueueListenerService, │ orchestration, cost calculation
│ PaperSendService, …) │
└──────┬─────────────────┬──────────┘
│ │
▼ ▼
┌────────────┐ ┌───────────────────────────────┐
│ DynamoDB │ │ External integrations │
│ (tables │ │ (MS clients + SQS producers) │
│ below) │ └───────────────────────────────┘
└────────────┘
All layers use Project Reactor (Mono/Flux) for non-blocking I/O. SQS consumers (QueueListener) bridge the reactive pipeline from incoming queue messages.
REST controllers
Controllers live in src/main/java/it/pagopa/pn/paperchannel/rest/v1/.
Controller Responsibility PaperMessagesRestV1ControllerInternal API — handles prepare and send paper delivery requests PaperChannelRestV1ControllerBack-office API — manages tenders, delivery drivers, FSU, costs, and geo keys PaperCalculatorRestV2ControllerCost estimation endpoint for rate-card lookups CheckAddressRestV1ControllerAddress validation and normalisation endpoint PaperChannelPcRetryV1ControllerManual retry endpoint for stalled External Channel requests NotificationReworkV1ControllerTimeline correction operations for re-processed notifications
DynamoDB entities
All DynamoDB entity classes live in src/main/java/it/pagopa/pn/paperchannel/middleware/db/entities/.
Entity Purpose PnDeliveryRequestCore record for each prepare/send request lifecycle PnEventMetaMetadata events associated with a delivery request PnEventDematDematerialisation (scan) events for physical mail items PnEventErrorUnrecoverable processing errors recorded for a request PnRequestErrorErrors persisted when retry budgets are exhausted PnTenderTender (gara d’appalto) contract header PnDeliveryDriverDelivery driver (recapitista) linked to a tender PnCostPostal rates for a given driver, product, and geo-zone combination PnZoneGeographic zone definitions for postal routing PnAddressEncrypted address record linked to a request PnDiscoveredAddressAddress resolved from National Registries PnAttachmentInfoAttachment metadata (safe-storage key, SHA256, page count) PnAttachmentsConfigRules for which attachments are included per product/CAP PnClientIDClient identifiers for cross-service calls PnErrorMessageHuman-readable error messages for audit and alerting PnErrorDetailsStructured error detail payloads PnPaperChannelTenderSimplified tender records (new tender flow) PnPaperChannelDeliveryDriverSimplified delivery driver records PnPaperChannelCostSimplified cost records PnPaperChannelGeoKeyGeographic routing keys for the simplified tender flow PnDeliveryFileReferences to delivery documents stored in Safe Storage PnRangeNumeric range definitions used in rule engines PnRuleParamsParameters for the document-filter rule engine
External service clients
Generated WebClient stubs live under src/main/java/it/pagopa/pn/paperchannel/middleware/msclient/. Each interface is backed by an OpenAPI-generated reactive client in generated/openapi/msclient/.
Client interface Remote service Key operations SafeStorageClientpn-safe-storage Download and upload notification documents NationalRegistryClientpn-national-registries Request verified address lookups ExternalChannelClientpn-ec (External Channel) Submit postal send requests AddressManagerClientpn-address-manager Normalise and validate Italian addresses F24Clientpn-f24 Request on-demand F24 PDF generation RaddAltClientpn-radd-alt Interact with RADD alternative access points PaperTrackerClientpn-paper-tracker Query physical mail tracking status
SQS queue topology
Consumed queues
Property key Purpose pn.paper-channel.queue-internalInternal retry and async-flow events (prepare, address-manager errors, EC errors, F24 errors) pn.paper-channel.queue-national-registriesAddress lookup responses from National Registries pn.paper-channel.queue-external-channelDelivery status updates from External Channel / carriers pn.paper-channel.queue-f24F24 PDF-ready notifications pn.paper-channel.queue-delayer-to-paperchannelPhase-2 prepare events relayed from the Delayer service
Produced queues / topics
Producer class Destination Purpose DeliveryPushMomProducerpn.paper-channel.queue-delivery-pushOutcome events sent to Delivery Push NormalizeAddressQueueMomProducerpn.paper-channel.queue-normalize-addressAddress normalisation requests to Address Manager PaperchannelToDelayerMomProducerpn.paper-channel.queue-paperchannel-to-delayerPhase-1 prepare results forwarded to the Delayer InternalQueueMomProducerpn.paper-channel.queue-internalInternal retry scheduling EventBridgeProducerEventBridge bus PaperChannelOutcomeEvent published for cross-service consumersOcrProducerpn.paper-channel.queue-url-ocr-inputsDocument images queued for OCR processing
Encryption flow
Sensitive address fields are encrypted before being persisted in DynamoDB using AWS envelope encryption:
Paper Channel calls AWS KMS to generate a data key (configured via aws.kms.keyId).
The AWS Encryption SDK (KmsEncryptionImpl) encrypts the address payload with the data key.
Only the encrypted ciphertext is stored in DynamoDB (PnAddress, PnDiscoveredAddress).
On read, the SDK retrieves and decrypts the data key from KMS and decrypts the payload in memory.
A second encryption path (DataVaultEncryptionImpl) delegates to the Data Vault microservice for token-based pseudonymisation of PII.
For local development with LocalStack, you must obtain the KMS key ARN from the LocalStack startup logs and set it as aws.kms.keyId in your configuration. Without this, address encryption will fail at runtime.
Introduction Return to the service overview and integration map.
Quickstart Run the service locally and send your first prepare request.