---
feature: Enrollment and payment
slug: enrollment
surface: client
consumer: flutter
version: 0.2.0
status: in-progress
brd_version: "1.0 plus additional requirements and cancellation policy"
brd_ids: [TRN-010, TRN-011, TRN-012, TRN-017, PLT-002]
business_rules: [BR-ENR-01, BR-ENR-03, BR-ENR-05, BR-FIN-02, BR-FIN-03]
decisions: [D6, DEC-05, DEC-06, DEC-07, DEC-15, DEC-24, DEC-25, DEC-29, DEC-31, DEC-34, TD-15, TD-17]
schema_tables: [courses, course_packages, purchases, enrollments, payments, enrollment_tickets, course_earnings, app_configs]
screens: [client--enrollment--*]
related_docs: []
last_updated: 2026-11-12
---

# Enrollment and payment — Flutter integration guide

## Quick reference

| | |
|---|---|
| Version | 0.2.0 — domain actions only; app action: none |
| Status | In progress; not available to integrate |
| Auth | N/A |

**Endpoints:** None implemented. **Open decisions:** DEC-05, DEC-06, DEC-07, DEC-15, DEC-24, DEC-25.

## 1. Business summary

Checkout records course and package prices and snapshots before payment. Confirmation locks courses and confirms all courses together; a paid purchase without available seats requires an external refund.

The planned course details response exposes `can_enroll` as a boolean; course details endpoints are not implemented yet. Checkout refuses an unavailable course with `COURSE_NOT_ENROLLABLE`.

## 2. User flow and screens

N/A: HTTP integration is not implemented.

## 3. Endpoints

N/A.

## 4. Statuses and enums

Payment: pending, paid, failed. Enrollment: awaiting_payment, confirmed, completed, cancelled, payment_failed. Purchase: awaiting_payment, paid, failed, expired.

## Data model

Purchases, enrollments, payments, tickets and pending course earnings record the checkout and outcome.

## 5. Dart models

N/A.

## 6. Business rules enforced by the backend

DEC-29: no seat hold; DEC-31: package confirmation is all or nothing; DEC-34: price is locked after the first confirmed enrollment; BR-ENR-05: snapshots preserve purchase details.

## 7. Notifications and real-time events

N/A.

## 8. Localization and UI notes

N/A.

## 9. Integration checklist

Wait for HTTP endpoints and real response examples.

## 10. Acceptance scenarios

Domain tests cover course and package payment, failure, repeated callbacks, unavailable seats and snapshots. SQLite does not verify concurrent row locking.

## 11. Open decisions and known limitations

DEC-06: gateway is fake until a provider is supplied. DEC-24 and DEC-25: cashback and points are not posted. DEC-15: center commission source is unresolved; `center_commission_rate` defaults to 0. `trainer_commission_rate` also defaults to 0 when absent. The real payment integration and HTTP layer remain outstanding. The schema has no enrollment window; the availability check closes at the course end, when known. An explicit enrollment opening or closing policy remains to be decided.

## Version history

| Version | Date | Type | Summary | App action required |
|---|---|---|---|---|
| 0.2.0 | 2026-11-12 | Minor | Course availability and typed checkout refusal; details response remains planned. | None until endpoints are available. |
| 0.1.0 | 2026-11-12 | Initial | Domain actions only. | None. |

## Changelog

### 0.2.0 — 2026-11-12

- Added enrollment availability and checkout refusal for unavailable courses. App action required: none until endpoints are available.

### 0.1.0 — 2026-11-12

- Added domain checkout actions; no endpoints. App action required: none.
