Bối cảnh dự án
Phần lớn các trận bóng phong trào ở Việt Nam vẫn được chốt qua Zalo và điện thoại. Gọi hỏi sân còn giờ không, gom cho đủ người, rồi nhắc nhau chuyển tiền. BallBall đưa việc đó vào một ứng dụng. Người chơi tìm và đặt sân (một buổi hoặc cố định hàng tuần), lập đội, tuyển thêm người, nhắn tin. Chủ sân quản lý lịch, bảng giá và sân ghép trên cùng hệ thống. VAON đồng phát triển BallBall với anh Nguyễn Văn Hảo, founder sản phẩm. Anh Hảo phụ trách mô hình kinh doanh và làm việc với chủ sân. VAON thiết kế sản phẩm và làm toàn bộ phần kỹ thuật, từ app Flutter, backend Laravel, trang quản trị cho tới việc đưa app lên store. Commit đầu tiên là ngày 25/11/2025, ứng dụng lên App Store và Google Play vào tháng 7/2026.
Thách thức
Sân 7 người thường là hai sân 5 người ghép lại, đặt sân này thì phải khoá sân kia
Nhiều cụm sân mini cho thuê cùng một mặt cỏ theo hai cách: hai sân 5 người riêng, hoặc gộp thành một sân 7 người. Nếu hệ thống coi đây là ba sân độc lập, khách A vẫn đặt được sân 7 lúc 19h. Trong khi đó khách B đã giữ sân 5 cùng giờ. Chủ sân chỉ phát hiện ra khi cả hai đội đã đến nơi.
Đội đá cố định hàng tuần nhưng thỉnh thoảng lại nghỉ một buổi
Đội bóng phong trào hay giữ một khung giờ cố định mỗi tuần trong nhiều tháng. Nếu lưu mỗi buổi thành một lượt đặt riêng, lịch 3 tháng sinh ra khoảng 13 bản ghi, đổi giờ là phải sửa hàng loạt. Chủ sân cũng cần quyền duyệt việc nghỉ, vì khung giờ bỏ trống sát giờ đá là mất doanh thu.
Link mời gửi qua Zalo, Messenger mở ra trang web thay vì mở app
Người chơi rủ nhau chủ yếu qua Zalo và Messenger. Trình duyệt nhúng trong các ứng dụng này thường không chuyển Universal Links (iOS) và App Links (Android) sang app. Vậy là link mời vào trận hay vào đội lại mở ra trong webview. Với một sản phẩm mới, mỗi link mời hỏng là mất một người dùng ngay từ bước đầu.
Tin nhắn trong đội phải đến đủ dù sóng 4G ở sân chập chờn
Đội nhắn tin nhiều nhất ngay trước giờ đá, lúc mọi người đang đi đường hoặc đứng ở sân sóng yếu. Rớt mạng vài giây là đủ lọt tin, hoặc người dùng bấm gửi lại thành hai tin giống nhau. Server cũng có thể bắn thông báo đẩy cho người đang mở sẵn cuộc trò chuyện đó.
Người duyệt app của Apple không nhận được OTP gửi về số điện thoại Việt Nam
Người mới đăng nhập BallBall bằng mã OTP gửi qua SMS hoặc Zalo về số điện thoại Việt Nam. Người duyệt app của Apple không nhận được mã này, đúng trường hợp Guideline 2.1. Chat, đánh giá sân và hồ sơ công khai lại là nội dung do người dùng tạo, nên phải có chặn và báo cáo theo Guideline 1.2.
Việt Nam bỏ cấp quận, huyện năm 2025, dữ liệu sân và bộ lọc phải đổi theo
Năm 2025 Việt Nam sáp nhập tỉnh và bỏ cấp quận, huyện. Địa chỉ sân, khu vực người chơi hay đá và bộ lọc tìm sân đều phải theo đơn vị mới. Trong khi đó, các bản app đã cài trên máy người dùng vẫn gọi API theo cấu trúc cũ và không thể bắt tất cả cập nhật cùng lúc.
Giải pháp của VAON
VAON xây dựng toàn bộ nền tảng BallBall từ đầu đến cuối: cơ chế đặt sân ghép chống trùng lịch, lịch cố định hàng tuần có xin nghỉ/duyệt nghỉ, deep link mở đúng app từ Zalo và Messenger, chat thời gian thực qua WebSocket chịu được mạng chập chờn, chuẩn bị hồ sơ để vượt kiểm duyệt App Store/Google Play, và di chuyển dữ liệu sang địa giới hành chính mới mà không làm gãy các bản app cũ.
Đặt sân & lịch trình
Khai báo quan hệ sân ghép bằng một bảng liên kết riêng: mỗi sân ghép ghi rõ các sân con tạo nên nó. Khi kiểm tra một khung giờ, hệ thống quét cả sân được chọn lẫn mọi sân liên kết, gồm lượt đặt lẻ, lịch cố định và lịch bảo trì. Lượt đặt mới ở trạng thái chờ chủ sân xác nhận; một job chạy 10 phút một lần tự huỷ các lượt quá hạn để trả lại khung giờ.
Lưu lịch cố định thành một bản ghi duy nhất (thứ trong tuần, ngày bắt đầu, thời hạn 3 tháng), các buổi nghỉ ghi vào bảng ngày huỷ riêng. Chọn cách này thay vì sinh sẵn từng buổi vì đổi hay kết thúc lịch chỉ phải sửa một dòng; cái giá là mọi truy vấn lịch trống phải tự triển khai chuỗi ngày trong code. Khách gửi yêu cầu nghỉ, chủ sân duyệt hoặc từ chối. Giá được chốt vào lượt đặt ngay lúc đặt, nên chủ sân đổi bảng giá không làm thay đổi các lịch đã có.
Cho link chia sẻ trỏ về một trang trung gian trên domain BallBall thay vì trỏ thẳng vào app. Trang này thử mở app qua scheme `ballball://`; sau 2,5 giây nếu app chưa mở thì chuyển sang App Store hoặc Google Play theo loại máy. Link hỏng hoặc nội dung đã bị xoá vẫn hiện một trang giới thiệu chung, không trả lỗi 404.
Ổn định & tuân thủ kiểm duyệt store
Gắn cho mỗi tin nhắn một mã UUID ngay trên máy trước khi gửi, để tin hiện ra tức thì rồi khớp với bản lưu trên server. Tin đi qua WebSocket (Laravel Reverb); khi mất kết nối và nối lại, app gọi REST lấy các tin sau ID cuối cùng đã nhận để lấp khoảng trống. Trước khi gửi thông báo đẩy, server kiểm tra người nhận có đang mở cuộc trò chuyện không, nếu có thì bỏ qua.
Tạo sẵn tài khoản riêng cho người duyệt app ở phía backend, để đội duyệt của Apple và Google đăng nhập được mà không cần SIM Việt Nam. Làm đủ luồng chặn người dùng, báo cáo 4 loại nội dung, gỡ nội dung và khoá tài khoản từ trang quản trị, xoá tài khoản ngay trong app, kèm privacy manifest cho iOS trước khi nộp.
Giữ song song bảng địa giới cũ và mới, API trả dữ liệu mới dưới đúng tên trường cũ để các bản app đã cài vẫn chạy bình thường. Với những thay đổi không tương thích về sau, backend có thêm lớp kiểm tra phiên bản app tối thiểu (từ 22/07/2026) để yêu cầu bản cũ cập nhật khi thật sự cần.
Tính năng chính
Đặt sân ghép, tự động khoá các sân liên kết để chống trùng lịch
Lịch cố định hàng tuần, có xin nghỉ và chủ sân duyệt
Deep link mở đúng ứng dụng từ Zalo và Messenger
Chat nhóm thời gian thực qua WebSocket, chịu được mạng 4G chập chờn
Giá trị mang lại
Dưới 4 tháng từ commit đầu tiên đến khi ứng dụng có mặt trên App Store và Google Play
5 build mới trong 3 tuần đầu sau bản phát hành 1.0.0
1 backend phục vụ 3 vai trò qua 125 route API, có 38 file test tự động
5.399 sân bóng có đủ toạ độ được nạp sẵn để người chơi tìm sân ngay từ ngày đầu