Rent Receipts (Quittances de loyer)
Generate legally compliant rent receipts for tenants. Per Art. 21 of Loi 89-462, landlords must provide a free rent receipt upon request, clearly separating rent and charges. Partial payments produce a "reçu" instead of a "quittance".
Quick Example
Code
Code
Common Workflows
Generate monthly receipts
- Ensure the lease has active lessees with
rent_sharepercentages - Ensure charges are set up on the lease
POST /api/leases/{id}/receipts/generate— generates one receipt per active tenantGET /api/leases/{id}/receipts/{receipt_id}/pdf— download the PDF
Multiple tenants (colocation)
When a lease has multiple tenants with different rent_share values (e.g., 60% / 40%), the system generates a separate receipt for each tenant with proportional amounts:
| Tenant | Rent share | Rent | Charges | Total |
|---|---|---|---|---|
| Marie (60%) | 60% | 450.00 | 52.50 | 502.50 |
| Pierre (40%) | 40% | 300.00 | 35.00 | 335.00 |
Authentication
All endpoints require authentication:
- LeasesRead: GET operations (list, get, download PDF)
- LeasesWrite: POST generate
- LeasesDelete: DELETE operations
Key Concepts
Quittance vs. Reçu
| Scenario | Document type | Meaning |
|---|---|---|
amount_paid >= total_due | QUITTANCE | Full payment — legally binding rent receipt |
amount_paid < total_due | RECU | Partial payment — acknowledgment of amount received |
Per Art. 21, only a full payment produces a "quittance". Any partial payment produces a "reçu" instead.
Rent Share (rent_share)
Each tenant on a lease has a rent_share percentage (default: 100%). When generating receipts:
- Rent =
lease.rent_amount × (rent_share / 100) - Each charge =
charge.amount × (rent_share / 100) - Total due = rent + sum of charges
Charges Snapshot
The charges_detail array is a frozen snapshot of the charge breakdown at the time of generation. Even if charges are later modified on the lease, existing receipts retain their original values.
Duplicate Prevention
A unique constraint on (tenant_id, lease_id, lessee_id, period_start, period_end) prevents generating duplicate receipts. If a receipt already exists for a tenant/period combination, it is silently skipped during generation.
Endpoints
Generate rent receipts
Code
Generates one receipt per active tenant for the specified period. Automatically produces a PDF for each receipt.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
period_start | date | Yes | Start of the rental period |
period_end | date | Yes | End of the rental period (must be after start) |
payments | array | Yes | Payment amounts per tenant |
payments[].lessee_id | uuid | Yes | Tenant ID |
payments[].amount_paid | decimal | Yes | Amount paid by this tenant |
payment_date | date | No | Date of payment (shown on PDF) |
Response: 201 Created — Array of RentReceipt objects
List rent receipts
Code
Returns all receipts for a lease, ordered by period (most recent first).
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
lessee_id | uuid | No | Filter by tenant |
Response: 200 OK — Array of RentReceipt objects
Get a rent receipt
Code
Response: 200 OK — RentReceipt object
Download receipt PDF
Code
Returns the generated PDF file as application/pdf with a Content-Disposition header for download.
The PDF includes:
- Header: "QUITTANCE DE LOYER" (blue) or "REÇU DE LOYER" (red) with period
- Bailleur: Landlord name, address
- Locataire: Tenant name, address, rent share percentage
- Bien loué: Property name and address
- Détail du paiement: Rent amount, itemized charges (Art. 23 Loi 89-462), totals
- Legal text: Art. 21 reference
- Signature area
Response: 200 OK — PDF binary
Delete a rent receipt
Code
Deletes the receipt from the database and removes the associated PDF file from storage.
Response: 204 No Content
Receipt Model
| Field | Type | Description |
|---|---|---|
id | uuid | Receipt unique ID |
lease_id | uuid | Associated lease |
lessee_id | uuid | Tenant this receipt is for |
lessee_name | string | Tenant full name |
period_start | date | Rental period start |
period_end | date | Rental period end |
rent_amount | decimal | Rent portion for this tenant |
charges_total | decimal | Total charges for this tenant |
charges_detail | array | Itemized charges by category |
charges_detail[].category_name | string | Charge category name |
charges_detail[].amount | decimal | Charge amount |
total_due | decimal | Total amount due (rent + charges) |
amount_paid | decimal | Amount paid |
document_type | string | QUITTANCE or RECU |
has_pdf | boolean | Whether a PDF has been generated |
Legal Reference
Art. 21, Loi n°89-462 du 6 juillet 1989 : « Le bailleur est tenu de transmettre gratuitement une quittance au locataire qui en fait la demande. La quittance porte le détail des sommes versées par le locataire en distinguant le loyer, le droit de bail et les charges. »
- The receipt is free of charge and mandatory upon request
- Electronic delivery is allowed with the tenant's explicit consent
- Partial payment produces a reçu, not a quittance
Error Responses
| Status | When |
|---|---|
400 | Invalid period (start >= end) |
401 | Missing or invalid authentication |
403 | Insufficient permissions |
404 | Lease, receipt, or PDF not found |
500 | Server error |