Backend (Laravel)
The TendoPay backend is a Laravel monolith written in PHP. It is the core application that handles customer accounts, KYC, loan origination, repayment, merchant integration, payroll integration, and the public APIs that power both the web frontend and the mobile app.
Language and Framework
- Language: PHP — the application runs on a current, actively-supported PHP release (PHP 8.x).
- Framework: Laravel (currently on Laravel 12). We follow Laravel's standard project layout — Eloquent for ORM, Blade for any server-rendered views, Artisan for CLI tooling, and the Laravel scheduler for cron-style work.
Application Boundaries
The monolith exposes several surfaces:
- Public web app for customers — Vue 3 single-page experiences served from Laravel. (Vue 2 surfaces are being retired by 15 June 2026 — see the Frontend page.)
- Admin dashboard for internal operations, risk, and collections.
- REST APIs consumed by the mobile apps and merchant integrations.
- A GraphQL surface used by parts of the admin dashboard and other internal consumers.
- Webhooks and callbacks for payment partners, payroll providers, and other integrations.
A handful of small Go services sit alongside the monolith for specific workloads where Laravel is not the right fit (typically high-throughput or low-latency tasks). They communicate with the monolith over HTTP and Redis.
Authentication and Authorisation
- OAuth 2.0 for first-party and third-party clients (mobile app, merchant integrations).
- Token-based authentication for lightweight API clients.
- Role and permission management to gate admin features.
- Two-factor authentication for admin and sensitive customer flows.
- Single Sign-On with Apple for customer login. Apple is the only social-login provider currently active; the other providers that previously appeared on the sign-in screen (Facebook, Google, Yahoo) have been disabled.
Background Work, Queues, and Scheduling
- Redis-backed queues drive all asynchronous work — emails, SMS, webhooks, exports, statement generation, KYC processing, and so on.
- A queue dashboard (Laravel Horizon) gives operators visibility into queue depth, throughput, and failures across multiple supervised worker pools (web, batch, export).
- The Laravel scheduler runs recurring jobs, with a monitoring layer that alerts when scheduled jobs fail to run on time.
The supervised worker layout splits work into separate process pools so that long-running batch jobs (statement exports, payroll runs) cannot starve user-facing queues (OTP delivery, webhook handling).
Data Layer
- Amazon Aurora (MySQL-compatible) as the primary relational store, accessed through Eloquent ORM. The application talks to a cluster endpoint for writes and a reader endpoint for read-heavy workloads.
- Redis for cache, sessions, queues, and rate limiting.
- Meilisearch as the search backend behind a Laravel Scout integration — used for fast lookups in the admin dashboard.
- AWS S3 for file storage (KYC documents, signatures, exported reports), accessed via Laravel's filesystem abstraction. Buckets are versioned and cross-region replicated.
API Layer
- REST endpoints for mobile and merchant clients, versioned and rate-limited.
- GraphQL for internal consumers that benefit from a flexible query shape.
- Webhooks in both directions — TendoPay receives callbacks from payment and KYC partners, and emits webhooks to merchants for repayment events.
Quality, Testing, and Tooling
- PHPUnit for unit and feature tests, with parallel test execution to keep CI fast.
- Static analysis via PHPStan/Larastan at a strict level.
- Coding standards enforced via PHP_CodeSniffer with project-specific rules.
- Automated refactoring via Rector to keep the codebase aligned with newer PHP/Laravel idioms.
- Cypress for end-to-end coverage of critical user journeys (see the Frontend page).
- GitHub Actions runs analyse + test on every pull request.