API Smash

Use APIs to Mail Invoices Programmatically [Rails API Tutorial]

Emailed invoices are easy to ignore. But a physical letter? Mailed invoices can earn higher response rates–especially for overdue payments. One brand study reported that the majority (59%) of its customers  failed to pay on first billing when emailed and needed additional reminders. Yikes. On the other hand, only 29% of those billed by direct mail failed to pay on first billing and required follow-up.

In this tutorial, we will build a simple Rails app that acquires all invoices associated with your invoicing system and gives you the option to send the invoices by mail programmatically using the Lob API. Read on for the full tutorial or skip ahead to GitHub code.

Setting Up

This tutorial is written primarily for Rails, but the concepts can be translated across languages.

What you’ll need

  • A free RapidAPI account to test API calls and export code snippets
  • A Lob account to send the physical mail
  • An invoicing system (we’ll use Freshbooks’ free 30 day trial)

What you’ll build

We’ll build this project in Rails and define two routes: get_invoices, and send_invoice. Using ERB and the Lob invoice template, we will dynamically generate an invoice with all of the Freshbooks invoice details filled out. We will call the Freshbooks and Lob APIs using RapidAPI. RapidAPI allows us to test the API calls in our browser and see a JSON response. It will also export the API call as a code snippet in the language of your choice.

What the final project will do

This tutorial will walk through how to programmatically send an invoice from Freshbooks via the US Postal Service with Lob. Note, we won’t be covering how to build a frontend.

When the app is visited, all of your Freshbooks’ invoices will rendered in a list along with a Send Mail button. When you click the Send Mail button, ERB will dynamically generate an invoice with all of the invoice information.

 

 

The resulting invoice document will look something like this, but you can customize it as you see fit.

 

 

 

Finally, the app will send the invoice through the United States Postal Service via Lob’s API. Pretty cool, right?

Building the Project

Let’s walk through the steps to build this application. If you reach a roadblock, you can compare your code to the finished project in this repo.

Step 1: Create an invoice controller

Before we mail the invoices out, we’ll need to retrieve them! The invoice controller will send all the invoices to the frontend and populate the app. Since we’re using Freshbooks as our invoicing system (thank you, 30 day free trial!), we’ll call our controller the Freshbooks controller. Here are the steps we took:

  1. Make a Freshbooks account

1a. Travel to https://my.freshbooks.com/#/signup and create an account.

1b. Populate a new business with invoices or import your existing business invoices. We chose to make Dave’s Construction business because, hey, who wouldn’t want to build stuff all day?

  1. Call the Freshbooks API getInvoices endpoint on RapidAPI

2a. The first thing you will need to do is generate an access token. Head to https://rapidoauth.com/freshbooks

2b. After you generate the access token, you’ll be taken directly into the RapidAPI testing environment. Test out your new access token with the getIdentityInfo endpoint!

2c. Look through the JSON response and find your Freshbooks accountID. (response -> roles -> accountId). Copy this ID onto your clipboard.


2d. Go to the
getInvoices endpoint. Enter your access token and paste your account ID. Expand the optional parameters section and add the word “lines” to the “include” parameter. This addition will give us access to all the details about each item on an invoice.

2e. Click the TEST Function button to call the API!

2f. Sign in to generate a code snippet in Ruby. You can call an API without a RapidAPI account, but you’ll need one to access the code snippet.

3. Build a custom route and controller

3a. Start a new Rails project (rails new [project_name]) or navigate to an existing project.

3b. Type rails g controller freshbooks into your terminal. 

3c. Define a custom route ( get 'freshbooks/get_invoices', :to => ‘freshbooks#get_invoices’) in your config/routes.rb file.

3d. Write gem 'rapidapi', '~> 0.1.3'  in your Gemfile. Then, run bundle install in Terminal.

3e. In your FreshbooksController, define a method called get_invoices and copy and paste your RapidAPI getInvoices code snippet that was saved from the previous step.

Note: Prefix each RapidAPI class with a double colon “::”. These colons tell Rails to not implicitly call ‘self’ before calling the RapidAPI class.

3f. Finally, write render json: JSON.pretty_generate(root[‘payload’][‘response’] [‘result’][‘invoices’]) as the last line in your controller.

3g. Start your server with rails s and navigate to localhost:3000/freshbooks/get_invoices. You should see a JSON response of all the invoices within your Freshbooks account.

Ta-da!

Your invoice controller should look like this:

def get_invoices

   require 'rapidapisdk'

   ::RapidAPI.config(project: "LobFreshbooks", token: ‘############’)

   root = ::RapidAPI.call('FreshbooksAPI', 'getInvoices', {

    'accessToken': '###################',

    'accountId': '#####',

      'include': 'lines'

   })

   render json: JSON.pretty_generate(root['payload']['response']['result']['invoices'])

end

 

Step 2: Make a Lob Controller

Now that the invoicing controller is all set, we can move onto the Lob controller. The Lob controller will actually call the Lob API and send the invoice as a physical piece of mail (or a virtual one if we’re in test mode). Let’s build it!

Since this process is slightly more complicated than the invoice controller, we’ve divided it into three sections: set up, connect to RapidAPI, generate invoice.

 

A) Set up your Lob account and Lob controller

To kick this process off, we’ll create a Lob account and skeleton Lob controller.

1.Create a Lob account and get your Test API Key

1a. Head to Lob to sign up for an API key: https://dashboard.lob.com/#/settings/keys

1b. Copy the “Test API Key” onto your clipboard.

Why are we using the test API key? This key allows us to make calls and test them without sending out physical mail just yet. Another bonus? We won’t be charged for calls using a test API key.

2. Set up your Lob controller

2a. Run rails g controller Lob in Terminal.

2b. Create another custom route in your routes.rb file to look like get 'lob/send_invoice', :to => 'lob#send_invoice'.

2c. Define a method in your LobController called send_invoice.


B) Connect your Lob controller to the Lob API with RapidAPI

Here’s where it gets interesting…We will be sending our Freshbooks invoice details along with our AJAX call to the send_invoice route.

1. Connect to RapidAPI to call Lob’s createLetter endpoint

1a. This step should feel familiar! Go to the createLetter endpoint on RapidAPI’s Lob package. Paste your Lob “Test API Key” into the apiKey form.

1b. Test the API call and see the JSON results. Generate the code snippet in Ruby. Copy and paste this code snippet directly into your send_invoice method.

Note: Again, prefix each RapidAPI class with a double colon “::”.

2. Fill out the API parameters

2a. Create letterTo and letterFrom address objects. The letterTo and letterFrom parameters in your Lob RapidAPI call take a JSON address object that looks like this:

‘letterTo’: JSON.generate({

name: params['name'],

        address_line1: params['address_line_1'],

        address_city: params['city'],

        address_state: Lob.state[params['state'].to_sym],

        address_country: Lob.iso[params['country']],

        address_zip: params['zip_code']

})

Notice that each line of the letterTo address object contains an invoice parameter.

2b. Next, implement state and country conversions. Why do we need these? The Freshbooks JSON response returns full country and state names (ie. “California” or “India”) but the Lob API takes state and country abbreviations.

Since the address_country and address_state parameters access a Lob model, we’ll need to generate a new Lob model (rails g model Lob).  Take a look at our Lob model to see how we built it and see the two country and state hash objects. Then, implement the two state and country hash objects into two methods respectively.

2c. Fill in the letterFrom parameter with your company’s information:

'letterFrom': JSON.generate({

        name: "Dave's Construction",

        address_line1: "600 California St.",

       address_city: 'San Francisco',

        address_state: 'CA',

       address_country: 'US',

        address_zip: '94109'

     })

 


C) Generate an invoice programmatically within your Lob controller

Finally, we’ll use ERB to generate an invoice within the Lob controller.

1. Create an .erb file

1a. If Rails hasn’t already created a lob/send_invoice.html.erb within your views folder, go ahead and do so now.

1b. Navigate to Lob’s invoice template and copy Lob’s invoice template into the send_invoice.html.erb file that you just created.

2. Alter the file to generate the invoice based on Freshbooks params

2a. Access to the @params variable we defined in our LobController in the .erb file. Check out our finished .erb file here to get an idea of how you should modify this file.

3. Modify send_invoices method in LobController to generate the .erb file

3a. Bind the @params variable to the .erb file to generate its result using this code snippet.      

3b. Add these four lines to your code above the RapidAPI.call function

@params = params

  Dir.chdir(File.dirname(__FILE__))

  erb_string = File.read('../views/lob/send_invoice.html.erb')

  renderer = ERB.new(erb_string)

  result = renderer.result(binding)

The first line just ensures that our master directory is set as our current directory, then we read our .erb file. Once we have read our .erb file we need to create a new instance of the ERB class, pass our .erb file as an argument, and render the result. The “binding” key word is Rails’ way of passing all of our needed variables (in this case, the instance variable @params) to our template.

3c. Our RapidAPI.call method takes a file parameter. Go ahead and set the variable “result” as our file. The final line of your send_invoice method should say render json: response.

Boom!

Once your are finished, your LobController#send_invoice method should look similar to this:

def send_invoice

   require 'rapidapisdk'

   ::RapidAPI.config(project: [YourRapidProject], token: [YourRapidProjectKey])

   @params = params

   

   Dir.chdir(File.dirname(__FILE__))

   erb_string = File.read('../views/lob/send_invoice.html.erb')

   renderer = ERB.new(erb_string)

   result = renderer.result(binding)

   response = ::RapidAPI.call('Lob', 'createLetter', {

    'apiKey': '###########################',

    'letterTo': JSON.generate({

        name: params['name'],

        address_line1: params['address_line_1'],

        address_city: params['city'],

        address_state: Lob.state[params['state'].to_sym],

        address_country: Lob.iso[params['country']],

        address_zip: params['zip_code']

      }),

    'letterFrom': JSON.generate({

        name: "Dave's Construction",

        address_line1: "600 California St.",

        address_city: 'San Francisco',

        address_state: 'CA',

       address_country: 'US',

        address_zip: '94109'

     }),

    'color': true,

    'file': result

   })

   render json: response

 end

 

Step 3: Build a Frontend

We won’t go into too much detail about how your frontend should look, but just know that you should have two AJAX calls: one to the freshbooks/get_invoices route, and another to your lob/send_invoice route. This project populates the frontend with invoices on the initial loading of the app and displays buttons for each invoice to send by mail respectively. The frontend uses React.js. Feel free to use our sample frontend as a way to get this app up and running.

get_invoices:

$.get({

    url: 'freshbooks/get_invoices'

  });

send_invoice:

$.get({

      url: 'lob/send_invoice',

      data: {

        name: invoice.fname + " " + invoice.lname,

        amount: invoice.amount,

        organization: invoice.organization,

        address_line_1: invoice.street,

        city: invoice.city,

        state: invoice.province,

        zip_code: invoice.code,

        country: invoice.country,

        invoice_number: invoice.invoice_number,

        customer_id: invoice.customerid,

        create_date: invoice.create_date,

        lines: invoice.lines

     }

}).done(function(res) {

      console.log(res);

   });

 

Conclusion

While this tutorial focuses on Freshbooks, you can replicate the project with any invoicing system. RapidAPI has Shopify, SquareEcommerce and Stripe, or you could call the APIs directly.

Let us know what you build and feel free to raise an issue on GitHub with any questions or concerns. Happy invoicing!

4.8/5 - (55 votes)
Share
Published by

Recent Posts

Power Up Your Enterprise Hub: New March Release Boosts Admin Capabilities and Streamlines Integrations

We're thrilled to announce the latest update to the Rapid Enterprise API Hub (version 2024.3)!…

2 weeks ago

Unveiling User Intent: How Search Term Insights Can Empower Your Enterprise API Hub

Are you curious about what your API consumers are searching for? Is your Hub effectively…

2 weeks ago

Rapid Enterprise API Hub Levels Up Custom Branding, Monetization, and Management in February Release

The RapidAPI team is excited to announce the February 2024 update (version 2024.2) for the…

1 month ago

Supercharge Your Enterprise Hub with January’s Release: Search Insights, Login Flexibility, and More!

This January's release brings exciting features and improvements designed to empower you and your developers.…

3 months ago

Enhanced Functionality and Improved User Experience with the Rapid API Enterprise Hub November 2023 Release

Rapid API is committed to providing its users with the best possible experience, and the…

5 months ago

The Power of Supporting Multiple API Gateways in an API Marketplace Platform

In today's fast-paced digital world, APIs (Application Programming Interfaces) have become the backbone of modern…

6 months ago