Rossum Integration (3): AI-based Invoice Data Capture Integration with S/4HANA
In this week’s installment of our series of Rossum integration success stories, we’re pleased to present an abridged version of a post written by certified SAP consultant Kimveasna Pen. More technical than our usual blog posts, this article will provide you with an understanding of how easily you can work with the Rossum API as an SAP developer.
We’re thrilled that a growing number of SAP experts like Mr. Pen clearly see the value of integrating Rossum’s automated document data extraction solution into enterprise resource planning (ERP) systems. We appreciate the time he took to share his Rossum experience and demonstrate the simplicity and effectiveness of this integration.
Introduction
I recently discovered Rossum, an AI-powered document data capture tool. This is not a traditional optical character recognition (OCR) solution, but an AI platform that recognizes data fields then extracts data from those fields for you to export to your SAP system.
I really like the company’s trial offer, which gives you time to work with and evaluate the platform free of charge, with no obligation to subscribe. This is a surprisingly uncommon approach, as invoice data capture solution providers in the SAP landscape usually require you to speak with their sales representatives before you can get your hands on their products.
The Rossum API is simple, efficient, and well-documented, so you can get started with SAP integration in no time. To show you what I mean, I will take you through a simple demo use case.

- First, we create a purchase order (PO) with 2 line items in S/4HANA.

- Next, we print a simple supplier invoice for the PO we just created – to save paper, we can print it as a PDF
- If we print a paper copy, we’ll need to scan the paper invoice and save that scan as an image file (PNG or JPEG)

- We upload the invoice PDF or image file to Rossum
- The platform automatically annotates and captures data
- We manually check and validate the captured data – the intuitive UI makes this step quick and easy, as shown in the example below

- Rossum automatically exports the invoice data it just captured to S/4HANA, which posts the corresponding incoming invoice document.

To execute the process I just outlined, we will need to carry out these implementation steps:
- Set up accounts in both Rossum and S/4HANA, adjusting settings according to our needs
- Analyze and understand API message payloads with a REST client (Postman)
- Extend the Rossum data fields schema by adding a custom field containing the SAP supplier code
- Implement the hook listening on initial extraction and user updates for simple supplier matching to retrieve the SAP supplier code from name
- Implement the hook listening to export event to transfer data extracted from invoices to S/4HANA
The final process will look like this:
Setup
Rossum
We must first set up our Rossum account, which we can start using after we take a few minutes to complete the simple registration process. We can upload invoices and check out Rossum’s automated data extraction capabilities immediately, with no overwhelming setup or training.
To explore Rossum’s API, we can set up our demo either directly within Rossum or by using the rossum command line tool.
SAP S/4HANA
We need to make sure that OData services for Business Partner and Supplier Invoices are activated in /IWFND/MAINT_SERVICES: API_BUSINESS_PARTNER and API_SUPPLIERINVOICE_PROCESS_SRV.
API: understanding annotation structure
The Rossum API is easy to use. Every request must be authorized by a token, which is provided as we login.
- Login and retrieve authentication token

Field value key in response payload is our authorization token, and must be provided in our request headers.
- Retrieve queues (in our case, only one is available)

- Retrieve annotations from queue

The annotation structure is exactly as it is on the validation screen:

Extend the schema with the custom SAP Supplier field
We can extend the Rossum schema directly with the schema editor. Just open the schema editor, copy-paste one of the field snippets, and tweak it as you see fit to define a new field:

After saving our new field, it will be available and visible in the settings:

Now SAP Supplier ID is directly available to us as a data field. We can follow the steps outlined above to add as many custom fields as we want, including SAP Material Code, SAP Company Code, and SAP Transaction Codes. To keep this demo simple, we’ll stick with one custom field.
Note: Mr. Pen’s post in the SAP Community Blog recommends using the “elisctl” tool to edit a schema. Since its publication, we’ve updated Rossum and now recommend using the schema editor directly within the Rossum application.
The new added field is just a placeholder for now: Rossum is not going to magically determine our backend supplier code as this number does not appear on our invoice. We could have the end-user manually enter it during the validation step, but this defeats the purpose of automated data capture. This is where the Rossum extension comes into play.
In the next step, we will declare a custom hook that will be triggered during validation: the “validate” extension. This extension will call the OData service API_BUSINESS_PARTNER (visit the SAP Portal for more information on implementing this OData service in SAP) and match a supplier code with the supplier name as recognized by Rossum.
Implement the custom hook validate
Declare a custom plugin – use the endpoint connector to post a new extension, which is simply a name and a url. Pay attention to the authorization token: it is our responsibility to only authorize requests providing this token (it is up to us to determine the token value/validation in our code).

The extension is an external microservice (at the given service URL) and needs to run somewhere. One alternative is to get an actual server or cloud instance to run it. But a hassle-free service to implement these hooks without running a server is using Firebird Cloud Functions, as I explained in another post. We could also do the same with AWS lambda.
Once we’ve declared our extension, we need to implement the endpoint function /validate. This function is called every time invoice data is updated.
To get the supplier name from the hook payload (see the original post for a sample), we will loop over all datapoints in search of the supplier name by checking schema_id. Once we have this, we will call our SAP backend OData service to match it with the SAP Supplier Number. Finally, we will update our custom SAP Supplier ID datapoint in Rossum with the correct number by responding to the hook call with this message.
{ "messages": [ { "content": "SAP Supplier <name> is matched with SAP number <sap_code>", "id": "<datapoint_id (=137835750 in sample)>" "type": "info" } ], "updated_datapoints": [ { "id": "<datapoint_id (=137835750 in sample)>", "value": "<sap_code>" } ] }

A sample implementation of /validate is available in the full version of this post.
Implement custom hook save
As with the previous section, implement endpoint /save. In this part, we will integrate Rossum data as a supplier invoice in S/4HANA.
The incoming payload has the same structure as for /validate, and no response payload is expected in case of successful processing, just HTTP status code 204.
Creating an invoice in S/4HANA is as easy as posting OData service API_SUPPLIERINVOICE_PROCESS_SRV with the following payload:
{ "CompanyCode": "1710", "DocumentDate": "/Date(1574208000000)/", "PostingDate": "/Date(1574208000000)/", "SupplierInvoiceIDByInvcgParty": "Vendor invoice number", "InvoicingParty": "17300032", "DocumentCurrency": "USD", "InvoiceGrossAmount": "120000.00", "to_SuplrInvcItemPurOrdRef": [ { "SupplierInvoiceItem": "1", "PurchaseOrder": "4500000004", "PurchaseOrderItem": "10", "Plant": "1710", "TaxCode": "I1", "DocumentCurrency": "USD", "SupplierInvoiceItemAmount": "120000.00", "PurchaseOrderQuantityUnit": "PC", "QuantityInPurchaseOrderUnit": "30", "PurchaseOrderPriceUnit": "PC", "QtyInPurchaseOrderPriceUnit": "30" } ] }
Our /save function is not very complex: we start by parsing an annotation in a key-value structure, then call the API in two steps: first GET to retrieve the CSRF token and cookie, then POST to actually create the supplier invoice. For details, see the full version of this post.
Conclusion
The simplicity and efficiency of Rossum is truly impressive, and I am glad the company offers a trial version of their platform for us to test and play with. My demo was straightforward, but we can carry out more complex scenarios with higher integration points, such as supplier repository, purchase order, and material, and build a more complete and efficient tool for invoice recognition and matching.
Rossum is really worth a try, especially in comparison to more complex, expensive, and monolithic VIM tools we usually plug into SAP ECC or S/4HANA.