Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

INTRODUCTION


 

In this document I'll try to explain the basics of the web services usage giving essential information that are valid for all of them. Each webservice has its own peculiarities and if you need more specific details have a look in Web Service APIs in SAP Cloud for Customer 1511 - November 2015.

In C4C, you can find the webservice list in: "Application and User Management > Input and Output Management > Service Explorer".

This topic is important for developers and analysts that are planning some custom integration or are just looking for another way of query and manipulate information in C4C. You can create the requests using tools like SOAPUI.

Basically, I'll explain how to use Query*In and Manage*In webservices and its main concepts.

My knowledge is still insufficient and I'm sorry if I wrote something wrong and for my english grammar mistakes =P. I hope you like it and, if necessary, please leave a post to correct me, so we can learn together.

 

QUERY*IN


 

When you download a webservice .wsdl file and open its definition, you will find the available methods that can be used, such as FindByElements, FindByIdentification, FindByCommunicationData etc, that vary from which webservice you are using. Despite of it, all of them work exactly the same way, but for different purposes. In this example, I'll use the QueryCustomerIn webservice and its FindByElements method.


 

First of all, lets understand the basic request structure tags.




  • Selection by elementsEach tag SelectionBy<FieldName> filters the query by a field and all of them have the following sub tags:

    • InclusionExclusionCode 

      • Excluding

      • Including



    • IntervalBoundaryTypeCode

      • 1: Equal to

      • 2: Between (excl. upper boundary)

      • 3: Between

      • 4: Between (excl. both boundaries)

      • 5: Between (excl. lower boundary)

      • 6: Less Than

      • 7: Less Than or Equal to

      • 8: Greater Than

      • 9: Greater Than or Equal to



    • LowerBoundary<FieldName>

      • Used to specify the initial value.



    • UpperBoundary<FieldName>

      • Used to specify the upper value. It's not mandatory when the IntervalBoundaryTypeCode is '1'.






 

  • Processing conditions: This tag is not mandatory. It's used to filter the result size.

    • QueryHitsMaximumNumberValue:

      • Number of records that will be send in the response. By default, only 100 records are returned.



    • QueryHitsUnlimitedIndicator:

      • If true, it blocks the response if exists more records than the number specified in QueryHitsMaximumNumberValue.









    • LastReturnedObjectID:

      • All responses that returns at least one record contains the last returned object ID. I'll show the use of it in the example 6 .






 

  • Requested elements: This tag is used to filter the response. You can use it to hide response tags you don't need and, consequently, reduce the message size. I'll show the use of it in the example 4. The table below shows a simplified options descriptions.

























1 Complete Structure The node element and all its elements, its child node elements and all their elements will be returned.
2 Complete Node The node element and all its elements will be returned.
3 Node with Key Elements The node element and its key elements will be returned (not supported by all web service interfaces.
4 Excluded Node The node element and its child node elements will not be returned.

 

  • Example 1: Query customer with ID 1000012.


<soap:Envelope>
<soap:Header/>
<soap:Body>
<glob:CustomerByElementsQuery_sync>
<CustomerSelectionByElements>
<SelectionByInternalID>
<InclusionExclusionCode>I</InclusionExclusionCode>
<IntervalBoundaryTypeCode>1</IntervalBoundaryTypeCode>
<LowerBoundaryInternalID>1000012</LowerBoundaryInternalID>
</SelectionByInternalID>
</CustomerSelectionByElements>
</glob:CustomerByElementsQuery_sync>
</soap:Body>
</soap:Envelope>


  • Example 2: Query customers with ID between 1000000 and 1000012.


<soap:Envelope>
<soap:Header/>
<soap:Body>
<glob:CustomerByElementsQuery_sync>
<CustomerSelectionByElements>
<SelectionByInternalID>
<InclusionExclusionCode>I</InclusionExclusionCode>
<IntervalBoundaryTypeCode>3</IntervalBoundaryTypeCode>
<LowerBoundaryInternalID>1000000</LowerBoundaryInternalID>
<UpperBoundaryInternalID>1000012</UpperBoundaryInternalID>
</SelectionByInternalID>
</CustomerSelectionByElements>
</glob:CustomerByElementsQuery_sync>
</soap:Body>
</soap:Envelope>


  • Example 3: Query customers with ID between 1000000 and 1000012 excluding 1000011.


<soap:Envelope>
<soap:Header/>
<soap:Body>
<glob:CustomerByElementsQuery_sync>
<CustomerSelectionByElements>
<SelectionByInternalID>
<InclusionExclusionCode>I</InclusionExclusionCode>
<IntervalBoundaryTypeCode>3</IntervalBoundaryTypeCode>
<LowerBoundaryInternalID>1000000</LowerBoundaryInternalID>
<UpperBoundaryInternalID>1000012</UpperBoundaryInternalID>
</SelectionByInternalID>
<SelectionByInternalID>
<InclusionExclusionCode>E</InclusionExclusionCode>
<IntervalBoundaryTypeCode>1</IntervalBoundaryTypeCode>
<LowerBoundaryInternalID>1000011</LowerBoundaryInternalID>
</SelectionByInternalID>
</CustomerSelectionByElements>
</glob:CustomerByElementsQuery_sync>
</soap:Body>
</soap:Envelope>

* It's possible to use the same selection tag more than once \o/

 

  • Example 4: Query customers with ID between 1000000 and 1000012 excluding 1000011. The response must contain only the customer node with key elements but the address information must exists.


<soap:Envelope>
<soap:Header/>
<soap:Body>
<glob:CustomerByElementsQuery_sync>
<CustomerSelectionByElements>
<SelectionByInternalID>
<InclusionExclusionCode>I</InclusionExclusionCode>
<IntervalBoundaryTypeCode>3</IntervalBoundaryTypeCode>
<LowerBoundaryInternalID>1000000</LowerBoundaryInternalID>
<UpperBoundaryInternalID>1000012</UpperBoundaryInternalID>
</SelectionByInternalID>
<SelectionByInternalID>
<InclusionExclusionCode>E</InclusionExclusionCode>
<IntervalBoundaryTypeCode>1</IntervalBoundaryTypeCode>
<LowerBoundaryInternalID>1000011</LowerBoundaryInternalID>
</SelectionByInternalID>
</CustomerSelectionByElements>
<RequestedElements customerTransmissionRequestCode="3">
<Customer addressInformationTransmissionRequestCode="1"/>
</RequestedElements>
</glob:CustomerByElementsQuery_sync>
</soap:Body>
</soap:Envelope>


  • Example 5: Query customers with ID between 1000000 and 1000012 excluding 1000011. The response must contain only the customer node with key elements but the address information must exists. Only the first customer is needed.


<soap:Envelope>
<soap:Header/>
<soap:Body>
<glob:CustomerByElementsQuery_sync>
<CustomerSelectionByElements>
<SelectionByInternalID>
<InclusionExclusionCode>I</InclusionExclusionCode>
<IntervalBoundaryTypeCode>3</IntervalBoundaryTypeCode>
<LowerBoundaryInternalID>1000000</LowerBoundaryInternalID>
<UpperBoundaryInternalID>1000012</UpperBoundaryInternalID>
</SelectionByInternalID>
<SelectionByInternalID>
<InclusionExclusionCode>E</InclusionExclusionCode>
<IntervalBoundaryTypeCode>1</IntervalBoundaryTypeCode>
<LowerBoundaryInternalID>1000011</LowerBoundaryInternalID>
</SelectionByInternalID>
</CustomerSelectionByElements>
<ProcessingConditions>
<QueryHitsMaximumNumberValue>1</QueryHitsMaximumNumberValue>
<QueryHitsUnlimitedIndicator>false</QueryHitsUnlimitedIndicator>
</ProcessingConditions>
<RequestedElements customerTransmissionRequestCode="2">
<Customer addressInformationTransmissionRequestCode="1"/>
</RequestedElements>
</glob:CustomerByElementsQuery_sync>
</soap:Body>
</soap:Envelope>

* If QueryHitsUnlimitedIndicator is true the request will show an error because I want only one customer but there are more than one for the specified conditions. If you want all customers in the specified conditions, the processing conditions must be:



<ProcessingConditions>
<QueryHitsUnlimitedIndicator>false</QueryHitsUnlimitedIndicator>
</ProcessingConditions>

* Be carefull with timeout and response message size =]

 

  • Example 6: Query the next customer from the previous query.


 

All responses contains the following tag, that shows how many records have returned, whether there are more records available and the last record node ID:


 
<ProcessingConditions>
<ReturnedQueryHitsNumberValue>1</ReturnedQueryHitsNumberValue>
<MoreHitsAvailableIndicator>true</MoreHitsAvailableIndicator>
<LastReturnedObjectID>00163E162F981ED5B6FCD7D58739E476</LastReturnedObjectID>
</ProcessingConditions>

Considering this, if you want the next record, in the request, specify the LastReturnedObjectID.



<ProcessingConditions>
<QueryHitsMaximumNumberValue>1</QueryHitsMaximumNumberValue>
<QueryHitsUnlimitedIndicator>false</QueryHitsUnlimitedIndicator>
<LastReturnedObjectID>00163E0924E61EE5B49B609769B5146E</LastReturnedObjectID>
</ProcessingConditions>

It's usefull if you wat to "page" the query results.

 

MANAGE*IN

 

The Manage*In webservices are used to create and maintain information and they always have the CheckMaintainBundle and MaintainBundle methods. The CheckMaintainBundle method is equal to the MaintainBundle but not persists the data in C4C, so, can be used to simulate the real request. In this document I'll use the ManageCustomerIn webservice for explanation.

Important request structure tags/attributes:

Most of the nodes have the following attributes/tags:



    • ActionCode: Attribute to specify the operation. Below, the simplified description is shown:









      • 01: Create

      • 02: Change

      • 03: Delete

      • 04: Save (Create if not exists, otherwise, update the record)

      • 05: Remove

      • 06: No action (check)









    • CompleteTransmissionIndicators: Attributes to specify if the node is complete or not. If you set it to true, all existing nodes that exists in C4C but aren't in the request will be removed from C4C.







    • ObjectNodeSenderTechnicalID: This tag contains a custom ID that represents the node (many nodes have this tag) and is set by the sender. As these webservices accepts many records in the same request (bundle), and considering that if one of them fails then the whole request fails too, this tag is very important to identify which record has failed. The response will return this ID, then you can handle it properly.




 

  • Example 1: Create a customer with address.


<soap:Envelope>
<soap:Header/>
<soap:Body>
<glob:CustomerBundleMaintainRequest_sync_V1>
<BasicMessageHeader/>
<Customer actionCode="01" addressInformationListCompleteTransmissionIndicator="true">
<ObjectNodeSenderTechnicalID>SENDER_CUSTOMER_1</ObjectNodeSenderTechnicalID>
<CategoryCode>2</CategoryCode>
<ProspectIndicator>false</ProspectIndicator>
<CustomerIndicator>true</CustomerIndicator>
<LifeCycleStatusCode>2</LifeCycleStatusCode>
<Organisation>
<CompanyLegalFormCode>14</CompanyLegalFormCode>
<FirstLineName>COMPANY NAME</FirstLineName>
</Organisation>
<ContactAllowedCode>1</ContactAllowedCode>
<AddressInformation actionCode="01">
<ObjectNodeSenderTechnicalID>SENDER_ADDRESS_1</ObjectNodeSenderTechnicalID>
<AddressUsage actionCode="01">
<AddressUsageCode>XXDEFAULT</AddressUsageCode>
<DefaultIndicator>true</DefaultIndicator>
</AddressUsage>
<Address actionCode="01">
<CorrespondenceLanguageCode>PT</CorrespondenceLanguageCode>
<PostalAddress>
<CountryCode>BR</CountryCode>
<RegionCode>PR</RegionCode>
<CountyName>BRASIL</CountyName>
<CityName>Curitiba</CityName>
<DistrictName>CENTRO</DistrictName>
<StreetPostalCode>80000-000</StreetPostalCode>
<StreetName>R TEST</StreetName>
<AdditionalStreetSuffixName/>
<HouseID>225</HouseID>
</PostalAddress>
</Address>
</AddressInformation>
</Customer>
</glob:CustomerBundleMaintainRequest_sync_V1>
</soap:Body>
</soap:Envelope>

 

  • Example 2: Adding a new main address, without modifying the customer and its existing address in C4C.


* The customer information won't change (actionCode="06")
* The address previously created won't be removed (addressInformationListCompleteTransmissionIndicator="false").


* Now it's mandatory to specify the customer key.



<soap:Envelope>
<soap:Header/>
<soap:Body>
<glob:CustomerBundleMaintainRequest_sync_V1>
<BasicMessageHeader/>
<Customer actionCode="06" addressInformationListCompleteTransmissionIndicator="false">
<InternalID>1000058</InternalID>
<AddressInformation actionCode="01">
<ObjectNodeSenderTechnicalID>SENDER_ADDRESS_2</ObjectNodeSenderTechnicalID>
<AddressUsage actionCode="01">
<AddressUsageCode>XXDEFAULT</AddressUsageCode>
<DefaultIndicator>true</DefaultIndicator>
</AddressUsage>
<Address actionCode="01">
<CountryCode>BR</CountryCode>
<RegionCode>PR</RegionCode>
<CountyName>BRASIL</CountyName>
<CityName>Curitiba</CityName>
<DistrictName>CENTRO</DistrictName>
<StreetPostalCode>80000-000</StreetPostalCode>
<StreetName>R TEST 2</StreetName>
<AdditionalStreetSuffixName/>
<HouseID>225</HouseID>
</Address>
</AddressInformation>
</Customer>
</glob:CustomerBundleMaintainRequest_sync_V1>
</soap:Body>
</soap:Envelope>

 

COMMON ERRORS

In this section I'll describe common error when using webservices. If someone knows some document that explains it better (what are the types, categories etc), I'd be pleased if you post a comment 😃

 

  • Some errors are shown in: "Application and User Management > Input and Output Management > Web Service Message Monitoring".


 

  • Gerneral errors: A general error in one of the customers in the request to illustrate the importance of the ObjectNodeSenderTechnicalID. The customer with sender ID 'SENDER_CUSTOMER_1' was rejected, but all the others were ok:


<env:Envelope>
<env:Header/>
<env:Body>
<n0:CustomerBundleMaintainConfirmation_sync_V1>
<Log>
<MaximumLogItemSeverityCode>3</MaximumLogItemSeverityCode>
<Item>
<TypeID>286(//APBP/R1/)</TypeID>
<CategoryCode>INC.BOI</CategoryCode>
<SeverityCode>3</SeverityCode>
<ReferenceObjectNodeSenderTechnicalID>SENDER_CUSTOMER_1</ReferenceObjectNodeSenderTechnicalID>
<Note>Business partner 1000058 already exists</Note>
</Item>
</Log>
</n0:CustomerBundleMaintainConfirmation_sync_V1>
</env:Body>
</env:Envelope>


  • Web service processing error: Apparently, it's related to some error in the xml structure. Review your request and check for mandatory fields.


<env:Envelope>
<env:Header/>
<env:Body>
<env:Fault>
<env:Code>
<env:Value>env:Receiver</env:Value>
</env:Code>
<env:Reason>
<env:Text xml:lang="en">Web service processing error; more details in the web service error log on provider side (UTC timestamp 20160512004624; Transaction ID 00163E162F571EE685FB5E7780150450)</env:Text>
</env:Reason>
<env:Detail/>
</env:Fault>
</env:Body>
</env:Envelope>


  • Authorization role missing for service: Some issue with the user permissions. Possibly, you'll have to create a communication arrangement for this service:


<env:Envelope>
<env:Header/>
<env:Body>
<env:Fault>
<env:Code>
<env:Value>env:Receiver</env:Value>
</env:Code>
<env:Reason>
<env:Text xml:lang="en">Authorization role missing for service "ServiceInterface http://sap.com/xi/A1S/Global ReadSalesPriceListIn &lt;default> &lt;default>", operation "Operation http://sap.com/xi/A1S/Global Read" (UTC timestamp 20160509191431; Transaction ID 00163E19BB2F1EE685C3483BF5E6CB73)</env:Text>
</env:Reason>
<env:Detail/>
</env:Fault>
</env:Body>
</env:Envelope>

 

  • Authentication error: Check the user and password.


 

 

Best regards,

Alexandre Kaminagakura
27 Comments
Labels in this area