Skip to content

Sending Process

Philip Helger edited this page Apr 1, 2026 · 18 revisions

Sending Process

Overview

The sending process handles outbound Peppol document transmission from the Sender Backend (within C2) through the AP to the remote receiving AP (C3).

Process Steps

  1. Receive document via API - The Sender Backend provides data via the REST API (raw document + metadata, pre-built SBD, or S3 reference + metadata). Optionally includes an MLS_TO override. When an S3 reference is provided, the AP fetches the document from the sender's S3 bucket before proceeding.
  2. Store document and metadata - The document is written to disk under storage.outbound.path and the file path and metadata are persisted to the outbound_transaction table in the database.
  3. Optional verification - The document is validated via the pluggable verification SPI (IDocumentVerifier). If verification fails, the transaction status is set to rejected, a notification is triggered, and no sending attempt is made.
  4. AS4 sending via phase4 - SMP lookup, SBDH creation (if needed, including MLS_TO in SBDH extensions), AS4 message construction, signing, and transmission. The synchronous AS4 receipt is checked.
  5. Record sending attempt - Insert a row into outbound_sending_attempt with the outcome (AS4 Message ID, Receipt Message ID, HTTP status code, or error details). Update the parent outbound_transaction status accordingly.
  6. On success: trigger outbound reporting - The onSuccessfulAS4Sending callback triggers Peppol reporting for the outbound transaction.
  7. On failure: schedule retry - The transaction is marked for retry. The retry strategy (max attempts, backoff) is defined via customizable Java interfaces.
  8. On permanent failure: notify - When max retries are exhausted, the generic notification interface is invoked.
  9. Receive MLS response (asynchronous) - At a later point, the remote C3 may send an MLS response back via AS4. The AP receives it, correlates it with the original outbound transaction via the SBDH Instance Identifier, and updates the MLS status (received_ap, received_ab, or received_re).

Sequence Diagram: Sending

sequenceDiagram
    participant SB as Sender Backend
    participant AP as AP API
    participant DB as DB
    participant P4 as phase4
    participant RA as Remote AP (C3)

    SB->>AP: 1. Submit doc (raw+meta, SBD, or S3 ref+meta, optional mlsTo)
    AP->>DB: 2. Insert into outbound_transaction
    DB-->>AP: stored OK

    AP->>AP: 3. Verify doc (optional)
    note over AP: If rejected: update DB, notify, return error

    AP->>P4: 4. Trigger AS4 send
    P4->>RA: AS4 UserMessage
    RA-->>P4: AS4 Receipt
    P4-->>AP: AS4 result (Receipt MsgID, HTTP status)

    AP->>DB: 5. Insert into outbound_sending_attempt
    AP->>DB: Update outbound_transaction status

    AP-->>SB: API response (queued/not queued + SBDH Instance ID)

    opt On success
        AP->>AP: 6. Trigger outbound reporting callback
        AP->>DB: Store reporting record
    end
Loading

Retry Flow (asynchronous, triggered by scheduler)

sequenceDiagram
    participant S as Scheduler
    participant DB as DB
    participant P4 as phase4
    participant RA as Remote AP (C3)

    S->>DB: Query outbound_transaction where status = failed
    DB-->>S: list of pending

    loop For each failed transaction
        S->>P4: Trigger AS4 send
        P4->>RA: AS4 UserMessage
        RA-->>P4: AS4 Receipt/Error
        P4-->>S: AS4 result

        S->>DB: Insert sending attempt row
        S->>DB: Update outbound_transaction status

        opt On success
            S->>S: Trigger reporting callback
        end

        opt Max retries exhausted
            S->>S: Trigger notification
        end
    end
Loading

MLS Reception Flow (asynchronous, initiated by remote C3)

sequenceDiagram
    participant RA as Remote AP (C3)
    participant PS as phase4 Servlet
    participant DB as DB

    RA->>PS: AS4 UserMessage (MLS response)
    PS->>PS: Parse MLS, extract SBDH Instance ID reference
    PS->>DB: Lookup outbound_transaction by SBDH Instance ID
    DB-->>PS: original transaction

    PS->>DB: Update outbound_transaction MLS fields (mls_status, mls_received_dt, mls_id)
    PS-->>RA: AS4 Receipt
Loading

Outbound Message Metadata

outbound_transaction (one row per document)

Field Description
transaction_type Type of outbound transaction: business_document or mls_response
sender_id Peppol Participant ID of the sender
receiver_id Peppol Participant ID of the receiver
doc_type_id Peppol Document Type Identifier
process_id Peppol Process Identifier
sbdh_instance_id Peppol SBDH Instance Identifier
source_type How the document was submitted: payload_only (AP creates SBDH) or prebuilt_sbd (SBDH already present)
document_path Path to the document file — either an absolute filesystem path or an s3://bucket/key URI depending on storage.mode
document_size Size of the document in bytes
document_hash SHA-256 hash of the document payload for integrity verification
c1_country_code Country of the sender (C1)
sbdh_standard SBDH Standard override for non-XML payloads (e.g. urn:peppol:doctype:pdf+xml). Null if auto-derived. Set via sbdhStandard query parameter on the submit endpoint.
sbdh_type_version SBDH TypeVersion override (e.g. 0). Null if auto-derived. Set via sbdhTypeVersion query parameter on the submit endpoint.
sbdh_type SBDH Type override (e.g. factur-x). Null if auto-derived. Set via sbdhType query parameter on the submit endpoint.
payload_mime_type MIME type for binary payloads (e.g. application/pdf). Null for XML payloads. Set via payloadMimeType query parameter on the submit endpoint. When set, the payload is wrapped in <BinaryContent> instead of being embedded as XML.
status pending, rejected, sending, sent, failed, permanently_failed
attempt_count Total number of sending attempts (default 0)
created_dt When the transaction was initially created
completed_dt When the transaction reached its final successful state
reporting_status Whether outbound reporting has been triggered (pending, reported)
next_retry_dt Planned date/time of the next sending retry (null unless status is failed)
error_details Summary error from the permanently failed attempt
mls_to MLS_TO override (only for business_document)
mls_status MLS reception status: pending, received_ap, received_ab, received_re, not_applicable (only for business_document)
mls_received_dt When the MLS response was received (only for business_document)
mls_id The MLS message ID from the received MLS (only for business_document)
mls_inbound_transaction_id FK to the inbound_transaction that triggered this MLS response (only for mls_response)

outbound_sending_attempt (one row per sending try)

Field Description
outbound_transaction_id FK to the parent outbound transaction
as4_message_id AS4 Message ID used for this attempt
as4_timestamp AS4 MessageInfo/Timestamp from this attempt (UTC). MLS Milestone M1 for business documents; M2 for MLS responses.
receipt_message_id AS4 Message ID from the synchronous receipt
http_status_code HTTP status code from the AS4 response
attempt_dt Date and time of this sending attempt
attempt_status Outcome of this attempt (success, failed)
error_details Error message or reason for failure

Clone this wiki locally