Skip to content

Sending Process

Philip Helger edited this page Feb 24, 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, or pre-built SBD).
  2. Store in database - The document and metadata are persisted to the outbound_transaction table in PostgreSQL.
  3. Optional verification - Configurable validation of the document. May lead to rejection (status updated in DB, notification triggered).
  4. AS4 sending via phase4 - SMP lookup, SBDH creation (if needed), 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.

Sequence Diagram

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 or SBD)
    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

Outbound Message Metadata

outbound_transaction (one row per document)

Field Description
SBDH Instance ID The Peppol SBDH Instance Identifier
Business Document ID Optional: the ID from the business document itself
Document bytes The raw document payload
C1 Country Code Country of the sender (C1), provided via API or extracted from SBDH
Transaction Status Current state (pending, sending, sent, failed, permanently_failed)
Created timestamp When the transaction was initially created
Reporting status Whether outbound reporting has been triggered (pending, reported)

outbound_sending_attempt (one row per sending try)

Field Description
Outbound Transaction ID FK to the parent outbound transaction
AS4 Message ID The AS4 Message ID used for this attempt
Receipt Message ID The AS4 Message ID from the synchronous receipt (null on failure)
HTTP Status Code The HTTP status code from the AS4 response
Attempt timestamp Date and time of this sending attempt
Attempt status Outcome of this attempt (success, failed)
Error details Error message or reason for failure (null on success)

Clone this wiki locally