
Groovy scripting is the primary way to add custom logic to integration flows in SAP Integration Suite (formerly SAP CPI). When standard components — Content Modifier, Message Mapping, Router — can’t express the business logic you need, a Groovy script steps in. With it you can transform payloads, read and write headers and exchange properties, handle exceptions, call external APIs, log custom trace data, and control iFlow execution at runtime.
This guide covers Groovy fundamentals for SAP Integration Suite developers: what Groovy is, how to add it to an iFlow, the most common use cases with code examples, and practical tips from our integration consultants.
Groovy is a dynamic, JVM-based scripting language that combines the power of Java with a concise, readable syntax. In SAP Integration Suite, Groovy scripts run inside the Script step of an integration flow and receive the SAP Message object — giving full programmatic access to the payload, headers, and exchange properties of the message being processed.
Key features that make Groovy ideal for SAP CPI scripting:
def; type resolution happens at runtime, reducing boilerplate code.com.sap.gateway.ip.core.customdev.util.Message class for reading and modifying payload, headers, and properties..groovy file.processData(Message message) method.Tip: Use groovyide.com/cpi to test and validate Groovy scripts against a CPI-compatible sandbox before deploying to your tenant. This eliminates the slow deploy-run-check cycle during development.
Every Groovy script in SAP Integration Suite must implement the processData method. This is the entry point called by the integration runtime when the Script step executes:
import com.sap.gateway.ip.core.customdev.util.Message
import java.util.HashMap
def Message processData(Message message) {
// Your custom logic here
return message
}The method receives the current Message object and must return it (modified or unchanged) after processing. The integration flow proceeds with the returned message.
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String
// Modify the body string as needed
def modifiedBody = body.replace('OldValue', 'NewValue')
message.setBody(modifiedBody)
return message
}def Message processData(Message message) {
def headers = message.getHeaders()
def contentType = headers.get('Content-Type')
// Set a new header
message.setHeader('X-Custom-Header', 'MyValue')
return message
}def Message processData(Message message) {
def properties = message.getProperties()
def orderNumber = properties.get('OrderNumber')
// Write a new property for use in downstream steps
message.setProperty('ProcessedOrderNumber', orderNumber + '-PROCESSED')
return message
}By default, message payloads are only visible in trace mode. Use the message log API to capture custom data at any log level:
import com.sap.gateway.ip.core.customdev.util.Message
import java.util.HashMap
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String
def messageLog = messageLogFactory.getMessageLog(message)
if (messageLog != null) {
messageLog.addAttachmentAsString('Payload Snapshot', body, 'text/plain')
}
return message
}This is especially useful for debugging production issues without enabling full trace mode on the iFlow.
import com.sap.gateway.ip.core.customdev.util.Message
def Message processData(Message message) {
def xmlPayload = new XmlSlurper().parseText(message.getBody(java.lang.String) as String)
def orderID = xmlPayload.OrderID.text()
message.setProperty('OrderID', orderID)
return message
}import com.sap.gateway.ip.core.customdev.util.Message
import groovy.json.JsonSlurper
def Message processData(Message message) {
def json = new JsonSlurper().parseText(message.getBody(java.lang.String) as String)
def customerId = json.customer.id
message.setProperty('CustomerID', customerId.toString())
return message
}import com.sap.gateway.ip.core.customdev.util.Message
def Message processData(Message message) {
def status = message.getProperty('ResponseStatus')
if (status != '200') {
throw new Exception("Upstream system returned error status: ${status}")
}
return message
}The thrown exception triggers any Exception Subprocess configured in the iFlow, allowing structured error handling and alerting.
import com.sap.gateway.ip.core.customdev.util.Message
import com.sap.it.api.exception.IgnoreMessageException
def Message processData(Message message) {
def flag = message.getProperty('SkipProcessing')
if (flag == 'true') {
throw new IgnoreMessageException()
}
return message
}The IgnoreMessageException terminates the iFlow cleanly with a Completed status and no error, useful for conditional processing logic.
SAP Integration Suite supports both Groovy and JavaScript as scripting languages. For most integration developers, Groovy is the preferred choice because:
XmlSlurper and JsonSlurper — common tasks in integration.JavaScript remains useful if your team has strong JS expertise or if you’re doing light string manipulation that doesn’t require Java library access.
ITApiFactory API.PROCESSING_FAILED errors that are hard to diagnose..groovy files in a Git repository alongside your iFlow transport exports for full change history.The required entry point is def Message processData(Message message). The SAP integration runtime calls this method when the Script step executes. The method must return the Message object after any modifications. Additional helper methods can be defined in the same script but are called from processData.
Use message.getProperties() to retrieve a map of all exchange properties, then access individual values with .get('PropertyName'). To set a property: message.setProperty('PropertyName', value). Headers are accessed with message.getHeaders() and set with message.setHeader('HeaderName', value).
Yes. Standard Java libraries available on the Integration Suite runtime (Java SE classes, SAP-provided APIs) can be imported with standard import statements. You cannot add arbitrary third-party JAR files; only libraries bundled with the Integration Suite runtime are available.
In message mapping (Graphical Mapping), Groovy is used to write custom User-Defined Functions (UDFs) that transform individual field values during mapping. In a Script step, Groovy operates on the entire message object — payload, headers, and properties — outside of mapping. Script steps are more powerful but also more complex; use them for logic that cannot be expressed in standard mapping functions.
Three approaches: (1) Enable Trace level logging on the iFlow during development and inspect message processing steps in the Monitor. (2) Use the messageLogFactory API to attach custom snapshots to the message log at any log level without requiring trace mode. (3) Use an external Groovy IDE (groovyide.com/cpi or IntelliJ IDEA with the CPI stubs) to test script logic locally before deploying.

SAP PI/PO & SAP Integration Suite (CPI) Consultant
Enes Varinli is an integration consultant who works on the analysis, design, and implementation of end-to-end ERP integrations between SAP and non-SAP systems and third-party applications. He focuses on developing sustainable and scalable integration architectures that are centered on business processes.
Your mail has been sent successfully. You will be contacted as soon as possible.
Your message could not be delivered! Please try again later.