This blog post belongs to a Tutorial Blog Post series about where its simulating a sales transaction on buying a new refrigerator using a SAP AppGyver custom app, while consuming different SAP and 3rd party services.
In the previous blog post we set up Write and Filter talks into the Integration Flow to passed the needed Payload for the previous service call (to Stripe), and also set up the Get task to retrieve the Payload needed to request a sales order creation in SAP Sales and Service Core (formerly SAP Sales and Service Cloud, SAP Cloud for Customer or SAP C4C).
In this blog post you’ll review how to create a Message Mapping artifact to correctly pass the needed payload to C4C to create the saler order. Plus you’ll see how to configure and test your XSD schemas for the source and target messages.
Tutorial Blog Post Series – Sections
They are divided into several blog posts to not make it so long in one alone.
- Build an integral SAP Integration Suite project and consume it from a SAP AppGyver custom app – Tutorial Blog Post Series Introduction [Link]
- Consume a Stripe service from SAP Open Connectors and SAP Cloud Integration to create payment transactions [Link]
- Set up Write, Filter and Get tasks in SAP Cloud Integration to save, filter and get your needed message to execute other operations in your Integration Flow [Link]
- Consume a SAP Sales and Service Core API to create Sales Orders using an OData receiver adapter in SAP Cloud Integration [Here you are in this blog post]
- Send application/x-www-form-urlencoded data to a HTTP receiver adapter in SAP Cloud Integration to send SMS messages consuming a Twilio API [Link]
- Integrate SAP AppGyver with SAP Integration Suite, consuming an Integration Flow levering SAP API Management policies (soon to be published)
Let’s start adding the service to the IFlow
Once you have your SAP Sales and Service Core tenant (formerly SAP Cloud for Customer or SAP C4C), you can test the API using the SAP API Business Hub, by clicking in “Try Out” and entering your tenant domain.
Your API endpoint is https://<your C4C* domain>/sap/c4c/odata/v1/c4codataapi. Add /CustomerOrderCollection as the Resource Path to POST new Sales Orders in C4C.
Now that we have set up the getting of the payload as we structured it, we are going to call the SAP Sales and Service Core API to create a Sales Order. For this purpose, we need to create a Message Mapping artifact to map the XML of the incoming payload to the needed structure in SAP Sales and Service Core.
To view first this structure, let’s add a Request Reply task, a new Receiver and the OData Adapter (select the OData V2). For more information, check the documentation here.
Here you need to add your SAP Sales and Service Core API endpoint and credentials.
To create the credentials, you need to follow the same steps we used to create the Open Connector credentials. Go to the “eye icon” (Monitor) -> “Security Material” tile and create the credentials to access your SAP Sales and Service Core (SAP C4C) environment. Use “User Credentials” as the Type. And Deploy it.
Go back to the iFlow and by selecting the Odata adapter, go to the Connection tab and add:
- Address: paste your SAP C4C API endpoint as mentioned above.
- Proxy type: Internet
- Authentication: Basic
- Credential Name: paste the credential name you configured
And check the box “CSRF Protected”: this is very important because it automatically requests the CSRF token (simulates the GET request call) to later request the POST call to create the sales order.
Go to the Processing tab. Here is we are going to select the Resource Path “CustomerOrderCollection” and download the XSD schema (this will be your XSD schema for your target message).
Click on Select
Leave the data as it shows and click on Step 2.
Change the Operation to “Create (POST)” and look for “CustomerOrderCollection” as the entity (as mentioned at the beginning of the blog). Go to the Sub Level “1”, this is important to be able to send CustomerOrderItems (such as product items).
In the Fields, check the box to:
- ObjectID
- BuyerPartyID
- Inside CustomerOrderItem, select:
- ProductID
- ObjectID
- Quantity
We could add more fields if we want to, but for the purpose of this demo scenario I’ll leave it with those.
You should see them like the image below.
And select:
- As Content Type: Atom
- and Content Type Encoding: UTF-8
Create a Message Mapping Artifact
Now let’s create the Message Mapping artifact. Click on the path at the top “CPI Best Run Demo”. Be sure to be on Edit mode to add the artifact.
Enter the artifact. And you will see this page:
The source message is going to be the payload coming from the AppGyver (which we have not created yet hehe), but in other words it’s the payload from the application that we are going to send to the Cloud Integration flow.
The Target Message is the XSD schema we created in the previous step while configuring the CustomerOrderCollection Post rules, with the fields we selected (mainly productID, BuyerID, quantity, etc.).
So let’s first upload the XSD schema from the CustomerOrderCollection. Be sure to be on Edit mode.
- Source: Integration Flow
- Package: CPI Best Run Demo
- Integration Flow: CPIsalesIntegrationFlow
Select and add the generated XSD schema.
Now click on “Add target message” and select the XSD schema.
You should see it like this (it is on red because we haven’t mapped them with the source message yet).
So in order to do this upload the needed source XSD schema, we need first to manually convert the JSON Payload structure to a XSD structure.
Remember this is the payload structure we are using:
{
"AppGyverSalesOrder": {
"customer": {
"ObjectID": "<Object ID from SAP C4C>",
"BuyerPartyID": <BuyerPartyID from SAP C4C>
},
"paymentData": {
"amount": <Payment transaction amount to be processed in Stripe>,
"customer": "<stripe customer id>",
"currency": "<currency selected in stripe account>",
"source": "<card id>",
"description": "Test payment via CPI"
},
"product": [
{
"ProductID": "<Product ID from SAP C4C>",
"Quantity": <Product quantity to be purchased>
}
]
}
}
By converting it to XML, it should look like this (replace the XXXX with your data):
<?xml version="1.0" encoding="UTF-8"?>
<AppGyverSalesOrder>
<customer>
<ObjectID>XXXXXX</ObjectID>
<BuyerPartyID>XXXXXX</BuyerPartyID>
</customer>
<paymentData>
<amount>XXXXXX</amount>
<customer>XXXXXX</customer>
<currency>XXXXXX</currency>
<source>XXXXXX</source>
<description>XXXXXX</description>
</paymentData>
<product>
<ProductID>XXXXXX</ProductID>
<Quantity>XXX</Quantity>
</product>
</AppGyverSalesOrder>
You can also download the target XSD schema to use it as a guide to build the source XSD schema.
This is the source XSD schema:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xsd:element name="AppGyverSalesOrder">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="customer" minOccurs="1">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ObjectID" type="xsd:string"/>
<xsd:element name="BuyerPartyID" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="paymentData" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="amount" type="xsd:decimal"/>
<xsd:element name="customer" type="xsd:string"/>
<xsd:element name="currency" type="xsd:string"/>
<xsd:element name="source" type="xsd:string"/>
<xsd:element name="description" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="product" minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ProductID" nillable="false" minOccurs="1" type="xsd:string"/>
<xsd:element name="Quantity" minOccurs="1" type="xsd:double"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Note: Remember that when we are setting the possible values for each XSD element, using minOccurs and maxOccurs we need to make it consistent with the Message Mapping artifact messages’ structures. You’ll be able to see them in the source and target message’s structure, and these are the definitions:
- 1..1 -> needs and allows only one value.
- 0..1 -> doesn’t need a value but if there is, it would be only one.
- 0..* -> it can go from no value to multiple values.
To test the Message Mapping, save the Payload converted to XML in a local file (I saved is as “payloadInputSimulation.xml”). And validate it with the source XSD schema before uploading the source XSD schema to the Message Mapping artifact.
A helpful editor: Notepad++ and XML vs XSD validation in this link.
This is how it looks (using the validation’s link above):
Now, save the XSD schema as local files in your computer, and upload it as the source XSD schema file as I uploaded the target one. I named it appgyverSchema.xsd
Click on “Add source message” and select it. You should see it like this:
Now it is time to map them together.
For the 2 ones that are hanging (CustomerOrderItem father and ObjectiID child) map them to a constant as shown in the screenshot.
Now we are going to test the Message Mapping. Save it, deploy it and click on Simulate on the top-right. It is important you save it and deploy it first to avoid issues while doing the simulation testing. Now upload the Payload converted to XML and click on “Test”. It can take some seconds/minutes to load the first time. When it is done, you should see this message “Mapping test completed”, which lets you know the test was successful.
Add Message Mapping to the IFlow
Now let’s go back to the Integration Flow. Click on the pencil icon “Design”, select your package and enter your Integration Flow artifact.
We first need to add the Message Mapping we just created as a Resource for the iFlow to consume. Make sure you click anywhere (blank space in your iFlow) and maximize the configuration panel below in the Edit mode. Go to the tab “Resources” and inside click on the “References” tab. Click on Add and add your Message Mapping artifact.
Now, add a Message Mapping task in the iFlow. Once selected, go to the “Processing tab” click in select and in the Reference resource you should see it, select it.
You should see it like this:
Don’t mind the warning signs, the iFlow is going to work out.
With this message mapping, we are ensuring that the payload message is readable to send the payload to C4C and create the Sales Order with the info provided.
Integration Suite works best with XML messages, there are some transactions you can run with messages in JSON, but for complex message transformations or mappings like we did above, it is highly recommended (and needed) to adopt XML and XSD format/structures.
Now save your iFlow and deploy it. If you want to export your package, make sure you save your iFlow and Message Mapping with versions.
When the deployment is finished, let’s test the integration again using Postman as we did in the previous blog post testing the Stripe Open Connector.
Go to the eye icon “Monitor”, and click on “Manage Integration Content”, when the Status changes to “Started”, change the Log Level to “Trace” to be able to trace any potential error, then copy the API endpoint to use it on Postman, with your SAP Business Technology Platform credentials, send the JSON payload (as mentioned previously).
Execute the call in Postman and return to Cloud Integration, click on Monitor Message Processing to check the messages til the end. Remember to activate the Trace log after deploying your iFlow. You should able to see all calls in 200 OK, and the end response message from SAP Sales and Service Core with a XML format.
And you should see the Message content in the “Monitor Message Processing” capability, with the response of the API, with a Sales Order already generated, like this:
Conclusion and next step
Now you have already set up in the right way the OData receiver adapter to create Sales Orders in SAP Sales and Service Core, while configure a Message Mapping artifact to transform the payload with the XML and XSD schema needed for this Sales Order creation.
Now as a next step, we are going to send a SMS as a notification that the order was successfully created, leveraging a Twilio SMS API. For this step, check out this next blog post: Send application/x-www-form-urlencoded to a HTTP receiver adapter in SAP Cloud Integration to send SMS consuming a Twilio API [Link]
Want to know more about SAP Business Technology Platform?
To learn more about SAP BTP, see the learning journey Discover SAP Business Technology Platform, a great introduction to BTP and the Intelligent Enterprise strategy to see what it’s all about for free. Discover BTP, LCNC plus much more free learning at SAP Learning site.