Skip to content

Peppol Ap Admin Applet

Overview

The Peppol AP Admin Applet is the console for operating BigLedger’s own Peppol Access Point, not for a customer’s own Peppol traffic. Where the My Peppol Admin Applet is a tenant looking at its own outgoing and incoming documents, this applet is the access point looking at everything the network delivers to it — the inbox queue that every inbound AS4 message lands in, the history of what was delivered, the tenant-company receiver mappings that decide which customer a document is handed to, and the PINT Malaysia testbed used to prove conformance to OpenPeppol and MDEC.

It is an operations and accreditation tool. It creates no accounting entries, moves no stock, and has no document of its own that can be finalised or voided.

AP here means Access Point, not Accounts Payable. Nothing on this page is about supplier invoices or payables.

Where it fits

UpstreamThis appletDownstream
Any Peppol access point on the network sending an AS4 message to a participant ID that resolves to BigLedgerInbox Queue — one transient row per inbound message (bl_ppl_ap_inbox_queue)PplApInboxQueueProcessor routes the document into the receiving tenant and deletes the queue row
The routed documentInbox History (bl_ppl_ap_inbox_doc_hdr) — the retained access-point recordThe tenant’s own External Reception screens in the My Peppol Admin Applet
Participant registrations created in My Peppol Admin Applet → Peppol Config → RegistrationRegistered Companies (bl_ppl_ap_tnt_comp_receiver_mapping) — the routing table, written by the registration serviceRouting decisions for every inbound document
Sample XML supplied by OpenPeppol / MDEC for accreditationTestbed → Validation Test, Testbed → Sending TestValidation results, and (when the sending path works — see Troubleshooting) test transmissions through the access point

Screens and menus

MenuRouteWhat it showsActions
Inbox Queuepeppol-testbed-receiving-test-queuebl_ppl_ap_inbox_queue, newest first — Sender ID, Receiver ID, Organization ID, Document Creation Datetime, Document Creation Datetime UTC, Document Type ID, Process ID, Payload ID, Lookup Results Status, Lookup Results Endpoint URL, Lookup Results Duration, App Domain, App ModeView only — click a row for the read-only Details tab
Inbox Historypeppol-testbed-receiving-test-historybl_ppl_ap_inbox_doc_hdr, same columns, newest firstView only
Registered Companiesregistered-companiesbl_ppl_ap_tnt_comp_receiver_mapping for one selected tenant — Tenant Code, Tenant Comp Peppol ID, Comp Name, Comp Code, Created Date, Updated Date. A Tenant dropdown at the top lists every tenant on the platform; company name and code are resolved per row through the Company servicePick a tenant; quick search; view only — the Edit screen has a SAVE button that does nothing (see Troubleshooting)
Testbed → Sending Testpeppol-testbed-sending-testbl_ppl_ap_testbed_sending_doc_hdr — Test Name, DescriptionCreate (choose one of the four PINT MY test cases, paste XML, Submit)
Testbed → Validation Testpeppol-testbed-validation-testbl_ppl_ap_validation_test_hdr — Validation Test Name, Validation Test Code, Validation Test Description, Validation Test DateCreate; open a test, upload a ZIP of XML files, Run Checking, Send Only Valid XML; drill into one file to Revalidate or Send
Settingssettings/field-settings, settings/default-selection, plus the shared Webhook, Feature Visibility and Permission Set / User / Team / Role screensSee Configuration
Personalizationpersonalization/personal-default-selection, personalization/sidebarPer-user defaults and sidebar

The Registered Companies grid starts empty: its tenant code defaults to peppolap — the access point’s own tenant, which normally has no mappings of its own — and only fills in once a tenant is chosen from the dropdown.

Two things in the navigation do not do what their labels suggest. The Testbed parent entry (peppol-testbed) is a grouping node with no route of its own, so only its two children are reachable. And the Personalization menu lists a Field Settings item pointing at field-settings, which is not a child route of personalization — selecting it falls through to the applet’s 404 redirect (menu-items.ts vs app.routing.ts, commit 5f24872).

Inside the Inbox Queue listing there is an advanced-search box, but its onSearch handler is empty and the search model it is given is internalSalesOrderSearchModel, copied from the Sales Order applet. Typing in it has no effect. Submit / Export / Withdraw buttons appear in the template as commented-out markup on both the listing and the edit screen; they do not render.

Screenshots needed

No screenshots exist for this applet. A capture session should take: the Inbox Queue listing with rows; the Inbox Queue Details read-only tab; the Registered Companies listing; the Validation Test listing; Validation Test → upload ZIP; the Checking grid showing VALID and INVALID rows with an error message; and the Sending Test input form with the Test Name dropdown open. Because every row on these screens is a real trading party’s identifier, captures must come from a scratch tenant or be redacted before publishing.

Configuration

Before you can use it

PrerequisiteWhereWhy
A session in the access-point tenant (peppolap)Applet installation and loginThe Inbox screens read bl_ppl_ap_inbox_queue and bl_ppl_ap_inbox_doc_hdr with the current tenant’s visa, and those tables are written in BigLedger’s access-point tenant — on an ordinary customer tenant both grids are empty. Registered Companies goes further: it uses a visa pinned to tenant code peppolap (AppConfig.peppolVisa), and the backend returns invalidTenantCode unless the caller is that tenant (TenantCodeConstants.peppolApTenantCode = "peppolap").
A participant registration for each company that should receive documentsMy Peppol Admin Applet → Peppol Config → RegistrationPplApParticipantRegistrationService.insertIntoCompRcvrMapping writes the bl_ppl_ap_tnt_comp_receiver_mapping row from the registration header. There is no way to add a mapping by hand in this applet.
The AS4 receiving endpoint wired to the SPIPlatform configurationPeppolIncomingSBDHandlerSPI.handleIncomingSBD is what creates the inbox-queue row; without it nothing arrives.
The inbox job processor enabledBigLedger supportPplApInboxQueueProcessor is a PRIMARY processor queued RUN_NOW by the SPI. If it is not running, rows pile up in Inbox Queue and no tenant receives anything.
Server-side permissions assignedSettings → Permission Set / Role PermissionEach screen’s data is behind its own permission constant — see below.

Applet settings

There are no working applet settings. The classification is applet-local (the applet defines its own FieldConfigurationComponent rather than importing the shared one from blg-shared-utilities), and both local screens are inert:

  • Settings → Field Settings renders eight slide toggles — Unit Discount, SST/VAT/GST, WHT, Blanket Order, Segment, G/L Dimension, Profit Center, Project — with no formControlName, no form group and a SAVE button with no click handler. These are the labels of a sales-document settings screen and have nothing to do with Peppol. No exposed control found (routes and settings components checked at commit 5f24872).
  • Settings → Default Selection and Personalization → Default Selection offer a Default Branch and a Default Location dropdown, and write DEFAULT_BRANCH / DEFAULT_LOCATION into an APPLET_SETTINGS extension object. Both components are routed directly in app.routing.ts, so their @Input() appletSettings$ and @Output() save are never bound: appletContainer is undefined when a dropdown changes, and the SAVE button emits to nothing.

Neither key is read anywhere in the applet — a repo-wide grep for DEFAULT_BRANCH, DEFAULT_LOCATION, APPLET_SETTINGS and appletSettings at commit 5f24872 returns only the two settings components themselves. Nothing on any screen changes when they are set.

Settings in other applets that control this applet

SettingWhere it is setEffect here
Company Peppol participant ID and registrationMy Peppol Admin Applet → Peppol Config → Registration; the same records appear in the Organisation AppletCreates the receiver mapping row that makes a company routable, and so decides whether an inbound document reaches a tenant at all.

Feature visibility / permissions

No client-side permission definitions are seeded for peppolApAdminApplet (0 rows in bl_applet_client_side_perm_dfn, checked 2026-09-14), and the applet reads no HIDE_* / SHOW_* keys, so the Feature Visibility screen has nothing to gate. Access is decided entirely server-side, per endpoint, from MyPeppolPermissions:

ScreenPermission needed to read
Inbox QueueAPI_TNT_DM_ERP_PPL_AP_INBOX_QUEUE_READ
Inbox HistoryAPI_TNT_DM_ERP_PEPPOL_AP_INBOX_DOC_HDR_READ
Registered CompaniesNo permission constant — PeppolApTntCompReceiverMappingController exposes only /{crossTenantCode}/cross-tenant-login-ep endpoints and gates them on the caller being the peppolap tenant, not on a permission
The Tenant dropdown on Registered CompaniesWhatever the platform Tenant service requires; it is called with the current tenant’s visa, and an empty dropdown is the symptom of not having it
Sending TestAPI_TNT_DM_ERP_PEPPOL_AP_TESTBED_SENDING_DOC_HDR_READ (create needs …_CREATE)
Validation Test listing and createAPI_TNT_DM_ERP_PEPPOL_AP_VALIDATION_TEST_HDR_READ / …_CREATE
Uploaded file listingAPI_TNT_DM_ERP_PEPPOL_AP_VALIDATION_TEST_FILE_ZIP_HELPER_READ
Run Checking and RevalidateAPI_TNT_DM_ERP_PEPPOL_AP_VALIDATION_TEST_FILE_ZIP_HELPER_RUN_CHECKING_READ

A role with none of these opens the applet and sees empty grids rather than an authorisation error.

Fields

Inbox Queue / Inbox History → Details — every control is readonly; this is a viewer, not a form.

FieldMeaning
Sender IDThe sending participant’s Peppol ID, as it arrived in the SBDH
Receiver IDThe receiving participant’s Peppol ID — the value matched against the receiver mapping table
Organization IDThe organisation identifier carried in the envelope
Document Creation Datetime / … UTCCreation timestamp as sent, and its UTC form
Document Type IDThe Peppol document-type identifier (which PINT profile and version)
Process IDThe Peppol process identifier
Payload IDThe unique payload identifier of the AS4 message
Lookup Results Status / Endpoint URL / DurationOutcome of the SMP lookup performed for this message, the endpoint it resolved to, and how long it took
App Domain, App ModeWhich deployment and mode handled the message

Registered Companies → Details — also entirely readonly: Tenant Code, Tenant Comp Peppol ID, Company Name, Company Code, Created Date, Updated Date.

Validation Test → Create

FieldMeaningRequiredNotes
Validation Test CodeShort code for the test runNo validatorStored in bl_ppl_ap_validation_test_hdr.code
Validation Test NameDescriptive nameNo validatorStored in …hdr.name
Validation Test DescriptionFree textNo validatorStored in …hdr.description

Sending Test → Create

FieldMeaningRequiredNotes
Test NameOne of four fixed PINT Malaysia test cases: PINT-TC-BISC1-1 (MY Invoice to MY recipient), -2 (MY Credit Note), -3 (MY Self Billing Invoice), -4 (MY Self Billing Credit Note)No validatorThe list is hard-coded in the component, not fetched
XMLThe document to send, pasted as textNo validator

Checking grid (Validation Test → open a test → open an uploaded ZIP): No., File Name, File Size, File Format, Validation Status, Validation Error, Error Message, User Error Message, Created Date, Updated Date — one row per XML file found in the ZIP (bl_ppl_ap_validation_test_file_zip_helper).

Lifecycle and effects

This is a master-data and operations applet. It has no server document type, no amount or quantity signum, no journal and no stock processor; nothing here is finalised or voided.

Receiving — what happens to an inbound document

  1. An AS4 message arrives. PeppolIncomingSBDHandlerSPI.handleIncomingSBD parses the Standard Business Document and calls MyPeppolReceivingInboxService.insertIntoPplApInboxQueue, which writes one bl_ppl_ap_inbox_queue row in the access point’s database, then queues PplApInboxQueueProcessor with ExecutionStrategy.RUN_NOW.
  2. PplApInboxQueueProcessor.processEvent copies the queue row into bl_ppl_ap_inbox_doc_hdr (bl_ppl_ap_inbox_doc_hdr.fromBl_ppl_ap_inbox_queue) — this is the permanent access-point record shown in Inbox History.
  3. It then reads bl_ppl_ap_tnt_comp_receiver_mapping by the message’s receiver Peppol ID (PeppolApTntCompReceiverMappingUow.getByCompanyPeppolId). For every mapping found it opens that tenant’s database, creates a bl_ppl_from_peppol_doc_hdr_queue row from the inbox document header, and queues FromPeppolDocHdrQueueProcessor inside that tenant.
  4. Finally it permanently deletes the bl_ppl_ap_inbox_queue row (deletePermanent).

Two consequences follow directly, and they are the two facts an operator needs. Inbox Queue is transient — under normal operation it is empty, because rows are deleted microseconds after they are written; a row sitting in it means the processor has not run. And a receiver ID with no mapping is not an error — the loop simply finds nothing to iterate, the inbox document header is still written, and the message is silently not delivered to any tenant.

Registration — how a mapping appears

Registered Companies is written by PplApParticipantRegistrationService.insertIntoCompRcvrMapping, which copies the tenant GUID, tenant code, company GUID and participant ID from a bl_ppl_ap_participant_registration_hdr when a registration succeeds. The applet only reads the table.

Validation Test — what “Run Checking” actually checks

Run Checking calls GET …/ppl/ap/validation-test-file-helper/run-checking/{zip_hdr_guid}/backoffice-ep, which runs PeppolApValidationTestFileZipHelperService.validateAndUpdateZipHelper over every file extracted from the ZIP. For each file:

  • the document type is inferred from the file name — a name containing invoice selects the invoice rules, a name containing creditnote the credit-note rules, anything else yields an empty type;
  • the XML is validated against the PINT UBL schematron for that type (peppol/<doctype>/PINT-UBL-validation-preprocessed.sch) using the Ph schematron engine;
  • it is validated a second time against the Malaysian jurisdiction rules (peppol/pint-my/1.0.0/xslt/billing/PINT-jurisdiction-aligned-rules.xslt), whose failed assertions are collected from the SVRL output;
  • one assertion is deliberately dropped before the verdict — [ibr-119]-A time MUST be formatted hh:mm:ss with optional fractional seconds .sss and time zone expression (ibt-168).;
  • if nothing remains, validation_status is set to VALID and error_message cleared; otherwise INVALID with the collected texts. The row’s updated_date is stamped either way.

Revalidate on a single file posts the XML to …/validate-document-one-by-one/backoffice-ep?docType=… and returns either the failure texts or the single token THIS_DOCUMENTS_IS_VALID.

Uploading a ZIP dispatches uploadAttachmentsInit, which calls PeppolAPTestbedValidationTestZipHdrService.addAttachment against the open validation test’s GUID. The success toast reads “Upload Image Successful” — a label inherited from the applet this screen was cloned from. Delete and download effects exist in the same file but are commented out, so the delete and download buttons on the uploaded-file screen dispatch actions nothing handles.

SendingSend Only Valid XML and the per-file Send are described under Troubleshooting; at commit 5f24872 they call a URL the backend does not serve.

Related applets

  • My Peppol Admin Applet — the tenant-side counterpart. Registrations made there create the receiver mappings listed here, and documents routed from here surface there under External Reception.
  • My E-Invoice Admin Applet — the parallel LHDN pipeline; it shares the mandatory-field check but not this applet’s data.
  • Organisation Applet — holds the company Peppol status and participant IDs that a registration is built from.

Troubleshooting

SymptomCauseFix
Rows accumulate in Inbox Queue instead of clearingPplApInboxQueueProcessor is not running. The SPI queues it RUN_NOW; when it runs it deletes the row it processed, so a non-empty queue is by itself the symptom.Ask support to check the job processor on the access-point tenant. The documents are not lost — they are re-processed when it resumes.
A document appears in Inbox History but the customer never received itNo bl_ppl_ap_tnt_comp_receiver_mapping row matches the message’s Receiver ID. The processor writes the history row first and then iterates an empty mapping list — nothing fails, nothing is delivered.Check the receiver ID against Registered Companies. If it is missing, complete the participant registration for that company in the My Peppol Admin Applet; registration is what writes the mapping.
The same document is delivered to two tenantsgetByCompanyPeppolId returns every mapping for that participant ID and the processor loops over all of them. A duplicate registration produces a duplicate delivery.Remove the stale registration; there should be one mapping per participant ID.
Registered Companies → Edit → SAVE appears to do nothingIt does nothing. onSubmit() writes the form to the browser console and the rest of the handler is commented out; every field on the form is readonly anyway.Do not try to correct a mapping here. Fix it at the registration.
Run Checking fails with a server error for a whole ZIPThe document type is taken from the file name. A file whose name contains neither invoice nor creditnote yields an empty type, the schematron resource path peppol//PINT-UBL-validation-preprocessed.sch does not resolve, and the resulting FileNotFoundException is rethrown as a RuntimeException that aborts the run for every file in the ZIP.Name each file so it contains invoice or creditnote — for example PINT-MY-invoice-01.xml, PINT-MY-creditnote-01.xml — and upload again.
A file is reported VALID although it has a malformed timeThe [ibr-119] time-format assertion is removed from the result list before the verdict is decided.Expected behaviour of this build; validate time formats separately if they matter to you.
Send Only Valid XML or the per-file Send returns a 404The front end calls …/ppl/ap/validation-test-file-helper/send-all/{guid}/backoffice-ep and …/send-valid-one/{guid}/backoffice-ep. The backend registers both of those only under …/ppl/ap/validation-test-file-**helper-sending**/…; the non-sending controller exposes only delete, read, run-checking and validate-document-one-by-one. The same wrong base path is in the applet’s own copy of the service and in blg-akaun-ts-lib.Use the validation results only; sending from the testbed needs the front-end fix. Both calls also hard-code accesspoint_id=1001, which is not configurable from the UI.
Sending Test → Submit toasts Send Successfully but nothing is sentThe effect builds an eventcontainer variable it never assigns and POSTs that undefined body to the coupon event service — a leftover from the voucher applet this one was cloned from. No Peppol endpoint is called.Treat the Sending Test screen as not implemented at commit 5f24872.
The Inbox Queue advanced search does nothingonSearch is an empty method and the search model supplied is the Sales Order one.Sort and filter with the grid’s own column filters instead.
Personalization → Field Settings shows the 404 pageThe menu entry points at a route that is not registered under personalization.Use Settings → Field Settings (which is itself inert — see Configuration).

Related documentation

Last updated on