Creating a JWT Token
Note: It is recommended to use the library from JWT.io.
A JWT (JSON Web Token) needs to be created by the consumer application using the details provided below.
JWT Header:
- alg: The algorithm used for JWT, i.e., HS256.
- typ: The token type, i.e., JWT.
JWT Payload:
-
sub:
- Data Type: String.
- Client Company Name: For example, Company name.
exp:
- Data Type: Integer or String.
- Token expiry timestamp in UTC (timestamp should be in seconds; for example, 2019/09/16 22:50:28 → 1568674228).
site_id:
- Data Type: Integer or String.
- The Annex Cloud site ID assigned to the client.
hmac:
- Data Type: String.
- This will be the HMACSHA256 hash of the JSON object using a shared secret. The JSON object will be:
- Payload for POST or PATCH APIs, or
- URL parameters for GET APIs.
For POST or PATCH Requests:
- Transfer the payload into JSON format and escape special characters (for example, Chinese characters "零一" → "\u96f6\u4e00").
- In PHP, we use the json_encode function, which not only formats the payload to JSON but also escapes non-ASCII characters into ASCII escape sequences.
-
Important Note:
If your payload contains non-ASCII characters, and you skip the escaping process, it could lead to JWT authentication failures. Be sure to properly escape these characters to ensure smooth authentication.
- Base64 encodes the escaped JSON string → encoded_payload.
- Use the shared secret key to encrypt the encoded_payload with SHA256 → encrypted_payload.
- Base64 encodes the encrypted_payload → hmac value.
PHP Code Example for POST or PATCH Request:
//POST
//Create User & Opt-in User API
$payload = [
"id" => '2',
"email" => 'abrar2@sdsol.com',
"firstName" => 'Abrar',
"lastName" => 'Khan'
];
$payload = json_encode($payload);
$payload = base64_encode($payload);
$hmac = base64_encode(hash_hmac('sha256', $payload, $key, true));For GET Requests:
- For GET requests, there can be at most one parameter. Transfer this parameter into JSON format and escape special characters (similar to POST requests).
- In PHP, use the json_encode function to format the parameter into JSON and escape non-ASCII characters.
- Follow the same steps (Base64 encode the payload, hash with HMACSHA256, and encode the hash) as in the POST request to generate the hmac value.
Example of GET Request:
// Get User Details API
// GET /users/{id}
// id = manojit9@gmail.com
$payloadUserGet = 'manojit9@gmail.com';
$payload = json_encode($payloadUserGet);Important Note:
When sending http POST or PATCH requests, the request body must match the raw payload that was used to generate the hmac. A mismatch will result in a 401 unauthorized error.
JWT Signature:
- The JWT must be signed using a shared secret.
- Use the following formula to sign the JWT:
HMACSHA256(base64urlencoded(JWT_header) + "." + base64urlencoded(JWT_payload), sharedsecret)- JWT Token:
base64urlencoded(JWT_Header).base64urlencoded(JWT_Payload).JWT_SignatureThis JWT token should be passed as the token to display the loyalty dashboard.
Using Client Access Token:
To access public APIs, you need to add the following headers to your requests:
- Authorization: Bearer <token>
- X-AnnexCloud-Site: <site_id>
- Content-Type: application/json
Fetch JWT Token for POST API Call:
Implementation Note: This API is used to fetch the JWT token for POST method API calls.
Request:
| Method | URL |
|---|---|
| POST |
https://api.socialannex.com/sapcrm/token.php |
Fetch JWT Token for GET API Call:
Implementation Note: This API is used to fetch the JWT token for GET method API calls.
Request:
| Method | URL |
|---|---|
| POST | https://api.socialannex.com/sapcrm/gettoken.php |
Loyalty APIs
Create User and Opt-In User API: POST
Implementation Note: This API is used to create a user in the database and add that particular user to the loyalty program (i.e., Opt-in for the loyalty program).
Request:
| Method | URL |
|---|---|
| POST | /users |
| Parameter | Parameter Description | Parameter Type |
|---|---|---|
| id | Enter the user’s unique ID. | string |
| Enter the user’s email address. | string | |
| firstName | Enter the user’s first name. | string |
| lastName | Enter the user’s last name. | string |
| optInStatus | Enter the opt-in status as YES for opt-in and NO for opt-out. By default, it will be YES. | string |
| status | Enter the user status as active (default) or inactive. | string |
| phone | Enter the user’s phone number. | string |
| birthdate | Enter the user’s birthdate. | date (yyyy-mm-dd) |
| createDate | Enter the create date of the user. | date (yyyy-mm-dd) |
| anniversaryDate | Enter the anniversary date, which can be either birthdate or loyalty program joining date. | date (yyyy-mm-dd) |
| userProfileImageUrl | Enter the user’s profile image URL. | string |
| extendedAttribute | Enter the attribute keys and their values apart from the ones mentioned above. | string |
Sample Request:
{
"id": "user@domain.com",
"email": "user@domain.com",
"firstName": "John",
"lastName": "Doe",
"zipCode": "90002",
"optInStatus": "YES",
"status": "ACTIVE",
"phone": "123-123-4567",
"birthDate": "2018-04-01T00:00:00-0700",
"anniversaryDate": "2018-04-01T00:00:00-0700",
"userProfileImageUrl": "https://www.socialannex.com/public/manageoptionsdesign16/images/product_landing/loyalty-hover.png",
"createDate": "2018-04-01T00:00:00-0700",
"updateDate": "2018-04-01T00:00:00-0700",
"extendedAttribute": {"KEY1": "VALUE1", "KEY2": "VALUE2"}
}Response:
This API will create a user and opt them into the loyalty program, returning details such as the user's name, opt-in status, phone, birthdate, anniversary date, and so on.
Output Fields:
| Parameter | Parameter Description | Parameter Type |
|---|---|---|
| id | Displays unique identifier (in the SA system) used to identify the user. | string |
| Displays the email address of the user. | string | |
| firstName | Displays the first name of the user. | string |
| lastName | Displays the last name of the user. | string |
| optInStatus | Displays the opt-in status of the user. | string |
| status | Displays the status of the user (active or inactive). By default, it will be active, but can be changed to inactive if the client requests. | string |
| phone | Displays the phone number of the user. | string |
| birthDate | Displays the birthdate of the user in yyyy-MM-dd'T'HH:mm:ssZ format. | date (yyyy-mm-dd) |
| anniversaryDate | Displays the anniversary date of the user in yyyy-MM-dd'T'HH:mm:ssZ format. | date (yyyy-mm-dd) |
| userProfileImageUrl | Displays the URL of the user’s profile image. If not passed during creation, this field will be blank. | string |
| createDate | Displays the date on which the user was created in yyyy-MM-dd'T'HH:mm:ssZ format. | date (yyyy-mm-dd) |
| updateDate | Displays the date on which the user details were updated in yyyy-MM-dd'T'HH:mm:ssZ format. | date (yyyy-mm-dd) |
| extendedAttribute | Displays the extra user attributes, which will vary according to the client. | string |
| errorCode | Displays only when the API request fails, indicating the type of error. | string |
| errorMessage | Displays the reason why the API request has failed. | string |
Sample Positive Response:
| Status Code | Response |
|---|---|
| 200 |
An example of positive response is: { "id": "user@domain.com", "email": "user@domain.com", "firstName": "John", "lastName": "Doe", "zipCode": "90002", "optInStatus": "YES", "status": "ACTIVE", "phone": ""123-123-4567", "birthDate": "2018-04-01T00:00:00-0700", "anniversaryDate": "2018-04-01T00:00:00-0700", "userProfileImageUrl": "https://www.socialannex.com/public/manageoptionsdesign16/images/product_landing/loyalty-hover.png", "createDate": "2018-04-01T00:00:00-0700", "updateDate": "2018-04-01T00:00:00-0700", "extendedAttribute": ["KEY1": "VALUE1", "KEY2": "VALUE2"] } |
Sample Error Response:
| Status Code | Response |
|---|---|
| AC1002 |
An example of error response is: { "errorCode": "AC1001", "errorMessage": "Oops! Something went wrong." } |
Add or Remove Points API: POST
Implementation Note: This API is used to give and redeem loyalty points to a user.
Request:
| Method | URL |
|---|---|
| POST | /points |
To Give Points:
| Parameter | Parameter Description | Parameter Type |
|---|---|---|
| id | Enter the user’s unique ID. | string |
| actionId | Enter the action ID (it is mandatory if the action ID is set at the site admin). | string |
| activity | Enter the activity as CREDIT or DEBIT. | string |
| orderId | If the activity is DEBIT, pass the order ID. | string |
| reason | Enter the reason for adding or removing the points. (If the action ID is not passed, then the reason is mandatory). | string |
To Redeem Points:
| Parameter | Parameter Description | Parameter Type |
|---|---|---|
| id | Enter the user’s unique ID. | string |
| rewardId | Enter the reward ID (it is mandatory if the reward ID is set at the site admin). | string |
| activity | Enter the activity as CREDIT or DEBIT. | string |
| orderId | If the activity is DEBIT, pass the order ID. | string |
| reason | Enter the reason for adding or removing the points (If the reward ID is not passed, then the reason is mandatory). | string |
| source | Enter the source as web or store. | string |
To Redeem Custom Points:
| Parameter | Parameter Description | Parameter Type |
|---|---|---|
| id | Enter the user’s unique ID. | string |
| activity | Enter the activity as DEBIT. | string |
| orderId | If the activity is DEBIT, pass the order ID. | string |
| debit | Enter the number of debited points. | string |
| reason | Enter the reason for adding or removing the points. | string |
| source | Enter the source as web or store. | string |
To Award or Deduct Custom Points:
| Parameter | Parameter Description | Parameter Type |
|---|---|---|
| id | Enter the user’s unique ID. | string |
| actionId | Enter the action ID. (It is mandatory if the action ID is set at the site admin) | string |
| activity | Enter the activity as CREDIT or DEBIT. | string |
| orderId | If the activity is DEBIT, pass the order ID. | string |
| credit or debit | Enter the number of credited or debited points. | string |
| reason | Enter the reason for adding or removing the points. (If the action ID is not passed then the reason is mandatory) | string |
Sample Requests:
To Give Points:
{
"id": "user@domain.com",
"actionId": "100",
"activity": "CREDIT",
"reason": "Bonus",
"credit": "50"
}To Redeem Points:
{
"id": "user@domain.com",
"rewardId": "111",
"activity": "DEBIT",
"orderId": "OD001",
"reason": "Claim",
"source": "web"
}To Redeem Custom Points:
{
"id": "user@domain.com",
"activity": "DEBIT",
"orderId": "OD001",
"debit": "500",
"reason": "Used for purchase",
"source": "web"
}To Award Custom Points:
{
"id": "user@domain.com",
"actionId": "100",
"activity": "CREDIT",
"credit": "50",
"reason": "Bonus"
}To Deduct Custom Points:
{
"id": "user@domain.com",
"actionId": "100",
"activity": "DEBIT",
"orderId": "OD001",
"debit": "50",
"reason": "Adjustment"
}Response:
The API will return a success response with the details of the points that were added or redeemed from the user’s account.
Output Fields:
| Parameter | Parameter Description | Parameter Type |
|---|---|---|
| id | Displays the unique user’s ID. | string |
| actionId | Displays the particular action ID. | string |
| activity | Displays the action as credit or debit. | string |
| credit | Displays the number of points credited in the user's account. | integer |
| pointsAwarded | Displays the number of points awarded. | integer |
| updatedUserTier | Displays the updated user tier after the points awarded or removed. | string |
| updatedAvailablePoints | Displays the number of updated available points. | integer |
| updatedLifetimePoints | Displays the number of updated lifetime points. | integer |
| releaseDate | Displays the release date in yyyy-mm-dd format on which the hold points will be released. | date (yyyy-mm-dd) |
| reason | Displays the reason for adding or removing the points. | string |
| errorCode | Displays only when the API request fails, this will denote the type of error. | string |
| errorMessage | Displays the reason why the API request has been failed. | string |
Sample Positive Responses:
Give Points Response:
{
"id": "johan28.sa@gmial.com",
"actionId": 100,
"activity": "CREDIT",
"credit": 50,
"pointsAwarded": 50,
"reason": "Bonus",
"updatedUserTier": "Gold",
"updatedAvailablePoints": 7561,
"updatedLifetimePoints": 7561
}Redeem Points Response:
{
"id": "user@domain.com",
"rewardId": "111",
"activity": "DEBIT",
"orderId": "OD001",
"debit": "500",
"reason": "Claim",
"updatedUserTier": "Gold",
"updatedAvailablePoints": 4545,
"updatedLifetimePoints": 7860
}Redeem Custom Points Response:
{
"id": "user@domain.com",
"activity": "DEBIT",
"orderId": "OD001",
"debit": "500",
"reason": "Used for purchase",
"updatedUserTier": "Gold",
"updatedAvailablePoints": 4545,
"updatedLifetimePoints": 7860
}Add Custom Points Response:
{
"id": "user@domain.com",
"actionId": "100",
"activity": "CREDIT",
"credit": "50",
"reason": "Bonus",
"updatedUserTier": "Gold",
"updatedAvailablePoints": 4545,
"updatedLifetimePoints": 7860
}Deduct Custom Points Response:
{
"id": "user@domain.com",
"actionId": "100",
"activity": "DEBIT",
"orderId": "OD001",
"debit": "50",
"reason": "Adjustment",
"updatedUserTier": "Gold",
"updatedAvailablePoints": 4545,
"updatedLifetimePoints": 7860
}Sample Error Response:
| Status Code | Response |
|---|---|
| AC1002 |
An example of error response is: { "errorCode": "AC1002", "errorMessage": "Request Not Authorized" } |
View Points Details API: GET
Implementation Note: This API allows you to view the point details of a user.
Request:
| Method | URL |
|---|---|
| GET | /points/{id} |
Sample Request:
/points/user@domain.com
Response:
This will return the point details of the user.
Output fields:
| Parameter | Parameter Description | Parameter Type |
|---|---|---|
| id | Displays the unique ID of the user. | string |
| availablePoints | Displays the available points of the user. | integer |
| usedPoints | Displays the points that have been used by the user. | integer |
| expiredPoints | Displays the points that have expired. | integer |
| lifetimePoints | Displays the total points the user has earned since the account was created. | integer |
| earnedPointsPeriod | Displays the earned points period (For example., anniversaryYear, calendarYear, quarter, semester). | string |
| spendPointsPeriod | Displays the spend points period (For example., anniversaryYear, calendarYear, quarter, semester). | string |
| earnedPoints | Displays the total earned points in the selected earnedPointsPeriod. | integer |
| spendPoints | Displays the total spent points in the selected spendPointsPeriod. | integer |
| holdPoints | Displays the total number of hold points. | integer |
| usedPointsOnReward | Displays the number of points used on rewards. | integer |
| pointsToExpire | Displays the number of points that are about to expire. | integer |
| pointsToNextTier | Displays the number of points needed to achieve the next tier. | integer |
| pointsToExpireDate | Displays the date (in yyyy-mm-dd format) on which the points will expire. | date (yyyy-mm-dd) |
| spendToNextTier | Displays the amount the user needs to spend to achieve the next tier (only shown if the tier functionality is based on spending). | integer |
| creditsToCurrencyRatio | Displays the credits to currency ratio set by the site admin. | float |
| creditsToCurrencyValue | Displays the converted value of credits to currency based on the ratio. | float |
| errorCode | Displays only when the API request fails, this will denote the type of error. | string |
| errorMessage | Displays the reason why the API request has been failed. | string |
Sample Positive Response:
| Status Code | Response |
|---|---|
| 200 |
An example of a positive response is: { "id": "johan19.sa@gmail.com", "availablePoints": "6656", "usedPoints": "600", "expiredPoints": "0", "lifetimePoints": "7256", "earnedPointsPeriod": "anniversaryYear", //calenderYear,quarter,semester "spendPointsPeriod": "calenderYear", //anniversaryYear,quarter,semester "earnedPoints": "1200", "spendPoints": "350", "holdPoints": 1000, "usedPointsOnReward": "600", "pointsToExpire": "56", "pointsToNextTier": 0, "spendToNextTier": 0, "pointsToExpireDate": "2020-01-30T05:30:00+0000", "creditsToCurrencyRatio": "1", "creditsToCurrencyValue": 6656, } |
Sample Error Response:
| Status Code | Response |
|---|---|
| AC1002 |
An example of an error response is: { "errorCode": "AC1002", "errorMessage": "Request Not Authorized" } |
Get Tier Information API: GET
Implementation Note: This API retrieves information about the user’s tier.
Request:
| Method | URL |
|---|---|
| GET | /users/{id}/tiers |
Sample Request:
/users/user@domain.com/tiers
Response:
This will return the tier details of the user.
Output Fields:
| Parameter | Parameter Description | Parameter Type |
|---|---|---|
| currentTier | Displays the name of the current tier. | string |
| previousTier | Displays the previous tier that was assigned to the user. | string |
| tierAchieveDate | Displays the date when the current tier was achieved (in yyyy-MM-dd'T'HH:mm:ssZ format). | date (yyyy-mm-dd) |
| tierExpirationDate | Displays the date when the current tier will expire (in yyyy-MM-dd'T'HH:mm:ssZ format). | date (yyyy-mm-dd) |
| nextTier | Displays the name of the next tier. | string |
| pointsToNextTier | Displays the number of points required to achieve the next tier. | integer |
| purchaseRatio | Displays the purchase ratio applied to the user (from this tier) for earning purchase points. | float |
| currentTierPurchaseRatio | Displays the purchase ratio applied to the user for the current tier. | float |
| spendAmountToNextTier | Displays the amount the user needs to spend to achieve the next tier. | integer |
| errorCode | Displays only when the API request fails, this will denote the type of error. | string |
| errorMessage | Displays the reason why the API request has failed. | string |
Sample Positive Response
| Status Code | Response |
|---|---|
| 200 |
An example of a positive response is: { "currentTier": "Silver", "previousTier": "Bronze", "tierAchieveDate": "2018-04-01T14:00:00-0700", "tierExpirationDate": "2018-04-01T14:00:00-0700", "nextTier": "Gold", "PointsToNextTier": "120", "purchaseRatio": "2", "currentTierPurchaseRatio": "0.5", "spendAmountToNextTier": "" } |
Sample Error Response:
| Status Code | Response |
|---|---|
| AC1002 |
An example of an error response is: { "errorCode": "AC1002", "errorMessage": "Request Not Authorized" } |
Update User Details API: PATCH
Implementation Note: This API allows you to update the details of a user.
Request:
| Method | URL |
|---|---|
| PATCH | /users/{id} |
| Parameter | Parameter Description | Parameter Type |
|---|---|---|
| id | Enter the user’s unique ID. | string |
| Enter the user’s email address. | string | |
| updateId | Enter the user’s new email address. | string |
| firstName | Enter the user’s first name. | string |
| lastName | Enter the user’s last name. | string |
| optInStatus | Enter the opt-in status as YES for opt-in and NO for opt-out. By default, it will be YES. | string |
| status | Enter the current status of the user. For example, active or inactive. | string |
| phone | Enter the user’s phone number. | string |
| birthdate | Enter the user’s birthdate. | date (yyyy-mm-dd) |
| createDate | Enter the create date of the user. | date (yyyy-mm-dd) |
| anniversaryDate | Enter the anniversary date which can be either birthdate or loyalty program joining date. | date (yyyy-mm-dd) |
| userProfileImageUrl | Enter the user’s profile image URL. | string |
| extendedAttribute | Enter the attribute keys and their values apart from the ones mentioned above (according to client’s request). | string |
Sample Request:
{
"id": "user@domain.com",
"updateId": "user_1@domain.com",
"email": "user@domain.com",
"firstName": "John",
"lastName": "Doe",
"zipCode": "90002",
"optInStatus": "YES",
"status": "ACTIVE",
"phone": "123-123-4567",
"birthDate": "2018-04-01T00:00:00-0700",
"anniversaryDate": "2018-04-01T00:00:00-0700",
"userProfileImageUrl": "https://www.socialannex.com/public/manageoptionsdesign16/images/product_landing/loyalty-hover.png",
"createDate": "2018-04-01T00:00:00-0700",
"updateDate": "2018-04-01T00:00:00-0700",
"extendedAttribute": [
{"KEY1": "VALUE1"},
{"KEY2": "VALUE2"}
]
}Response:
This will update the details of the user.
Output Fields:
| Parameter | Parameter Description | Parameter Type |
|---|---|---|
| id | Displays unique identifier (in the SA system) used to identify the user. | string |
| Displays the email address of the user. | string | |
| firstName | Displays the first name of the user. | string |
| lastName | Displays the last name of the user. | string |
| zipCode | Displays the zip code of the user’s location. | string |
| status | Displays the current status of the user (active or inactive). | string |
| phone | Displays the phone number of the user. | string |
| birthDate | Displays the birthdate of the user in yyyy-MM-dd'T'HH:mm:ssZ format. | date (yyyy-mm-dd) |
| anniversaryDate | Displays the anniversary date of the user in yyyy-MM-dd'T'HH:mm:ssZ format. | date (yyyy-mm-dd) |
| userProfileImageUrl | Displays the URL of the user’s profile image. | string |
| createDate | Displays the date on which the user was created in yyyy-MM-dd'T'HH:mm:ssZ format. | date (yyyy-mm-dd) |
| updateDate | Displays the date on which the user details were updated in yyyy-MM-dd'T'HH:mm:ssZ format. | date (yyyy-mm-dd) |
| extendedAttribute | Displays the extra user attributes which will vary according to the client. | string |
| errorCode | Displays only when the API request fails, this will denote the type of error. | string |
| errorMessage | Displays the reason why the API request has failed. | string |
Sample Positive Response:
| Status Code | Response |
|---|---|
| 200 |
An example of a positive response is: { "id": "user_1@domain.com", "email": "user_1@domain.com", "firstName": "John", "lastName": "Doe", "zipCode": "90002", "optInStatus": "YES", "status": "ACTIVE", "phone": "123-123-4567", "birthDate": "2018-04-01T00:00:00-0700", "anniversaryDate": "2018-04-01T00:00:00-0700", "userProfileImageUrl": "https://www.socialannex.com/public/manageoptionsdesign16/images/product_landing/loyalty-hover.png", "createDate": "2018-04-01T00:00:00-0700", "updateDate": "2018-04-01T00:00:00-0700", "extendedAttribute": ["KEY1": "VALUE1", "KEY2": "VALUE2"] } |
Sample Error Response:
| Status Code | Response |
|---|---|
| AC1002 |
An example of an error response is: { "errorCode": "AC1002", "errorMessage": "Request Not Authorized" } |
SAP Service Cloud
Login to SAP Cloud Application Studio
- Download SAP Cloud Application Studio from the SAP Marketplace using your S-User ID and Password.
- After the installation is complete, you must connect to your repository by clicking on the SAP Cloud Application Studio icon.
- A popup will appear.
- Click on the pencil icon and refer to the image below to log in to your repository.
- After completing the above steps, log in to SAP Cloud Application Studio using the technical user account.
Creating a REST API Call in SAP Cloud Application Studio
- Always create a folder structure to keep your code organized as shown in the image below.
- Create a new folder in the solution explorer as illustrated above.
- Click on the folder you created, then right-click it and select ADD → NEW ITEM. The following popup will open.
- Click on Extend Web Service Integration, choose REST API, and enter the app URL. The REST parameters will be added automatically.
- Click on Communication Scenario, choose REST, then select Custom Outbound Service. Select the checkbox for the web service integration name.
- After completing these two steps, proceed with creating Communication Arrangements.
- Right-click on the communication scenario you created in the solution explorer and click Manage Communication Arrangement.
- Search for your communication scenario and configure it properly. Once done, the API call will be functional.
Creating Tables in the Database (Extended Business Object)
- Create a new folder in the solution explorer as mentioned in section 3.2.
- Right-click on the folder you created and select ADD → NEW ITEM. The following popup will open. Search for Business Object Extension or Business Object.
- If you want to create a new database table, select Business Object.
- If you want to extend an existing table, select Business Object Extension.
Example of a Business Object:
[Extension] businessobject AP.FO.BusinessPartner.Global:Customer raises MsgAnnexCloudCreate {
message MsgAnnexCloudCreate text "Annex says: &1":LANGUAGEINDEPENDENT_MEDIUM_Text;
// You must activate this business object before you can access the extension fields
// or messages in script files, forms, and screens.
node AddressInformation {}
node Common {
// These fields are requested by Annex Cloud
//Those are already part of standard
//1. First Name (Text)
//2. Last Name (Text)
//3. Email (Email)
//4. Phone Number (Number)
//5. Birth Date (Date)
// Those are extended below
//6. Opt-in Status (Text)
//7 Available Points (Number)
//8 Current Tier (String)
//9 Next Tier (String)
//10 Points To Next Tier (Number)
//11 Spend Amount To Next Tier (Number)
//12 Previous Tier (String)
[Label("Opt-in")] element OptInCheckBox:Indicator;
[Label("Opt-in Status")] element OptInStatus:MediumText;
[Label("Available Points")] [Decimal (10,0)] element AvailablePoints:DecimalValue;
[Label("Current Tier")] element CurrentTier :MediumText;
[Label("Next Tier")] element NextTier:MediumText;
//[Label("Next Tier")] [Decimal (10,0)] element NextTier:DecimalValue;
[Label("Points To Next Tier")] [Decimal (10,0)] element PointsToNextTier:DecimalValue;
[Label("Spend Amount To Next Tier")] [Decimal (10,0)] element SpendAmountToNextTier:DecimalValue;
[Label("Previous Tier")] element PreviousTier:MediumText;
} node Identification {}
node CurrentEmployeeResponsible {}Note: You must activate this business object before you can access the extension fields or messages in script files, forms, and screens.
Generating Script File
- After creating a Business Object or Extended Business Object, you need to create a script file to write the business logic.
- Right-click on the Business Object or Extended Business Object, and select Create Script File.
- Generate the script file, and you will be ready to write your business logic.
- Refer to the image below for the steps to generate the script file.
Creating Mashups
- Mashups are used to load or integrate (via iFrame) third-party UI into SAP Service Cloud.
To Access Mashups:
- Navigate to Administration → Mashup Authority.
We can create three different types of mashups. In our case, we will create an HTML Mashup.
- In the HTML Mashup, add all the required parameters, including input parameters.
Example 1:

- Add all the data mentioned in the image above to load from the URL link.
Example 2:

- Pass parameters such as email, token, and pageID to the URL.

- To load the Mashup into the desired location, follow these steps:
- Open the location where you want to add the Mashup screen.
- Click on Adaptation Mode and add the Mashup.

- To add the Mashup to your UI:
- Click the Add button and add your tabs.
- Click on the tab you created and click the pencil icon.
- After clicking the pencil icon, you can add the mashups.
Creating OData
- It is possible to update data into SAP C4C from third-party integrations using OData.
To Access OData:
- Navigate to Administration → OData Service Explorer.
- Create a new custom OData service and configure it as required.
- Provide the Service Name and enable Data Workbench.
- Specify the Business Object and add the required fields you want to update via OData.
- After completing the setup, it should look like the image below.
- Use Postman to test the OData API.
OData Service API Call: Pushing Data into SAP C4C System
This section explains how to push data into the SAP C4C system using the OData API.
Generating CSRF Token in SAP C4C OData Service
You can create a user in SAP C4C using the OData API with Postman.
OData Service URL:
Steps to Generate the CSRF Token:
URL:
Authorization:
Basic authentication is required using your SAP C4C username and password.
Method:
| KEY | VALUE | |
|---|---|---|
| Header | x-csrf-token | fetch |

Creating a User in SAP C4C
Once you have obtained the CSRF token, you can use it to create a user in SAP C4C.
OData Service URL for User Creation:
https://my348600.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi/IndividualCustomerCollection
Steps to Create a User:
- Method: POST
- Authorization: Basic authentication is required using your SAP C4C username and password.
| KEY | VALUE | |
|---|---|---|
| Header | x-csrf-token | xaDnKGdvABrFgwTkbeUcxw== |
Request Body:
{
"FirstName": "Delta",
"LastName": "Jena",
"NextTier_SDK": "200",
"Mobile": "809325",
"Email": "jena@test.com",
"PointsToNextTier_SDK": "",
"OptInStatus_SDK": "",
"CurrentTier_SDK": "",
"SpendAmountToNextTier_SDK": "",
"PreviousTier_SDK": "",
"AvailablePoints_SDK": "100"
}Response:
Upon successful creation of the user, you will receive a response in XML format similar to the one below:
<?xml version="1.0" encoding="utf-8"?>
<entry m:etag="W/"datetimeoffset'2021-05-17T06%3A35%3A57.0717100Z'""
xml:base="https://my348600.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi/"
xmlns="http://www.w3.org/2005/Atom"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>https://my348600.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi/IndividualCustomerCollection('00163EB
03F731EEBADDB4445DB5EED43')</id>
<title type="text">IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')</title>
<updated>2021-05-17T06:35:57Z</updated>
<category term="c4codata.IndividualCustomer"
scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')" rel="edit"
title="IndividualCustomer"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerAddress"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerAddress"
type="application/atom+xml;type=feed" title="IndividualCustomerAddress"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerAttachmentFolde
r"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerAttachmentFolder"
type="application/atom+xml;type=feed" title="IndividualCustomerAttachmentFolder"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerIdentification"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerIdentification"
type="application/atom+xml;type=feed" title="IndividualCustomerIdentification"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerSalesData"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerSalesData"
type="application/atom+xml;type=feed" title="IndividualCustomerSalesData"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerSkills"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerSkills"
type="application/atom+xml;type=feed" title="IndividualCustomerSkills"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerTaxNumber"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerTaxNumber"
type="application/atom+xml;type=feed" title="IndividualCustomerTaxNumber"/>
<link href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerTeam"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerTeam"
type="application/atom+xml;type=feed" title="IndividualCustomerTeam"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerTextCollection"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerTextCollection"
type="application/atom+xml;type=feed" title="IndividualCustomerTextCollection"/>
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerVisitingInforma
tionDetails"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerVisitingInformation
Details" type="application/atom+xml;type=feed" title="IndividualCustomerVisitingInformationDetails"/>
<link href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/OwnerEmployeeBasicData"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/OwnerEmployeeBasicData"
type="application/atom+xml;type=entry" title="OwnerEmployeeBasicData"/>
<content type="application/xml">
<m:properties>
<d:ObjectID>00163EB03F731EEBADDB4445DB5EED43</d:ObjectID>
<d:CustomerID>1000839</d:CustomerID>
<d:UUID>00163EB0-3F73-1EEB-ADDB-4445DB5EED43</d:UUID>
<d:ExternalID/>
<d:ExternalSystem/>
<d:RoleCode>CRM000</d:RoleCode>
<d:RoleCodeText>Customer</d:RoleCodeText>
<d:LifeCycleStatusCode>2</d:LifeCycleStatusCode>
<d:LifeCycleStatusCodeText>Active</d:LifeCycleStatusCodeText>
<d:CustomerABCClassificationCode/>
<d:CustomerABCClassificationCodeText/>
<d:ContactPermissionCode/>
<d:ContactPermissionCodeText/>
<d:TitleCode/>
<d:TitleCodeText/>
<d:AcademicTitleCode/>
<d:AcademicTitleCodeText/>
<d:FirstName>Dell</d:FirstName>
<d:MiddleName/>
<d:LastName>Jena</d:LastName>
<d:AdditionalLastName/>
<d:Initials/>
<d:NickName/>
<d:GenderCode>0</d:GenderCode>
<d:GenderCodeText>Gender not known</d:GenderCodeText>
<d:NamePrefixCode/>
<d:NamePrefixCodeText/>
<d:MaritalStatusCode/>
<d:MaritalStatusCodeText/>
<d:LanguageCode/>
<d:LanguageCodeText/>
<d:BirthName/>
<d:BirthDate m:null="true"/>
<d:NationalityCountryCode/>
<d:NationalityCountryCodeText/>
<d:ProfessionCode/>
<d:ProfessionCodeText/>
<d:FormattedName>Dell Jena</d:FormattedName>
<d:FormattedPostalAddressDescription/>
<d:CountryCode/>
<d:CountryCodeText/>
<d:StateCode/>
<d:StateCodeText/>
<d:CareOfName/>
<d:AddressLine1/>
<d:AddressLine2/>
<d:HouseNumber/>
<d:AdditionalHouseNumber/>
<d:Street/>
<d:AddressLine4/>
<d:AddressLine5/>
<d:District/>
<d:City/>
<d:DifferentCity/>
<d:StreetPostalCode/>
<d:County/>
<d:POBoxIndicator>false</d:POBoxIndicator>
<d:POBox/>
<d:POBoxPostalCode/>
<d:POBoxDeviatingCountryCode/>
<d:POBoxDeviatingCountryCodeText/>
<d:POBoxDeviatingStateCode/>
<d:POBoxDeviatingStateCodeText/>
<d:POBoxDeviatingCity/>
<d:TimeZoneCode/>
<d:TimeZoneCodeText/>
<d:TaxJurisdictionCode/>
<d:TaxJurisdictionCodeText/>
<d:Building/>
<d:Floor/>
<d:Room/>
<d:Phone/>
<d:NormalisedPhone/>
<d:Mobile/>
<d:NormalisedMobile/>
<d:Fax/>
<d:Email>Dell@test.com</d:Email>
<d:EmailInvalidIndicator>false</d:EmailInvalidIndicator>
<d:WebSite/>
<d:BestReachedByCode/>
<d:BestReachedByCodeText/>
<d:OrderBlockingReasonCode/>
<d:OrderBlockingReasonCodeText/>
<d:DeliveryBlockingReasonCode/>
<d:DeliveryBlockingReasonCodeText/>
<d:BillingBlockingReasonCode/>
<d:BillingBlockingReasonCodeText/>
<d:SalesSupportBlockingIndicator>false</d:SalesSupportBlockingIndicator>
<d:RecommendedVisitingFrequency/>
<d:VisitDuration/>
<d:LastVisitingDate m:null="true"/>
<d:NextVisitingDate m:null="true"/>
<d:LatestRecommendedVisitingDate m:null="true"/>
<d:OwnerID/>
<d:OwnerUUID m:null="true"/>
<d:CreationOn>2021-05-17T06:35:57.0717100Z</d:CreationOn>
<d:CreatedBy>Eddie Smoke</d:CreatedBy>
<d:CreatedByIdentityUUID>00163E03-A070-1EE2-88BA-39BD20F290B5</d:CreatedByIdentityUUID>
<d:ChangedOn>2021-05-17T06:35:57.0717100Z</d:ChangedOn>
<d:ChangedBy>Eddie Smoke</d:ChangedBy>
<d:ChangedByIdentityUUID>00163E03-A070-1EE2-88BA-39BD20F290B5</d:ChangedByIdentityUUID>
<d:EntityLastChangedOn>2021-05-17T06:35:57.0717100Z</d:EntityLastChangedOn>
<d:ETag>2021-05-17T06:35:57.0717100Z</d:ETag>
<d:NextTier_SDK>0</d:NextTier_SDK>
<d:AvailablePoints_SDK>0</d:AvailablePoints_SDK>
<d:PointsToNextTier_SDK>0</d:PointsToNextTier_SDK>
<d:OptInStatus_SDK/>
<d:CurrentTier_SDK/>
<d:SpendAmountToNextTier_SDK>0</d:SpendAmountToNextTier_SDK>
<d:PreviousTier_SDK/>
</m:properties>
</content>
</entry>
<?xml version="1.0" encoding="utf-8"?>
<entry m:etag="W/"datetimeoffset'2021-05-17T06%3A35%3A57.0717100Z'""
xml:base="https://my348600.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi/"
xmlns="http://www.w3.org/2005/Atom"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<id>https://my348600.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi/IndividualCustomerCollect
ion('00163EB03F731EEBADDB4445DB5EED43')</id>
<title
type="text">IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')</title>
<updated>2021-05-17T06:35:57Z</updated>
<category term="c4codata.IndividualCustomer"
scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')" rel="edit"
title="IndividualCustomer"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerAdd
ress"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerAddress
" type="application/atom+xml;type=feed" title="IndividualCustomerAddress"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerAtt
achmentFolder"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerAttachm
entFolder" type="application/atom+xml;type=feed"
title="IndividualCustomerAttachmentFolder"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerIde
ntification"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerIdentif
ication" type="application/atom+xml;type=feed" title="IndividualCustomerIdentification"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerSal
esData"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerSalesDa
ta" type="application/atom+xml;type=feed" title="IndividualCustomerSalesData"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerSki
lls"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerSkills"
type="application/atom+xml;type=feed" title="IndividualCustomerSkills"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerTax
Number"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerTaxNumb
er" type="application/atom+xml;type=feed" title="IndividualCustomerTaxNumber"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerTea
m"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerTeam"
type="application/atom+xml;type=feed" title="IndividualCustomerTeam"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerTex
tCollection"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerTextCol
lection" type="application/atom+xml;type=feed" title="IndividualCustomerTextCollection"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/IndividualCustomerVis
itingInformationDetails"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/IndividualCustomerVisitin
gInformationDetails" type="application/atom+xml;type=feed"
title="IndividualCustomerVisitingInformationDetails"/>
<link
href="IndividualCustomerCollection('00163EB03F731EEBADDB4445DB5EED43')/OwnerEmployeeBasicDat
a"
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/OwnerEmployeeBasicData"
type="application/atom+xml;type=entry" title="OwnerEmployeeBasicData"/>
<content type="application/xml">
<m:properties>
<d:ObjectID>00163EB03F731EEBADDB4445DB5EED43</d:ObjectID>
<d:CustomerID>1000839</d:CustomerID>
<d:UUID>00163EB0-3F73-1EEB-ADDB-4445DB5EED43</d:UUID>
<d:ExternalID/>
<d:ExternalSystem/>
<d:RoleCode>CRM000</d:RoleCode>
<d:RoleCodeText>Customer</d:RoleCodeText>
<d:LifeCycleStatusCode>2</d:LifeCycleStatusCode>
<d:LifeCycleStatusCodeText>Active</d:LifeCycleStatusCodeText>
<d:CustomerABCClassificationCode/>
<d:CustomerABCClassificationCodeText/>
<d:ContactPermissionCode/>
<d:ContactPermissionCodeText/>
<d:TitleCode/>
<d:TitleCodeText/>
<d:AcademicTitleCode/>
<d:AcademicTitleCodeText/>
<d:FirstName>Dell</d:FirstName>
<d:MiddleName/>
<d:LastName>Jena</d:LastName>
<d:AdditionalLastName/>
<d:Initials/>
<d:NickName/>
<d:GenderCode>0</d:GenderCode>
<d:GenderCodeText>Gender not known</d:GenderCodeText>
<d:NamePrefixCode/>
<d:NamePrefixCodeText/>
<d:MaritalStatusCode/>
<d:MaritalStatusCodeText/>
<d:LanguageCode/>
<d:LanguageCodeText/>
<d:BirthName/>
<d:BirthDate m:null="true"/>
<d:NationalityCountryCode/>
<d:NationalityCountryCodeText/>
<d:ProfessionCode/>
<d:ProfessionCodeText/>
<d:FormattedName>Dell Jena</d:FormattedName>
<d:FormattedPostalAddressDescription/>
<d:CountryCode/>
<d:CountryCodeText/>
<d:StateCode/>
<d:StateCodeText/>
<d:CareOfName/>
<d:AddressLine1/>
<d:AddressLine2/>
<d:HouseNumber/>
<d:AdditionalHouseNumber/>
<d:Street/>
<d:AddressLine4/>
<d:AddressLine5/>
<d:District/>
<d:City/>
<d:DifferentCity/>
<d:StreetPostalCode/>
<d:County/>
<d:POBoxIndicator>false</d:POBoxIndicator>
<d:POBox/>
<d:POBoxPostalCode/>
<d:POBoxDeviatingCountryCode/>
<d:POBoxDeviatingCountryCodeText/>
<d:POBoxDeviatingStateCode/>
<d:POBoxDeviatingStateCodeText/>
<d:POBoxDeviatingCity/>
<d:TimeZoneCode/>
<d:TimeZoneCodeText/>
<d:TaxJurisdictionCode/>
<d:TaxJurisdictionCodeText/>
<d:Building/>
<d:Floor/>
<d:Room/>
<d:Phone/>
<d:NormalisedPhone/>
<d:Mobile/>
<d:NormalisedMobile/>
<d:Fax/>
<d:Email>Dell@test.com</d:Email>
<d:EmailInvalidIndicator>false</d:EmailInvalidIndicator>
<d:WebSite/>
<d:BestReachedByCode/>
<d:BestReachedByCodeText/>
<d:OrderBlockingReasonCode/>
<d:OrderBlockingReasonCodeText/>
<d:DeliveryBlockingReasonCode/>
<d:DeliveryBlockingReasonCodeText/>
<d:BillingBlockingReasonCode/>
<d:BillingBlockingReasonCodeText/>
<d:SalesSupportBlockingIndicator>false</d:SalesSupportBlockingIndicator>
<d:RecommendedVisitingFrequency/>
<d:VisitDuration/>
<d:LastVisitingDate m:null="true"/>
<d:NextVisitingDate m:null="true"/>
<d:LatestRecommendedVisitingDate m:null="true"/>
<d:OwnerID/>
<d:OwnerUUID m:null="true"/>
<d:CreationOn>2021-05-17T06:35:57.0717100Z</d:CreationOn>
<d:CreatedBy>Eddie Smoke</d:CreatedBy> <d:CreatedByIdentityUUID>00163E03-A070-1EE2-
88BA-39BD20F290B5</d:CreatedByIdentityUUID>
<d:ChangedOn>2021-05-17T06:35:57.0717100Z</d:ChangedOn>
<d:ChangedBy>Eddie Smoke</d:ChangedBy> <d:ChangedByIdentityUUID>00163E03-A070-1EE2-
88BA-39BD20F290B5</d:ChangedByIdentityUUID>
<d:EntityLastChangedOn>2021-05-17T06:35:57.0717100Z</d:EntityLastChangedOn>
<d:ETag>2021-05-17T06:35:57.0717100Z</d:ETag>
<d:NextTier_SDK>0</d:NextTier_SDK>
<d:AvailablePoints_SDK>0</d:AvailablePoints_SDK>
<d:PointsToNextTier_SDK>0</d:PointsToNextTier_SDK>
<d:OptInStatus_SDK/>
<d:CurrentTier_SDK/>
<d:SpendAmountToNextTier_SDK>0</d:SpendAmountToNextTier_SDK>
<d:PreviousTier_SDK/>
</m:properties>
</content>
</entry>Updating Users using SAP C4C ODATA Service
After creating a user in SAP C4C, you need to check the response to retrieve the user ID for performing update operations.

URL for the Update Operation:
- Authorization: Basic authentication is required using your SAP C4C username and password.
- HTTP Method: PATCH
| KEY | VALUE | |
|---|---|---|
| Header | x-csrf-token | xaDnKGdvABrFgwTkbeUcxw== |
Request Body:
{
"FirstName": "Delta",
"LastName": "Jena",
"NextTier_SDK": "200",
"Mobile": "809325",
"Email": "jena@test.com",
"PointsToNextTier_SDK": "",
"OptInStatus_SDK": "",
"CurrentTier_SDK": "",
"SpendAmountToNextTier_SDK": "",
"PreviousTier_SDK": "",
"AvailablePoints_SDK": "100"
}Response:
- Status Code: 204 (No content)
Once the user is created in SAP C4C, you can proceed to create the same user in Annex Cloud by setting the Opt-In status to Yes.

Opt-Out User from Annex Cloud Loyalty
A user can opt-out from the loyalty program in Annex Cloud by the customer support agent in SAP Service Cloud.

Logging into SAP C4C
Creating Users in SAP C4C
In SAP Cloud for Customer (C4C), users can be created in two ways:
- Using the SAP C4C terminal
- Using the ODATA Service
Creating Users Using the SAP C4C Terminal
-
Login: Access SAP C4C by logging in with your credentials.
-
Navigate: From the sidebar, choose Customer → Individual Customer.
-
Complete the Form: Fill in the required details, and once done, the user will be created in both SAP C4C and the Annex Cloud loyalty dashboard.