Note: This tutorial uses the legacy Node SDK; for a list of updated tools, please reference Lob's API documentation for Checks and see our list of updated SDKs.
Lob’s global print delivery network helps businesses and enterprises simplify and automate their direct mailing, payment, and address verification processes. The link between digital and physical communications gives these organizations greater flexibility, visibility, and accuracy when reaching out to customers.
Lob builds APIs to automate and increase connectivity between the offline and online worlds. We leverage the cloud to help organizations send postcards, letters, checks, and other print mail faster, enabling new growth opportunities through automation.
You can create and send physical payments digitally using the Lob Print & Mail API. The API provides endpoints for creating, retrieving, and canceling checks and fetching a list of previous checks with their status.
You can also use Lob’s robust webhooks to track and automate important check events. Our flexible webhooks can enable you to send automated notifications to the check’s payor, payee, and drawee (the bank or other institution honoring the check).
In this tutorial, we’ll explore Lob’s API features for creating and sending checks to a physical address. We’ll build an Express Node.js application, integrate Lob’s Print & Mail API, then send checks to a physical address.
To proceed you need the following prerequisites installed on your local machine:
You’ll also need to have a basic understanding of Node.js and ES6 syntax. Find the complete application code on Github to follow along.
Before starting, create your free Lob account. You don’t need to add payment information if you’ll only be testing.
Now, let’s start setting up our project by creating our application’s folder structure.
First, make a folder named “lobchecks.” Open it in an editor of your choice.
Next, create a basic Node.js application using this folder structure:
mkdir src
cd src
mkdir controllers models routes views
lobchecks
src
controllers
checks.controller.js
models
check.js
routes
web.js
views
index.hbs
checks.hbs
check.hbs
index.js
.env
.babelrc
README.md
In the above application folder structure, you see our three view files:
Download these 3 files along with the CSS, JavaScript, and images used in this application by cloning the application repository. Then copy everything in the view folder into your project.
The css folder contains the bootstrap CSS and the application’s custom CSS where we wrote and minified all the application CSS. The js folder contains the jQuery script, which bootstrap requires to aid certain functions like modals and navigation bar toggles.
We want to manage our dependencies using NPM (node package manager). We start by initializing our project with the command.
npm init
Enter responses to the prompt of hit enter to accept the default value.
package name: lobchecks
version: 1.0.0
description: A sample node project, demonstrating the use of Lob checks.
entry point: ./src/index.js
test command: echo "Error: no test specified" && exit 1
git repository: https://github.com/lob/lob-node-examples.git
keywords: Lob, Checks, Finance
author: your name
license: ISC
Is this OK? yes
Next, install the following packages using the npm install command in your command-line interface (CLI), as this code snippet shows:
npm install express mongoose cors hbs path lob dotenv
Since we’ll be using ES6 in the application, we need some Babel packages to transpile our code to plain ES5 JavaScript. Install these packages as dev dependencies using the following command:
npm install @babel/cli @babel/core @babel/node @babel/preset-env --save-dev
Let’s go over the packages installed in the first code snippet:
Open package.json in your editor and add the following to the script block
"start-dev": "babel-node ./src/index.js",
"dev": "nodemon --exec npm run start-dev",
"start": "npm run build && node ./build/index.js",
"build": "npm run clean && npm run build-babel",
"clean": "npx rimraf /F /Q build",
"build-babel": "babel src --out-dir build --source-maps inline --copy-files"
Your package.json should look something like this.
{
"name": "lobchecks",
"version": "1.0.0",
"description": "A sample node project, demonstrating the use of Lob checks.",
"main": "./src/index.js",
"scripts": {
"start-dev": "babel-node ./src/index.js",
"dev": "nodemon --exec npm run start-dev",
"start": "npm run build && node ./build/index.js",
"build": "npm run clean && npm run build-babel",
"clean": "npx rimraf /F /Q build",
"build-babel": "babel src --out-dir build --source-maps inline --copy-files",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/lob/lob-node-examples.git"
},
"keywords": [
"Lob",
"Checks",
"Finance"
],
"author": "YOUR NAME",
"license": "ISC",
"bugs": {
"url": "https://github.com/lob/lob-node-examples/issues"
},
"homepage": "https://github.com/lob/lob-node-examples#readme",
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^10.0.0",
"express": "^4.17.2",
"hbs": "^4.2.0",
"lob": "^6.5.2",
"mongoose": "^6.1.3",
"path": "^0.12.7"
},
"devDependencies": {
"@babel/cli": "^7.16.0",
"@babel/core": "^7.16.5",
"@babel/node": "^7.16.5",
"@babel/preset-env": "^7.16.5"
}
}
In the scripts tag in the above code snippet, we configured the application’s runtime parameters for local and production environments.
To configure Babel, we add the following code snippet to the .babelrc file. This enables us to transpile our cutting edge JavaScript into plain ES5 JavaScript that can run in any browser:
touch .babelrc
Copy and paste the following in the new .babelrc file.
{
"presets": [
"@babel/preset-env"
]
}
Now, to integrate Lob into our app, we need the API credentials from our Lob account. Retrieve these credentials from your Lob dashboard by clicking on the Settings menu on the sidebar, then clicking on the API Keys tab, as this screenshot illustrates:
The screenshot shows we have API keys for live and test environments. We can use the test keys for development, but we can only use the live key after Lob has verified our payment information.
Although Lob offers subscription packages for all types of businesses, the free trial will work for our example.
For this project we’ll use environment variables to securely store our API keys. In the root of your project create a new file .env
touch .env
Open the .env file and add your API keys.
LOB_API_KEY = test_6b2fXXXXXXXXXXXXXXXXXbd3586
After setting these configurations in the Lob dashboard, we import Express, Mongoose, CORS, and Path. We then configure the app to use Handlebars as its templating engine. Then, we configure it to listen to requests on port 5000.
To do all this, enter the following code in your src/index.js file:
import express from "express";
import mongoose from "mongoose";
import cors from "cors";
import path from "path";
const app = express();
const PORT = 5000;
const dbConnectionString = "mongodb://localhost:27017/lobchecks";
app.use(express.urlencoded({ extended: true }));
app.use(express.text());
app.use(express.json({ type: "application/json" }));
app.use(cors());
// views and static files
app.set('views', path.join(__dirname, 'views'));
app.use(express.static(path.join(__dirname, 'views')));
app.set('view engine', 'hbs');
mongoose.connect(dbConnectionString, { useNewUrlParser: true, useUnifiedTopology: true });
mongoose.connection.on("error", console.error.bind(console, "Connection Error:"));
// require routes
const routes = require("./routes/web.js");
app.use(routes);
app.listen(PORT, (error) => {
console.log(`Node is listening on port ${PORT}`);
if (error) {
console.log(error);
}
});
Now that we’ve configured the application, let's create and deliver some dummy checks to imaginary addresses using Lob’s Print & Mail API. We’ll first model a check then set up our application routes and controllers.
First, we define a Mongoose database schema with the necessary properties for a check, then export the schema to use in other parts of our application.
Enter the following code in your src/models/check.js file:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Check schema definition
const CheckSchema = new Schema(
{
checkId: { type: String, required: true },
description: { type: String, default: null },
to: { type: Schema.Types.Mixed, default: null },
from: { type: Schema.Types.Mixed, default: null },
bank_account: { type: String, default: null },
amount: { type: Number, default: null }
},
{ timestamps: true }
);
// Exports the CheckSchema for use elsewhere.
module.exports = mongoose.model("Check", CheckSchema);
Now that we’ve created our model let’s set up the application routes. To do this, we import Express and declare the router variable in the web.js file. Then, we set up the various routes the application will use and connect them to their appropriate controllers.
To do this, add the following code to your src/routes/web.js file:
const express = require("express");
const router = express.Router();
// Controller Import
const checkController = require("../controllers/check.controller");
// Route Declaration
router.route("/")
.get(checkController.createCheck)
.post(checkController.createCheckPost);
router.route("/getCheck/:checkId")
.get(checkController.getACheck);
router.route("/getChecks")
.get(checkController.getChecks);
router.route("/cancelACheck/:checkId")
.get(checkController.cancelACheck);
// Route Export
module.exports = router;
Now, let’s create four functions in the src/controllers/check.controller.js file: createCheck, createCheckPost, getChecks, and getACheck. We’ll examine these functions after we introduce their code.
First, add the following code to the check.controller.js file to create these functions and set up communication between your Node.js application and Lob’s servers:
import dotenv from 'dotenv';
dotenv.config();
const Lob = require('lob')(process.env.LOB_API_KEY);
import Check from "../models/check";
/*
* GET / route to show the createCheck form.
*/
function createCheck(req, res) {
let response = req.query.response;
res.render('index', { response });
}
/*
* POST / route to process the checks.
*/
async function createCheckPost(req, res) {
const { amount, receiver, sender, memo, date } = req.body;
// Create the bank account
const bankAccount = await Lob.bankAccounts.create({
description: 'Test Bank Account',
routing_number: 322271627,
account_number: 123456789,
signatory: 'John Doe',
account_type: 'company'
});
const bankAccountVerification = await Lob.bankAccounts.verify(bankAccount.id, {
amounts: [25, 63]
});
// Create address
const senderAddress = await Lob.addresses.create({
name: 'Harry Zhang',
email: 'test@gmail.com',
phone: '123456789',
address_line1: '210 King St',
address_city: 'San Francisco',
address_state: 'CA',
address_zip: '94107',
address_country: 'US'
});
Lob.checks.create({
description: 'My First Check',
bank_account: bankAccount.id,
to: {
name: receiver,
address_line1: '210 King St',
address_line2: '# 6100',
address_city: 'San Francisco',
address_state: 'CA',
address_zip: '94107'
},
from: senderAddress.id,
amount: amount,
memo: memo,
logo: 'https://s3-us-west-2.amazonaws.com/public.lob.com/assets/check_logo.png',
check_bottom: '<h1 style="padding-top:4in;">Demo Check for {{sender}} to {{receiver}}</h1>',
merge_variables: {
sender: sender,
receiver: receiver
},
// send_date: date
})
.then((check) => {
const { id, ...otherProperties } = check;
Check.create({ checkId: id, ...otherProperties });
res.redirect('/?response=Your check was successfully sent');
})
.catch((err) => {
console.log(err);
});
}
/*
* GET / route to get created checks.
*/
function getChecks(req, res) {
Lob.checks.list({ limit: 50 }, function (err, response) {
const checks = response.data;
res.render('checks', { checks });
});
}
/*
* GET / route to get a check.
*/
function getACheck(req, res) {
const checkId = req.params.checkId;
Lob.checks.retrieve(checkId, function (err, response) {
const check = response;
res.render('check', { check });
});
}
/*
* GET / route to cancel a cheque.
*/
function cancelACheck(req, res) {
const checkId = req.params.checkId;
Lob.checks.delete(checkId, function (err, response) {
const check = response;
res.render('check', { check });
});
}
// Export all the functions
module.exports = { createCheck, createCheckPost, getChecks, getACheck, cancelACheck };
The createCheck function accepts a GET request and returns a form. The form, visible in the following screenshot, lets us send dummy checks to the Lob server using their API.
The form only captures the essential parameters the Lob Print & Mail API requires for sending checks. You can check out Lob’s documentation for optional parameters to customize the form further.
The createCheckPost function accepts a POST request from the createCheck form, processes it, then sends the content to Lob’s server.
The getChecks and getACheck functions each accept GET requests. The getChecks function returns a list of all the checks created on Lob and displays it on the src/view/checks.hbs page. The getACheck function returns a check’s complete details, selected by check ID, and shows it on the views/check.hbs page, as the screenshot below shows.
Clicking the Cancel Check button cancels this check on Lob if its send_date is still in the future.
To implement this check canceling option, create a cancelCheck function in the src/controllers/check.controller.js file and paste the code snippet below inside the newly-created function:
/*
* GET / route to cancel a check.
*/
function cancelACheck(req, res) {
const checkId = req.params.checkId;
Lob.checks.delete(checkId, function (err, response) {
const check = response;
res.render('check', { check });
});
}
The above code snippet implements a call to the Lob server to cancel a check with the given check ID. If the request is successful, Lob updates the check and returns the updated information. See the check details page below for some key details.
We now have a working Node.js application that uses Lob’s Print & Mail API to create and send checks to a physical address. Although this was a quick demonstration, you can expand the application to integrate Lob webhooks. The webhooks listen to events as Lob processes the check and can automate mail delivery and notify the payor and payee.
Integrating Lob APIs and webhooks into your business processes is hassle-free. Their robust code is compatible with major programming languages, so you can easily configure Lob to suit your needs.
Lob’s simple sign-up process and free developer account help you get started and explore its capabilities. Create a Lob account today, experiment with payments, mailers, and webhooks, and let Lob automate your physical mail and increase the connectivity between your offline and online worlds.