Wednesday, 24 September 2025

Consuming EUDR Webservices from SAP ECC

  • There are number of us who're still stuck in the old SAP ECC or S/4 Hana on Premise and yet to move into Private or Public Cloud. A recent regulation in Europe requires us to implement tracebility on products produced by our plants. A requirement requires us to automatically submit the Due Diligent Statement (DDS) to EUDR website to compliance with the EUDR. For this, APIs have been developed to do just that, submitting DDS and getting the reference number and verification number. The APIs are available via Webservices, and to implement this, it is not that hard since SAP has automate the generation of consumer proxy and all required objects based on the WSDL available from EUDR. During first few Conformance Test (CF) that I've tested so far, there are few that probably will be helpful to point out: 
  • After you've loaded and generate the WSDL, using SOAMANAGER, you need to configure logical port. This is where you specified the end point, the username/password etc. In the first CF, this is the easiest one to just ping the server, sending hello in the payload with the correct cridential and header. However, for me, this is not a straight forward thing. 
    1. In SOAMANAGER, while creating logical port, you need to create logical port with "WSDL based configuration with template", and for the template, you need to use the "WSSE_USERNAMETOKEN". This will make the username/password appear in the next step. You need to use your username and authentication key you've created in the system (for testing, we need to get it from acceptance system). Finish the rest and save/activate the logical port. 
    2. While testing the generated class and sending the "hello" in the payload for CF1, I found out that SAP is sending a password and not a password digest as required by EUDR server. From my almost full day of debugging and trying so many options, I finally said that there will be no way that we could configure SAP to send a password digest, so at the end, I do what most of us trying not to do... implicit enhancement! 
    3. The implicit enhancement to Class CL_WSSE_FT_OUT_CFG and method GET_ST_CFG_711. At the end of the method, I put the following codes (this will trigger the passworddigest).   
     IF lf_supp_tk_type = co_t_type_unt.
     DATA(lv_soapaction) = to_upper( get_cfg_value( name = tsrtp_f_bdg_action ) ).            IF lv_soapaction CS 'EUDR' AND unt_st_cfg-digest_type IS INITIAL.                      unt_st_cfg-digest_type = abap_true.
     ENDIF.

          ENDIF.

  • I'm using the SOAPAction field since it has EUDR defined there in the WSDL and I don't want the enhancement gets triggered by other consumer proxy that doesn't have the same requirement for the authentication method. 2. There is also a requirement in the API for us to send a custom tag in the SOAP header. We need to add <v4:WebServiceClientId>eudr-test</v4:WebServiceClientId>  in the SOAP header. The only way to do this is in ABAP, when you call your proxy, you need to inject this custom tag to the header. I managed to do this using the following codes:
            DATA: lr_xml_document TYPE REF TO if_ixml_document,

          lr_xml_element  TYPE REF TO if_ixml_element.

    TRY.
        DATA(lo_ws_header) = CAST if_wsprotocol_ws_header( mr_interface->get_protocol( if_wsprotocol=>ws_header ) ).
      CATCH cx_ai_system_fault.
        RETURN.
      CATCH cx_ai_application_fault.
        RETURN.
    ENDTRY.

    CONCATENATE
      '<env:Header>'
      '<v4:WebServiceClientId xmlns:v4="http://ec.europa.eu/sanco/tracesnt/base/v4">'
      client_id
      '</v4:WebServiceClientId>'
      '</env:Header>' INTO DATA(lv_header).

    DATA(lv_xheader) = cl_proxy_service=>cstring2xstring( lv_header ).

    CALL FUNCTION 'SDIXML_XML_TO_DOM'
      EXPORTING
        xml      = lv_xheader
      IMPORTING
        document = lr_xml_document
      EXCEPTIONS
        OTHERS   = 0.

    DATA(lr_xml_root) = lr_xml_document->get_root_element( ).
    lr_xml_element ?= lr_xml_root->get_first_child( ).

    WHILE NOT lr_xml_element IS INITIAL.
      DATA(l_name) = lr_xml_element->get_name( ).
      DATA(l_namespace) = lr_xml_element->get_namespace_uri( ).
      lo_ws_header->set_request_header(
                  name      = l_name
                  namespace = l_namespace
                  dom       = lr_xml_element ).
      lr_xml_element ?= lr_xml_element->get_next( ).
    ENDWHILE.


  • The next that I found during the CF2 is, I need to send the geojson and this needs to be in base64 and since the xsd refered as base64Binary, the geojson code needs only be converted from the JSON to xstring. No further process needed, SAP will convert it to base64 automatically during the XML creation. 

I will update the blog as and when I find new things. Till then have fun!!!

No comments:

Consuming EUDR Webservices from SAP ECC

There are number of us who're still stuck in the old SAP ECC or S/4 Hana on Premise and yet to move into Private or Public Cloud. A rece...