NON-PRODUCTION

Mini Poker — tài liệu ghép client

Video poker 5 lá. Server chia bài, trả combination_type (int hạng bài) + multiplier. Jackpot khi sảnh thông có Át. Credit ngay mỗi spin. Trang này chỉ được serve khi ENVIRONMENT != production.

1. Tổng quan

MụcGiá trị
Hand5 lá · cards[] là card id (int)
Paywin_amount = round(multiplier × bet) trừ khi jackpot
JackpotStraight flush chứa Ace → boom pool, win_amount = jackpot_win_amount (không nhân multiplier)
Tiền−bet rồi +win trong cùng POST /spins
Base path/api/v1
Gọi GET /gameplay khi vào bàn. GameInfo không có user_money — lấy số dư từ spin / jackpots / wallet.

2. Luồng ghép

  1. Vào game → GET /gameplay (+ GET /jackpots cho meter). Vẽ 5 lá init_cards.
  2. User chọn bet ∈ bets.
  3. POST /spins. Lật 5 lá cards, hiện hạng từ combination_type + multiplier.
  4. is_jackpot → fanfare, cộng jackpot_win_amount. Cập nhật meter = jackpot.
  5. Chip = user_money. History / top-win cho panel phụ.

3. Auth & envelope

Authorization: Bearer <access_token>
Content-Type: application/json

JWT bắt buộc dưới /api/v1. HTTP 200 + code = 0; payload trong msg.

{ "code": 0, "msg": { ... } }
codeÝ nghĩa
0OK
-1Unknown / JWT invalid (HTTP 401 nếu thiếu token)
-2Invalid input
69Wrong state — chưa /gameplay, bet không hợp lệ
1000Popup i18n

4. Bài, id & combination_type

Ví dụ Full House (3 K♥ + 2 A♠) — combination_type do server trả, client map label.

K♥
K♦
K♠
A♠
A♥

card_id = rank * 4 + suit. Suit: 0 ♠ · 1 ♣ · 2 ♦ · 3 ♥. Rank: 0 = 2 … 8 = 10 · 9 = J · 10 = Q · 11 = K · 12 = A. Ví dụ A♥ = 51, K♠ = 44, 2♠ = 0.

combination_typeint từ server (hạng bài). Map tham chiếu (iota server); luôn tin giá trị response, đừng tự chấm lại trừ khi debug:

intHạng (tham chiếu)multiplier mẫuVí dụ 5 lá
0Big pair (J+)2.5×J♠ J♥ 3♣ 7♦ 9♠
1Two pairK♠ K♥ 9♣ 9♦ 2♠
2Three of a kindQ♠ Q♥ Q♦ 4♣ 8♠
3Straight13×5♠ 6♥ 7♦ 8♣ 9♠
4Flush20×cùng chất, không sảnh
5Full house50×K K K A A
6Four of a kind150×7 7 7 7 + kicker
7Straight flush1000×sảnh đồng chất; +Ace → jackpot
8None0không ăn
Hiển thị tên hạng theo bảng locale client. Nguồn sự thật là int + multiplier trên response. Pair nhỏ hơn J không thắng (None).

5. GET /api/v1/gameplay

GET /api/v1/gameplay
FieldTypeClient dùng để
init_cardsint[5]5 lá preview idle (id), không phải ván đang chơi
bets / show_betsint64[]Mức hợp lệ / hiển thị
betint64Bet đang chọn trên server
{
  "code": 0,
  "msg": {
    "init_cards": [0, 6, 12, 18, 24],
    "bets": [100, 500, 1000, 5000],
    "show_bets": [100, 500, 1000, 5000],
    "bet": 1000
  }
}

6. POST /api/v1/spins

POST /api/v1/spins
{ "bet": 1000 }
FieldTypeÝ nghĩa
user_moneyint64Chip sau −bet +win
win_amountint64Chip thắng (0 nếu None). JP = boom amount
betint64Bet vừa dùng
cardsint[5]5 card id (đã sort server)
combination_typeintHạng bài (xem mục 4)
multiplierfloatHệ số (0 nếu None / JP)
is_jackpotboolStraight flush có Ace
jackpot_win_amountint64Tiền boom (0 nếu không JP)
jackpotint64Pool còn lại sau boom (cùng mức bet)

Full house

{
  "code": 0,
  "msg": {
    "user_money": 549000, "win_amount": 50000, "bet": 1000,
    "cards": [44, 45, 47, 48, 51],
    "combination_type": 5, "multiplier": 50,
    "is_jackpot": false, "jackpot_win_amount": 0, "jackpot": 880000
  }
}

Jackpot (A-high straight flush)

{
  "code": 0,
  "msg": {
    "user_money": 2500000, "win_amount": 2000000, "bet": 1000,
    "cards": [35, 39, 43, 47, 51],
    "combination_type": 7, "multiplier": 0,
    "is_jackpot": true, "jackpot_win_amount": 2000000, "jackpot": 5000
  }
}

Không ăn

{
  "code": 0,
  "msg": {
    "user_money": 499000, "win_amount": 0, "bet": 1000,
    "cards": [0, 6, 12, 18, 25],
    "combination_type": 8, "multiplier": 0,
    "is_jackpot": false, "jackpot_win_amount": 0, "jackpot": 880000
  }
}

7. GET /api/v1/jackpots

GET /api/v1/jackpots
FieldÝ nghĩa
jackpots[].betMức cược (show bet)
jackpot_amountPool hiện tại
{ "code": 0, "msg": { "jackpots": [{ "bet": 100, "jackpot_amount": 88000 }, { "bet": 1000, "jackpot_amount": 880000 }] } }

8. GET /api/v1/jackpots-history

GET /api/v1/jackpots-history
FieldÝ nghĩa
jackpots[].timeUnix seconds
user_id / usernameNgười nổ
bet / win_amount / cardsCược, tiền JP, 5 lá
{
  "code": 0,
  "msg": {
    "jackpots": [
      { "time": 1710000200, "user_id": 2001, "username": "ace", "bet": 1000, "win_amount": 2000000, "cards": [35,39,43,47,51] }
    ]
  }
}

9. GET /api/v1/top-win

GET /api/v1/top-win
FieldÝ nghĩa
winners[].rank / user_id / username / total_winBXH lãi
{ "code": 0, "msg": { "winners": [{ "rank": 1, "user_id": 2001, "username": "ace", "total_win": 1990000 }] } }

10. GET /api/v1/spins-history

GET /api/v1/spins-history
FieldÝ nghĩa
Giống SpinResult+ created_at unix seconds
{
  "code": 0,
  "msg": {
    "spins": [{
      "user_money": 549000, "win_amount": 50000, "bet": 1000, "cards": [44,45,47,48,51],
      "combination_type": 5, "multiplier": 50, "is_jackpot": false,
      "jackpot_win_amount": 0, "jackpot": 880000, "created_at": 1710000300
    }]
  }
}

11. Animation

  1. Lock Deal tới khi có response.
  2. Lật 5 lá theo cards (decode id → rank/suit; đỏ nếu ♦/♥).
  3. Hiện badge hạng theo combination_type + số multiplier.
  4. JP: bỏ qua anim nhân, hiện boom jackpot_win_amount, cập nhật meter jackpot.

12. Cheat (chỉ non-prod / cheater)

reels = 5 cột, mỗi cột 1 card id (handler flatten):

{ "bet": 1000, "reels": [[35], [39], [43], [47], [51]] }

Production bỏ qua. 5 id phải hợp lệ 0–51.

13. Error & tiền

Tình huốngHành vi client
HTTP 401Relogin
code 69GET /gameplay, bet ∈ bets
code 1000Popup i18n
code -1 khi spinHết tiền / lỗi — đừng trừ chip local
HTTP 400 blockedUser đang room PvP khác
Mỗi ván: −bet rồi +win_amount trong cùng response. JP boom thay cho multiplier.

14. Checklist client