- Given Một trung tâm vừa được tạo qua luồng onboarding
- When Việc tạo trung tâm hoàn tất
- Then Một thuê bao
trialingvới gói dùng thử (giới hạn bằng gói cao nhất không phải Doanh nghiệp, 1 chi nhánh, 5 người dùng nhân sự) và hạn = ngày tạo + 30 ngày được tạo; thanh trên cùng hiển thị "Dùng thử, còn N ngày"; không yêu cầu thông tin thanh toán; bộ phận kinh doanh của FLYER nhận thông báo.
PRD 19 · Gói dịch vụ và thuê bao
Danh mục gói dịch vụ của Trường Số với giới hạn theo gói (học viên đang học, chi nhánh, người dùng nhân sự, dung lượng, tin ZNS gộp, mô-đun), vòng đời thuê bao của tenant từ dùng thử đến chấm dứt, điểm kiểm soát giới hạn dùng chung, nâng cấp có tính lại theo chu kỳ 12 tháng, hoá đơn thuê bao thu qua chuyển khoản đối soát SePay, và bảng điều khiển nội bộ của FLYER. Backend hiện chưa có thực thể gói hay thuê bao ở cấp tenant.
Xuất xứ / Prompt / Giới hạn
Tài liệu do trợ lý AI soạn trong một phiên làm việc ngày 16/09/2026, mở rộng bộ PRD theo yêu cầu gốc được trích nguyên văn ở trang mục lục. Đây là bản đề xuất để đội thảo luận, chưa phải quyết định của đội sản phẩm.
Nguồn
- Nghiên cứu công khai về đối thủ cạnh tranh (PSE ONE, pse4.one), mã nguồn
center-crm-frontendvà đặc tả OpenAPI/v3trên staging (182 endpoint), tính đến ngày 10/09/2026. - Nhãn existing / extend / new trong trang được xác định bằng cách đối chiếu với đặc tả
/v3trên staging tại thời điểm trên. - Đợt quét thứ hai các nguồn công khai của PSE ONE ngày 16/09/2026 (trang tính năng, bảng phí dịch vụ, mục hướng dẫn sử dụng).
- Tham chiếu đối thủ cạnh tranh: bảng giá công khai của PSE ONE (pse4.one, khảo sát ngày 16/09/2026) gồm Basic 199.000 đ/tháng (thanh toán theo năm, tối đa 100 học viên, 1 GB), Pro 400.000 đ/tháng (300 học viên, 2 GB), Business 700.000 đ/tháng (500 học viên, 4 GB) và Enterprise 1.000.000 đ/tháng (không giới hạn học viên, 5 GB, mở thêm giáo trình trực tuyến, khoá học, luyện thi, tài khoản học viên, trò chơi); dung lượng mua thêm 2.500.000 đ/năm cho mỗi 40 GB. Mọi gói đều gồm toàn bộ mô-đun vận hành (ứng dụng di động, nhân sự, lead, học thử, lịch học, điểm danh, tài chính, kho, báo cáo, sao lưu hằng ngày, hỗ trợ 24/7). Quy tắc nâng cấp được công bố nguyên văn: "hợp đồng sẽ được tính lại 12 tháng mới theo gói đã chọn", "phần chi phí còn lại của gói cũ sẽ được khấu trừ trực tiếp vào gói mới", "Hợp đồng cũ chấm dứt ngay tại thời điểm nâng cấp"; ví dụ công bố: Basic đã dùng 7/12 tháng, giá trị còn lại 199.000 × 5 = 995.000 đ, nâng lên Pro 4.800.000 đ, phải trả 3.805.000 đ. Đối thủ không công bố quy tắc hạ gói, thời gian dùng thử, gia hạn và lưu giữ dữ liệu. Các con số trên chỉ dùng để định vị; giá của Trường Số là quyết định của kinh doanh.
Giới hạn
- Cần xác minh khi khảo sát trực tiếp trong ứng dụng, vì đăng nhập tự động vào sản phẩm tham chiếu chưa được cấp phép trong phiên soạn:
- Thời gian dùng thử của đối thủ, có yêu cầu thông tin thanh toán không, và điều gì xảy ra khi hết dùng thử.
- Hành vi khi hết hạn gói: khoá hoàn toàn, chỉ đọc hay chỉ cảnh báo; có ân hạn không và bao lâu.
- Quy tắc hạ gói và liệu có hoàn tiền phần chênh lệch.
- "Học viên" trong giới hạn gói được đếm là học viên đang học hay toàn bộ hồ sơ; hồ sơ đã nghỉ có tính không.
- Dung lượng tính trên loại tệp nào, có hiển thị cho tenant không; dung lượng mua thêm có tính theo tỷ lệ thời gian còn lại hay trọn năm.
- Có trang tự phục vụ để nâng cấp và xem hoá đơn trong ứng dụng hay phải liên hệ kinh doanh.
Thiết kế đề xuất
Tám màn hình theo hệ thiết kế FLYER Cloud: trang Gói dịch vụ trong Cài đặt với thanh mức sử dụng đổi màu từ 90% và bảng so sánh gói để giá ở dạng "Cần quyết định", báo giá nâng cấp theo công thức 12 tháng, hoá đơn thuê bao, banner và hộp thoại chặn 402 trên danh sách học viên, và bảng điều khiển nội bộ của FLYER; điều quan trọng nhất là ở mọi điểm chạm giới hạn người dùng luôn thấy số đang dùng / giới hạn và đường nâng cấp.








1Mục đích
Trường Số được bán theo gói dịch vụ trả trước cho từng trung tâm (tenant). Mỗi gói quy định số học viên đang học, số chi nhánh, số người dùng nhân sự, dung lượng tài nguyên số, số tin ZNS gộp mỗi tháng và những mô-đun được mở. Mô-đun này là nguồn duy nhất trả lời "trung tâm đang dùng gói nào, còn được dùng bao nhiêu, đến bao giờ hết hạn và phải trả bao nhiêu để nâng cấp". Các mô-đun khác chỉ hỏi một điểm kiểm soát chung trước khi tạo thêm bản ghi. Chủ trung tâm xem mức sử dụng so với giới hạn tại một trang trong Cài đặt, nhận cảnh báo trước khi chạm ngưỡng và tự nâng cấp mà không cần liên hệ bộ phận kinh doanh của FLYER.
Trong phạm vi
- Danh mục gói: tên, giá tháng và giá năm (giá trị cụ thể do kinh doanh quyết định), giới hạn theo chỉ số, quyền dùng mô-đun P2 (giáo trình số PRD 14, học trực tuyến PRD 18).
- Vòng đời thuê bao: dùng thử 30 ngày, đang hoạt động, sắp hết hạn, quá hạn có ân hạn 14 ngày, tạm khoá chỉ đọc, chấm dứt và xoá dữ liệu sau 90 ngày theo PRD 12.
- Điểm kiểm soát giới hạn dùng chung: cảnh báo mềm ở 90%, chặn tạo mới khi vượt giới hạn kèm lời mời nâng cấp, chế độ chỉ đọc khi tạm khoá.
- Nâng cấp có tính lại theo chu kỳ 12 tháng; hạ gói vào cuối kỳ khi mức sử dụng nằm trong giới hạn gói mới; gói mở rộng (dung lượng, tin ZNS, chi nhánh, người dùng).
- Hoá đơn thuê bao: chuyển khoản có đối soát SePay như PRD 05, cổng VNPay ở P2, hoá đơn điện tử do FLYER phát hành cho tenant.
- Bảng điều khiển nội bộ của FLYER: đặt gói, gia hạn dùng thử, cấp tín dụng, tạm khoá và mở khoá.
- Đo lường mức sử dụng, trang "Gói dịch vụ" trong Cài đặt (PRD 10), thông báo T-30, T-7, T-1, T+0, nhật ký mọi thay đổi thuê bao.
Ngoài phạm vi
- Gói bán cho phụ huynh và học viên (gói học phí thuộc PRD 05; gói học tập FLYER thuộc ứng dụng học tập).
- Hoa hồng đại lý và chiết khấu theo kênh bán.
- Đa tiền tệ; v1 chỉ dùng VND.
- Tự động trừ tiền định kỳ qua thẻ (đề xuất cho P3 sau khi có VNPay).
2Hiện trạng
Backend đã có tenant (Center của CRM) và chi nhánh (School của FLYER) theo quyết định D1 ở PRD 00, cùng luồng onboarding tạo trung tâm. Không có thực thể nào ghi nhận gói, giới hạn hay thời hạn của một tenant; mọi trung tâm hiện được mở không giới hạn. Ứng dụng giáo viên có gói bản quyền cho cá nhân giáo viên; đó là mẫu tham khảo về cấu trúc dữ liệu, không phải gói của tenant.
| Năng lực hiện có | Endpoint | Giữ lại? |
|---|---|---|
| Danh sách và chi tiết trung tâm (tenant) của người dùng | GET /v3/crm/centers existing | Giữ; mở rộng response với khối subscription_summary. |
| Onboarding: trung tâm đã tạo, tạo trung tâm mới | GET /v3/crm/onboarding/centers, POST /v3/crm/onboarding/create-center existing | Giữ; create-center khởi tạo thuê bao dùng thử 30 ngày ngay khi tạo trung tâm. |
| Chi nhánh mà người dùng được truy cập | GET /v3/crm/me/accessible-schools existing | Giữ; nguồn đếm chi nhánh và nơi gắn cờ read_only khi tenant bị tạm khoá. |
| Gói bản quyền cá nhân của giáo viên FLYER | GET /v3/teacher/package/my-subscriptions existing | Giữ nguyên cho ứng dụng giáo viên; chỉ tham khảo cấu trúc (package, start, end, status). |
| Đối soát chuyển khoản SePay trên tài khoản của trung tâm | webhook SePay (PRD 05) extend | Mở rộng để nhận giao dịch vào tài khoản của FLYER và khớp hoá đơn thuê bao theo payment_code. |
| Gói, giới hạn, thuê bao, bộ đếm mức sử dụng, hoá đơn thuê bao, tín dụng, bảng điều khiển nội bộ | không có new | Xây mới ở /v3/crm/subscription/* (tenant tự phục vụ) và /v3/admin/tenants/* (nội bộ FLYER). |
3User story và tiêu chí chấp nhận
- Given Có quyền
subscription.view - When Mở Cài đặt → Gói dịch vụ
- Then Trang hiển thị tên gói, trạng thái, ngày hết hạn và một thanh cho mỗi chỉ số dạng "đã dùng / giới hạn" kèm phần trăm; chỉ số từ 90% đổi sang màu cảnh báo kèm chữ; số liệu không cũ quá 15 phút và có nút "Tính lại ngay".
- Given Số học viên đang học đạt 90% giới hạn của gói
- When Bất kỳ người dùng nào tạo hoặc chuyển đổi thêm học viên (PRD 01, PRD 02)
- Then Thao tác vẫn thành công; banner "Đã dùng 92/100 học viên của gói Tiêu chuẩn" xuất hiện trên danh sách học viên và trang tổng quan; chủ trung tâm nhận thông báo trong ứng dụng và email một lần cho mỗi chỉ số, lặp lại tối đa 7 ngày một lần.
- Given Số học viên đang học đã bằng giới hạn
- When Giáo vụ nhập học thêm một học viên hoặc chuyển một học viên bảo lưu về đang học
- Then API trả về 402
PLAN_LIMIT_REACHEDkèm chỉ số, giới hạn, mức đang dùng; hộp thoại "Gói Tiêu chuẩn cho phép 100 học viên đang học. Nâng cấp lên gói Nâng cao để tiếp tục." có nút Xem gói (chủ trung tâm) hoặc Báo cho chủ trung tâm (vai trò khác); bản ghi không được tạo; xem, sửa, điểm danh, thu tiền trên bản ghi hiện có vẫn hoạt động.
- Given Thuê bao kỳ năm, gói Tiêu chuẩn, đã dùng 7 trong 12 tháng
- When Chọn gói Nâng cao tại trang Gói dịch vụ
- Then Báo giá hiển thị giá gói mới 12 tháng, trừ giá trị còn lại của gói cũ (đơn giá tháng × 5 tháng chưa dùng), trừ tín dụng, bằng số tiền phải trả; hạn mới = ngày xác nhận + 12 tháng; sau khi xác nhận, một hoá đơn thuê bao kèm mã QR được tạo; giới hạn gói mới có hiệu lực khi hoá đơn được thanh toán đủ, hoặc ngay lập tức nếu bảng điều khiển nội bộ đã bật "tin cậy thanh toán" cho tenant.
- Given Mức sử dụng nằm trong giới hạn của gói thấp hơn
- When Chọn "Hạ xuống gói Khởi đầu từ kỳ tiếp theo"
- Then Yêu cầu được lưu với ngày hiệu lực = ngày hết hạn hiện tại; trang hiển thị "Sẽ chuyển sang gói Khởi đầu vào dd/MM/yyyy" kèm nút Huỷ yêu cầu; tại T-1 hệ thống kiểm tra lại: nếu vượt giới hạn gói mới, yêu cầu bị huỷ và chủ trung tâm nhận thông báo liệt kê chỉ số cần giảm; nếu không, hoá đơn gia hạn được lập theo gói mới.
- Given Mức sử dụng vượt giới hạn của gói thấp hơn
- When Chọn hạ gói
- Then Nút bị vô hiệu hoá kèm giải thích "Đang có 180 học viên, gói Khởi đầu cho phép 100".
- Given Hoá đơn thuê bao chưa thanh toán với
payment_codetrong mã QR và nội dung chuyển khoản - When Giao dịch đến tài khoản của FLYER với đúng mã và đủ tiền
- Then Trong 5 phút, hoá đơn chuyển sang đã thanh toán, thuê bao chuyển sang
activevới gói và hạn theo hoá đơn, phiếu thu PDF gửi đến email người thanh toán và chủ trung tâm; giao dịch sai mã hoặc thiếu tiền vào mục Chưa đối soát của bảng điều khiển nội bộ.
- Given Thuê bao đang hoạt động, ngày hết hạn sắp đến
- When Đến T-30, T-7, T-1 và T+0
- Then Chủ trung tâm và kế toán nhận thông báo trong ứng dụng và email tại từng mốc, hoá đơn gia hạn được tạo sẵn tại T-30; tại T+0 thuê bao chuyển sang
past_due, banner đỏ "Gói dịch vụ đã hết hạn, còn 14 ngày ân hạn" hiển thị cho mọi người dùng, tính năng vẫn dùng được; tại T+14 chưa thanh toán, thuê bao chuyển sangsuspended: endpoint ghi trả về 423TENANT_READ_ONLY, người dùng vẫn đăng nhập, xem, tìm kiếm, xuất Excel và tải phiếu thu; phụ huynh vẫn xem được cổng phụ huynh; tin nhắn tự động dừng gửi. - Given Thuê bao ở trạng thái
suspended - When Hoá đơn gia hạn được thanh toán đủ
- Then Thuê bao trở lại
activetrong 5 phút; kỳ mới tính từ ngày hết hạn cũ (thời gian ân hạn và tạm khoá thuộc kỳ mới, không được cộng thêm).
- Given Người dùng nội bộ có quyền
tenant.admin - When Chọn một trung tâm trong bảng điều khiển nội bộ, đặt gói Doanh nghiệp kỳ 12 tháng từ ngày ký, nhập số hợp đồng và lý do
- Then Thuê bao được cập nhật ngay, một hoá đơn thuê bao được tạo ở trạng thái đã thanh toán ngoài hệ thống (phương thức
offline, kèm số hợp đồng), chủ trung tâm nhận email xác nhận, nhật ký ghi người thực hiện, giá trị trước và sau. - Given Trung tâm dùng thử sắp hết hạn và đang đàm phán
- When Chọn "Gia hạn dùng thử" thêm 7, 14 hoặc 30 ngày kèm lý do
- Then Hạn được cộng thêm; tổng thời gian dùng thử không vượt 90 ngày nếu không có quyền
tenant.admin.override. - Given Cần bù đắp sự cố dịch vụ
- When Cấp tín dụng kèm lý do
- Then Tín dụng cộng vào số dư của tenant, tự động trừ vào hoá đơn tiếp theo, hiển thị tại trang Gói dịch vụ.
4Màn hình
Phần đầu: tên gói, chip trạng thái (Đang hoạt động, Sắp hết hạn, Quá hạn, Dùng thử), ngày hết hạn, nút Nâng cấp, Hoá đơn, Hạ gói từ kỳ sau. Phần thân: một dòng cho mỗi chỉ số với thanh tiến độ và phần trăm, dấu cảnh báo kèm chữ từ 90%, dòng mô-đun theo gói. Phần cuối: tín dụng còn lại, thời điểm cập nhật, nút Tính lại ngay. Bên dưới là bảng so sánh các gói (giá năm, giá tháng, từng giới hạn, mô-đun) với gói hiện tại được đánh dấu. Không có trạng thái rỗng vì mọi tenant luôn có thuê bao; khi dùng thử, phần đầu hiển thị "Dùng thử, còn N ngày" và bảng so sánh được mở sẵn. Chọn Nâng cấp mở hộp thoại báo giá (/settings/plan/upgrade?plan=advanced): giá gói mới 12 tháng, trừ giá trị còn lại của gói cũ (đơn giá tháng × số tháng chưa dùng), trừ tín dụng, số tiền phải trả, ngày hết hạn mới, ghi chú cố định "Kỳ hiện tại kết thúc tại thời điểm nâng cấp; kỳ mới 12 tháng bắt đầu từ hôm nay", nút Xác nhận và tạo hoá đơn.
Danh sách: số hoá đơn (TS-INV-yyyy-nnnnnn), loại (gia hạn, nâng cấp, gói mở rộng, điều chỉnh), kỳ áp dụng, số tiền, tín dụng đã trừ, còn phải trả, trạng thái (Chưa thanh toán, Đã thanh toán, Quá hạn, Đã huỷ), hạn thanh toán, thao tác (Xem, Tải PDF, Tải HĐĐT). Chi tiết: dòng mục, mã QR chuyển khoản với tài khoản của FLYER và payment_code, nút Thanh toán qua VNPay (P2), khối hoá đơn điện tử (số, mã tra cứu, PDF), bên mua lấy từ hồ sơ pháp nhân (PRD 10). Trạng thái rỗng: "Chưa có hoá đơn. Hoá đơn đầu tiên được tạo khi chọn gói."
Banner ở thanh trên cùng theo trạng thái: dùng thử (xanh dương, "Dùng thử, còn N ngày. Chọn gói"), sắp hết hạn (vàng cam, từ T-30), quá hạn (đỏ, đếm ngược ngày ân hạn), tạm khoá (đỏ, "Chỉ xem. Thanh toán để tiếp tục"). Nút hành động chỉ hiển thị với vai trò có subscription.manage hoặc subscription.pay; vai trò khác thấy "Liên hệ chủ trung tâm". Hộp thoại chặn tạo mới (402): giới hạn, số đang dùng, gói tiếp theo đủ đáp ứng, nút Xem gói hoặc Báo cho chủ trung tâm. Hộp thoại chỉ đọc (423): "Trung tâm đang ở chế độ chỉ xem do gói dịch vụ chưa được gia hạn."
Chỉ dành cho người dùng FLYER có tenant.admin, tách khỏi điều hướng của tenant. Danh sách: bộ lọc trạng thái, gói, hết hạn trong N ngày, người phụ trách, tìm theo tên hoặc center_id; cột trung tâm, chủ trung tâm, gói, trạng thái, hạn, học viên đang học / giới hạn, chi nhánh, MRR quy đổi; tab Dùng thử sắp hết · Quá hạn · Chưa đối soát. Chi tiết: tab Thuê bao (đặt gói và kỳ, gia hạn dùng thử, tạm khoá / mở khoá, chấm dứt, "tin cậy thanh toán"), Mức sử dụng (90 ngày), Hoá đơn (điều chỉnh, đánh dấu đã thanh toán ngoài hệ thống, huỷ), Tín dụng, Nhật ký. Mọi hành động ghi đều yêu cầu lý do. Trạng thái rỗng theo tab, ví dụ "Không có trung tâm nào quá hạn."
5Quy tắc nghiệp vụ
- Mỗi tenant (Center) có đúng một thuê bao, tạo tự động ở trạng thái
trialingkhi tạo trung tâm; thuê bao không bao giờ bị xoá, chỉ chuyển trạng thái. - Chuyển đổi hợp lệ:
trialing→active(thanh toán hoặc đặt gói nội bộ) hoặc →past_due(hết 30 ngày);active→expiring(T-30, chỉ là cờ hiển thị) →past_due(T+0) →suspended(T+14) →terminated(T+14+90 hoặc theo yêu cầu bằng văn bản của chủ trung tâm) → xoá dữ liệu 90 ngày sau chấm dứt theo PRD 12. Thanh toán đủ tại bất kỳ trạng thái nào trướcterminatedđưa thuê bao vềactive. Chuyển đổi khác trả về 409INVALID_TRANSITION. Mốc thời gian tính theo cuối ngày múi giờ Asia/Ho_Chi_Minh, lưu trữ theo UTC. - Cách đếm: học viên đang học = học viên ở trạng thái Đang học trên mọi chi nhánh (Bảo lưu, Chờ xếp lớp, Học thử không tính); chi nhánh = School thuộc Center chưa lưu trữ; người dùng nhân sự = tài khoản đăng nhập chưa vô hiệu hoá (nhân sự không có tài khoản và tài khoản phụ huynh không tính); dung lượng = tổng dung lượng tệp do tenant tải lên (tài liệu giáo trình PRD 14, bài giảng PRD 18, tệp đính kèm, PDF phiếu thu), không tính nội dung học tập của FLYER; tin ZNS = số tin gửi thành công trong tháng dương lịch, đặt lại ngày 1.
- Điểm kiểm soát chung
enforce_limit(metric)chạy trước mọi thao tác làm tăng chỉ số: tạo học viên, chuyển đổi lead, đổi trạng thái về Đang học, nhập từ Excel (PRD 11, kiểm tra trước toàn bộ tệp), tạo chi nhánh, mời người dùng, tải tệp, gửi ZNS. Từ 90%: cho phép và cảnh báo. Từ 100%: từ chối với 402PLAN_LIMIT_REACHED. Riêng ZNS khi hết hạn mức: chuyển sang kênh dự phòng theo thứ tự của PRD 07 (Zalo OA, trong ứng dụng, email) với lý do "Hết hạn mức ZNS"; tenant có thể bật "Cho phép vượt hạn mức ZNS" và trả phí phần vượt trên hoá đơn tiếp theo (P2). - Xem, sửa bản ghi hiện có, điểm danh, thu tiền, xuất dữ liệu không bao giờ bị chặn bởi giới hạn số lượng. Ở trạng thái
suspended, endpoint ghi trả về 423TENANT_READ_ONLY, trừ thanh toán hoá đơn thuê bao, đăng nhập, đổi mật khẩu, quản lý sự đồng ý của phụ huynh và yêu cầu xuất dữ liệu. - Phí nâng cấp = giá gói mới (12 tháng) − giá trị còn lại của gói cũ, trong đó giá trị còn lại = đơn giá tháng của gói cũ × số tháng chưa dùng; tháng đang dùng dở tính là đã dùng; kỳ cũ chấm dứt tại thời điểm nâng cấp, kỳ mới 12 tháng bắt đầu từ ngày xác nhận. Tín dụng trừ sau cùng; kết quả âm ghi thành tín dụng, không hoàn tiền. Gói mới có hiệu lực khi hoá đơn nâng cấp được thanh toán đủ. Nâng cấp trong thời gian dùng thử kết thúc dùng thử ngay, số ngày còn lại không quy đổi thành tiền.
- Hạ gói chỉ có hiệu lực vào ngày hết hạn của kỳ hiện tại và chỉ khi mọi chỉ số tại T-1 nằm trong giới hạn gói mới; không hoàn tiền phần chênh lệch; mỗi thuê bao có tối đa một yêu cầu hạ gói đang chờ.
- Gói mở rộng (khối 40 GB, khối 1.000 tin ZNS/tháng, thêm chi nhánh, thêm 5 người dùng) có kỳ hạn trùng với thuê bao; giá lần đầu tính theo tỷ lệ số tháng còn lại làm tròn lên; giới hạn tăng ngay khi thanh toán; tự động vào hoá đơn gia hạn theo giá trọn năm trừ khi bị gỡ trước T-1; chỉ mua được khi thuê bao
activehoặcexpiring. - Hoá đơn thuê bao đánh số TS-INV-yyyy-nnnnnn theo dãy toàn hệ thống; hạn thanh toán 7 ngày với hoá đơn nâng cấp và gói mở rộng, bằng ngày hết hạn với hoá đơn gia hạn. Thanh toán một phần không kích hoạt gói. Hoá đơn gia hạn được tạo tại T-30 theo gói hiện tại (hoặc gói đã yêu cầu hạ), cộng gói mở rộng, trừ tín dụng; kỳ mới luôn nối tiếp ngày hết hạn cũ, kể cả khi thanh toán trong ân hạn hoặc tạm khoá; hoá đơn gia hạn chưa thanh toán bị huỷ khi thuê bao chấm dứt.
- Hoá đơn điện tử cho thuê bao do FLYER phát hành cho tenant qua nhà cung cấp của FLYER; bên mua lấy từ hồ sơ pháp nhân (
SchoolCompany); phát hành tự động trong 24 giờ sau khi thanh toán đủ nếu tenant đã bật "Nhận hoá đơn điện tử", hoặc theo yêu cầu. - Trung tâm thử nghiệm và hợp đồng đặc thù dùng gói nội bộ
pilothoặccustomdo bảng điều khiển nội bộ đặt, có giới hạn riêng và ngày hết hạn tường minh; không hiển thị trong bảng so sánh của tenant. - Mọi thay đổi trạng thái thuê bao, gói, giới hạn, tín dụng, hoá đơn và mọi hành động của bảng điều khiển nội bộ đều ghi nhật ký (PRD 12) với người thực hiện, lý do, giá trị trước và sau; tenant xem được lịch sử của chính tenant tại Cài đặt → Nhật ký.
6Mô hình dữ liệu
| Thực thể | Trường | Ghi chú |
|---|---|---|
| plan (toàn hệ thống) | id uuid; code enum(trial, starter, standard, advanced, enterprise, pilot, custom); name_vi; name_en; price_month_vnd; price_year_vnd; billing_cycles [year | month]; is_public bool; sort_order; modules jsonb {curriculum bool, elearning bool}; retired_at null | new; giá là placeholder "cần quyết định"; gói ngừng bán vẫn giữ để thuê bao cũ tham chiếu |
| plan_limit | id; plan_id; metric enum(active_students, branches, staff_users, storage_gb, zns_month); limit_value int null (null = không giới hạn) | new; unique (plan_id, metric) |
| subscription (cấp tenant) | id uuid; center_id (unique); plan_id; status enum(trialing, active, expiring, past_due, suspended, terminated); billing_cycle; term_start; term_end; trial_end null; grace_end null; suspended_at null; terminated_at null; purge_after null; pending_downgrade_plan_id null; trust_payment bool; contract_no null; account_manager_id null; version int; updated_at | new; mọi mốc thông báo tính từ term_end |
| subscription_addon | id; subscription_id; type enum(storage_40gb, zns_1000, branch, staff_5); quantity int; unit_price_year_vnd; starts_at; ends_at (= term_end); auto_renew bool; invoice_id | new |
| subscription_event | id; subscription_id; type enum(trial_started, trial_extended, activated, plan_changed, downgrade_scheduled, downgrade_cancelled, addon_changed, state_changed, credit_applied); from jsonb; to jsonb; reason; actor_type enum(tenant_user, flyer_admin, system); actor_id; created_at | new; nguồn cho nhật ký |
| usage_counter | id; center_id; metric; value numeric; limit_snapshot int null; computed_at; source enum(incremental, nightly, manual); history_daily jsonb (90 ngày) | new; unique (center_id, metric); tăng dần khi ghi, tính lại toàn bộ 02:00 hằng đêm |
| subscription_invoice | id uuid; number (TS-INV-yyyy-nnnnnn, unique); center_id; subscription_id; type enum(renewal, upgrade, addon, adjustment); status enum(unpaid, paid, overdue, void); lines jsonb [{description, plan_id | addon_type, qty, unit_price, amount}]; subtotal; credit_applied; total_due; paid_amount; payment_code (unique); due_at; paid_at null; payment_method enum(bank_transfer, vnpay, offline) null; payments jsonb [{amount, method, sepay_transaction_id, received_at}]; einvoice {provider, number, lookup_code, pdf_url} null; buyer jsonb | new; hoá đơn của FLYER xuất cho tenant, tách khỏi Tuition của PRD 05 |
| credit | id; center_id; amount_vnd; remaining_vnd; reason; granted_by; expires_at null; created_at | new; trừ theo thứ tự hết hạn sớm nhất |
| Center (mở rộng) | + subscription_id; + read_only bool (dẫn xuất) | extend; read_only trả kèm trong accessible-schools |
Phạm vi: plan và plan_limit là dữ liệu toàn hệ thống do FLYER quản lý. subscription, usage_counter, subscription_invoice, credit thuộc cấp tenant (center_id), không thuộc chi nhánh; chỉ số chi nhánh tổng hợp từ các School của Center. Tenant chỉ đọc được bản ghi mang center_id của chính tenant; id của tenant khác trả về 404 theo PRD 12.
7Hợp đồng API
| Method | Path | Mục đích | Trạng thái |
|---|---|---|---|
| GET | /v3/crm/centers | Danh sách trung tâm; thêm subscription_summary {plan_code, status, term_end, read_only} | extend |
| GET | /v3/crm/onboarding/centers | Trung tâm đã tạo trong onboarding | existing |
| POST | /v3/crm/onboarding/create-center | Tạo trung tâm; sau khi tạo, khởi tạo thuê bao trialing 30 ngày | extend |
| GET | /v3/crm/me/accessible-schools | Chi nhánh của người dùng; thêm cờ read_only và subscription_status | extend |
| GET | /v3/teacher/package/my-subscriptions | Gói cá nhân của giáo viên FLYER; không thay đổi, chỉ tham khảo cấu trúc | existing |
| GET | /v3/crm/subscription | → {subscription, plan, limits, usage: [{metric, value, limit, percent}], addons, credit_remaining, pending_downgrade} | new |
| GET | /v3/crm/subscription/plans | Danh mục gói công khai kèm giới hạn và mô-đun, theo X-Locale | new |
| GET | /v3/crm/subscription/usage | metric, from, to → lịch sử theo ngày; ?recompute=true tính lại ngay (1 lần/5 phút) | new |
| POST | /v3/crm/subscription/upgrade-quote | {plan_code, billing_cycle} → {new_price, remaining_value, months_unused, credit_applied, total_due, new_term_end, quote_hash} | new |
| POST | /v3/crm/subscription/upgrade | {plan_code, billing_cycle, quote_hash} → subscription_invoice; 409 STALE_QUOTE khi báo giá quá 24 giờ; Idempotency-Key | new |
| POST · DELETE | /v3/crm/subscription/downgrade | {plan_code} lên lịch hạ gói tại term_end; 422 USAGE_EXCEEDS_PLAN kèm danh sách chỉ số; DELETE huỷ yêu cầu | new |
| GET · POST · DELETE | /v3/crm/subscription/addons | {type, quantity} → báo giá theo tỷ lệ và hoá đơn; DELETE tắt tự gia hạn | new |
| GET | /v3/crm/subscription/invoices · /{id} · /{id}/pdf · /{id}/qr | Danh sách, chi tiết, PDF, mã QR chuyển khoản của hoá đơn thuê bao | new |
| POST | /v3/crm/subscription/invoices/{id}/vnpay · /einvoice | → {redirect_url}, callback cập nhật thanh toán (P2); {buyer} → phát hành hoá đơn điện tử, trả về số và mã tra cứu | new |
| GET · POST | /v3/crm/subscription/events · /notify-owner | Lịch sử thuê bao của tenant, phân trang; báo cho chủ trung tâm về giới hạn đã chạm (1 lần/giờ/người) | new |
| POST | /v3/internal/sepay/webhook | Webhook SePay hiện có (PRD 05) nhận thêm tài khoản của FLYER; khớp payment_code dạng TS-INV | extend |
| GET | /v3/admin/tenants · /{center_id} | status, plan_code, expiring_within_days, account_manager_id, q → danh sách kèm usage; chi tiết → subscription, usage, invoices, credits, events; chỉ tenant.admin | new |
| PATCH | /v3/admin/tenants/{center_id}/subscription | {plan_code, term_start, term_end, billing_cycle, contract_no, trust_payment, reason, version}; tuỳ chọn tạo hoá đơn offline đã thanh toán | new |
| POST | /v3/admin/tenants/{center_id}/trial-extend · /credits · /suspend · /reactivate · /terminate | {days ∈ 7|14|30, reason} (quá 90 ngày tổng cần tenant.admin.override); {amount_vnd, reason, expires_at?}; {reason}; terminate đặt purge_after = now + 90 ngày | new |
| GET · POST · PATCH | /v3/admin/plans · /{id} · /v3/admin/subscription-transactions/unmatched · /{id}/match | Danh mục gói và giới hạn (PATCH giới hạn của gói đang có thuê bao chỉ áp dụng cho kỳ mới); giao dịch SePay chưa khớp trên tài khoản FLYER (bảng unmatched_subscription_transaction, cùng mẫu PRD 05) và gán vào hoá đơn | new |
| middleware | mọi endpoint ghi dưới /v3/crm và /v3/school | 402 PLAN_LIMIT_REACHED {metric, limit, usage, suggested_plan}; 423 TENANT_READ_ONLY {term_end, grace_end}; header X-Plan-Warning: metric=active_students;percent=92 khi từ 90% | new |
8Phân quyền
| Mã quyền | owner | branch_manager | admissions | academic_admin | accountant | teacher | parent |
|---|---|---|---|---|---|---|---|
subscription.view (trang Gói dịch vụ, mức sử dụng) | tất cả | tất cả (chỉ xem) | không | không | tất cả (chỉ xem) | không | không |
subscription.manage (nâng cấp, hạ gói, gói mở rộng, bật hoá đơn điện tử) | có | không | không | không | không | không | không |
subscription.pay (hoá đơn thuê bao, mã QR, VNPay, tải HĐĐT) | có | không | không | không | có | không | không |
subscription.notify_owner (báo cho chủ trung tâm khi bị chặn) | không cần | có | có | có | có | có | không |
| Banner trạng thái thuê bao | có, kèm nút hành động | có | có | có | có, kèm nút thanh toán | có | chỉ thông báo chỉ đọc trên cổng phụ huynh khi tạm khoá |
tenant.admin, tenant.admin.override (bảng điều khiển nội bộ) | Chỉ cấp cho người dùng nội bộ FLYER qua vai trò hệ thống; không xuất hiện trong permissions-catalog của tenant; mọi hành động yêu cầu lý do và ghi nhật ký. | ||||||
9Sự kiện phân tích
| Sự kiện | Thuộc tính |
|---|---|
| trial_started | center_id, source (onboarding|admin) |
| trial_converted · trial_expired | days_in_trial, plan_code, billing_cycle, actor_type, max_active_students |
| plan_page_viewed | status, highest_percent_metric, highest_percent |
| limit_warning_shown | metric, percent, surface (banner|email|in_app) |
| limit_block_shown | metric, limit, usage, action (view_plans|notify_owner|dismiss), by_role |
| upgrade_quote_viewed · upgrade_completed | from_plan, to_plan, months_unused, total_due, trigger (limit_block|plan_page|admin) |
| downgrade_scheduled · downgrade_cancelled | from_plan, to_plan, cancelled_by (user|usage_check) |
| addon_purchased | type, quantity, prorated_months, total_due |
| subscription_invoice_paid | type, method, hours_to_pay, matched (auto|manual) |
| expiry_notification_sent | milestone (T-30|T-7|T-1|T+0|T+14), channel |
| subscription_state_changed | from, to, actor_type |
| admin_tenant_action | action (set_plan|trial_extend|credit|suspend|reactivate|terminate), admin_id (không có dữ liệu cá nhân của tenant) |
10Trường hợp biên
- Nhập từ Excel (PRD 11) làm số học viên vượt giới hạn: bước kiểm tra trước liệt kê số dòng vượt ngưỡng và từ chối toàn bộ tệp; không nhập một phần.
- Học viên chuyển từ Bảo lưu về Đang học khi đã hết chỗ: bị chặn như tạo mới; giao diện gợi ý nâng cấp hoặc kết thúc một ghi danh khác.
- Mức sử dụng vượt giới hạn sau khi FLYER thay đổi giới hạn của gói hoặc hạ gói nội bộ: không xoá dữ liệu, chỉ chặn tạo mới; trang Gói dịch vụ hiển thị 118% và lý do.
- Tệp xoá mềm trong 30 ngày (PRD 12) vẫn tính vào dung lượng cho đến khi bị xoá hẳn; giao diện ghi rõ.
- Hai giao dịch SePay cùng
sepay_transaction_id(webhook gửi lại): loại trùng. Chuyển đúng mã nhưng thừa tiền: phần thừa thành tín dụng; thiếu tiền: ghi nhận một phần, không kích hoạt. - Nâng cấp khi còn hoá đơn gia hạn chưa thanh toán: hoá đơn gia hạn bị huỷ và thay bằng hoá đơn nâng cấp. Nâng cấp ở tháng cuối của kỳ: số tháng chưa dùng bằng 0, công thức vẫn áp dụng.
- Chủ trung tâm yêu cầu chấm dứt khi còn hạn: chuyển
terminatedtheo ngày yêu cầu, không hoàn tiền phần còn lại theo điều khoản dịch vụ; dữ liệu giữ 90 ngày và có thể xuất toàn bộ theo PRD 12. - Thanh toán đến sau khi dữ liệu đã bị xoá: giao dịch vào mục Chưa đối soát để FLYER hoàn tiền thủ công; không khôi phục được tenant.
- Tenant ở chế độ chỉ đọc nhưng có buổi học đang diễn ra: giáo viên vẫn mở được phiếu điểm danh ở chế độ xem; phiếu lưu offline giữ trong hàng đợi của thiết bị và đồng bộ sau khi thuê bao hoạt động trở lại (PRD 04).
11Câu hỏi còn mở
- Tên gói và giá tháng, giá năm cho từng gói (cần quyết định của kinh doanh); đề xuất bốn gói công khai Khởi đầu, Tiêu chuẩn, Nâng cao, Doanh nghiệp, trong đó Doanh nghiệp không giới hạn học viên.
- Có bán kỳ tháng ở P1 hay chỉ kỳ năm? Đề xuất: P1 chỉ kỳ năm, kỳ tháng mở cùng VNPay ở P2.
- Ba trung tâm thử nghiệm P1 dùng gói
pilotmiễn phí bao lâu và chuyển sang gói trả phí theo điều kiện nào? - PRD 12 mục 7 hiện ghi 30 ngày gia hạn trước khi xoá tenant; PRD này đề xuất 90 ngày lưu giữ sau chấm dứt. Cần thống nhất một con số và cập nhật PRD 12.
- Nhà cung cấp hoá đơn điện tử cho hoá đơn của chính FLYER có trùng với nhà cung cấp mà tenant dùng ở PRD 05 không?
- Bộ phận kinh doanh của FLYER có cần "đăng nhập với tư cách tenant" để hỗ trợ không? Chưa đưa vào vì rủi ro bảo mật và bảo vệ dữ liệu cá nhân.
Trường Số (truongso.net) · Nội bộ FLYER