API Documentation

Oauth 2.0 Implementation for Xoxoday Client

Xoxoday implemented standard Oauth 2.0 protocol for its clients to access relevant resources.

Let’s go through the steps of implementing the Oauth Client side.

STEP 1 - Client Registration

Firstly, you need to register your app as a client on the Xoxoday side. For registration, you have to give your redirect_uri and scope which is required for the app with the explanation.

After approval, the Client will be given client_id and client_secret.

(As of now these details are to be shared over an email to our Xoxoday Support Team. After registration client_id and client_secret are shared with the client by Xoxoday Support Team)

Xoxoday supports the following scopes

User Scopes

  • xoxo_link

PLEASE NOTE: OAUTH_URL value for Development - https://stagingaccount.xoxoday.com/chef

Production - https://accounts.xoxoday.com/chef

STEP 2 - Authorization Request

This is the first request in Oauth process when client requests for authorization code by redirecting to following url {OAUTH_URL}/v1/oauth/authorize?client_id=a597871aeb01fc7715e7f064bf6846fc&response_type=code&redirect_uri={client_redirect_url}&scope=xoxo_link&state={client_state}

client_id* (required) - This is the client_id value that you got after registration.

response_type* (required) - Although Oauth supports different response_type values. The only value supported by Xoxoday is code

redirect_uri* (required) - The URL domain must match to URL which you have shared in the registration STEP 1.

scope* (required) - The scope values must be the values mentioned in STEP 1. If there are multiple scopes send them separated by a comma. For eg. xoxo_link.

state (optional, Recommended) - As per OAuth protocol, this value is optional. This value is generated by the client. When the authorization request is completed the same value is passed to client in the redirected url so that client can verify the request.

If all the above parameters are validated successfully and user is already authenticated, then the user is redirected to the following authorization consent page

If the user is not authenticated, then the user will be redirected to the following login/signup page

After authentication, the user will again be redirected to the authorization consent(allow/deny) page.

If the user is denied access, then the browser will be redirected to the following URL:

{client_redirect_url}?error=access_denied&error_description=The+user+denied+the+request&state={client_state}

If the user allowed the request, then the browser will be redirected to the following URL:

{client_redirect_url}?code=exxxx69660xxxxa6413c17d897xxxxx99&state={client_state}

In the above-redirected URL, code is a temporary token created on account of client allowed access which is valid for 5 min duration. Later this code is exchanged for access_token which is used for accessing Xoxoday resources granted based on the scopes allowed by the user.

STEP 3 - Token Exchange

In this step as per Oauth protocol the code received by the client in STEP 2, will be exchanged to get the access_token which is used for accessing Xoxoday resources granted based on the scopes allowed by the user.

The client-server (As this request involves sensitive information i.e, client_secret) must make the following POST request to get the access_token

curl -X POST {OAUTH_URL}/v1/oauth/token/{token_type}
-d '{
"grant_type":"authorization_code",
"code":"exxxx69660xxxxa6413c17d897xxxxx99",
"redirect_uri":"{client_redirect_url}",
"client_id":"{client_id}",
"client_secret":"{client_secret}"
}'

Let's discuss the variables which are involved in the above request

token_type* (required) - token_type value is user

grant_type* (required) - Although Oauth supports different grant_type values. The values supported by Xoxoday is authorization_code, refresh_token

code* (required) - This is the temporary code value that the client has obtained after STEP 2.

redirect_uri* (required) - The URL must match to URL which you have shared in the registration STEP 2.

client_id* (required) - This is the client_id value that you got after registration in STEP 1.

client_secret* (required) - This is the client_secret value that you got after registration in STEP 1.

After validation of these parameters by the Xoxoday server, the successful response will be

{
"access_token": "eyJ0b2tlbkNvbnRlbnQiOnsiaXNzdWVkRm9yIjoiRnJlc2h3b3JrcyIsInNjb3BlIjoiIiwiaXNzdWVkQXQiOjE1NTk4MDQ1NTAxMzYsImV4cGlyZXNBdCI6IjIwMTktMDctMDZUMDc6MDI6MzAuMTM2WiIsInRva2VuX3R5cGUiOiJDT01QQU5ZIn0sImFfdCI6ImY3ZWM1MWMyYmE0ZGNmNzY2ZWE0ZDExMTI3ZjEzZjQzZjAwZmNhN2EifQ==",
"token_type": "bearer",
"expires_in": 2592000,
"refresh_token": "064be187f42e9238122ef9d7a985c8800dff3752",
"email":"
" //email will only be in the response of company session generation
}

In the above response

access_token is the bearer token that can be used by a client to access the API of Xoxoday.

token_type is a bearer that must be passed in the Authorization header.

expires_in is the duration (in seconds) for which access_token is valid. The default user session lasts for 15 days.

refresh_token is the value with which the client can regenerate expired access_token. This refresh token for the user session lasts for 30 days.

Failure response

This service returns 200 ok if successful.

All other HTTP code returned by the service has conventional meanings.

Please refer to the meaning of HTTP codes here -> https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

Diagram for STEP 2 and STEP 3

STEP 4 - Apis and Options

Based on the user access_token obtained in STEP 3 or STEP 4, clients can make requests to Xoxoday based on the scoped allowed requests for generating user access_token.

Here is the sample API request for accessing the campaign list API.

curl -X POST {OAUTH_URL}/v1/oauth/api
-H 'Authorization: Bearer eyJ0b2tlbkNvbnRlbnQiOnsiaXNzdWVkRm9yIjoiRnJlc2h3b3JrcyIsInNjb3BlIjoiIiwiaXNzdWVkQXQiOjE1NTk4MDQ1Nzg1ODIsImV4cGlyZXNBdCI6IjIwMTktMDYtMjFUMDc6MDI6NTguNTgyWiIsInRva2VuX3R5cGUiOiJVU0VSIn0sImFfdCI6ImV5SmxibU1pT2lKQk1USTRRMEpETFVoVE1qVTJJaXdpWVd4bklqb2lSVU5FU0MxRlV5SXNJbXRwWkNJNkltVnVZeUlzSW1Wd2F5STZleUpyZEhraU9pSkZReUlzSW1OeWRpSTZJbEF0TWpVMklpd2llQ0k2SWpoMmJVTkVRMUZQZW1wQlNHWndabXQ0TVhjNVluZHphM1JhZWtRek0ySXRZamx0VVhSclEyRnhNV3NpTENKNUlqb2lZMGR0V2kxdWIySjBWbUptTVdGdVNraDBUMmxoWW5VMFZHUlVhRzVVYmpCYWRuWnJabGMwYzBWb2N5SjlmUS4uU1h3TlNUSWhFUXNlN0htaXpPUmFIQS5NRzBVUy1lek1IOEFsbWFLc2ZTY3Nwa2FlYzBIcW9FcUV1YXRoNHRSTTRpeVg2dFByX1ZjTnlsdnk5YjlGLTZHR01DbjY1TjYwYnpIUUJtRVZvZGRYVWlvQS1kTkpuaE9KdThHczRfeW9pM042VGFOdWhjRENCUGtwWk1CeTlDRjJBaEh4UGotQkd0SzdEamhNbjBBQXpTM1VhTE11eUdrTmNwSGxQSUxNcFlVM'
-d '{
"tag":"xoxo_link",
"query":"xoxo_link.query.campaignList",
"variables" : { "add_data": { "limit": 10, "offset": 0, "name": "", “enabled” : 1} }
}'

“enabled” key is optional (1: all enabled campaigns, 0: all disabled campaigns) If the “enabled” key is not sent, it will return all the campaigns with status in each.

Here in the above request

Authorization header is the Bearer User access_token obtained by the client from STEP 3/STEP

The response to the above request is:

{
"data": {
"campaignList": {
"success": 1,
"data": [
{
"campaignId": 1,
"campaignName": "Campaign 1",
"denomination_value": 50,
"countryName": "India",
"currencyCode": "INR",
"created_date": "2020-06-03T22:06:23.000Z",
"product_count": 2,
"status" : 1
},
{
"campaignId": 2,
"campaignName": "Campaign 2",
"denomination_value": 100,
"countryName": "India",
"currencyCode": "INR",
"created_date": "2020-06-01T11:33:22.000Z",
"product_count": 10,
"status" : 0
},
{
"campaignId": 3,
"campaignName": "Campaign 3",
"denomination_value": 500,
"countryName": "India",
"currencyCode": "INR",
"created_date": "2020-06-01T11:26:35.000Z",
"product_count": 5,
"status" : 1
}
]
}
}
}

Success<Integer>: 0 (Failure) / 1 (Successful)

data<Array>: campaign list and overview details in the array

Here is the sample API request for accessing Campaign Details API.

curl -X POST {OAUTH_URL}/v1/oauth/api
-H 'Authorization: Bearer eyJ0b2tlbkNvbnRlbnQiOnsiaXNzdWVkRm9yIjoiRnJlc2h3b3JrcyIsInNjb3BlIjoiIiwiaXNzdWVkQXQiOjE1NTk4MDQ1Nzg1ODIsImV4cGlyZXNBdCI6IjIwMTktMDYtMjFUMDc6MDI6NTguNTgyWiIsInRva2VuX3R5cGUiOiJVU0VSIn0sImFfdCI6ImV5SmxibU1pT2lKQk1USTRRMEpETFVoVE1qVTJJaXdpWVd4bklqb2lSVU5FU0MxRlV5SXNJbXRwWkNJNkltVnVZeUlzSW1Wd2F5STZleUpyZEhraU9pSkZReUlzSW1OeWRpSTZJbEF0TWpVMklpd2llQ0k2SWpoMmJVTkVRMUZQZW1wQlNHWndabXQ0TVhjNVluZHphM1JhZWtRek0ySXRZamx0VVhSclEyRnhNV3NpTENKNUlqb2lZMGR0V2kxdWIySjBWbUptTVdGdVNraDBUMmxoWW5VMFZHUlVhRzVVYmpCYWRuWnJabGMwYzBWb2N5SjlmUS4uU1h3TlNUSWhFUXNlN0htaXpPUmFIQS5NRzBVUy1lek1IOEFsbWFLc2ZTY3Nwa2FlYzBIcW9FcUV1YXRoNHRSTTRpeVg2dFByX1ZjTnlsdnk5YjlGLTZHR01DbjY1TjYwYnpIUUJtRVZvZGRYVWlvQS1kTkpuaE9KdThHczRfeW9pM042VGFOdWhjRENCUGtwWk1CeTlDRjJBaEh4UGotQkd0SzdEamhNbjBBQXpTM1VhTE11eUdrTmNwSGxQSUxNcFlVM'
-d '{
"tag":"xoxo_link",
"query":"xoxo_link.mutation.campaignDetails",
"variables": { "data": {
"campaignId" : <campaignId>
}
}
}'

The response of above request is:

{
"data": {
"campaignDetails": {
{
"success": 1,
"data": [
{
"campaignId": 1,
"campaignName": "Campaign 1",
"denomination_value": 50,
"currency_code": "INR",
"countryName": "India",
"vouchers": [
{
"name": "Cafe Coffee Day",
"image": "https://res.cloudinary.com/dyyjph6kx/image/upload/gift_vouchers/phpEM8etY_o4j0il.jpg"
},
{
"name": "Gaana",
"image": "https://res.cloudinary.com/dyyjph6kx/image/upload/gift_vouchers/data/vendor_experience/157527386957b2cac6b37385.57735634.jpg"
}
],
}
]
}
}
}
}

Status<Integer>: 0 (Failure) / 1 (Successful)

Message<String!Object>: User-friendly Error message in case of Failure / Success message in case of success.

Links<Array>: links in the array as per quantity requested.

Here is the sample API request for accessing generate link API.

curl -X POST {OAUTH_URL}/v1/oauth/api
-H 'Authorization: Bearer eyJ0b2tlbkNvbnRlbnQiOnsiaXNzdWVkRm9yIjoiRnJlc2h3b3JrcyIsInNjb3BlIjoiIiwiaXNzdWVkQXQiOjE1NTk4MDQ1Nzg1ODIsImV4cGlyZXNBdCI6IjIwMTktMDYtMjFUMDc6MDI6NTguNTgyWiIsInRva2VuX3R5cGUiOiJVU0VSIn0sImFfdCI6ImV5SmxibU1pT2lKQk1USTRRMEpETFVoVE1qVTJJaXdpWVd4bklqb2lSVU5FU0MxRlV5SXNJbXRwWkNJNkltVnVZeUlzSW1Wd2F5STZleUpyZEhraU9pSkZReUlzSW1OeWRpSTZJbEF0TWpVMklpd2llQ0k2SWpoMmJVTkVRMUZQZW1wQlNHWndabXQ0TVhjNVluZHphM1JhZWtRek0ySXRZamx0VVhSclEyRnhNV3NpTENKNUlqb2lZMGR0V2kxdWIySjBWbUptTVdGdVNraDBUMmxoWW5VMFZHUlVhRzVVYmpCYWRuWnJabGMwYzBWb2N5SjlmUS4uU1h3TlNUSWhFUXNlN0htaXpPUmFIQS5NRzBVUy1lek1IOEFsbWFLc2ZTY3Nwa2FlYzBIcW9FcUV1YXRoNHRSTTRpeVg2dFByX1ZjTnlsdnk5YjlGLTZHR01DbjY1TjYwYnpIUUJtRVZvZGRYVWlvQS1kTkpuaE9KdThHczRfeW9pM042VGFOdWhjRENCUGtwWk1CeTlDRjJBaEh4UGotQkd0SzdEamhNbjBBQXpTM1VhTE11eUdrTmNwSGxQSUxNcFlVM'
-d '{
"tag":"xoxo_link",
"query":"xoxo_link.mutation.generateLink",
"variables": { "data": {
"campaignId" : <campaignId>,
"links_quantity" : <quantity>
}
}
}'

The response to the above request is:

{
"data": {
"generateLink": { "success": Status,
"message": "Message",
"links" : ["{link1}, {link2}, {link2}, ..."] }
}
}

Status<Integer>: 0 (Failure) / 1 (Successful)

Message<String!Object>: User-friendly Error message in case of Failure / Success message in case of success.

Links<Array>: links in the array as per quantity requested