Portrait of Patrice GADEGBEPatrice GADEGBE

Rentapp

Rentapp is a prototype rent payment application, intended for tenants and landlords, whose development stopped in 2022 before a payment provider was integrated.

Role
Author of the API; mobile application developed with a second contributor
Period
From February to October 2022
Status
Prototype. Unfinished prototype, simulated payment
Technologies
Django 3.2, Django REST Framework, PostgreSQL, Flutter, flutter_bloc
Repositories
Two
Architecture of RentappA Flutter application calls a Django API served by nginx and gunicorn, which stores its data in PostgreSQL.ApplicationFlutter, flutter_bloctoken in secure storageAPIDjango 3.2, REST Frameworknginx and gunicornPostgreSQLleases, due payments, paymentsHTTP, tokenORM
Figure 1. Architecture of Rentapp in autumn 2022. Neither a payment provider nor an SMS gateway appears in it, since none was integrated.

Context

Rentapp was meant to let a tenant pay their rent from their phone, by bank card or by mobile money, and to let a landlord follow the payments of their residences. To that end the server models landlords, residences, tenants, leases, monthly due payments and payments, while the 2022 application offered the tenant a view of their months, a payment sheet and a receipt.

The project went through two successive overhauls and was never connected to a payment provider. It seemed preferable to me to present it for what it is, namely a prototype some of whose modelling choices deserve to be kept.

Problem

A lease produces one due payment per month, and the usual solution is to create them with a scheduled task, which requires a scheduler to deploy and to monitor for a prototype that had no other use for one. It also had to be possible to say without ambiguity whether a due payment was settled, and by what means, and to identify a tenant by phone number rather than by email address.

Answer

Due payments generated on read

The due payments are not created by any background task. When a tenant looks up what they owe, the lease goes through the months elapsed since its creation and creates the due payment of each month that does not yet have one, at the amount of the rent.

def generate_due_payments(self):
    months = Util.months_between(self.created_at.date(), datetime.date.today())
    for month in months:
        PaymentDue.objects.get_or_create(due_date__month=month.month, due_date__year=month.year,
                                         defaults={
                                             'contract': self,
                                             'label': "Due",
                                             'amount': self.rent,
                                             'due_date': month,
                                         })
Listing 1. Generation of a lease's due payments, called on read.

A payment tied to its instrument

A due payment is settled when it points to a payment, and a tenant’s arrears are derived from the sum of the due payments that have none. The payment carries a unique reference and a database constraint requires it to designate a card or a mobile money account, so that no payment can be recorded without its means of payment. The receipt, for its part, was produced on the phone, as a PDF bearing a QR code.

Phone, one-time code and PIN

Sign-in by username and password was replaced in August 2022 by a three-step flow: the phone number and the device identifier, a one-time code valid for two minutes, then a PIN chosen at registration. Registration requires a recent validation of the code, the same device and acceptance of the terms.

Limits and outlook

The payment is simulated from end to end, no provider being integrated, and no gateway sends the one-time code, which the server returns only in the development environment. The listing above moreover contains a defect: the lookup of an existing due payment covers only the month and the year, and not the lease, so that two leases would share the same due payment.

Finally, the overhaul of the sign-in disabled the business routes of the API, which the application was still calling when the work stopped; the two repositories are therefore no longer aligned. The tests never went beyond drafts. The mobile application was reduced in April 2026 to a mere home screen, and a resumption of the project should start again from the data model rather than from the existing code.

Back to the other projects