Phòng chờ cho mở bán vé và flash sale
Đặt một hàng chờ công bằng, cập nhật trực tiếp trước trang mở bán: khách thấy vị trí của mình tiến lên, vào theo tốc độ bạn đặt, và trang của bạn kiểm tra pass có chữ ký. Dùng được với mọi hosting, kể cả Laravel và Filament.
Mở bán vé, ra mắt sản phẩm giới hạn hay mở đặt trước: lưu lượng của cả một ngày dồn vào phút đầu tiên. Tự động mở rộng không phản ứng kịp, thanh toán chậm đi với tất cả mọi người, và cuối cùng ai có mạng nhanh nhất sẽ thắng. Phòng chờ đặt một hàng chờ bình tĩnh, công bằng trước những trang đông người: khách lấy số, xem hàng tiến lên theo thời gian thực, và vào theo tốc độ mà trang của bạn phục vụ được. Bạn tự đăng ký và tự thiết lập, không cần gọi cho bộ phận bán hàng, không cần đổi hosting hay CDN.
Khách truy cập nhận được gì
- Số thứ tự và dòng "còn 4.812 người phía trước", cập nhật trực tiếp trong lúc chờ.
- Tải lại trang hay mở thêm tab cũng không làm mất chỗ hay chen lên trước.
- Trang chờ được lưu trữ sẵn bằng tiếng Anh, tiếng Trung phồn thể, tiếng Trung giản thể, tiếng Nhật, tiếng Hàn, tiếng Thái và tiếng Việt.
- Đếm ngược rõ ràng trước giờ mở bán, và thông báo "đã bán hết" rõ ràng khi kết thúc.

Bạn nhận được gì
- Một hàng chờ tiến lên theo tốc độ bạn đặt, ví dụ 300 khách mỗi phút.
- Các nút cho những lúc quan trọng: tạm dừng hàng chờ, cho 500 người vào ngay, đóng khi hết hàng.
- Mỗi khách được vào nhận một pass có chữ ký, trang của bạn kiểm tra trước khi phục vụ trang được bảo vệ, nên đoán URL cũng không chen hàng được.
- Nếu muốn, dùng ticket ID trong pass để mỗi số thứ tự chỉ thanh toán được một lần.
- Khách đang xếp hàng không tính vào số kết nối của ứng dụng, nên các tính năng realtime khác trên trang vẫn còn chỗ trong lúc cao điểm.
- Thông báo cho mọi người đang xếp hàng, ví dụ "Khu A đã hết vé", hiện ngay trên trang chờ.

Phòng chờ là tiện ích bổ sung cho mọi gói Hibira. Miễn phí 1 phòng và 5.000 khách xếp hàng mỗi tháng; gói trả phí từ $29 mỗi tháng, và vé sự kiện một lần là $49 trong 72 giờ. Vượt quá gói, khách thêm được trừ vào tín dụng và không ai bị từ chối. Xem bảng giá.
Dùng những gì
- Phòng chờ trong ứng dụng Hibira của bạn, quản lý trên portal hoặc bằng các lệnh gọi HTTP API có chữ ký.
- Trang chờ được lưu trữ sẵn
ws.hibira.io/wait/APP_KEY/ROOM, hoặc trang của riêng bạn với @hibira-io/waiting-room. - Mỗi phòng một cache channel (
cache-waitroom-ROOM): một tin nhắn cho mọi khách đang chờ biết hàng đã đi đến đâu, và mỗi trình duyệt tự tính vị trí của mình. - Pass ký bằng app secret của bạn (HMAC-SHA256), trang của bạn tự kiểm tra mà không cần gọi Hibira.
?hibira_pass=…Cho hàng chờ tiến lên
Chọn cách kết nối
Chọn theo nơi trang của bạn đang chạy. Càng ở trên trong danh sách thì càng khó lách.
| Trang chạy ở đâu | Kết nối thế nào | Kiểm tra lúc nào |
|---|---|---|
| Cloudflare Workers, Next.js trên Vercel, Deno, Bun | protect() từ @hibira-io/waiting-room | trước khi trả trang |
| Máy chủ của bạn: Express, Laravel và các framework khác | một middleware kiểm tra pass | trước khi route chạy |
| Trang chờ tự làm hoàn toàn | joinWaitingRoom() trong trình duyệt, cùng một trong các cách kiểm tra ở trên | trước khi route chạy |
| Ứng dụng iOS, Android, Flutter hoặc Unity | các endpoint công khai của phòng chờ, rồi gửi pass trong header của API | trong API của bạn |
| Không có backend riêng (cửa hàng được lưu trữ sẵn) | trang chờ lưu trữ sẵn, cộng kiểm tra pass khi thanh toán | khi thanh toán |
Bước 1: tạo phòng
Tạo phòng trên portal, hoặc bằng một yêu cầu HTTP API có chữ ký, ký giống như khi gửi sự kiện:
POST /apps/APP_ID/waiting_rooms/presale
{
"admit_per_minute": 300,
"state": "paused",
"starts_at": "2026-12-04T12:00:00+09:00",
"title": "Winter tour presale",
"return_urls": ["https://shop.example.com/"]
}open cho khách vào theo tốc độ, paused giữ hàng chờ đứng yên, và closed ngừng phát số khi bạn đã bán hết. Khách đến trước starts_at sẽ nhận số và xem đếm ngược; hàng chờ bắt đầu tiến lên vào đúng thời điểm đó.
Bước 2: bảo vệ trang ở edge
Trên Cloudflare Workers, middleware của Next.js, Deno hoặc Bun, chỉ cần một lệnh gọi:
// middleware.js (Next.js)
import { NextResponse } from 'next/server';
import { protect } from '@hibira-io/waiting-room/server';
export async function middleware(request) {
const blocked = await protect(request, {
appKey: process.env.HIBIRA_KEY,
secret: process.env.HIBIRA_SECRET,
room: 'presale',
});
return blocked ?? NextResponse.next();
}
export const config = { matcher: ['/drop/:path*'] };Khách không có pass được chuyển đến trang chờ. Khi đến lượt, họ quay lại với pass, protect() kiểm tra và lưu nó trong cookie HttpOnly. Với Express, dùng expressWaitingRoom() trong cùng gói.
Bước 3: Laravel
Với hibira-io/laravel 0.4 trở lên (có thể bạn đã dùng cho broadcasting), tạo phòng bằng dòng lệnh và bảo vệ route bằng một middleware:
composer require hibira-io/laravel:^0.4
php artisan hibira:waiting-room presale create --rate=300 --title="Winter presale"Route::middleware('hibira.waiting:presale')->group(function () {
Route::get('/drop', [DropController::class, 'show']);
Route::post('/drop/checkout', [DropController::class, 'checkout']);
});Khách chưa có pass được chuyển tới trang chờ, theo ngôn ngữ của ứng dụng. Pass họ mang về được kiểm tra bằng app secret của bạn, không cần gọi API, và lưu trong cookie HttpOnly tới khi hết hạn. Một POST không có pass nhận 403. Trong controller, pass nằm trên request:
$pass = $request->attributes->get('hibira_pass');
$pass->number; // queue number
$pass->ticketId; // record it at checkout: one order per numberĐiều khiển phòng từ code, job trong hàng đợi hoặc dòng lệnh:
use Hibira\Laravel\Facades\Hibira;
Hibira::waitingRoom('presale')->pause();
Hibira::waitingRoom('presale')->admit(500);
Hibira::waitingRoom('presale')->notice('Zone A is sold out');
Hibira::waitingRoom('presale')->close();Khi phát triển trên máy, đặt HIBIRA_WAITING_ROOMS=false để bỏ qua hàng chờ.
Bước 4: điều khiển hàng chờ từ Filament
Ngày mở bán, đội của bạn không cần thêm một dashboard nữa. Với hibira-io/filament 0.5 trở lên, một dòng thêm trang "Phòng chờ" vào panel:
HibiraPlugin::make()->waitingRooms(
authorize: fn ($user) => $user->is_admin,
)Trang này hiện trực tiếp số người đang chờ, hàng đã đi tới đâu và tốc độ cho vào của từng phòng. Từ đây đội của bạn có thể tạm dừng và mở lại, cho người vào ngay, đăng thông báo, đóng phòng khi hết hàng, và tạo hoặc sửa phòng. Bỏ authorize thì mọi người dùng panel đều vào được.
Bước 5: trang chờ của riêng bạn
Trang lưu trữ sẵn phù hợp với hầu hết các trang web. Muốn khớp hoàn toàn với thương hiệu, hãy tự làm trang:
import { joinWaitingRoom } from '@hibira-io/waiting-room';
joinWaitingRoom({
key: 'APP_KEY',
room: 'presale',
onUpdate: ({ ahead, etaMinutes }) => render(ahead, etaMinutes),
onTurn: (turn) => turn.redirect('https://shop.example.com/drop'),
onClosed: () => showSoldOut(),
});Client lưu vé của khách trong trình duyệt, nên tải lại trang vẫn giữ chỗ. Nếu không mở được kết nối, nó chuyển sang kiểm tra trạng thái vài giây một lần, và không ai bị chặn ở ngoài.
Bước 6: trong ứng dụng của bạn
Client di động hay game dùng cùng các endpoint công khai với trang lưu trữ sẵn: vào hàng, theo dõi cache channel của phòng, xin pass khi đến số của mình, rồi gửi pass kèm các lệnh gọi API. API của bạn kiểm tra pass bằng app secret, không cần gọi Hibira; trên Laravel, dùng WaitingRoom::verifyPass($pass, 'presale').
POST /waitroom/APP_KEY/presale/join -> {"ticket": "…", "number": 5121}
GET /waitroom/APP_KEY/presale -> {"admitted": 4980, "state": "open", …}
POST /waitroom/APP_KEY/presale/pass {"ticket": "…"} -> {"pass": "…"}So với Queue-it và Cloudflare Waiting Room
| Hibira | Queue-it | Cloudflare Waiting Room | |
|---|---|---|---|
| Bắt đầu thế nào | Tự đăng ký và tự tạo phòng | Liên hệ bộ phận bán hàng; có một gói theo sự kiện công khai giá | Gói Business hoặc Enterprise |
| Trang chạy ở đâu | Bất kỳ hosting, CDN hay framework nào | Bất kỳ hosting nào, qua connector của họ | Lưu lượng phải đi qua proxy của Cloudflare |
| Hẹn giờ mở với đếm ngược | Có | Có | Enterprise |
| Nhiều phòng | Có | Có | Enterprise, kèm add-on Advanced |
| Trang chờ của riêng bạn | Có, với một client trình duyệt nhỏ gọn | Có | Template tùy chỉnh của Enterprise |
| Điều khiển hàng chờ từ trang quản trị của bạn | Có, ví dụ một trang Filament | Bảng điều khiển của họ | Bảng điều khiển hoặc API của Cloudflare |
Dựa trên trang giá và gói công khai của từng bên vào tháng 11/2026. Các gói có thể thay đổi, hãy kiểm tra với từng bên trước khi quyết định.
So sánh đầy đủ, kèm giá và khi nào mỗi bên phù hợp hơn: Queue-it, Cloudflare Waiting Room, CrowdHandler và Queue-Fair.
Mẹo
- Bảo vệ những trang thật sự có thể hết hàng: trang sản phẩm, giỏ hàng và thanh toán. Để trang chủ và hình ảnh ở ngoài phòng chờ.
- Kiểm tra pass ở yêu cầu quan trọng, không chỉ trong trình duyệt. Khách có thể sửa mọi script trên trang của họ, nhưng không giả được chữ ký.
- Nếu mỗi số thứ tự chỉ được mua một lần, hãy ghi lại ticket ID của pass khi thanh toán và từ chối đơn thứ hai dùng cùng ID.
- Mở phòng 15 đến 30 phút trước giờ bán và đặt
starts_at. Khách đến sớm sẽ chờ ở trang đếm ngược thay vì bấm tải lại liên tục trên trang của bạn. - Bắt đầu với tốc độ mà khâu thanh toán phục vụ thoải mái, rồi tăng dần trong khi theo dõi tỉ lệ lỗi. Tạm dừng luôn chỉ cách một cú nhấp.