Skip to Content
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:

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.

 

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.