Contents

Modern Treasury empowers teams to make payment operations simple, scalable, and secure. The “Guides” series walks through representative businesses or payment processes and explains step by step how best to go about building them from scratch.


Introduction

Paying rent may be everyone’s least favorite time of the month, so tenants appreciate landlords doing what they can to make it an easy and painless process. As recently as 2014, only 17% of households paid their rent electronically, whether by ACH, credit, or debit. [1] That is changing, however. To help landlords migrate from paper payments, many property management apps and companies have sprung up. These companies, such as Avail, Rhino, AppFolio, and others, contract with landlords to communicate with tenants, set up automatic payment collections, and disburse cash to the right account. 

There are many setups that can complicate the system, including collecting and returning security refunds, splitting rent between roommates, handling one-off fees or refunds, and other unique cases. And there’s a lot to think through if you want to start a company that deals with property management. But, at a high level, these companies are built in a similar way. The intent of this post is to walk you through the technical aspects of setting up payments for a property management app, which we’ll call Rent.ly, taking a residential rent collection use case as an example. Whether for offices, apartments, or single-family homes, the overall payment ops architecture below serves as a good starting point. 


The User Experience

Let’s start by defining the user experience Rent.ly wants to offer. We’ll use the personas of Taylor Tenant and Logan Landlord to go through the experience step by step. 

  1. Taylor Tenant accepts a lease agreement. 
  2. The app prompts Taylor Tenant to provide a method of payment and their bank account details. 
  3. Taylor Tenant pays the security deposit amount. 
  4. Close to or on the 1st of every month, Taylor Tenant’s bank account is debited for the rent amount. 
  5. Once the funds clear, the funds are sent from Rent.ly to Logan Landlord. 
  6. Repeat.
  7. One day, Taylor Tenant moves out, and receives a security deposit refund for the balance left after cleaning and damages. That balance is sent to Logan Landlord. 

With this user experience in mind, you can begin designing the payment ops architecture and setting up the right bank accounts. 


Payment Ops Architecture

Your new property management app, Rent.ly, needs to have a bank account. This account will be where funds from tenants will come to, and from where funds for landlords will be disbursed. It’ll likely be a “FBO” account, which stands “for the benefit of” and means the funds are managed on behalf of your customers and do not legally belong to Rent.ly. 

Monthly money movement from Taylor Tenant to Logan Landlord.


In addition, you might want to set up two separate corporate accounts: a Security Deposit Reserve account, and a Rental Reserve account. Depending on what state you are in, there may be additional regulations on these; for example, in New York landlords must credit the tenant with interest on the security deposit amount. 

Taylor Tenant pays a security deposit.


To keep things simple for the purposes of this example, let’s assume that the tenants pay the security deposit into Rent.ly’s Security Deposit Reserve account, and monthly rent into the Rental Reserve account, and that the landlords receives funds from the Rental Reserve account. And, once the tenant moves out, the Security Deposit Reserve account credits the tenant and the landlord for the amounts due to each. 

Taylor Tenant and Logan Landlord receive security deposit credits.


Now, with your bank accounts set up, you can connect both to Modern Treasury and use the API to build your app. 


API Calls and Timings

The process starts with a tenant applying and getting accepted by the landlord. Once a tenant is signed, Rent.ly can start managing the flow of funds.


Step 1: Collect bank account details

You first need to collect the tenant’s bank account details. There’s a number of ways to collect bank account details. You can pick your preferred method and, once you have collected the routing and account numbers, you need to create a counterparty: 

curl --request POST \
  -u ORGANIZATION_ID:API_KEY \
  --url https://app.moderntreasury.com/api/counterparties \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "Taylor Tenant",
  "accounts": [
    {
      "account_type": "checking",
      "routing_details": [
        {
          "routing_number_type": "aba",
          "routing_number": "121141822"
        }
      ],
      "account_details": [
        {
          "account_number": "123456789"
        }
      ]
    }
  ]}’
Step 2: Collect the Security Deposit

Once a counterparty is created, you can collect the security deposit. You might want to collect it via ACH, wire, or check. Here’s the API call to collect it via an ACH debit from their account. Note that the amount is in cents, so $1000 is sent as 100000:

curl --request POST \
  -u ORGANIZATION_ID:API_KEY \
  --url https://app.moderntreasury.com/api/payment_orders \
  -H 'Content-Type: application/json' \
  -d '{
  "type": "ach",
  "amount": 100000,
  "direction": "debit",
  "currency": "USD",
  "originating_account": "Security Deposit Reserve account ID",
  "receiving_account_id": "Taylor Tenant’s bank account ID",
  "counterparty_id": "Taylor Tenant’s counterparty ID"
}'
Step 3: Collect rent

Now, to collect rent you need to setup an identical recurring ACH debit every month, but this time you need to collect it into the Rental Reserve account. Let’s suppose rent is $1200. In this case the API call you need to send is: 

curl --request POST \
  -u ORGANIZATION_ID:API_KEY \
  --url https://app.moderntreasury.com/api/payment_orders \
  -H 'Content-Type: application/json' \
  -d '{
  "type": "ach",
  "amount": 120000,
  "direction": "debit",
  "currency": "USD",
  "originating_account": "Rental Reserve account ID",
  "receiving_account_id": "Taylor Tenant’s bank account ID",
  "counterparty_id": "Taylor Tenant’s counterparty ID"
}'
Step 4: Disburse rent

As soon as the rent funds are in the Rental Reserve account, you can disburse them to the landlord. Once you’ve created a counterparty for Logan Landlord in a similar way to that outlined in Step 1 for Taylor Tenant, you can now set up an ACH credit to their account. Note that Logan Landlord might have multiple apartments, and so instead of getting paid $1200 for Taylor Tenant’s apartment, the ACH credit might be for three identical apartments. Let’s suppose on a given month Logan Landlord collects $3600. In that case, the ACH credit call would be: 

curl --request POST \
  -u ORGANIZATION_ID:API_KEY \
  --url https://app.moderntreasury.com/api/payment_orders \
  -H 'Content-Type: application/json' \
  -d '{
  "type": "ach",
  "amount": 360000,
  "direction": "credit",
  "currency": "USD",
  "originating_account": "Rental Reserve account ID",
  "receiving_account_id": "Logan Landlord’s bank account ID",
  "counterparty_id": "Logan Landlord’s counterparty ID"
}'

Note that you need to be conscious of ACH timings in deciding when to pay out to Logan Landlord. For the best customer service, you might want to make that call as soon as the ACH debit clears. But for risk management purposes, you might want to let the funds season a few days, to make sure that Taylor Tenant’s bank account had sufficient funds and they were not going to dispute the transaction. In the worst case scenario, you could pay out to Logan Landlord and then discover that Taylor Tenant has not actually paid. This needs to be managed closely. 


Step 5: Return Security Deposit

Finally, after a few months or years Taylor Tenant decides to move out. Rent.ly needs to take instructions from Logan Landlord as to how much of the security deposit should be returned, and how much should go to pay for cleaning and any damages. Let’s suppose Taylor Tenant has only broken a door handle and the $1000 security deposit will be split $200 to Logan Landlord for fixing the door handle, and $800 to Taylor Tenant. However, perhaps Taylor Tenant needs to get the final security deposit refund by check instead of ACH. In that case, you might need to send an ACH credit to Logan Landlord and a check made out to Taylor Tenant. Both should come from the Security Deposit Reserve account: 

curl --request POST \
  -u ORGANIZATION_ID:API_KEY \
  --url https://app.moderntreasury.com/api/payment_orders \
  -H 'Content-Type: application/json' \
  -d '{
  "type": "ach",
  "amount": 20000,
  "direction": "credit",
  "currency": "USD",
  "originating_account": "Security Deposit Reserve account ID",
  "receiving_account_id": "Logan Landlord’s bank account ID",
  "counterparty_id": "Logan Landlord’s counterparty ID"
}'
curl --request POST \
  -u ORGANIZATION_ID:API_KEY \
  --url https://app.moderntreasury.com/api/payment_orders \
  -H 'Content-Type: application/json' \
  -d '{
  "type": "check",
  "amount": 80000,
  "direction": "credit",
  "currency": "USD",
  "originating_account": "Security Deposit Reserve account ID",
  "receiving_account_id": "Taylor Tenant’s bank account ID",
  "counterparty_id": "Taylor Tenant’s counterparty ID"
}'

That’s it! Now, you’ve built the happy path of a property management app and you can start offering Rent.ly to landlords so they can collect rent, hold security deposits, and refund those when tenants move out.


What Can Go Wrong?

Tenants aren’t perfect, and neither are landlords, so naturally lots can go wrong. You have to think through the possibilities in advance in order to be able to handle the errors that can come along the way. 

A common occurrence could be a tenant that isn’t willing to or cannot pay. In those cases there may be late fees attached to the payment once it is negotiated with the tenant. It may be a case of fraud or of true hardship—it will be important to be able to build the app in a way flexible enough for Logan Landlord and Taylor Tenant to handle their contractual obligations. 

There may also be inadvertent mistakes. A common one could be that on the 1st of the month, Taylor Tenant’s bank account does not have the full amount for rent. In that case, the ACH debit call we send will return with a “Insufficient Funds” return code (R1), with the webhook object below:

{
  "event": "created",
  "data": {
    "id": <webhook_id>,
    "object": "return",
    "status": "pending",
    "returnable_id": <payment_order_id>,
    "returnable_type": "payment_order",
    "transaction_line_item_id": null,
    "transaction_id": null,
    "type": "ach",
    "amount": 10000,
    "currency": "USD",
    "code": "R01",
    "reason": "Insufficient Funds"
  }
}

In that case you need to think through customer service: who contacts Taylor Tenant, and how do they contact them? And, when Taylor Tenant authorizes you to debit them again, how does that customer service agent initiate that ACH debit? Modern Treasury provides an app for finance, customer service, and other payment ops teams to see these errors and handle issues as they occur. To make them most productive, it’s important for you to also add metadata on the API calls above, such as “Due date: October 1, Rent Month: September, Address: 123 Main St.” In that way, the payments are all displayed with the correct context that would help the customer service team contact Taylor Tenant and say, “Your payment for September due Oct 1 was returned. We need to redraft your account.” 

Again, this is only the basic architecture you would use to create a new property management app, but it offers a strong foundation from which to build. 

To make all your payment operations simple, scalable, and secure, request a demo of Modern Treasury.

References

1.

https://www.bostonfed.org/publications/research-data-report/2016/how-do-people-pay-rent.aspx

2.
3.
4.
5.
6.
7.
8.
9.
10.