The requestId and idempotency
TherequestId is the primary key of every delivery request. It is set by the caller (pn-delivery-push) and is stored in the requestId column of the RequestDeliveryDynamoTable DynamoDB table (PnDeliveryRequest.COL_REQUEST_ID).
All endpoints are idempotent on requestId:
- A second
POST /paper-deliveries-prepare/{requestId}with the same body returns200with the last known state instead of creating a duplicate. - A second
POST /paper-deliveries-send/{requestId}with the same body returns200with the previously calculatedSendResponse. - A request that conflicts with a stored one (different body, same
requestId) returns409.
requestId and sets relatedRequestId to the original requestId. Paper Channel uses this to retrieve the first-attempt address and run the second-attempt address resolution flow.
Two-phase async flow
Prepare – phase 1: address validation
The caller POSTs to
/paper-channel-private/v1/b2b/paper-deliveries-prepare/{requestId} with a PrepareRequest.PaperMessagesServiceImpl.preparePaperSync() runs synchronously:- Validates the request against any existing
PnDeliveryRequestin DynamoDB. - Creates a new
PnDeliveryRequestwith statusIN_PROCESSING(PC000) and saves the receiver address as aPnAddressentity. - Pushes an internal SQS event that triggers
PreparePhaseOneAsyncServiceImpl.preparePhaseOneAsync(). - Returns
204to the caller (the address resolution happens asynchronously).
PreparePhaseOneAsyncServiceImpl) then:- Calls
PaperAddressService.getCorrectAddress()to pick the right address (see Address resolution). - Hashes the resolved address and updates
PnDeliveryRequest.addressHash. - Transitions the request to
SEND_TO_DELAYER(PC006). - If the address is domestic, looks up cost via
PaperTenderService.getSimplifiedCost()and pushes the result to the phase-1 output queue → the request moves toTAKING_CHARGE(PC001). - If the address is international, routes to the phase-2 queue for further attachment processing.
Prepare – phase 2: attachment processing and National Registry fallback
PreparePhaseTwoAsyncServiceImpl.prepareAsyncPhaseTwo() handles:- Retrieving the resolved address from DynamoDB (
AddressTypeEnum.RECEIVER_ADDRESS). - Filtering attachments through
CheckCoverageAreaService. - If F24 attachments are present, delegating PDF generation to
F24Service.preparePDF(); on error, retrying viaprepareFlowStarter.redrivePreparePhaseTwoAfterF24Error(). - For regular documents, calling
SafeStorageServiceto retrieve page counts and dates from each PDF. - On success, updating the request to
TAKING_CHARGE(PC001) and sending aPrepareEvent(statusOK) to pn-delivery-push via SQS.
- The request is set to
NATIONAL_REGISTRY_WAITING(PC002). NationalRegistryService.finderAddressFromNationalRegistries()is called with the fiscal code and receiver type.- When the registry responds, a
correlationIdis used to look up the delivery request and resume phase 1.
Send: submission to External Channel
After a successful Prepare the caller POSTs to
/paper-channel-private/v1/b2b/paper-deliveries-send/{requestId} with a SendRequest.PaperMessagesServiceImpl.executionPaper() runs synchronously:- Loads the
PnDeliveryRequestwith strong consistency. - Validates the
SendRequestagainst the stored entity (idempotency check). - Calls
PaperCalculatorUtils.calculator()to compute the final shipping cost (CostWithDriver). - Compares the calculated cost against the cost stored during Prepare (
PnDeliveryRequest.cost). If they differ, setsreworkNeeded = trueand returns422. - Transitions the request to
READY_TO_SEND(PC003). - Calls
PcRetryUtils.callInitTrackingAndEcSendEngage()to submit to External Channel. - Persists
driverCodeandtenderCodeon thePnDeliveryRequest. - Returns
SendResponsewithamount(eurocents),numberOfPages, andenvelopeWeight.
Request status machine
ThestatusCode field on PnDeliveryRequest is set by RequestDeliveryMapper.changeState(). The statusDetail value is either PROGRESS, OK, or KO.
| Code | Enum name | Description | Detail |
|---|---|---|---|
PC000 | IN_PROCESSING | Request received, processing started | PROGRESS |
PC001 | TAKING_CHARGE | Picked up by paper channel / new send request | PROGRESS |
PC002 | NATIONAL_REGISTRY_WAITING | Waiting for address from National Registry | PROGRESS |
PC003 | READY_TO_SEND | Address resolved, ready for External Channel | PROGRESS |
PC005 | NATIONAL_REGISTRY_ERROR | Error retrieving address from National Registry | PROGRESS |
PC006 | SEND_TO_DELAYER | Request sent to the phase-2 delayer queue | PROGRESS |
PC010 | UNTRACEABLE | Recipient completely untraceable | KO |
PC011 | PAPER_CHANNEL_DEFAULT_ERROR | Generic error | KO |
PC012 | PAPER_CHANNEL_ASYNC_ERROR | Error during prepare phase | KO |
PC013 | SAFE_STORAGE_IN_ERROR | Error fetching attachments from Safe Storage | KO |
PC014 | DEFAULT_ERROR | Generic error | KO |
PC015 | F24_WAITING | Waiting for F24 PDF generation | PROGRESS |
PC016 | F24_ERROR | Error during F24 PDF generation | PROGRESS |
PNALL001 | DEDUPLICATES_ERROR_RESPONSE | Normalisation error | PROGRESS |
001 | PRINTED | Printed by postal operator | PROGRESS |
002 | DELIVERY_DRIVER_AVAILABLE | Available to delivery driver | PROGRESS |
003 | DELIVERY_DRIVER_IN_CHARGE | Taken in charge by delivery driver | PROGRESS |
004 | DELIVERED | Delivered to recipient | OK |
005 | DELIVERY_MISSING | Delivery failed | OK |
006 | LOST_DAMAGE | Lost, stolen, or damaged | OK |
007 | DELIVERED_POST_OFFICE | Delivered at post office | OK |
008 | DELIVERY_MISSING_POST_OFFICE | Not picked up at post office | OK |
009 | IN_STOCK | In storage (compiuta giacenza) | PROGRESS |
Statuses
PC001 through PC016 are internal to pn-paper-channel. Statuses 001–009 are reported by External Channel and forwarded to pn-delivery-push.Key DynamoDB fields on PnDeliveryRequest
PnDeliveryRequest is stored in RequestDeliveryDynamoTable with requestId as the partition key. A secondary index on correlationId (correlation-index) supports National Registry callback lookups.
| Field | Type | Purpose |
|---|---|---|
requestId | String (PK) | Unique request identifier |
relatedRequestId | String | Points to the first-attempt requestId for second attempts |
correlationId | String (GSI) | National Registry callback correlation |
statusCode | String | Current lifecycle status (see table above) |
statusDetail | String | PROGRESS, OK, or KO |
addressHash | String | SHA-256 hash of the resolved delivery address |
cost | Integer | Delivery cost in eurocents calculated during Prepare |
tenderCode | String | Active tender used for cost calculation |
driverCode | String | Delivery driver code assigned |
reworkNeeded | Boolean | Set to true when Prepare cost differs from Send cost |
productType | String | Postal product (AR, RS, 890, RIR, RIS) |
attachments | List | Attachment metadata including page count and file key |
refined | Boolean | Whether refinement (perfezionamento) has been applied |