Portfolio
Proyecto propio (plugin FacturaScripts) · 2023–2024

MoodleManagement: invoicing that enrols itself

FacturaScripts ↔ Moodle plugin

A FacturaScripts plugin that turns a paid invoice into an automatic Moodle enrolment over the REST API, with PDF certificates and async workers.

My role Full design and implementation

  • PHP 8
  • FacturaScripts
  • Moodle Web Services (REST)
  • MySQL / MariaDB / PostgreSQL
  • Twig
  • Bootstrap 5
  • Chart.js 4
  • PHPUnit / PHPStan
MoodleManagement: invoicing that enrols itself
~22.200
Lines of code (app)
193
Commits
7
Moodle API clients
6
Async workers

Screenshots

Problem

A training business that invoices courses in FacturaScripts and delivers them in Moodle lives with two disconnected systems. Every sale forces someone to create the student in the LMS by hand, enrol them in the right course, make sure they paid before granting access and, once finished, issue and email the certificate. It is manual, repetitive and error-prone work: students enrolled without paying, duplicates, or access nobody revokes when an invoice is cancelled.

Solution

I designed and built MoodleManagement, a FacturaScripts plugin that links invoicing to Moodle enrolment through its REST web-services API (wstoken, moodlewsrestformat). At its core is a custom HTTP client over webservice/rest/server.php, split into 7 API classes (users, courses, enrolments, badges, completion, files). The flow fires itself: when a FacturaCliente is marked paid, an async EnrolmentWorker walks the lines mapped to courses and enrols them in Moodle; if the invoice is unpaid, it rolls back. Product→course and contact→user mapping, PDF certificate generation, cron-based progress sync, and a dashboard with charts. I hardened it with idempotency guards, a circuit breaker, retry-with-backoff, token encryption, signed URLs and anti-SSRF validation.

Result

The plugin gathers 27 controllers, 11 models, 6 async workers and a test suite (unit and integration) over PHPUnit, PHPStan and PHPCS. It covers the full "paid invoice → enrolment → certificate by email" cycle with no manual steps, supports multiple Moodle instances and ships in 24 locales. Its security and resilience layer (HMAC webhooks, idempotency, circuit breaker) prepares it to run unattended against an external API that can fail.