Skip to content

Receiving Process

Philip Helger edited this page Feb 24, 2026 · 21 revisions

Receiving Process

Overview

The receiving process handles inbound Peppol documents arriving at the AP (C3) via AS4 from a remote sending AP (C2) and forwards them to the Receiver Backend (an internal system within C3).

Process Steps

  1. Receive via AS4 - phase4 servlet receives the AS4 message. Duplicate detection is applied (configurable: reject or store-and-flag).
  2. Store in database - The document, metadata, and phase4 Incoming ID are persisted to the inbound_transaction table in PostgreSQL.
  3. If storage fails - Respond with an AS4 error to the remote sending AP (C2). The transaction is not recorded.
  4. Forward to Receiver Backend - Deliver the document via the configured forwarding mode (per AP instance):
    • HTTP POST (async reporting)
    • HTTP POST with sync response (C4 country code in response)
    • S3 + link forwarding
    • SFTP
  5. Record forwarding attempt - Insert a row into inbound_forwarding_attempt with the outcome (success or failure + error details). Update the parent inbound_transaction status accordingly.
  6. If forwarding fails - The document will be retried by a periodic scheduler. Each retry creates a new inbound_forwarding_attempt row.
  7. Reporting - Either triggered synchronously (from HTTP POST response containing C4 country code) or asynchronously (Receiver Backend calls reporting API with AS4 Message ID + C4 country code).
  8. On permanent forwarding failure - Notification via generic interface.

Sequence Diagram: Receiving and Forwarding

┌──────────┐       ┌────────┐       ┌────────┐       ┌───────────┐       ┌──────────┐
│ Remote   │       │ phase4 │       │   DB   │       │Forwarding │       │Receiver  │
│ AP (C2)  │       │Servlet │       │        │       │  Module   │       │ Backend  │
└────┬─────┘       └───┬────┘       └───┬────┘       └─────┬─────┘       └────┬─────┘
     │                 │                │                   │                  │
     │ AS4 UserMessage │                │                   │                  │
     │────────────────>│                │                   │                  │
     │                 │                │                   │                  │
     │                 │ 1. Duplicate   │                   │                  │
     │                 │    check       │                   │                  │
     │                 │───────────────>│                   │                  │
     │                 │  result        │                   │                  │
     │                 │<───────────────│                   │                  │
     │                 │                │                   │                  │
     │                 │ [if duplicate and reject mode: return AS4 error]      │
     │                 │                │                   │                  │
     │                 │ 2. Store doc   │                   │                  │
     │                 │  in inbound_   │                   │                  │
     │                 │  transaction   │                   │                  │
     │                 │───────────────>│                   │                  │
     │                 │                │                   │                  │
     │                 │ [if store fails: return AS4 error] │                  │
     │                 │                │                   │                  │
     │                 │  stored OK     │                   │                  │
     │                 │<───────────────│                   │                  │
     │                 │                │                   │                  │
     │  AS4 Receipt    │                │                   │                  │
     │<────────────────│                │                   │                  │
     │                 │                │                   │                  │
     │                 │ 3. Forward     │                   │                  │
     │                 │───────────────────────────────────>│                  │
     │                 │                │                   │                  │
     │                 │                │                   │  Deliver doc     │
     │                 │                │                   │────────────────>│
     │                 │                │                   │                  │
     │                 │                │                   │  [sync mode:     │
     │                 │                │                   │   C4 country     │
     │                 │                │                   │   in response]   │
     │                 │                │                   │<────────────────│
     │                 │                │                   │                  │
     │                 │ 4. Insert      │                   │                  │
     │                 │  forwarding    │                   │                  │
     │                 │  attempt row   │                   │                  │
     │                 │───────────────>│                   │                  │
     │                 │                │                   │                  │
     │                 │ 5. Update      │                   │                  │
     │                 │  inbound_      │                   │                  │
     │                 │  transaction   │                   │                  │
     │                 │  status        │                   │                  │
     │                 │───────────────>│                   │                  │
     │                 │                │                   │                  │
     │                 │ [sync mode:    │                   │                  │
     │                 │  store         │                   │                  │
     │                 │  reporting     │                   │                  │
     │                 │  record]       │                   │                  │
     │                 │───────────────>│                   │                  │
     │                 │                │                   │                  │

Async Reporting Flow (separate API call from Receiver Backend)

┌──────────┐          ┌──────────┐          ┌────────┐
│Receiver  │          │Reporting │          │   DB   │
│ Backend  │          │   API    │          │        │
└────┬─────┘          └────┬─────┘          └───┬────┘
     │                     │                    │
     │ Report message      │                    │
     │ (AS4 Message ID,    │                    │
     │  C4 country code)   │                    │
     │────────────────────>│                    │
     │                     │                    │
     │                     │ Lookup inbound     │
     │                     │ transaction by     │
     │                     │ AS4 Message ID     │
     │                     │───────────────────>│
     │                     │                    │
     │                     │ transaction data   │
     │                     │<───────────────────│
     │                     │                    │
     │                     │ Store reporting    │
     │                     │ record (C4 country │
     │                     │ + data from SBDH)  │
     │                     │───────────────────>│
     │                     │                    │
     │  OK                 │                    │
     │<────────────────────│                    │
     │                     │                    │

Forwarding Retry Flow (periodic scheduler)

┌──────────┐          ┌────────┐          ┌───────────┐          ┌──────────┐
│Scheduler │          │   DB   │          │Forwarding │          │Receiver  │
│          │          │        │          │  Module   │          │ Backend  │
└────┬─────┘          └───┬────┘          └─────┬─────┘          └────┬─────┘
     │                    │                     │                     │
     │ Query inbound_     │                     │                     │
     │ transaction where  │                     │                     │
     │ status = failed    │                     │                     │
     │───────────────────>│                     │                     │
     │                    │                     │                     │
     │ list of pending    │                     │                     │
     │<───────────────────│                     │                     │
     │                    │                     │                     │
     │ For each:          │                     │                     │
     │                    │                     │                     │
     │  Forward           │                     │                     │
     │─────────────────────────────────────────>│                     │
     │                    │                     │  Deliver doc        │
     │                    │                     │───────────────────>│
     │                    │                     │  result             │
     │                    │                     │<───────────────────│
     │  result            │                     │                     │
     │<─────────────────────────────────────────│                     │
     │                    │                     │                     │
     │ Insert forwarding  │                     │                     │
     │ attempt row        │                     │                     │
     │───────────────────>│                     │                     │
     │                    │                     │                     │
     │ Update inbound_    │                     │                     │
     │ transaction status │                     │                     │
     │───────────────────>│                     │                     │
     │                    │                     │                     │
     │ [if max retries    │                     │                     │
     │  exhausted: notify]│                     │                     │
     │                    │                     │                     │

Inbound Message Metadata

inbound_transaction (one row per received document)

Field Description
Incoming ID Unique ID assigned by phase4 on receipt
AS4 Message ID The AS4 Message ID from the inbound message
SBDH Instance ID The Peppol SBDH Instance Identifier
Business Document ID Optional: the ID from the business document itself
Receiving timestamp Date and time when the message was received
Document bytes The raw received document payload
Transaction Status Current state (received, forwarded, forward_failed, permanently_failed)
Duplicate flag Whether this message was detected as a duplicate
Reporting status Whether the reporting record has been created (pending, reported)
C4 Country Code Country of the final receiver (C4), provided via reporting API or sync response

inbound_forwarding_attempt (one row per forwarding try)

Field Description
Inbound Transaction ID FK to the parent inbound transaction
Attempt timestamp Date and time of this forwarding attempt
Attempt status Outcome of this attempt (success, failed)
Error details Error message or reason for failure (null on success)

Clone this wiki locally