Building the bank portal backend 

The bank portal backend server will carry out the following operations: 

  • Return the user's details (name and balance) based on the 'friendlyid' unique identifier. These will be displayed to the user upon logging in. The '/userdet' server will be used for this.
  •  Return the user's currency balance based on the 'friendlyid' unique identifier. The '/userbal' server will be used for this.
  • Handle payment requests. It will submit a payment request that's forwarded by the customer to the bridge server endpoint. Before submission, it will check whether the user has a sufficient balance for the payment transaction. After the bridge server communicates that the transaction has been executed successfully, it will update the customer's account to reflect the new balance, minus the remitted amount. This is done by the '/payment' service.
  •  Lastly, it returns a list of received transactions with the sender's KYC details for the bank user to view. This is implemented by the '/bankuser' service.

Now, let's start building our backend server. I'm calling my backend server apps DBServerA and DBServerB for Bank A and Bank B, respectively:

  1. Create a Node.js app called DBServerA. Start by declaring the dependencies shown in the following code. Make sure you have these installed in your nodejs environment:
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
const pg = require('pg');
const conString = "postgres://bankauser:bankauser@localhost:5432/banka";
const requestObj = require('request');
const client = new pg.Client(conString);
const USD = 'USD';
const issuer = 'GAIHBCB57M2SDFQYUMANDBHW4YYMD3FJVK2OGHRKKCNF2HBZIRBKRX6E';
var txid = 1001;

There are a few things you should observe here. Our pg client is pointed to the banka database URL. Also, take note of the USD asset and its issuer being mapped. We also set a counter variable to keep track of the current transaction ID. We start with the transaction ID set to 1001 and increment it after every request.

  1. Next, we set up bodyparser so that we can parse the incoming JSON requests, set up the CORS middleware, and initialize the app server at port 3600, as follows:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.use(function (req, res, next) {

// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');

// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);

// Pass to next layer of middleware
next();
});

var server = app.listen(process.env.PORT || 3600, function () {
var port = server.address().port;
console.log("App now running on port", port);

});

Now, let's start writing the endpoints one by one.

  1. Let's start with the '/userdet' service. This service fetches the customer's details based on the friendlyId of the customer from the internal users table of the banka database and returns the details in json format to the requestor:
app.post('/userdet', function (request, response) {

var idParts = request.body.friendlyid.split('*');
var friendlyId = idParts[0];

client.query('SELECT name,balance from users where friendlyid = $1', [friendlyId], (error, results) => {
if (error) {
throw error
}
if(results)
{
response.json({
name: results.rows[0].name,
balance: results.rows[0].balance
});
response.end();
}});
});
  1. Next is the '/userbal' service, which is similar to '/userdet' except for the fact that it returns the current balance of the user. It fetches the customer's current balance based on the friendlyid of the customer from the internal users table of the banka database and returns the details in JSON format to the requestor:
app.post('/userbal', function (request, response) { 
var idParts = request.body.friendlyid.split('*');
var friendlyId = idParts[0];
client.query('SELECT balance from users where friendlyid = $1', [friendlyId], (error, results) => {
if (error) {
throw error
}

if(results)
{
response.json({
balance: results.rows[0].balance
});
response.end();
}});
});

  1. Next, we have the '/payment' service, which posts incoming payment requests to the bridge server. Let's go through the steps one by one. First, we fetch the customer's friendlyId from the request body and split it into the customer ID and domain name, as follows:
app.post('/payment', function (request, response) {
var idParts = request.body.account.split('*');
var friendlyId = idParts[0];

Next, we use the customer's friendlyId to fetch their current balance and check whether the payment amount is greater than the customer's current balance. If the payment request amount is greater, an "Insufficient balance!" message is sent to the requestor:

client.query('SELECT balance from users where friendlyid = $1', [friendlyId], (error, results) => {
if (error) {
response.json({
msg: "ERROR!",
error_msg: error
});
response.end();
}

if(results)
{
balance = results.rows[0].balance;

if(balance < Number(request.body.amount))
{
response.json({
msg: "ERROR!",
error_msg: "Insufficient balance!"
});
response.end();
}

If the transfer amount is less than or equal to the balance, we post a new request to the bridge server '/payment' endpoint at localhost:8006. The params posted are as follows:

  • id: Current transaction ID. We fetch this from the txid variable we declared earlier and it is sent in string format.
  • amount: Transaction amount. Received from the customer's request that's submitted to the bank portal.
  • asset_code: Asset code (USD).
  • asset_issuer: Asset issuer account for USD.
  • destination: Friendly ID of the receiver. We get this from the customer's request that's submitted to the bank portal (for example, janesmith*bankb.com).
  • sender: Friendly ID of the sender. We get this from the customer when they log into the bank portal (for example, johndoe*banka.com).
  • use_compliance: This needs to be set to true if we wish to use the compliance server to exchange KYC information between remitting parties.

Let's take a look at the following code to understand how the code implements the request and response to the bridge server:

requestObj.post({
url: 'http://localhost:8006/payment',
form: {
id: txid.toString(),
amount: request.body.amount,
asset_code: USD,
asset_issuer: issuer,
destination: request.body.receiver,
sender: request.body.account,
use_compliance: true
}
},
function(err, res, body) {
if (err || res.statusCode !== 200) {
console.error('ERROR!', err || body);
response.json({
result: body,
msg: "ERROR!",
error_msg: err
});
response.end();
}

If we receive an error status code from the bridge server, the user is notified and an error message is printed to the console. 

As shown in the following code, if the bridge server response is success, the following steps are carried out:

  1. The user's current balance is fetched and updated. The transaction amount is deducted from the current balance.
  2. The variable that stores the transaction ID, txid, is incremented by 1 to the next transaction ID.
  3. After the preceding two steps, a success response is sent back to the requestor:
else {
console.log('SUCCESS!', body);
client.query('SELECT balance from users where friendlyid = $1', [friendlyId], (error, results) => {
if (error) {
console.log(error);
response.status(500).end("User Not found");
}
if (results)
{
var balance = Number(results.rows[0].balance)
balance = balance + - request.body.amount;
client.query('UPDATE users set balance = $1 where friendlyid = $2', [balance, friendlyId], (error, results) => {
if (error) {
console.log(error);
response.status(500).end("User Not found");
}
if (results)
{
response.json({
result: body,
msg: 'SUCCESS!'
});
txid++;
console.log("Next txid",txid);
response.status(200).end();
}
})
}
})
}
});
}
})
});

We are left with one last service for our backend server: '/bankuser'. This service simply queries the transactions table in the banka database and fetches all the information about the received transactions, including the sender's KYC details. This is then sent back to the requestor:

app.get('/bankuser', function (request, response) {
client.query('SELECT * from transactions', (error, results) => {
if (error) {
throw error
}

if(results)
{
response.json({
tx: results.rows
});
response.end();
}
})
});

That brings us to the end of the backend server for our bank portal for Bank A. Replicate and set up this server for Bank B as well. Make sure you change the database URL to postgres://bankbuser:bankbuser@localhost:5432/bankb and the port to '3602' or any other unused port. Also, make sure that you change the bridge server's internal port for Bank B in the '/payment' endpoint. In my case, this port is 8007. This is highlighted in the following code:

requestObj.post({
url: 'http://localhost:8007/payment',
form: {
id: txid.toString(),
amount: request.body.amount,
asset_code: USD,
asset_issuer: issuer,
destination: request.body.receiver,
sender: request.body.account,
use_compliance: true
}

That completes creating the backend servers for Bank A and Bank B.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.22.136