Walmart provides many APIs; one that seems to be often used is the Marketplace. This API implements multiple authentication mechanisms, including a delegated access based on Oauth2 Client Credentials. Documentation here: Walmart Marketplace Delegated Access.
Since Client Credentials is not provided by the native Make HTTP app, if you want to be able to call this API, the best way is to build a Custom App.
I will show you step by step how to start configuring the Custom App. It’s not a complete App, but it should help you get started.
Please note the following:
- It assumes that you already have an account in the Walmart Marketplace
- It will be configured to leverage the sandbox provided by Walmart. You will have to change the Base URL to the production server once you are sure the Custom App works
- It will contain a couple of modules to help you start with the API, you will need to build your own modules of you need different endpoints. However, we’ll add an Universal Module (Make an API Call) so that you can easily use the App as-is.
- We could build a more sophisticated App with the capability for the user in the scenario to choose between Sandbox and Production, but for the simplicity, we “hard-code” the base url (which will have to be changed when you’re ready to use the App in production).
Let’s start
Go to Custom Apps, and select “Create new app”
Give the App the name you want. But follow the pattern for internal name (I suggest wallmart-xxxx) with xxxx your initials or name.
For the Theme, I suggest #0072DC (I picked this color from the Walmart website).
For the logo, try and download the png I added below and use it.
In Base, add the following JSON (see after the screenshot)
{
// Default request configuration
"baseUrl": "https://sandbox.walmartapis.com/v3", // Default base URL for all modules and RPCs.
"headers": { // Default HTTP headers for all modules and RPCs.
"WM_SEC.ACCESS_TOKEN": "{{connection.accessToken}}",
"WM_SVC.NAME" : "{{connection.serviceName}}",
"WM_QOS.CORRELATION_ID" : "{{uuid}}"
},
// Default response handling
"response": {
"error": { // Error handling
"message": "[{{statusCode}}] {{body.error}}" // On error, returns error message as "[statusCode] error text".
}
},
"log": {
"sanitize": [ // Excludes sensitive parameters from logs.
"request.headers" // Omit HTTP header "Authorization".
]
}
}
And Save
Go to Connection, and Create a new Connection
Give it a Label (this name will appear in Connections, so make it clear), and choose Oauth 2 (client credentials)
In Communication, copy/paste the following JSON (see after screenshot)
{
// OAuth2 access token request
"token": {
"condition": "{{if(data.accessToken, data.expires < addMinutes(now, 1), true)}}",
// Request
"url": "https://sandbox.walmartapis.com/v3/token",
"headers": {
"Authorization" : "Basic {{base64(parameters.clientId + ':' + parameters.clientSecret)}}",
"WM_SVC.NAME" : "{{parameters.serviceName}}",
"WM_QOS.CORRELATION_ID" : "{{uuid}}",
"accept" : "application/json"
},
"method": "POST",
"body": {
"grant_type": "client_credentials"
},
"type": "urlencoded",
// Token response handling
"response": {
"data": {
"expires": "{{addSeconds(now, body.expires_in)}}", // Stores new accessToken expiration date.
"accessToken": "{{body.access_token}}" // Stores new accessToken.
}
},
"log": {
"sanitize": [ // Excludes sensitive parameters from logs.
"request.body.client_secret",
"response.body.access_token"
]
}
}
}
IMPORTANT: Note that the URL used is also the sandbox! When you change the App for production, you have to change the URL here as well.
After you have saved, go to Parameters, and copy/paste the following JSON
[
{
"name": "clientId",
"type": "text",
"label": "Client ID",
"required": true
},
{
"name": "clientSecret",
"type": "text",
"label": "Client Secret",
"required": true
},
{
"name": "serviceName",
"type": "text",
"label": "Wallmart Service Name",
"required": true
}
]
Save
We want to add an universal module so that you can add any new endpoint in your scenario, still leveraging the authentication. Let’s add it
Go to Modules and click Create a new Module
For Type, select Universal
For Subtype, select REST
Choose the Connection you created earlier
Give the module a Name, Label and Description
You don’t need to do anything else, keep all defaults, your module is ready.
Let’s add 2 other modules (Search Orders and Get an Order)
Note that Search Orders will not be complete, because it will not allow any filter. You may want to extend it later to allow the search of specific orders.
Go back to Modules, and click Create a new Module
In Type, select Search
In Connection, select the connection you created earlier
Give your module a Name, Label and Description
In Communication, copy/paste the JSON below
{
// Request to API endpoint.
"url": "/orders", // Relative to base URL
"method": "GET",
"headers": {
"Content-Type" : "application/x-www-form-urlencoded",
"accept" : "application/json"
}, // Additional HTTP headers
"qs": {
"limit" : "{{parameters.limit}}"
},
"response": {
"output": "{{body}}"
}
}
Save
Go to Mappable Parameters and copy/paste the JSON below
// Defines "search" and "limit" as module input parameters.
[
{
"name": "limit",
"type": "number",
"label": "Limit",
"default": 10,
"validate" : {"min": 1, "max": 100},
"help": "Maximum number of returned results (max 100)."
}
]
Save
Go to Interface and remove everything after [ and before ]
It should look like the screenshot below
Save
You are done with the Search Orders module. Let’s add a third module Get an Order
Go to Modules and click Create a new Module
For Type, select Search
Select the connection you created earlier
Give it a Name, Label and Description
In Communication, copy/paste the JSON below
{
// Request to API endpoint.
"url": "/orders/{{parameters.purchaseOrderId}}", // Relative to base URL
"method": "GET",
"headers": {
"Content-Type" : "application/x-www-form-urlencoded"
}, // Additional HTTP headers
// Response handling
"response": {
"output": "{{body}}"
}
}
Save
Go to Mappable Parameters and copy/paste the JSON below
[
{
"name": "purchaseOrderId", // Makes value accesible via "{{parameters.search}}".
"type": "text", // Sets the type to text.
"label": "Order ID", // Sets the user friendly label visible in the module
"help": "The ID of the order." // Sets the help text with an example under input field in the module.
}
]
Save
Go to Interface and remove everything after [ and before ]
It should look like the screenshot below
Save
Your 3 modules are ready to be tested!
But you need to make them Visible.
Go back to Modules and set the 3 modules to Visible
Now you can go to a scenario to test it.
It’s just a starting point. What you could now do is:
- add the capability for the user to choose between the Sandbox and Production when he creates the connection. In that case you will use “if” conditions in the URLs to choose the relevant URL based on the choice of the user.
- add as many modules as required, including action modules to create orders or other objects
- share your module with others (only the runtime not the source).
- add relevant parameters in Search Orders, in order to filter.
- etc, etc