In the “Using Heroku to Quickly Build a Multi-Tenant SaaS Product” article, I documented the foundation for a new SaaS solution that I am building (initially for my sister-in-law) — utilizing the Heroku ecosystem. Using Heroku allowed me to deploy the app quickly, without having to worry about infrastructure, DevOps, scalability when the app gets popular, etc. The “Integrating Twilio Into My SaaS Solution In Heroku” publication provided an example of how easy it is to create a Twilio instance and integrate the solution into my Fitness-based SaaS solution. This current journey has resulted in a feature set that both trainers and their clients have been able to enjoy.

This article is going to focus on invoicing clients for services that have been performed and will utilize messaging solutions within the Heroku ecosystem. The goals of the invoice process are as follows:

  • Quick and easy to use
  • Accurate and allow adjustments
  • Notify clients via SMS, including a link to an online invoice
  • Allow clients to submit payments using Venmo

Below, is a current version of the feature roadmap:


Invoice Processing and Flow

In order to illustrate the flow for sending invoices, the following diagram was created:

flow chart

I wanted to utilize a message-based approach, based upon my past experiences and satisfaction with the pattern. While one could argue that the current processing volume does not warrant a message-based approach, I did want to prove out this concept for use when the system gains more popularity.

About CloudAMQP

RabbitMQ is an open-source message broker solution, which allows asynchronous communication between different components of a multi-tier application. CloudAMQP is RabbitMQ wrapped into a service offering. Heroku not only offers CloudAMQP at price levels that match working directly with CloudAMQP, but also makes CloudAMQP very easy to install into an application. My experience with RabbitMQ and the ease of getting the message broker up and running made this product solution quite easy for me.

In a message broker solution, there are three main elements:

  • Producerthat has a message to be processed
  • Queuethatis the mechanism to store messages until they are processed
  • Consumerthatwatches the queue and handles the necessary processing

The producer requesting a task to be completed places a message on what is called a queue. In this case, the Invoice Submission process is handed off to an asynchronous process – which avoids making the Trainer wait for the invoicing process to complete. As a result, once the Trainer submits the request, the Fitness application can navigate to other sections of the application and continue working.

On the services side, the CloudAMQP service now has a message to be processed. A consumer (running in the Fitness application service within Heroku) listens for any messages to arrive and pulls them off the queue for processing, In the case of the Fitness application, the messages will be processed and sent to the customers via the Twilio service.

Invoicing Example

At a high level, the following actions take place during invoice processing:

1. Trainer navigates to the Create Invoices menu option to request a list of current invoices.

2. The Spring Boot service performs the necessary actions to return a List<InvoiceDto> of invoice data.

create invoices

3. The trainer can make adjustments to the invoice list, including changing a session to no-cost.

invoice items

4. When ready, the trainer uses the Submit Invoices button to initiate the invoice process.
5. The Spring Boot service persists the InvoiceDTO items.
6. Each InvoiceDTO is sent to CloudAMQP and added to the queue for processing asynchronously.
7. An instance of the Spring Boot service picks up the job from the queue, processes the request, which sends an SMS message to the client for the invoice.

At this point, each InvoiceDto is available for the trainer to view.

invoice history

The Customer Flow

The customer receives an SMS message similar to what is displayed below:

text messages

At that point, the end-user can use the first link to view an online version of their invoice:


Using the invoice, the customer can click the Pay Invoice using Venmo button to pay for their sessions using Venmo or they can click the second link on the original SMS message. Both messages navigate the user to the following page:


Here the user can sign-in or sign-up for Venmo. Once authenticated, the user can accept the request for payment and pay using the Venmo mobile application.

Configuring CloudAMQP in Heroku with Spring Boot

Getting started with CloudAMQP in Heroku is as easy as running the following command from the Heroku CLI:

heroku addons:create cloudamqp:lemur

Heroku adds everything your app needs to start working with the queue. Now we need to configure our app to use the queue, and define the message that we’ll be passing through the queue.

The properties related to CloudAMQP will now be available in the Heroku instance:


These configuration values are ultimately set in Heroku as shown below:

Config Vars

Within Spring Boot, the pom.xml needs to be updated to include the following dependency to support Rabbit AMQP:


Within the application.yml the following properties are introduced in order to allow the values to be dynamic:

invoice-topic-exchange: invoice-topic-exchange
invoice-processing-queue: invoice-processing-queue
 invoice-routing-key: invoice-processing.#

The three custom properties are available in Spring Boot as part of the MessagingConfigurationProperties bean:

public class MessagingConfigurationProperties {
private String invoiceTopicExchange;
private String invoiceProcessingQueue;
private String invoiceRoutingKey;

Finally, the messaging configuration class is configured as shown below:

At this point, Spring Boot can now connect to CloudAMQP to process messages in the topic exchange and queue.

Processing Requests

To process invoices using the CloudAMQP service, a request enters the system via the InvoiceService(the producer):

The InvoicePublisher class performs the task of sending the message to CloudAMQP (the queue):

From there the InvoiceProcessor class (the consumer,running on a Spring Boot service API instance), receives the message and processes the request:

The SmsService sends the invoice information over SMS and the Invoice object is marked as processed.


Before this functionality was introduced, my sister-in-law was manually sending invoices to her clients. She would look back at the sessions that had been completed since their last invoice, then note the cost for each session and the date range. The next step would be to paste a generic message about the invoice and update the values to match her client’s information.

The new process takes a mere fraction of the time to complete and has the ability to resend invoices at a later time. The system is smart enough to know which clients to invoice and which invoices still remain open. This allows my sister-in-law to focus on training her clients knowing that all of the invoicing goals (noted above) have been met.

In a similar fashion, Heroku provides the necessary tooling to introduce messaging concepts into an existing project with little effort. Just like the Heroku service does the DevOps work for me, CloudAMQP provides a quick setup and allows me to turn my attention to building intellectual property within the Fitness application to yield a better application experience.

In the current state, my Heroku ecosystem for the Fitness application currently appears as shown below:

gitlab system

I look forward to building upon this design as development continues across the feature roadmap.

Have a really great day!

Source link

Write A Comment