Introduction
Belgium's and Germany's B2B eInvoicing mandate requires invoices to be exchanged via the Peppol network in UBL 2.1 format. For companies that use Evaluated Receipt Settlement (ERS) – where the buyer automatically creates and sends an invoice on behalf of the supplier based on goods receipt – SAP's eDocument framework generates self-billing invoices through the INV_VERIF source type.
However, a known issue causes standard MIRO postings (manual supplier invoice entry) to also trigger self-billing eDocument creation in the eDocument Cockpit, even when no ERS process is involved. This occurs because the current Belgium / Germany self-billing scope in SAP does not differentiate between MIRO with ERS and MIRO without ERS: both use the same INV_VERIF source type, and both trigger eDocument creation when self-billing settings are active in EDOINVVERV.
Note: SAP KBA 3718221 documents an identical issue for Poland (KSeF) and proposes a customer-side BAdI workaround as a temporary measure. This blog post extends that approach for Belgium and Germany, replaces the fragile transaction-code check with a semantically correct ERS flag check at purchase order item level, and provides a sample implementation.
This blog post describes how to use BAdI EDOC_ADAPTOR with method IS_RELEVANT to suppress eDocument creation for INV_VERIF postings that do not originate from an ERS run, while preserving it for genuine ERS-based self-billing invoices.
Scope Note: This blog covers SAP S/4HANA on-premise and S/4HANA Cloud Private Edition using BAdI EDOC_ADAPTOR. For SAP S/4HANA Cloud Public Edition (ABAP Environment), the equivalent BAdI is EDOC_ADAPTOR_CLOUD. The logic is identical, but the method signature differs – the Cloud variant is described at the end of this post.
Root Cause
When self-billing is configured for Belgium in EDOINVVERV (transaction EDOIVV – Assign eDocument Type to Invoice Verification Transaction), the framework creates an eDocument for every posted incoming invoice that matches the configured eDocument type. The framework has no built-in mechanism to distinguish:
Posting path Business intent Current eDocument result
| MRRL (ERS run) | Self-billing – buyer creates invoice on supplier's behalf | eDocument created ✓ |
| MIRO (standard incoming invoice) | Supplier sends invoice – no self-billing | eDocument created ✗ (unintended) |
BAPI_INCOMINGINVOICE_CREATE1 (non-ERS) |
Programmatic standard invoice entry | eDocument created ✗ (unintended) |
The configuration table T003EDOC (document type → eDocument type) is not used for the INV_VERIF source type; control lies entirely with EDOINVVERV. There is therefore no standard configuration switch to restrict eDocument creation to ERS postings only.
Why the ERS Flag on the PO Is the Right Signal
SAP KBA 3718221 suggests checking BKPF-TCODE (e.g. MRRL vs MIRO) as the differentiator. This approach is fragile because:
- Programmatic postings via
BAPI_INCOMINGINVOICE_CREATE1may carry an arbitrary or blank TCODE, making the check unreliable. - Background ERS batch jobs may post under a different TCODE than the interactive session.
The ERS indicator XERSY on table EKPO is set at purchase order creation time and expresses the business configuration intent: this PO item is to be settled through Evaluated Receipt Settlement. When MRRL runs, it exclusively processes PO items where EKPO-XERSY = 'X'. This flag is stable across all posting channels and correctly captures the business intent regardless of whether the posting originated from an interactive transaction, a batch job, or a BAPI call.
Navigation path:INV_VERIF source key → RBKP BELNR + GJAHR → RSEG-EBELN / RSEG-EBELP → EKPO-XERSY
Prerequisites
Functional / Configuration Side
- The Belgium / Germany self-billing eDocument scenario is configured and active in
EDOINVVERVfor the relevant company code. - You can verify this in the Manage Electronic Documents app: after an MRRL run, a self-billing document should appear under the country process with status Created (In Process).
- ERS is configured on the relevant purchase orders (
EKPO-XERSY = 'X'). You can verify this on the PO item → Invoice tab → ERS checkbox.
ABAP / Developer Side
- BAdI
EDOC_ADAPTORis available in the system (verify via SE18). - A custom BAdI implementation will be created as described below.
- The relevant filter values are:
Filter Value
COUNTRY |
BE or DE |
GENERIC_FILTER |
(leave empty – see note below) |
Filter note: The
GENERIC_FILTERvalue for Peppol's country INV_VERIF processing is typically empty. If the BAdI does not get called after activation, debug theCL_EDOC_ADAPTOR=>GET_INSTANCEcall during an INV_VERIF posting to identify the exact filter value being passed, and update the BAdI registration accordingly. The source type guard insideIS_RELEVANTprovides an additional safety net regardless of filter scope.
Implementation: BAdI EDOC_ADAPTOR
Create the BAdI Implementation
-
Go to transaction SE18 and search for BAdI
EDOC_ADAPTOR. -
Create a new implementation, e.g.
ZEI_EDOC_ADAPTOR_BE_ERS. -
Set the filter values:
Filter Value
COUNTRYBEGENERIC_FILTER(leave empty) -
Navigate to method
IF_EDOC_ADAPTOR~IS_RELEVANTand add the implementation described in the following sections. -
Activate the BAdI implementation.
Step 1: Guard on Source Type and Downcast the Source Object
The first step is to verify that the document being processed is an INV_VERIF invoice verification document. If it is not – for example, if the BAdI fires for an SD Invoice because of a broad filter – the method exits immediately without modifying CX_RELEVANT, leaving the default framework behaviour intact.
Step 2: Check the ERS Indicator on Referenced PO Items
The DOCUMENT_ITEM component of the source data contains the RSEG line items for this MM invoice. Each row that references a purchase order carries EBELN (PO number) and EBELP (PO item). The ERS indicator lives on EKPO-XERSY. For API usage reasons, we utilize CDS view I_PurchaseOrderItemAPI01 in S/4HANA Cloud Private Edition or on premise Releases.
The relevant decision logic is:
ERS flag (EKPO-XERSY) on referenced PO items CX_RELEVANT result
At least one item has XERSY = 'X' |
abap_true – eDocument created |
| No PO references at all | abap_false – eDocument suppressed |
PO references exist but none have XERSY = 'X' |
abap_false – eDocument suppressed |
Complete Source Code
CLASS zcl_edoc_adaptor_be_ers_chk DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_badi_interface.
INTERFACES if_edoc_adaptor.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_edoc_adaptor_be_ers_chk IMPLEMENTATION.
* ─────────────────────────────────────────────────────────────────────────────
* IS_RELEVANT: suppress eDocument creation for INV_VERIF postings that do not
* originate from an ERS run (MRRL). The check is based on the ERS indicator
* EKPO-XERSY on the purchase order items referenced by the invoice verification
* document - not on BKPF-TCODE, which is unreliable for BAPI-based postings.
* ─────────────────────────────────────────────────────────────────────────────
METHOD if_edoc_adaptor~is_relevant.
DATA: lt_purchase_order_item TYPE STANDARD TABLE OF i_purchaseorderitemapi01 WITH DEFAULT KEY.
DATA: ls_inv_verif_src_data TYPE edoc_src_data_invoice_verif.
CASE io_source->mv_source_type.
WHEN cl_edoc_source_invoice_verif=>gc_src_inv_verif.
io_source->get_data( IMPORTING es_data = ls_inv_verif_src_data ).
WHEN OTHERS.
RETURN.
ENDCASE.
IF ls_inv_verif_src_data-document_item IS INITIAL.
cx_relevant = abap_false.
RETURN.
ENDIF.
" Check ERS indicator on the referenced PO items.
SELECT purchaseorder, purchaseorderitem, evaldrcptsettlmtisallowed
FROM i_purchaseorderitemapi01
FOR ALL ENTRIES IN _inv_verif_src_data-document_item
WHERE purchaseorder = _inv_verif_src_data-document_item-ebeln
AND purchaseorderitem = _inv_verif_src_data-document_item-ebelp
INTO CORRESPONDING FIELDS OF TABLE _purchase_order_item PRIVILEGED ACCESS.
READ TABLE lt_purchase_order_item WITH KEY evaldrcptsettlmtisallowed = abap_true TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
cx_relevant = abap_false.
ENDIF.
ENDMETHOD.
" ── Remaining IF_EDOC_ADAPTOR methods: no-op stubs required by framework ──
METHOD if_edoc_adaptor~change_edocument_type. ENDMETHOD.
METHOD if_edoc_adaptor~change_form. ENDMETHOD.
METHOD if_edoc_adaptor~get_variable_key. ENDMETHOD.
METHOD if_edoc_adaptor~restrict_cancel. ENDMETHOD.
METHOD if_edoc_adaptor~set_output_data. ENDMETHOD.
ENDCLASS.
Result and Verification
Once the BAdI implementation is active, verify the end-to-end behaviour using the following test scenarios.
Scenario 1 – Standard MIRO Posting (should be suppressed)
- Post an incoming invoice via MIRO against a purchase order that does not have the ERS indicator set (
EKPO-XERSYis blank). - Open the Manage Electronic Documents app and filter for the company code and the posting date.
- Confirm that no eDocument was created for this posting.
Scenario 2 – ERS Run via MRRL (should be created)
- Run an ERS settlement via transaction MRRL for a purchase order where
EKPO-XERSY = 'X'and a goods receipt has been posted. - Open the Manage Electronic Documents app.
- Confirm that a self-billing eDocument was created and appears under the Belgium eInvoice process with status Created (In Process) or Sent.
Scenario 3 – MIRO Against an ERS-Enabled PO (edge case – eDocument created by design)
- Post an incoming invoice via MIRO against a purchase order where
EKPO-XERSY = 'X'. - Confirm that an eDocument is created.
This edge case is intentional: the PO was explicitly configured for ERS, so the system treats any posting against it as potentially self-billing. If the customer also posts regular MIRO invoices against ERS-enabled POs and wishes to suppress eDocuments for those, an additional BKPF-TCODE check can be layered inside IS_RELEVANT. However, be aware that this check may break for BAPI_INCOMINGINVOICE_CREATE1 and background jobs.
Behaviour Matrix
Posting path EKPO-XERSY on referenced items eDocument outcome
| MRRL (ERS run, interactive) | X on all items |
Created ✓ |
| MRRL (ERS run, background / batch) | X on all items |
Created ✓ |
| MIRO, standard supplier PO (no ERS) | blank | Suppressed ✓ |
| MIRO against ERS-enabled PO | X |
Created (see Scenario 3) |
Cloud Note – EDOC_ADAPTOR_CLOUD
For SAP S/4HANA Cloud Public Edition (ABAP Environment), the BAdI to implement is EDOC_ADAPTOR_CLOUD with interface IF_EDOC_ADAPTOR_CLOUD. The IS_RELEVANT method receives different parameters: the source is not passed as an object but as a packed key and a generic source data structure.
METHOD if_edoc_adaptor_cloud~is_relevant.
DATA: lt_purchase_order_item TYPE STANDARD TABLE OF i_purchaseorderitemapi01 WITH DEFAULT KEY.
IF iv_source_type NE 'INV_VERIF' OR is_source_data-invoice_verif_item IS INITIAL.
cv_relevant = abap_false.
RETURN.
ENDIF.
" Check ERS indicator on the referenced PO items.
SELECT purchaseorder, purchaseorderitem, evaldrcptsettlmtisallowed
FROM i_purchaseorderitemapi01
FOR ALL ENTRIES IN _source_data-invoice_verif_item
WHERE purchaseorder = _source_data-invoice_verif_item-ebeln
AND purchaseorderitem = _source_data-invoice_verif_item-ebelp
INTO CORRESPONDING FIELDS OF TABLE _purchase_order_item PRIVILEGED ACCESS.
READ TABLE lt_purchase_order_item WITH KEY evaldrcptsettlmtisallowed = abap_true TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
cv_relevant = abap_false.
ENDIF.
ENDMETHOD.
BAdI filter for the Cloud variant:
Filter Value
COUNTRY |
BE |
GENERIC_FILTER |
(leave empty – verify as described in Prerequisites) |
Important Caveats
This Is a Workaround, Not a Standard SAP Fix
SAP has confirmed (via KBA 3718221 for Poland) that this BAdI suggestion is a customer-side workaround only. SAP cannot provide further support for custom BAdI implementations. A central, standard SAP solution – likely involving a new configuration table to restrict INV_VERIF eDocument creation to ERS-based postings – is not available as of Q2 2026.
The BAdI implementation described in this post is entirely contained within the customer namespace (Z/Y) and has no impact on SAP standard objects. It can be deactivated in SE19 without any code change the moment SAP delivers a standard update.
Scope: Belgium Only in This Post
The same root cause exists in any country where self-billing via INV_VERIF is configured. The same BAdI pattern – with the appropriate country filter – can be applied to other countries affected by KBA 3718221 or equivalent. The ERS flag check at PO level is country-neutral.
Summary
In this blog post, we covered how to prevent unintended self-billing eDocument creation for standard MIRO postings in Belgium using BAdI EDOC_ADAPTOR / method IS_RELEVANT on SAP S/4HANA on-premise.
Key takeaways:
- Both MIRO and MRRL use the same
INV_VERIFsource type – the standard eDocument Framework cannot distinguish between them when self-billing settings are active inEDOINVVERV. - Checking
BKPF-TCODE(as suggested in KBA 3718221 for Poland) may be unreliable for BAPI-based postings. The ERS indicatorEKPO-XERSYis the preferred signal. - The implementation casts the source object to
CL_EDOC_SOURCE_INVOICE_VERIF, uses the already-loaded RSEG items from memory, and makes a singleFOR ALL ENTRIESselect againstEKPO– no redundant database reads. - BAdI filter:
COUNTRY = BE or DE,GENERIC_FILTER = (empty). - For SAP S/4HANA Cloud Public Edition, use BAdI
EDOC_ADAPTOR_CLOUD– the logic is identical, the method signature differs (source key instead of source object). - This is a temporary workaround pending a central SAP solution. The BAdI can be deactivated in SE19 at any time without code changes.



