eDocuments or eInvoices are common these days. In many countries, companies needs to send invoice related data to government portals due to legal requirements. Even if the target formats are standardized (at least provided by governments), companies might need to change the XML content before sending out.
This blog explains how to do this for Poland in KSeF FA(3) format
SAP provides a BAdI named EDOC_ADAPTOR, which defines a method SET_OUTPUT_DATA. This method can be implemented to change the content before sending the XML document. This BAdI can be implemented for any country and there are many blogs and other resources available explaining on how to do so.
So why do I need to write the n+1 instruction on this?
What's the issue here?
This week, I was challenged with changing the content of eDocuments related to Poland. I already did this in past for other countries, so I felt comfortable in doing this. Create a BAdI Implementation, filtered by country PL, change content and I'm done.
Method SET_OUTPUT_DATA of BAdI provides a changing parameter CS_OUTPUT_DATA. This is pre-filled with the content generated by the eDoc framework.
If one need to tweak the data, CS_OUTPUT_DATA is the one which needs to be change, right?
Right!
But you might notice, that CS_OUTPUT_DATA seems to be somewhat of empty in case of KSeF. It's a deep structure with nested tables, but everything is initial. If you try visualize content of XML in EDOC_COCKPIT, XML shows up.
Why can you visualize data in EDOC_COKPIT if CS_OUTPUT_DATA is not filled at all? How can I change data, if system doesn't provide the outcome of framework?
CS_OUTPUT_DATA structure is empty
Solution
There is an OSS note https://me.sap.com/notes/3346323/E#Topic_F, which describes the issue and provides a small hint on what you need to do. Surprisingly, the note was released on 27th March 2026. As of this writing, it has been released TODAY. It feels like I'm the first person coming across this issue
The content is available in CS_OUTPUT_DATA-INVOICE-INVOICE_CONTENT but in an encoded manner.

How to change the content
- fetch data from CS_OUTPUT_DATA-INVOICE-INVOICE_CONTENT
- decode base64 content of 1 into XSTRING
- convert XSTRING into ABAP structure. XSTRING here is the XML itself
- change your data in ABAP structure
- convert ABAP structure back into XML XSTRING representation
- encode XString into base64 format
- return this as CS_OUTPUT_DATA-INVOICE-INVOICE_CONTENT
METHOD if_edoc_adaptor~set_output_data.
DATA io_edocument TYPE REF TO cl_edocument.
DATA xml_content_in TYPE xstring.
DATA output_data TYPE edo_pl_faktura3.
FIELD-SYMBOLS <output> TYPE edo_pl_send_invoice_type.
" read data provided by framework
ASSIGN cs_output_data TO <output>.
DATA(edoc_content) = <output>-invoice-invoice_content.
" decode Base64 encoded FA(3) Invoice to XString
CALL FUNCTION 'SCMS_BASE64_DECODE_STR'
EXPORTING input = edoc_content
* unescape = 'X'
IMPORTING output = xml_content_in
EXCEPTIONS failed = 1
OTHERS = 2.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
TRY.
" convert XML XString into ABAP structure
cl_proxy_xml_transform=>xml_xstring_to_abap( EXPORTING ddic_type = 'EDO_PL_FAKTURA3'
xml = xml_content_in
IMPORTING abap_data = output_data ).
CATCH cx_proxy_fault.
CATCH cx_transformation_error.
ENDTRY.
" CHANGE DATA HERE
" add your logic here
" CHANGE DATA HERE
" convert new output data to XML XString
DATA(xml_content_out) = cl_proxy_xml_transform=>abap_to_xml_xstring( abap_data = output_data
ddic_type = 'EDO_PL_FAKTURA3' ).
" encode XML XString to Base64 and use it as new output data
CALL FUNCTION 'SCMS_BASE64_ENCODE_STR'
EXPORTING input = xml_content_out
IMPORTING output = <output>-invoice-invoice_content.
ENDMETHOD.I found no resources about this issue and only one OSS note. I leave my solution here hoping someone else who comes across this situation will benefit. I'm glad if this saves you some hours of reading and debugging.