Cin7 API Test Integrations for Serial Keys Using Postman and Node
A quick getting started guide for Cin7 API endpoints, with a focus on the serial number module. I demonstrate Postman and Node fetch API interactions....
By John Phung
2020-10-09
Introduction
A company which I worked for required a way to allow customers to sign up to their portal using a product serial key created in Cin7 (Inventory Management System) with the relevant serial key checks and also populating the relevant product(s) to the customer's account.
Cin7 does provide API endpoints to perform CRUD operations on different platform modules, i.e. products, categories, serial numbers et al. However, the first time working with Cin7 API, there was a bit of confusion in terms how to interact with the provided endpoints concerning the headers and auth. Cin7 does provide a high level description in the docs, but won't hold your hand to get started.
From my experience with interacting with Cin7 API, I'll like to share my process of getting up and running (mini tutorial) using Postman and how I formulated my solution to do serial key queries with firebase cloud functions. I won't present the entire solution in code since this article is mainly just to explain Cin7 API interactions.
Getting Started with Cin7 API
To get started, you need a Cin7 account obviously, otherwise you won't be able to interact with any of the modules. From your account, a API key and API username is necessary for authorization when interacting with the endpoints.
To create a API key and username, go to Settings & Options (cog icon) -> Integrations & API -> API v1. Create a new API key and save it somewhere safe, then customize the preferences for the read, create, update and delete permissions for your required modules. In this use case, only read from serial numbers and products module is necessary.
The Process for Serial Key Signups
Before moving on to the technicalites of interacting with the Cin7 endpoints, framing the problem for the context of this article is necessary, particular to serial key sign ups.
There needs to be a check for whether a serial key exists in Cin7, and because serial number module does not indicate whether a serial has been redeemed or not, a secondary database is required to store that parameter. Therefore, a second check is conducted to determine if the status of the key has been used.
If serial key exists and is not utilised, then the user is allowed to sign up. After confirmation of sign up, the product related to the serial key is added to the user's account and the serial key status is updated to true.
The diagram below demonstrates my thought process of how the solution architecture may look like.
Testing with Postman
To first get a hang of interacting with the API, Postman is used to make API requests to Cin7 endpoints.
The endpoint is https://api.cin7.com/api/ followed by additional url respective to the module you're trying to access. For example to access the serial number list end point, this will be the entire endpoint url: https://api.cin7.com/api/v1/SerialNumbers/
Cin7 uses basic authentication as part of each request, therefore in the Auth tab for Postman, choose type -> Basic Auth, and for the username and password this refers to API username and API key, respectively.
Try send a GET request to any of the modules which you have data populated already to see if you're able to get a response. In the figure below, I made a request to the serial number endpoint and got back an array of serial numbers.
Additionally, you can pass query parameters if you want to filter the request based on certain attributes. More information on this can be found on the Cin7 docs API .
For example, for my use case, I need to check if a serial exists. Instead of returning the entire list and filtering the array for the matching serial number, I passed a 'where' clause to only results where serialNumber attribute equals desired number. Below indicates how the query param is passed.
Interacting with Node JS
Now that the request structure is understood, it's time to code the API request in javascript.
The easiest way is to do it client side, however there's difficulty in safely storing important information such as the API key and username on the client. Therefore, adopting for a server side request is probably more ideal as the variables can be stored in an environmental variables file.
In saying so, the implementation is very similar for both client and server side. In this example, I used firebase cloud functions, but you can also set up an express server with a route.
First install isomorphic fetch for node.
1npm i isomorphic-fetch
Import isomorphic fetch and firebase modules
1const fetch = require("isomorphic-fetch");
2const functions = require("firebase-functions");
Create a function to retrieve the serial number form Cin7
1const fetchSerialCin7 = (data) => {
2 const username = functions.config().cin7.username; // refer to setting environmental variables in firebase functions - API username
3 const password = functions.config().cin7.password; // API key
4
5 const url =
6 "https://api.cin7.com/api/v1/SerialNumbers/?where=serialNumber=" +
7 "'" +
8 data.serial +
9 "'";
10
11 const auth =
12 "Basic " + Buffer.from(username + ":" + password).toString("base64"); // base64 encode username and password
13
14 return new Promise((resolve, reject) => {
15 fetch(url, {
16 method: "GET",
17 headers: {
18 Authorization: auth,
19 },
20 })
21 .then((response) => {
22 if (response.status >= 400) {
23 reject("Bad response from server");
24 }
25
26 return response.json();
27 })
28 .then((data) => {
29 resolve(data);
30 })
31 .catch((error) => {
32 reject(error);
33 });
34 });
35};
Create firebase callable cloud function which the client side will call
1exports.fetchSerialCin7 = functions.https.onCall((data, context) => {
2 return
3 fetchSerialCin7(data)
4 .then((data) => {
5 return data; //returns serial json
6 })
7 .catch((error) => {
8 throw new functions.https.HttpsError("internal", error);
9 });
10 });
Deploy cloud functions using CLI - Must have installed globally firebase CLI
1firebase deploy --only functions:fetchSerialCin7
Interacting with the cloud function on the client. You will need to have initalised firebase functions scripts in your application. Refer to docs for more information.
1 const fetchSerialCin7 = firebase
2 .app()
3 .functions()
4 .httpsCallable("fetchSerialCin7");
5
6 try {
7 const result = await fetchSerialCin7({ serial: serial }); // serial variable is bind to an input text box value
8
9 if (!result.data || result.data.length === 0) {
10 console.log('serial does not exist');
11 return;
12 }
13
14 console.log('serial exists');
15 } catch (error) {
16 console.log(error);
17 }
18}
I have a left out quite of bit of initalisation setup for firebase as that's not the focus here. You can use any cloud function provider such as Lambda or run your own server which will change your code setup.
In a similar way to reading API endpoints, doing POST request is also much the same except you also need to pass along body information.
I hope this provide you a starting point with interacting with Cin7 API endpoints.