Technical Articles
Integrating SAP Commerce Cloud (Hybris) with SAP CRM/ERP via SCPI – Step by Step Tutorial – PART 3/6
In the first part, we looked at different options for integrating the SAP Commerce Cloud. In the second part, we briefly introduced SCP, SCP Cockpit and set up our own SCPI instance in our own SCP using a trial account. The SCPI makes both data and process integration possible among different systems regardless of whether they are cloud or on-premise versions and whether they are SAP or non-SAP versions. Within setting up the SCPI instance, you created and deployed a simple iFlow. In this article, we will talk more about iFlows and other SCPI concepts which will help you to achieve our goal: integrating SAP Commerce Cloud with SAP backend systems using SCPI.
SCPI vs HCI
In its early days, Sap Cloud Platform Integration was called SAP HANA Cloud Integration (HCI). Therefore, you may encounter the initialism HCI when reading documentation or watching videos of earlier SCPI versions.
API Business Hub – Packages, Artifacts, and iFlows
SAP API Business Hub is the publicly available catalog of packages. A package is a group of related artifacts. Different package types exist, but for us, Integration Packages are the most important because their artifacts are (among others) iFlows.
Figure 1 SAP API Business Hub lists all publicly available packages and lets you explore different APIs
In the discover area of your SCPI tenant, you can search for packages provided by SAP and other parties. Basically, what you see is part of the content you previously saw on the API Business Hub.
Figure 2 SCPI Discover Area – Search for available SCPI packages
Search for the SAP Commerce Cloud Integration with SAP ERP package and open it. You’ll see the current version of the package, the type of the package, when it was created and when the last version was published. In the example below, you’ll see that the package SAP Commerce Cloud Integration with SAP ERP is an integration package created on August 09th 2018 and that the current package version is 1.6, published on May 23rd, 2019.
Figure 3 SAP Commerce Cloud Integration with SAP ERP integration package
There is other information you can explore, but let’s focus on the most important one – Artifacts. At the time of writing this article, the package contains 19 artifacts. Every artifact has its own version and its own type. Also, it’s important to note that a package can contain both inbound and outbound integration. Note that if an artifact version changes, the package version is not automatically changed/increased. Whether the package version changes after the artifact version is changed, depends on the organization/person that owns the package.
The figure below highlights an example of replicating data (customers) from ERP to SAP Commerce Cloud as well as another direction with replicating data (orders) from SAP Commerce to ERP.
Figure 4 Artifacts from the SAP Commerce Cloud Integration with SAP ERP integration package
You can also see different artifact types with their own versions. You can see an artifact of type Integration Flow, i.e. iFlow and an artifact of type Value Mapping.
Below you can see the content of the Replicate-Orders-From-SAP-Commerce-Cloud-To-SAP-ERP iFlow. We will not go into detail with the iFlow itself. What is important to understand is that the designed iFlow takes IntegrationObjects from SAP Commerce via OData, it processes and transforms it in some way, and sends the order as IDoc to ERP.
Figure 5 Replicate-Orders-From-SAP-Commerce-Cloud-To-SAP-ERP iFlow
Deploying Replicate-Orders-From-SAP-Commerce-Cloud-To-SAP-ERP iFlow
Let us deploy the Replicate-Orders-From-SAP-Commerce-Cloud-To-SAP-ERP iFlow from the SAP Commerce Cloud Integration with SAP ERP package. First, you can copy the integration package to your design area. For that click on copy at the package level and go to the SCPI design area.
Figure 6 Copying an Integration Package from Discover Area to Design Area
Go back to the design area, open the package, click on artifacts, click on the button in the Action column, and finally click on Deploy in the menu. You will see a notification that the iFlow is triggered for the deployment and a few seconds later, that the iFlow has been deployed.
Figure 6 Deploying an iFlow
After that, go to the monitoring area where you will find your deployed iFlow.
Figure 7 In Monitoring area you can find deployed IFlows
Figure 8 Deployed iFlow
Here you can see the endpoint of the iFlow:
[HOST]/gw/odata/SAP/REPLICATE-ORDERS-FROM-SAP-COMMERCE-CLOUD-TO-SAP-ERP;v=1
Triggering the iFlow
Before we trigger the iFlow, find and set the log configuration at the bottom of the screen. Choose trace so that we can follow every detail during testing.
Use a Rest client of your choice and make a POST request to the endpoint above. As expected, you will get the status code 401 as a response which says that you have to authenticate yourself.
Figure 8 Making POST request to the previously deployed iFlow
We have to distinguish authentication at two different points. First, authenticating us (SAP Commerce Cloud) against the SCPI or in this case the Postman. Second, authenticating SCPI against the receiver system(s) (SAP ERP, SAP S4/HANA, etc.).
For the first authentication, we will use the OAuth approach, i.e. first we will call an OAuth service to obtain an accessToken (Bearer token) and afterward we will use that token to identify ourselves against the SCPI. There is already a nicely written step-by-step tutorial for this use case including setup, config, and test. Please go through that above-mentioned tutorial, so that you can continue with this one.
After going through the authentication tutorial, you can use the client_id and client_secret to obtain the Bearer token.
Figure 9 Obtaining Bearer token
So, let us use the Bearer token and make the POST request one more time. This time, we will get the 403 status code as a response because we do not have permission.
Figure 10 Status Code 403 as a response because X-CSRF token was not provided
What we are missing is the X-CSRF-Token. For that, change the request from POST to GET and add X-CSRF-Token:Fetch to the request header. You should get the status code 200 and the token attached in the response header.
Figure 11 Obtaining X-CSRF Token
Now, let us make the POST request again, but this time we’ll provide the X-CSRF token as well. You will get the status code 405 Method Not Allowed now as a response. The reason for that is we did not set EntitySet as the endpoint. Let’s go back to the iFlow, click on the Odata Adapter, then on the Adapter Specific, and at the bottom, you’ll see the entity set as SAPCpiOutboundOrders. That entity set is derived from the EDMX file. The EDMX file describes the entity set, i.e. payload, which is expected, and it is used as a guide to map the incoming payload to iFlow’s required data format. We will talk more about the EDMX file in the next tutorial part.
Figure 11 Looking at endpoint’s EDMX file
For now, update the endpoint to include the entity set and make the POST call again.
Figure 12 Calling the proper endpoint without payload
As a response, you’ll get the status code 500 Internal Server Error and the message response will say that EOFException was thrown, which makes sense because we did not send any payload. If you send a payload which is not compliant with the EDMX file, then you will also get the 500 Internal Server Error code as a response and the not always informative error message to help you figure out that you are sending non-compliant payloads. Also, it’s worth knowing that these errors, which all happened before successfully mapping the payload to the required data format, are not visible in the iFlow logs. As far as I know, you can see the logs only after the payload has been successfully mapped.
Take the JSON below and send it as payload. Basically, we are simulating the call which Hybris would make. How this JSON file came into existence and its meaning are going to be discussed in the next two tutorial parts as part of the IntegrationObjects, and gluing everything together. For the purpose of this part, it’s enough to copy and paste the JSON and send it. Note that the values are made up.
{
"sapCpiOutboundOrderItems": [
{
"unit": "pieces",
"productCode": "SKU-60002",
"quantity": "2",
"orderId": "0000490556",
"entryNumber": "0",
"productName": "Test Product",
"integrationKey": "0|0000490556"
}
],
"orderId": "0000490556",
"sapCpiOutboundPriceComponents": [
{
"conditionCounter": "2",
"orderId": "0000490556",
"absolute": "true",
"entryNumber": "-1",
"currencyIsoCode": "USD",
"value": "0.0",
"conditionCode": "XPAY",
"integrationKey": "-1|0000490556"
},
{
"conditionCounter": "1",
"orderId": "0000490556",
"absolute": "true",
"entryNumber": "-1",
"currencyIsoCode": "USD",
"value": "0.0",
"conditionCode": "HD00",
"integrationKey": "-1|0000490556"
},
{
"conditionCounter": "3",
"priceQuantity": "1.0",
"unit": "pieces",
"orderId": "0000490556",
"absolute": "true",
"entryNumber": "0",
"currencyIsoCode": "USD",
"value": "1.0",
"conditionCode": "XPAY",
"integrationKey": "0|0000490556"
}
],
"channel": "B2C",
"sapCpiConfig": {
"senderName": "SAP COMMERCE CLOUD",
"senderPort": "CC999",
"receiverName": "ERP",
"client": "001",
"receiverPort": "ERP",
"url": "http://erp.url.goes.here",
"username": "UN",
"integrationKey": "integrationKeyValue"
},
"creationDate": "20190731",
"salesOrganization": "0001",
"integrationKey": "0000490556",
"transactionType": "XVAL",
"division": "01",
"sapCpiOutboundAddresses": [
{
"languageIsoCode": "en",
"lastName": "Perisic",
"orderId": "0000490556",
"countryIsoCode": "US",
"city": "Berlin",
"postalCode": "10178",
"titleCode": "mr",
"integrationKey": "0000490556",
"firstName": "Filip",
"street": "Berlin Street 7",
"documentAddressId": "1",
"email": "demo@example.com",
"regionIsoCode": ""
},
{
"languageIsoCode": "en",
"lastName": "Perisic",
"orderId": "0000490556",
"countryIsoCode": "US",
"city": "Berlin",
"postalCode": "10178",
"titleCode": "mr",
"integrationKey": "0000490556",
"firstName": "Filip",
"street": "Berlin Street 7",
"documentAddressId": "2",
"regionIsoCode": ""
},
{
"languageIsoCode": "en",
"lastName": "Perisic",
"orderId": "0000490556",
"countryIsoCode": "US",
"city": "Berlin",
"postalCode": "76133",
"titleCode": "mr",
"integrationKey": "0000490556",
"firstName": "Filip",
"street": "Berlin Street 7",
"documentAddressId": "1",
"email": "demo@example.com",
"regionIsoCode": ""
}
],
"deliveryMode": "free-shipping",
"baseStoreUid": "baseStoreId",
"currencyIsoCode": "USD",
"distributionChannel": "01",
"sapCpiOutboundPartnerRoles": [
{
"partnerId": "default",
"partnerRoleCode": "LF",
"orderId": "0000490556",
"integrationKey": "null|0000490556"
},
{
"partnerId": "100026",
"documentAddressId": "2",
"partnerRoleCode": "WE",
"orderId": "0000490556",
"integrationKey": "null|0000490556"
},
{
"partnerId": "100026",
"documentAddressId": "1",
"partnerRoleCode": "RE",
"orderId": "0000490556",
"integrationKey": "null|0000490556"
},
{
"partnerId": "100026",
"documentAddressId": "1",
"partnerRoleCode": "AG",
"orderId": "0000490556",
"integrationKey": "null|0000490556"
}
]
}
Figure 13 Calling the proper endpoint with a payload
Because the values are made up, we will get the 500 Internal Server Error as a response again. However, this time it’s the error which happened within the iFlow execution, i.e. after successful mapping of the payload. In other words, we can see the logs. For that, go to SCPI’s Monitoring section, and then click on All Started iFlow within the Manage Integration Content subsection, find our deployed iFlow Replicate-Orders-From-SAP-Commerce-Cloud-To-SAP-ERP and click on Monitor Message Processing.
Figure 14 Looking at details of deployed iFlow
Open the last message (it will probably be the only one you see), go to the log section and click on trace.
Figure 15 Looking at messages of deployed iFlow
You will see the iFlow and the log of every step as well as hints as to what step failed.
Figure 15 Looking at logs of a given message produced by a deployed iFlow
If you click on the Configuration step on the left side, the details of the step will show up. Choose Message Content and then Payload. You will see that the JSON which we sent as the payload was mapped to an XML file.
Figure 16 IFlow converted JSON into XML
If you click on the Read Credentials Segment 1 step on the left side, you will come to the source of the error.
Figure 17 Log which describes the error
Solving this issue and posting the order in an ERP is out the scope for this part. The purpose of this article was to understand fundamental SCPI concepts and be able to find your way around them. We copied publicly available packages to our own design area, deployed iFlows, obtained Bearer X-CSRF token, called an SCPI endpoint, logged the messages and saw the logs.
If you want to learn more about SCPI, I encourage you to check out following recourses:
- Under the Hood of SAP HANA Cloud Integration,
- First Steps with SAP HANA Cloud Integration,
- Getting around SAP HANA Cloud Integration which has an older UI, but the concepts of discover, design and monitor areas are explained as well as packages and artifacts.
The one entry point for all documentation related to the SCPI is available here and a nice overview of blog-based documentation is available here.
In the next tutorial part, we will take a look at IntegrationObjects.
Great article,
OOTB example covers only simple response body, what If I wish to send back a little complex response body, in the same structure as request body
I want to send user something similar to this in the response :
<SAPCpiOutboundOrders>
<SAPCpiOutboundOrder>
<orderId>xxx</orderId>
<sapCpiOutboundOrderItems>
<SAPCpiOutboundOrderItem>
<integrationKey>xxx</integrationKey>
…..
</SAPCpiOutboundOrderItem>
<SAPCpiOutboundOrderItem>
<integrationKey>xxx</integrationKey>
…..
</SAPCpiOutboundOrderItem>
</sapCpiOutboundOrderItems>
<integrationKey>xxx</integrationKey>
<SAPCpiOutboundOrder>
</SAPCpiOutboundOrders>
When I send sapCpiOutboundOrderItems, I see a completed message in SCPI iflow messaging monitoring console, however in Hybris/Post man I get 400 ; nested exception
Error :
The metadata do not allow a null value for property 'integrationKey
thank you so much for this interesting article .it's very helpful.
where can i read part 5/6 and 6/6 ?
I have the same question, I think author forgot to write further articles.
Your Blog is awesome .
Please Share the link for 4/6 ,5/6 and 6/6
Thanks in advance
This is really helpful, followed it step by step and managed to get it working using Postman. However I am having problems with the configuration in Commerce Cloud, I set up everything as best as I could and when I run my cronJob i get an error on the outbound message. Could you please assist, thank you.
Muzi
Hi
I managed to get it to work. It sends messages through to SCPI.
On the SCPI monitoring, messages process successfully but I am also getting the
Error:
" The metadata do not allow a null value for property ‘integrationKey' "
Did you find a solution to this? Thank you.
Muzi
Hi Filip,
Could you pls share the example/request body of Retail inbound product as well?
We are facing challenge in mappings.
Hi There,
Can someone share PART 4/6, PART 5/6 and PART 6/6 url?
Many thanks!