Settle
ใช้งานได้{base}/api/settleปกติส่งหลังจาก /bet สำเร็จ พร้อมผลของรอบ ให้ credit ยอด amount เข้า wallet ของผู้เล่น ยกเว้นรอบแบบ single-state ที่ไม่มี /bet มาก่อน บิลกับผลจะมาพร้อมกันใน call นี้
ประมวล txns[] ทั้งชุดใน DB transaction เดียว (atomic) — ถ้าตัวใดพัง ให้ roll back ทั้งชุด แล้วตอบ error โดย balance_before == balance_after
ถ้าได้รับ txn_id เดิมซ้ำ ห้าม apply ซ้ำ ให้ตอบ balance ปัจจุบันพร้อม code 0 หรือตอบ 20002 · ข้อยกเว้นเดียวคือรายการที่ตามหลัง /rollback ของรอบนั้น ซึ่งเป็นผลที่ถูกแก้แล้วและต้อง apply (ดูหัวข้อ re-settle หลัง rollback ในหน้า Contract)
amount = 0 เกิดขึ้นจริง (feature spin, feature buy, tip หรือ stake ที่ค่ายระบุไม่ได้) ห้าม reject ให้ประมวลเป็นรายการยอด 0 แล้วตอบ code 0 โดยไม่ขยับ balance
BY_TRANSACTION = จัดการเฉพาะ txn_id นี้ · BY_ROUND = จัดการบิลทุกใบใน round_id เดียวกันพร้อมกัน โดย amount เป็นยอดรวมของทั้งรอบ
ตอบ HTTP 200 เสมอแม้เป็น business error
รอบ single-state: amount = |payout_amount − bet_amount| และ direction คือทิศที่ต้อง apply ตรวจ balance >= bet_amount ก่อนเสมอ เพราะ stake ถูกหักใน call เดียวกันนี้ ยอดไม่พอให้ตอบ 10002
Headers
| ฟิลด์ | ชนิด | จำเป็น | คำอธิบาย |
|---|---|---|---|
| X-Api-Key | string | ใช่ | API key ที่ best-system ออกให้ (ตรวจว่าตรงกับของคุณ) |
| X-Signature | string | ใช่ | hex(HMAC-SHA256(secret, raw body)) — verify จาก raw bytes ห้าม re-serialize · ไม่ตรง → ตอบ code 30002 |
Request bodyapplication/json
| ฟิลด์ | ชนิด | จำเป็น | คำอธิบาย |
|---|---|---|---|
| request_id | string | ใช่ | id ของ request นี้ |
| player_username | string | ใช่ | username ผู้เล่นในระบบของคุณ |
| currency | string | ใช่ | สกุลเงินของผู้เล่น ตาม ISO 4217 เช่น THB |
| product_code | string | — | รหัสค่ายเกม (เช่น PGSOFT) |
| timestamp | number | ใช่ | เวลาที่ส่ง (unix ms) |
| txns | object[] | ใช่ | รายการผลของรอบ |
| └ txn_id | string | ใช่ | รหัสรายการ ใช้เป็น idempotency key (ดูหมายเหตุ) |
| └ round_id | string | ใช่ | รหัสรอบเกม |
| └ amount | number | ใช่ | จำนวนเงินของรายการนี้ ไม่ติดลบ เป็น 0 ได้ (ดูหมายเหตุ) ทิศทางมาจาก endpoint หรือ field direction |
| └ game_code | string | — | รหัสเกม |
| └ is_feature | boolean | — | เป็น free spin หรือ feature spin หรือไม่ ไม่ส่ง = false |
| └ status | string | — | สถานะบิลจากค่ายเกม เป็น SETTLED เสมอOPEN | WAITING | SETTLED | REFUND | REJECT | ROLLBACK | VOID | TIPS |
| └ play_info | string | — | ตัวเลือกที่เดิมพัน เช่น player/banker หรือชื่อเกม ค่า `UNKNOWN` = ค่ายระบุไม่ได้ ใช้แสดงผลเท่านั้น |
| └ transaction_type | string | — | ขอบเขตของรายการ เป็น BY_TRANSACTION หรือ BY_ROUND (ดูหมายเหตุ)BY_TRANSACTION | BY_ROUND |
| └ single_state | boolean | — | รอบที่เดิมพันและผลมาใน call เดียว ไม่มี /bet มาก่อน ส่งมาทุกใบทั้ง true และ false (ดูหมายเหตุด้านล่าง) |
| └ payout_amount | number | — | ยอดจ่าย (stake + win) มาทุกใบ |
| └ bet_amount | number | — | ยอดเดิมพันของรอบ มาทุกใบ เป็น 0 ได้ |
| └ direction | string | — | ทิศทางของ amount เฉพาะตอน single_state = trueDEBIT | CREDIT |
| └ turn_over | number | — | valid stake ของบิลนี้ เป็น 0 ได้ |
| └ is_end_round | boolean | — | settle นี้ปิดรอบหรือไม่ false = ยังมีส่วนอื่นตามมา เช่น freespin ไม่ส่ง = ปิดรอบ |
| └ is_feature_buy | boolean | — | ผลของบิลซื้อฟีเจอร์ มีเฉพาะบางค่าย |
| └ skip_balance_update | boolean | — | true = ไม่ต้องขยับ balance บันทึกอย่างเดียว ตอบ code 0 พร้อม balance ปัจจุบัน |
{
"request_id": "6c1f2a3b-7d8e-4f90-a1b2-c3d4e5f60718",
"player_username": "foobar",
"currency": "THB",
"product_code": "PGSOFT",
"timestamp": 1783236601000,
"txns": [
{
"txn_id": "T-002",
"round_id": "R-1",
"amount": 500,
"game_code": "10300",
"is_feature": false,
"status": "SETTLED",
"play_info": "Baccarat",
"turn_over": 500,
"transaction_type": "BY_TRANSACTION",
"is_end_round": true,
"single_state": false,
"bet_amount": 200,
"payout_amount": 500
}
]
}{
"request_id": "8a2c4e60-91b3-4d75-8e0f-2b7c9d1a4f36",
"player_username": "foobar",
"currency": "THB",
"product_code": "PGSOFT",
"timestamp": 1783236742000,
"txns": [
{
"txn_id": "T-011",
"round_id": "R-4",
"amount": 900,
"game_code": "10300",
"is_feature": false,
"status": "SETTLED",
"play_info": "Baccarat",
"turn_over": 600,
"transaction_type": "BY_ROUND",
"is_end_round": true,
"single_state": false,
"bet_amount": 400,
"payout_amount": 900
}
]
}{
"request_id": "1d5b7f92-3c48-4a10-9e6d-5f2a8c0b7e14",
"player_username": "foobar",
"currency": "THB",
"product_code": "PGSOFT",
"timestamp": 1783236918000,
"txns": [
{
"txn_id": "T-050",
"round_id": "R-9",
"amount": 10,
"game_code": "10300",
"is_feature": false,
"status": "SETTLED",
"play_info": "Treasures of Aztec",
"turn_over": 0,
"transaction_type": "BY_ROUND",
"is_end_round": true,
"single_state": true,
"bet_amount": 10,
"payout_amount": 20,
"direction": "CREDIT"
}
]
}Expected Response
ฟิลด์ใน data
| ฟิลด์ | ชนิด | จำเป็น | คำอธิบาย |
|---|---|---|---|
| code | number | ใช่ | 0 = สำเร็จ · อื่นๆ ดูหน้า Seamless codes |
| request_id | string | ใช่ | echo จาก request |
| username | string | ใช่ | echo player_username (กันสลับคน) |
| currency | string | ใช่ | echo จาก request |
| balance_before | number | ใช่ | ยอดก่อนประมวล txns[] ทั้งชุด |
| balance_after | number | ใช่ | ยอดหลังประมวลทั้งชุด |
| timestamp | number | ใช่ | เวลาที่คุณประมวลผล (unix ms) |
{
"code": 0,
"request_id": "6c1f2a3b-7d8e-4f90-a1b2-c3d4e5f60718",
"username": "foobar",
"currency": "THB",
"balance_before": 800,
"balance_after": 1300,
"timestamp": 1783236601095
}Error codes ที่พบได้
| code | ชื่อ | HTTP | ข้อความ |
|---|---|---|---|
| 10001 | SEAMLESS_USER_NOT_FOUND | 200 | ไม่พบผู้เล่นในระบบของ agent |
| 10002 | SEAMLESS_INSUFFICIENT_BALANCE | 200 | ยอดเงินไม่พอสำหรับรายการหักเงิน (debit)balance < bet_amount เฉพาะ single-state |
| 20002 | SEAMLESS_DUPLICATE_TXN | 200 | รายการซ้ำ (txn_id เคยประมวลแล้ว) |
| 30002 | SEAMLESS_INVALID_SIGNATURE | 401 | X-Signature ไม่ถูกต้อง |
| 40003 | SEAMLESS_FORBIDDEN | 200 | ปฏิเสธการเข้าถึง (api-key/IP) |
| 50001 | SEAMLESS_INTERNAL_ERROR | 200 | ข้อผิดพลาดภายในระบบของ agent |