Authentication

Shoplazza API authentication

To make sure all transactions on Shoplazza's platform safe and secure, all apps connected with Shoplazza APIs must authenticated when making API request.


Authentication Types

Different types of Apps use different authentication methods:

  • Public apps use OAuth
  • Private apps use Access-Token

App Definition
Any web application connects with Shoplazza is referred as an App, regardless of how it's exposed to end users.

Please make sure you know the different between the authentication types mentioned above before your kick start your development.


OAuth

Public apps must authenticate using OAuth 2.0 to use Shoplazza's API resources.

Terminology
before we head into the details of OAuth process, please make sure you understand the terminology below:

  • Client: Client refer to Any App who want to access Store Resources.
  • APIShoplazza's RESTful API,Client could use API provided to retrieve and update Store Resources.
  • UserShoplazza Account's owner, also refer as Merchant. User need to authorised Client different permissions to access the Store Resources so that Client could use API to retrieve or update it.

OAuth Process
Here's a brief process for OAuth 2.0 to authenticate Shoplazza API Request.

  1. The merchant make a request to install the App.
  2. The App redirect to Shoplazza's permission page, which is a prompt page demonstrated the App's name and what scopes it required.
  3. The merchant consents to the scoped permissions and redirect back to the redirect_uri.
  4. The App make a access token request to Shoplazza including code, client_id, and client_secret
  5. Shoplazza return the correct access code
  6. The App use the access_code to make requests to Shoplazza RESTful API
  7. Shoplazza return the requested Data.

Step 1: Obtain the Client ID & Client Secret

To obtain the Client ID & Client Secret, you need to contact Shoplazza's support, during this process, you need to provide informations including app_uri and redirect_uri

📘

How to Obtain the Client ID & Client Secret

Please contact the developer of Shoplazza via email ([email protected]) to obtain the Client Key and Client Secret. During this process, you need to provide basic information as follows:

Company Information:

  • Company business brief introduction.
  • Official website address.
  • Partner contact email.

App basic information:

  1. App URL, which app provide service via this URL as the main entrance.
  2. Redirect URI, which is used for the OAuth callback address.
  3. App icon (size 150x150, PNG format).
  4. Email address for contact.
  5. App name, both in Chinese and English.
  6. App brief description, both in Chinese and English.
  7. Permissions you app needed: store information, customers, orders, products (see developer documentation for details) etc.

After review process by Shoplazza's developer, you will receive an email which contains your app's Client ID and Client Secret.

🚧

Further Notice

The way to obtain the Client ID & Client Secret described above will be changed to a more easier and more self assistant way through Partner Center website in the future, stay tuned for the further notice!

Step 2: Get API Access Token

1. Ask for permissions

To show the App's prompt page for the merchant to start with, Shoplazza will first call app_uri the app provided in Step 1, and response to redirect the merchant to the following URL with the query parameters defined below:

https://{store_name}.myshoplaza.com/admin/oauth/authorize?client_id={client_id}&scope={scopes}&redirect_uri={redirect_uri}&response_type={response_type}
  • store_name: The name of merchant's store.
  • client_id: The Client ID for the app.
  • scope: A space separated list of scopes. For example, to write orders and read customers, use scope=write_order read_customer.
  • redirect_uri: The URL to which a merchant is redirected after authorizing the app.
  • response_type: The response type of OAuth 2.0 process, here we need to fill in code

2. Confirm Installation

When the merchant clicks the install button in the prompt, they're redirected to your app's server and using redirect_uri provided in Step 2. The authorization_code is passed in the confirmation redirect.

http://example.com/some/redirect_uri?code={authorization_code}&shop={store_name}.myshoplaza.com&hmac={hmac}
Security Checks

Before we continue, make sure your app performs the following security checks. If any of the checks faill, then your app must reject the request with an error, and must not cotinue.

  • The hmac is valid and signed by Shoplazza
  • The shop parameter is a valid shop hostname, ends with myshoplazza.com
Get a permanent access token

If all security checks pass, then you can exchange the authorization_code for a permanent access token by sending a request to the shop's access_token endpoint:

POST https://{store_name}.myshoplaza.com/admin/oauth/token

In this request, store_name is the name of the merchant's store and alongs with the following parameters:

  • client_id: The Client ID for the App.
  • client_secret: The Client secret key for the app.
  • code: The authorization_code provided in the redirect.
  • grant_type: The grant type of OAuth 2.0 process, please fill in authorization_code here.
  • redirect_uri: The redirect_uri of the app.

The server responds with an access token:

{
  "token_type": "Bearer",
  "expires_at": 1550546245,
  "access_token": "eyJ0eXAiOiJKV1QiLCJh",
  "refresh_token": "def502003d28ba08a964e",
  "store_id": "2",
  "store_name": "xiong1889"
}
  • token_type: It will just return Bearer.
  • expires_at: The access_token expired time, in timestamp.
  • access_token: The correct access_token.
  • refresh_token: The refresh token used to refresh the access_token if needed.
  • store_id: Store's ID in Shoplazza
  • store_name: Store name
Refresh the access token

After access_token expired, The app need to call following endpoint to retrieve a new access_token and a new refresh_token ( Please save it into your app and you are gonna need it later)

POST https://{store_name}.myshoplaza.com/admin/oauth/token

In this request, following parameters are needed:

  • client_id: The Client ID that Shoplazza provided.
  • client_secret: The Client secret key that Shoplazza provided.
  • refresh_token: The refresh_token that mentioned above.
  • grant_type: The grant type of OAuth 2.0 process, please fill in refresh_token here.
  • redirect_uri: The redirect_uri of the app.

Step 3: Make authenticated requests

After your app has retrieved an API access_token, it can make authenticated request to Admin API.

These request are accompanied with a header Access-Token: {access_token} where {access_token} is replaced with the permanent token.

The following request show how to retrieve a list of products using the Admin API

curl -i -X GET \
     -H "Content-Type:application/json" \
     -H "Access-Token:B_x-_5aVeXNwI-4AB98s5xLIvgv0fNzGf_MuTpqtIBA" \
     'https://store.myshoplaza.com/openapi/2020-01/products'

Private App's Access-Token Authentication

Private App is required to using Access-Token authentication, The Access-Token can be retrieved by creating an Private App record in Store Admin's App Menu. The way to make the authenticated request for an Private App is the same as Public App, but simply just skip the OAuth 2.0 dance process.


Hmac Validation

Every request or redirect from Shoplazza to your app's server includes an hmac parameter that can be used to verify the authenticity of Shoplazza. For each reqeust, you must remove the hmac entry from the query string and process it through an HMAC-SHA256 hash function.

For example, for following request:

http://example.com/some/redirect/uri?code=1vtke5ljOOL2jPds6gM0TNCeYZDitYB&shop=simon.myshoplaza.com&hmac=22bad22eee1f92836f7773e87d973479

To remove the hmac, you can transform the query string to a map, remove the hmac key-value pair, and then lexicographically concatenate your map back to a query string. This leaves the remaining parameters from the example query string:

code=1vtke5ljOOL2jPds6gM0TNCeYZDitYB&shop=simon.myshoplaza.com

Process the hash function
After you remove hmac and reformat the query string, you can process the string through an HMAC-SHA256 hash function using the Client secret Shoplazza provided to your app. The message is authenticated if the generated hexdigest is equal to the value of the hmac parameer.

The following Ruby example show how to process the string through a hash function:

def verified_hamc?(hmac)
  sha256 = OpenSSL::Digest::SHA256.new
  query_string = "code=1vtke5ljOOL2jPds6gM0TNCeYZDitYB&shop=simon.myshoplaza.com"
  calculated_hmac = OpenSSL::HMAC.hexdigest(sha256, CLIENT_SECRET, query_string)
  ActiveSupport::SecurityUtils.secure_compare(calculated_hmac, hmac)
end

Verify a webhook

The HMAC verification process for OAuth is different from the process to verify webhooks.

Webhooks can be verified by calculating a digital signature. Each webhook request include a base64 encoded X-Shoplazza-Hmac-Sha256 header, which is generated using the app's Client Secret along with the data sent in the request.

To verify that the request came from Shoplazza, compute the HMAC digest according to the following algorithm and compare it to the value in the X-Shoplazza-Hmac-Sha256 header. If they match, then you can be sure that the webhook was sent from Shoplazza. As a best practice, the HMAC digest should be verified before the app responds to the webhook.

The following example use Ruby and Sinatra to verify a webhook request:

require 'rubygems'
require 'base64'
require 'openssl'
require 'sinatra'

# Shoplazza's Client Secret
SECRET = 'my_secret'

helpers do
  # Compare the computed HMAC digest based on the shared secret and the request contents to the reported HMAC in the headers
  def verify_webhook(data, hmac_header)
    calculated_hmac = Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', SECRET, data))
    ActiveSupport::SecurityUtils.secure_compare(calculated_hmac, hmac_header)
  end
end

# Responds to the HTTP POST request
post '/' do
  request.body.rewind
  data = request.body.read
  verified = verify_webhook(data, env["X-Shoplazza-Hmac-Sha256"])

  puts "Webhook verified: #{verified}"
end