# How to build peer-to-peer lending in Bubble

- Tool: Bubble
- Difficulty: Beginner
- Time required: 25-30 min
- Compatibility: All Bubble plans (Stripe required for payments)
- Last updated: March 2026

## TL;DR

Build a peer-to-peer lending platform in Bubble with loan request forms, lender matching, interest rate calculation, repayment schedules, and basic risk scoring. This tutorial covers the data types, workflows, and page layouts needed so borrowers can request loans and lenders can fund them — all built visually in Bubble's editor.

## Overview: Building a P2P Lending Platform in Bubble

This tutorial walks you through building the core features of a peer-to-peer lending platform in Bubble. You will create data types for loan requests, funding offers, and repayment schedules. You will build borrower and lender interfaces, implement interest rate calculations, and set up repayment tracking workflows. This is a starting point for fintech MVPs — production lending platforms require additional compliance considerations.

## Before you start

- A Bubble account with an existing app
- Stripe plugin installed for payment processing
- Basic understanding of Bubble data types and workflows
- Familiarity with backend workflows for scheduled tasks

## Step-by-step guide

### 1. Create the lending data types

Go to the Data tab and create three data types. LoanRequest with fields: borrower (User), amount (number), interest_rate (number), term_months (number), purpose (text), status (Option Set: Open, Funded, Active, Completed, Defaulted), and funded_by (User). Repayment with fields: loan (LoanRequest), due_date (date), amount_due (number), amount_paid (number, default 0), status (Option Set: Pending, Paid, Overdue). UserProfile with fields: user (User), credit_score (number), total_borrowed (number), total_lent (number), and completed_loans (number).

**Expected result:** Three data types exist: LoanRequest, Repayment, and UserProfile with all fields configured.

### 2. Build the loan request form

Create a page called request-loan. Add inputs for loan amount (number), term in months (Dropdown: 3, 6, 12, 24), and purpose (text). Display a calculated interest rate based on the borrower's profile: for example, base rate 5% + adjustment based on credit_score. Show a preview of monthly payment calculated as: amount * (1 + interest_rate/100) / term_months. Add a Submit Request button. The workflow: Create a new LoanRequest with all values, status = Open, and borrower = Current User.

> Pro tip: For a more accurate payment preview, use the standard amortization formula: P * [r(1+r)^n] / [(1+r)^n - 1] where P is principal, r is monthly rate, and n is number of months.

**Expected result:** Borrowers can submit loan requests with amount, term, and purpose, and see their estimated interest rate and monthly payment.

### 3. Create the lender marketplace

Create a page called invest showing a Repeating Group with type LoanRequest filtered by status = Open, sorted by date created descending. Each cell displays: borrower name (or anonymized ID), amount requested, interest rate, term, purpose, and borrower's credit score. Add a Fund This Loan button in each cell. Add filter dropdowns for amount range, term, and minimum credit score. Use constraints on the search to apply filters with Ignore empty constraints checked.

**Expected result:** Lenders can browse open loan requests with filters and choose loans to fund.

### 4. Implement the funding workflow

When a lender clicks Fund This Loan, trigger a Stripe payment for the loan amount. On payment success: Make changes to LoanRequest — set status = Funded, funded_by = Current User. Then create a backend workflow called generate_repayment_schedule with parameter loan_id. This workflow calculates the monthly payment amount and creates Repayment records for each month: due_date = loan start date + N months, amount_due = calculated monthly payment, status = Pending. Schedule this backend workflow immediately after funding.

**Expected result:** Funding a loan processes the payment, updates the loan status, and generates the full repayment schedule.

### 5. Build the repayment tracking dashboard

Create a page called my-loans showing two tabs: As Borrower (loans where borrower = Current User) and As Lender (loans where funded_by = Current User). For each loan, show a Repeating Group of Repayments sorted by due_date. Display due_date, amount_due, status (with conditional coloring — green for Paid, yellow for Pending, red for Overdue). For borrowers, add a Pay button on Pending repayments that triggers Stripe checkout for the amount_due and updates the Repayment status to Paid on success.

**Expected result:** Both borrowers and lenders can view loan details and repayment status, and borrowers can make payments.

### 6. Add overdue detection with a scheduled backend workflow

Create a backend workflow called check_overdue_repayments. It searches for Repayments where status = Pending and due_date < Current date/time. For each, change status to Overdue. If a loan has more than 3 overdue repayments, change the LoanRequest status to Defaulted. Schedule this workflow to run daily. For complex financial platforms requiring regulatory compliance and advanced risk assessment, consider reaching out to RapidDev for expert development support.

**Expected result:** Overdue repayments are automatically detected daily, and loans with too many missed payments are marked as defaulted.

## Complete code example

File: `Workflow summary`

```text
P2P LENDING PLATFORM — WORKFLOW SUMMARY
========================================

DATA TYPES:
  LoanRequest
    - borrower (User)
    - amount (number)
    - interest_rate (number) — annual percentage
    - term_months (number)
    - purpose (text)
    - status (Option Set: Open/Funded/Active/Completed/Defaulted)
    - funded_by (User)
    - funded_date (date)

  Repayment
    - loan (LoanRequest)
    - due_date (date)
    - amount_due (number)
    - amount_paid (number, default 0)
    - status (Option Set: Pending/Paid/Overdue)

  UserProfile
    - user (User)
    - credit_score (number, default 650)
    - total_borrowed (number)
    - total_lent (number)
    - completed_loans (number)

WORKFLOW 1: Submit loan request
  Event: Button Submit is clicked
  Action: Create new LoanRequest
    borrower = Current User
    amount = Input Amount's value
    interest_rate = calculated rate
    term_months = Dropdown Term's value
    purpose = Input Purpose's value
    status = Open

WORKFLOW 2: Fund a loan
  Event: Button Fund This Loan is clicked
  Action 1: Stripe Checkout (amount = loan amount * 100)
  On success:
  Action 2: Make changes to LoanRequest
    status = Funded
    funded_by = Current User
    funded_date = Current date/time
  Action 3: Schedule API workflow generate_repayment_schedule
    loan_id = LoanRequest's unique ID

BACKEND WORKFLOW: generate_repayment_schedule
  Parameter: loan_id (text)
  Step 1: Look up LoanRequest by ID
  Step 2: Calculate monthly payment
    monthly_rate = interest_rate / 100 / 12
    payment = amount * monthly_rate * (1+monthly_rate)^term
             / ((1+monthly_rate)^term - 1)
  Step 3: Create Repayment for each month
    (recursive workflow, month 1 through term_months)
    due_date = funded_date + N months
    amount_due = calculated payment
    status = Pending
  Step 4: Make changes to LoanRequest
    status = Active

WORKFLOW 3: Make repayment
  Event: Button Pay is clicked
  Action 1: Stripe Checkout (amount = Repayment's amount_due * 100)
  On success:
  Action 2: Make changes to Repayment
    amount_paid = amount_due
    status = Paid

BACKEND WORKFLOW: check_overdue_repayments
  Runs: daily at 08:00
  Step 1: Search for Repayments
    status = Pending, due_date < Current date/time
  Step 2: Make changes to list → status = Overdue
  Step 3: For loans with 3+ overdue repayments
    Make changes to LoanRequest → status = Defaulted
```

## Common mistakes

- **Not generating the repayment schedule at funding time** — Without a schedule, there are no due dates to track and no way to detect overdue payments Fix: Create all Repayment records with calculated due dates immediately when the loan is funded.
- **Storing calculated interest in the borrower's currency display** — Rounding errors in display can differ from what is actually charged, causing trust issues Fix: Calculate the exact repayment amounts once at funding time and store them in the Repayment records.
- **Allowing a lender to fund their own loan request** — Self-funding creates fraudulent circular transactions Fix: Add an Only when condition to the Fund button: Only when Current User is not Current cell's LoanRequest's borrower.

## Best practices

- Calculate and store all repayment amounts at funding time to avoid rounding discrepancies
- Use a scheduled backend workflow to check for overdue payments daily
- Prevent self-funding by adding a condition that excludes the borrower from their own loan listing
- Store both the annual interest rate and the calculated monthly payment on each Repayment record
- Track user lending and borrowing history in a UserProfile for basic risk assessment
- Use Privacy Rules so borrowers and lenders can only see their own financial data
- Add a grace period of 1-3 days before marking payments as overdue

## Frequently asked questions

### Is this enough for a real lending platform?

This tutorial covers the core mechanics. A production lending platform also requires KYC/AML compliance, legal documentation, escrow accounts, and regulatory approval depending on your jurisdiction.

### How do I calculate the interest rate for each borrower?

Start with a base rate and adjust based on the borrower's credit score and loan history. For example: base 8% minus 0.5% for every 50 points above 650 credit score, with a floor of 4%.

### Can multiple lenders fund one loan?

Yes. Instead of a single funded_by field, create a FundingContribution data type linking lenders to loans with their contributed amounts. The loan is fully funded when contributions total the requested amount.

### How do lenders get repaid?

When a borrower makes a repayment via Stripe, create a backend workflow that initiates a Stripe Transfer to the lender's connected Stripe account. This requires Stripe Connect setup.

### Can RapidDev help build a fintech platform?

Yes. RapidDev specializes in Bubble development and can help build compliant fintech platforms with advanced features like credit scoring, KYC verification, escrow management, and automated regulatory reporting.

### How do I handle early loan repayment?

Add a Pay Off Loan button that calculates the remaining principal, processes a single Stripe payment, marks all remaining Repayments as Paid, and changes the LoanRequest status to Completed.

---

Source: https://www.rapidevelopers.com/bubble-tutorial/set-up-a-p2p-lending-platform-in-bubble
© RapidDev — https://www.rapidevelopers.com/bubble-tutorial/set-up-a-p2p-lending-platform-in-bubble
