Skip to Content
Technical Articles
Author's profile photo Mariajose Martinez

Integrate SAP AppGyver with SAP Integration Suite, consuming an Integration Flow levering SAP API Management policies

Hello!

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.

As we saw in the previous blog posts, we have already configured Open Connectors to connect in an easy way with a 3rd party payment platform as it is Stripe, and leverage Message Mapping capabilities within Cloud Integration to execute a POST request to SAP Sales and Service Core (formerly SAP Cloud for Customer or SAP C4C) to create a Sales Order only after the payment transaction is successful. Also, we’ve configured a HTTP receiver adapter to send URL encoded parameters to send SMS messages, as a notification that the order was successfully created using a 3rd party solution (Twilio).

Now in this last blog post of the Tutorial Blog Series, we are going to call this Integration Suite API endpoint from a custom application in SAP AppgGyver. Here’s a sneak peak of the custom application consuming the API from SAP Integration Suite:

 

Tutorial Blog Post Series – Sections

They are divided into several blog posts to not make it so long in one alone.

  1. Build an integral SAP Integration Suite project and consume it from a SAP AppGyver custom app – Tutorial Blog Post Series Introduction [Link]
  2. Consume a Stripe service from SAP Open Connectors and SAP Cloud Integration to create payment transactions [Link]
  3. 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]
  4. Consume a SAP Sales and Service Core API to create Sales Orders using an OData receiver adapter in SAP Cloud Integration [Link]
  5. Send application/x-www-form-urlencoded parameters to a HTTP receiver adapter in SAP Cloud Integration to send SMS messages consuming a Twilio API [Link]
  6. Integrate SAP AppGyver with SAP Integration Suite, consuming an Integration Flow levering SAP API Management policies [Here you are in this blog post]

 

Now, we are going to set up the API management policies needed to integrate our IFlow / CPI Endpoint with the custom application in SAP AppGyver.

To configure this step we need to keep in mind that:

  1. We may run into CORS issues while calling the API
  2. If we call the API endpoint like we are doing it right know with Postman, we would need to put our SAP BTP credentials in SAP AppGyver.

For these reasons we need to leverage SAP API Management capabilities and apply policies to:

  1. Avoid CORS issue while calling the API from SAP AppGyver
  2. Enable an API Key to use it, instead of using your SAP Business Technology Platform (and therefore SAP Integration Suite) credentials. This is critical for security purposes.
    a. In addition, if you have a productive SAP AppGyver account, check out this new feature regarding SAP BTP Authentication in a SAP AppGyver application in this blog post by Marc Huber.

 

Let’s start setting up the policy to avoid CORS issues

This blog from Atakan Tokgoz was quite helpful to execute this task. However I needed to make some changes for the policy to work in AppGyver with my application (this is my personal experience, I don’t rule out other ways to do it). I’ll put it step by step below.

Go to your SAP API Portal (in the main SAP Integration Suite portal). Create an API and select URL. Here you’re going to paste your IFlow endpoint from past blog posts. Give it a name, I named mine “APIBestRunDemo”. Give it a path, I put the same path I used for my IFlow “/https/salesOrder”. And service type “REST”.

You should see it like this:

After creating it, go to the Proxy Endpoint tab and add the following in this order, and save it:

Now, let’s go to Policies (if it doesn’t show up in the top-right of your screen, click on the 3 dots). Here we’ll add the required policies to avoid CORS issues while calling this API from SAP AppGyver and configure the API Key policy later on.

On the Edit Mode, start adding the Policies as followed:

In the PostFlow inside the Proxy Endpoint configuration, add an “Assign Message” policy as an “OutgoingResponse” and name it “setCORS”. Like this:

Copy and paste this script (read my message on line 5):

<!-- This policy can be used to create or modify the standard HTTP request and response messages -->
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
		 <Add>
		     <Headers>
		      <!-- I had to remove this line of code as I was getting an error about The 'Access-Control-Allow-Origin' header contains multiple values, but only one is allowed when executing the test on AppGyver: <Header name="Access-Control-Allow-Origin">*</Header> -->
		         <Header name="Access-Control-Allow-Headers">set-cookie, origin, accept, maxdataserviceversion, x-csrf-token, authorization, dataserviceversion, accept-language, x-http-method, content-type, X-Requested-With, apikey</Header>
		         <Header name="Access-Control-Max-Age">3628800</Header>
		         <Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header>
		         <Header name="Access-Control-Expose-Headers">set-cookie, x-csrf-token, x-http-method</Header>
		     </Headers>
		 </Add>
		 <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
		 <AssignTo createNew="false" type="response">response</AssignTo>
</AssignMessage>

Note: notice that I’m already adding “apikey” as a header in the policy.

You should look it like this:

In the ProxyEndpoint click on “+” to add one. Name it “preflight” and in the condition string paste: request.verb == “OPTIONS”. Like this:

This is all we need to avoid CORS issues when calling our API from SAP AppGyver.

 

Let’s now add the Verify API Key policy

This great blog post from Benno Grimm about SAP API Management and policies. It was quite helpful for configuring the API Key. I’ll put it step by step below for the purpose of the exercise.

Before adding the needed policies, let’s create first a Key Value Map with our CPI credentials (to access the CPI API endpoint). We will need this credential to reference it in the API Key Policy.

Go to Configure (click on the tool icon) -> go to the “Key Value Maps” tab and create one.

Put a name and declare your CPI credentials (username and password), I named mine “CPICredentials” and check the “Encrypt Key Value Map” box.

Now let’s add the policies needed to create an API Key. Go back to your API policies.

In the TargetEndpoint we are going to add 3 policies in the PreFlow.

  • First, we are going to get the CPI credentials we created before as a Key Value Map. Add a Key Value Map Operations policy, name it and leave it as a Incoming Request. Like this:

    • Copy and Paste this script (see that I’m referencing my CPICredentials with the mapIdentifier parameter):
<KeyValueMapOperations mapIdentifier="CPICredentials" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
   <!-- Read parameter with key "username" and assign its value to private variable BasicAuthUsername-->
   <Get assignTo="private.BasicAuthUsername" index='1'>
   <Key><Parameter>username</Parameter></Key>
   </Get>
   <!-- Read parameter with key "password" and assign its value to private variable BasicAuthPassword-->
   <Get assignTo="private.BasicAuthPassword" index='1'>
   <Key><Parameter>password</Parameter></Key>
   </Get>
   <Scope>environment</Scope>
</KeyValueMapOperations>​

 

Like this:

  • Then, add a Basic Authentication policy, name it and leave it with the “IncomeRequest” stream. Like this:

    • Copy and paste this script:
<BasicAuthentication async='true' continueOnError='false' enabled='true' xmlns='http://www.sap.com/apimgmt'>
	<!-- Operation can be Encode or Decode -->
	<Operation>Encode</Operation>
	<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
	<!-- for Encode, User element can be used to dynamically populate the user value -->
	<User ref='private.BasicAuthUsername'></User>
	<!-- for Encode, Password element can be used to dynamically populate the password value -->
	<Password ref='private.BasicAuthPassword'></Password>
		
	<!-- Assign to is used to assign the encoded value of username and password to a variable. This should not be used if the operation is Decode -->
	<AssignTo createNew="true">request.header.Authorization</AssignTo>
</BasicAuthentication>​

 

    • You should look it like this:

  • Lastly, we are going to add a API Key verification policy to request the API Key every time our API is called (we’ll later need to create the API Product and subscribe to the application to get our API Key). Let’s add the “Verify API Key” policy, same in the Preflow. Like this:

    • Copy and paste this script:
<!--Specify in the APIKey element where to look for the variable containing the api key--> 
    <VerifyAPIKey async='true' continueOnError='false' enabled='true' 
		xmlns='http://www.sap.com/apimgmt'>
    <APIKey ref='request.header.ApiKey'/>
</VerifyAPIKey>
    • And this should be the first policy to be triggered. Make sure it is set it up as the first one (you can change the order with the arrows in the top-right). Like this:

Now click on Update, Save and Deploy your API project.

 

Let’s create an API Product and Subscribe to the Application

Now we need to create the API Product. Go to the pencil icon (develop), click on the “Products” tab and create one. I’m defining mine as APIBestRunDemoProduct.

Reference your API to your Product.

Now you can Publish your Product. Now go to the API Business Hub Enterprise portal.

You should be able to see it in your SAP API Business Hub:

Enter the API product and subscribe it by creating a new Application:

I named mine “APIBestRunDemoApplication”, like this:

Here’s where you can get your API Key, crucial to authenticate to this API endpoint when consuming its service.

 

Let’s add additional tasks to the IFlow for the purpose of the integral exercise

Right now, as following the whole exercises, the IFlow is returning us the SMS message sent by consuming the Twilio API. But for the purpose of the exercise with SAP AppGyver, I’m going to use as the return message, mainly the receipt URL when the payment transaction is successfully done with Stripe. For this, we need to save this message in the IFlow and retrieve it at the end of the IFlow.

Remember the blog about “Set up Write, Filter and Get Tasks in the Integration Flow…” for filtering the payment data and later calling the SAP C4C OData service? well, we are going to do the same, but in this case to retrieve the receipt URL from the Stripe request response.

Add a Write task after the Stripe Connector request reply, and configure the task as following:

And now add a Get task at the end of the IFlow to retrieve this returned message:

Save and deploy your IFlow.

 

Now let’s test the integration with SAP AppGyver

Go to your SAP AppGyver custom app, click on “Data” on the menu and Add a Data Resource and select “REST API direct integration”. Remember we are using for this exercise an already created custom app, if you haven’t done it yet, you can follow this blog post I created before.

Copy and paste your API endpoint from SAP API Management as the base resource url and name your Data Resource (I named mine “IntegrationSuite_API_CORS”):

Go now to the “Create Record (POST)” section, make sure “id” is erased from the relative path and enter your API Key as a header (make sure you don’t put it as optional and mark it as static).

Now, let’s set up the custom needed schema for testing a POST request. Remember the payload structure we are using for this exercise:

{
  "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>
      }
    ]
  }
}

So to “translated it” into the custom schema in SAP AppGyver, you’ll need to add these properties manually, as shown in the following image:

Now, go to the Test tab and open your custom object, where you are going to add the values as the payload for testing.

And setting for testing purposes a Product ID from SAP Sales and Service core (formerly SAP Cloud for Customer or SAP C4C).

Save it and now click on “Run Test”. You should see this response “Status: OK”:

If we check on the Stripe developers account, you can see the amount and description “Ta dá!! Integration scenario is set up” 🙂 :

Now, we need to set up the schema from response, to let AppGyver know we want to create a variable for getting the receipt url.

Now you can see “receipt_url” from the return message, as a property, like in the following image. Save your configuration.

Now, what you need to do is to create a variable to enable this “receipt_url” as a variable to be linked in your application UI. Click again on “Data” to close it and go back to your application design. Click on “View – Variables” and click on “Add Page Variable” as it is in the following image:

 

Finally, let’s call the service from the custom application in SAP AppGyver

Remember we’re following this previous exercise of a custom application developed in SAP AppGyver (as mentioned in the prerequisites in the Introduction blog post). The differences are:

  1. We are going to add one field to the QR code (ProductID) for the purpose of the integration exercise and update the variables we’ve already created in our SAP AppGyver app. Of course, in reality you would want to add as many Product fields as necessary to execute the Sales Order transaction.
  2. We are going to add an additional Button (to trigger the API call) and an WebView component (to see the Stripe’s payment confirmation with the receipt url).

Let’s go with the 1st point:

Go back to your QR code generator (I’m using this one), and paste this JSON object:

{
"ProductID": "<your SAP C4C product ID>",
"model": "Samsung French Door 29 ft",
"imgURL": "https://samsungmx.vtexassets.com/arquivos/ids/180853-800-auto?width=800&height=auto&aspect=true"
}

Save the generated QR Code:

Go back to your SAP AppGyver custom app, and click on “View – Variables”, go to Page Variables and update them, by adding “ProductID” as a new property of the parsedJson object:

Click again in “View – Variables” to go back to your UI editor, change the first title of the Product from “brand” to the “model” page variable, to make it consistent with the generated QR code:

Then, add the ProductID page variable to the second Product component:

Leave the image url as it is in the original exercise.

Let’s go now with the 2nd point:

Add the button and change its name to “Create Order consuming CPI”:

Add the WebView component (this one, you have to install it):

And link it to the page variable “receipt_url” we created before. Like this:

Let’s go back to the button and add it the needed logic. Select the button and click on the bottom-right “Show logic for BUTTON..” and add a “Create Record” logic component.

  • In the Resource name: select the Data Resource Id we created before “IntegrationSuite_API_CORS”
  • For the Records properties: here you’ll see the custom schema we created before for requesting POST calls from SAP AppGyver.

Click on “Record properties” -> “Custom object”. And add the newly created property: ProductID.

After save it, you’ll see it like this in the Product List Object:

If you want, you can create as may variables as you want to make the demo more dynamic. As I mentioned before, for the purpose of the integration exercise I’ll use only ProductID. If you are following me, you’ll see your payload structured in AppGyver, like this:

Save it.

Now let’s configure the getting of the receipt url from the Stripe request response. Add a Javascript logic component:

Erase the original “input1” name and change it for “response”. Click to bind the data.

Select the binding type: Output value of another node, then create record and select receipt_url as field we want to get from the response.

Save it and close it.

Now, let’s add a Dialog Toast, just to show up a message that the request call was successful.

And now we are going to finally retrieve the receipt url of the payment transaction. Add a “Set page variable” logic component and add as the variable name the page variable we created before (receipt_url):

Link the variable like this and save it:

Do the same for assigning the value. Here you are going to link it with the receipt_url Javascript component we created before:

Now it’s time to test the app and the whole integration 🙂

 

Test the results of the whole integration scenario now

Grab your phone and enter your SAP AppGyver mobile app. Link it to your account as explained in the original exercise. Read the generated QR code:

 

And click on “Create Order consuming CPI” and you’ll see that the order was successfully created. Like this:

 

Checking in the SAP Sales and Service Core tenant (formerly SAP Cloud for Customer / SAP C4C):

 

Conclusions

Congratulations for making it to this last part. You’ve successfully created an E2E integration demo using different SAP and third-party solutions. Just to summarize, we’ve integrated solutions and services from:

  • SAP Sales and Service Core (formerly SAP C4C)
  • Twilio
  • Stripe
  • SAP Integration Suite:
    • SAP Open Connectors
    • SAP API Management
    • SAP Cloud Integration
  • SAP AppGyver

To create a Sales Order in SAP C4C, after a the payment transaction using Stripe is successful, and then sending a SMS with the Order Id confirmation.

Hope you’ve enjoyed this exercise as much as I did 🙂

 

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.

 

 

 

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Piotr Tesny
      Piotr Tesny

      Hello Mariajose Martinez , a great blog of yours. Thanks for showcasing the value of SAP API Management and how one can leverage it as a conduit to implement various SAP security policies like the CORS policy for instance.

      Personally, I can see a great added value of API Management as a LCNC tool per se whenever there is need to implementing various API packages of any SAP LOBs with the SAP compliance in mind.

      Personally I tried it and did it for SAP S/4HANA Cloud APIs, for SAP S/4HANA OP, for SAP SuccessFactors, SAP Analytics Cloud or even SAP API Business Hub itself. It is so worth it. And additionally any of the "proxified" and CORS-enabled APIs can be used out-of-the-box with SAP Appgyver.

      kind regards; Piotr

      PS.

      FYI: Here goes a selection of my own blog posts where I feature SAP API Business Hub, SAP Appgyver and API Management:

      Author's profile photo Mariajose Martinez
      Mariajose Martinez
      Blog Post Author

      Hi Piotr, thanks for sharing your experience about API Management and AppGyver, and for sharing your blog posts! They are very useful to keep collaborating with the SAP community.

      Low-code/no-code will continue to increase interest as it helps to reduce time to value in developing custom applications, and API Management is also key to this purpose.

      Author's profile photo Burak Yilmaz
      Burak Yilmaz

      Hello Mariajose Martinez,

      Foremost, thank you for this excellent Blog series. I'm stuck at one step and need help. I followed all

      the steps correctly, but I still get the following error in Appgyver. One thing I noticed is that even

      though, I created a new Key Value Map. It shows Key Value Map Associated (undefined) in API

      overview.

       

       

      Kind regards

      Burak