Know Your Customer-consuming jenga-api EquityBank

LORCents tech
4 min readDec 11, 2022

Are you a business or startup ,need to verify and id your customer? Turns out there is an easy way to do that with jenga-api.

Lets build a node application to do that, but before that lets set up jenga hq account

  1. Use this link to signup and later sign-in
  2. On the JengaHq dashboard navigate to settings -> accounts and add a test account ,refer here. The account status should be active before consuming the api. Incase account activation takes forever please contact Jenga support.
  3. Still, on JengaHq ,navigate settings -> Subscriptions, click on add subscriptions button then subscribe to Jenga api.

Lets begin with the node application

mkdir kycId
cd kycId
npm init -y
npm i express cors axios dotenv
npm i -D nodemon
mkdir src
touch app.js auth.js .env kyc.js sign.js

First create a directory and initialize npm on that directory, Second install dependencies, create our dev directory and files to work with

Before we jump to code we need to generate a private public key pair that will be useful when generating signature.

For that you can follow this instructions or use below code.

const http = require("http"); // Loads the http module
const crypto = require("crypto"); // Loads the crypto module

const fs = require("fs");

http
.createServer((request, response) => {
// Generates your key pair
const { privateKey, publicKey } = crypto.generateKeyPairSync("rsa", {
modulusLength: 2048,
publicKeyEncoding: {
type: "spki",
format: "pem",
},
privateKeyEncoding: {
type: "pkcs8",
format: "pem",
},
});
response.writeHead(200, {
"Content-Type": "text/plain",
});
fs.writeFileSync("publickey.pem", publicKey);
fs.writeFileSync("privatekey.pem", privateKey);
response.end();
})
.listen(3000); // port server is running

Login to JengaHq navigate to settings -> Api keys -> your puplic key , Add your generated public key here without Begin and end quoutes.

Add public key and private key on our root directory of our project.

Lets begin with .env

# configs
merchantCode=
consumerSecret=
ApiKey=
#url
kycIdUrl="https://uat.finserve.africa/v3-apis//v3.0/validate/identity"

Login to JengaHq to get merchantCode, consumerSecret,ApiKey

You can get jenga end points here

Lets work on auth.js

const axios = require('axios');
const moment= require('moment');





const getAuth=async()=> {
const merchantCode = process.env..merchantCode;
const consumerSecret = process.env.consumerSecret;
const apiKey = process.env.ApiKey;

if (!merchantCode)
throw new Error("Jenga! Please provide the merchant code");

if (!consumerSecret)
throw new Error("Jenga! Please provide the consumer secret");

const response= (
await axios({
method: "post",
url: process.env.kycIdUrl,
data: {
merchantCode,
consumerSecret,
},
headers: {
"Api-Key": apiKey,
},
})
).data;

console.log("jenga-getAuth %o", response);

const { expiresIn: expiresInText, issuedAt: issuedAtText } = response;

return {
...response,
...{
expiresIn: moment.utc(expiresInText).toDate(),
issuedAt: moment.utc(issuedAtText).toDate(),
},
};
}
module.exports=getAuth

Lets work on sign.js

const http = require("http"); // Loads the http module
const crypto = require("crypto"); // Loads the crypto module

const getSignature= async(data)=>{
const pathToPrivateKey = path.resolve("privatekey.pem");
const privateKey = readFileSync(pathToPrivateKey);

const signature = crypto
.sign("sha256", Buffer.from(data), {
key: privateKey,
})
.toString("base64");

console.log("jenga-getSignature %o", signature);
const pathToPublicKey = path.resolve("publickey.pem");
const publicKey = readFileSync(pathToPublicKey);

const isVerified = crypto.verify(
"sha256",
Buffer.from(data),
{
key: publicKey,
},
Buffer.from(signature, "base64")
);

console.log("jenga-getSignature verified %o", isVerified);

return signature;
}

module.exports =getSignature

Now lets work on kyc.js


const axios = require('axios');
const moment= require('moment');
const getAuth=require('./auth');
const getSignature=require('./sign');


const IDVerification=async(data)=> {
const {
identity: {
documentNumber,
dateOfBirth,
documentType,
firstName,
lastName,
countryCode,
},
} = data;

const signature = getSignature(
`${countryCode}${documentNumber}`
);

const kycIdUrl = process.env.kycIdUrl;
const { accessToken } = await getAuth();

const response: any = (
await axios({
method: "post",
url: kycIdUrl,
headers: {
Authorization: `Bearer ${accessToken}`,
signature: signature,
"Content-Type": "application/json",
},
data: data,
})
).data;

console.log("jenga-getBalance %o", response);

return response;
}

module.exports=IDVerification

Lets finish with app.js

const dotenv= require('dotenv');
dotenv.config();
const express = require('express')
const cors = require('cors')
const bodyParser = require('body-parser')

const IDVerification=require('./kyc');





const app = express();

app.use(bodyParser.json());
app.use(
bodyParser.urlencoded({
extended: true,
})
);

app.use(cors());

app.get("/", async(req,res)=>{

const data = {
identity: {
documentType: "ALIENID",
firstName: "John",
lastName: "Doe",
dateOfBirth: "1995-01-01",
documentNumber: "123456",
countryCode: "KE",
},
};
const response = await IDVerification(data);
res.json(response);

});

const port = process.env.PORT || 8000;

const server = app.listen(port, () => {
console.log(`🚀 Server ready at: http://localhost:${port}`);
});

Add start script on package.json

"scripts": {
"dev": "node src/app.js",
}

Run your node app

npm run dev

Example Response

{
"status": true,
"code": 0,
"message": "success",
"data": {
"identity": {
"customer": {
"firstName": "JOHN",
"lastName": "DOE",
"occupation": "",
"gender": "M",
"nationality": "Kenyan",
"deathDate": "",
"fullName": "JOHN JOHN DOE DOE",
"middlename": "JOHN DOE",
"ShortName": "JOHN",
"birthCityName": "",
"birthDate": "1985-06-20T12:00:00",
"faceImage": ""
},
"documentType": "NATIONAL ID",
"documentNumber": "555555",
"documentSerialNumber": "55555555555",
"documentIssueDate": "2011-12-08T12:00:00",
"documentExpirationDate": "",
"IssuedBy": "REPUBLIC OF KENYA",
"additionalIdentityDetails": [
{
"documentType": "",
"documentNumber": "",
"issuedBy": ""
}
],
"address": {
"locationName": "",
"districtName": "",
"subLocationName": "",
"provinceName": "",
"villageName": ""
}
}
}
}

There you go 😆

--

--