Settle

ใช้งานได้
POST{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-Keystringใช่API key ที่ best-system ออกให้ (ตรวจว่าตรงกับของคุณ)
X-Signaturestringใช่hex(HMAC-SHA256(secret, raw body)) — verify จาก raw bytes ห้าม re-serialize · ไม่ตรง → ตอบ code 30002

Request bodyapplication/json

ฟิลด์ชนิดจำเป็นคำอธิบาย
request_idstringใช่id ของ request นี้
player_usernamestringใช่username ผู้เล่นในระบบของคุณ
currencystringใช่สกุลเงินของผู้เล่น ตาม ISO 4217 เช่น THB
product_codestring—รหัสค่ายเกม (เช่น PGSOFT)
timestampnumberใช่เวลาที่ส่ง (unix ms)
txnsobject[]ใช่รายการผลของรอบ
└ txn_idstringใช่รหัสรายการ ใช้เป็น idempotency key (ดูหมายเหตุ)
└ round_idstringใช่รหัสรอบเกม
└ amountnumberใช่จำนวนเงินของรายการนี้ ไม่ติดลบ เป็น 0 ได้ (ดูหมายเหตุ) ทิศทางมาจาก endpoint หรือ field direction
└ game_codestring—รหัสเกม
└ is_featureboolean—เป็น free spin หรือ feature spin หรือไม่ ไม่ส่ง = false
└ statusstring—สถานะบิลจากค่ายเกม เป็น SETTLED เสมอOPEN | WAITING | SETTLED | REFUND | REJECT | ROLLBACK | VOID | TIPS
└ play_infostring—ตัวเลือกที่เดิมพัน เช่น player/banker หรือชื่อเกม ค่า `UNKNOWN` = ค่ายระบุไม่ได้ ใช้แสดงผลเท่านั้น
└ transaction_typestring—ขอบเขตของรายการ เป็น BY_TRANSACTION หรือ BY_ROUND (ดูหมายเหตุ)BY_TRANSACTION | BY_ROUND
└ single_stateboolean—รอบที่เดิมพันและผลมาใน call เดียว ไม่มี /bet มาก่อน ส่งมาทุกใบทั้ง true และ false (ดูหมายเหตุด้านล่าง)
└ payout_amountnumber—ยอดจ่าย (stake + win) มาทุกใบ
└ bet_amountnumber—ยอดเดิมพันของรอบ มาทุกใบ เป็น 0 ได้
└ directionstring—ทิศทางของ amount เฉพาะตอน single_state = trueDEBIT | CREDIT
└ turn_overnumber—valid stake ของบิลนี้ เป็น 0 ได้
└ is_end_roundboolean—settle นี้ปิดรอบหรือไม่ false = ยังมีส่วนอื่นตามมา เช่น freespin ไม่ส่ง = ปิดรอบ
└ is_feature_buyboolean—ผลของบิลซื้อฟีเจอร์ มีเฉพาะบางค่าย
└ skip_balance_updateboolean—true = ไม่ต้องขยับ balance บันทึกอย่างเดียว ตอบ code 0 พร้อม balance ปัจจุบัน
ตัวอย่าง request (BY_TRANSACTION)
{
  "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 (BY_ROUND)
{
  "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 (BY_ROUND + single_state)
{
  "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

ฟิลด์ชนิดจำเป็นคำอธิบาย
codenumberใช่0 = สำเร็จ · อื่นๆ ดูหน้า Seamless codes
request_idstringใช่echo จาก request
usernamestringใช่echo player_username (กันสลับคน)
currencystringใช่echo จาก request
balance_beforenumberใช่ยอดก่อนประมวล txns[] ทั้งชุด
balance_afternumberใช่ยอดหลังประมวลทั้งชุด
timestampnumberใช่เวลาที่คุณประมวลผล (unix ms)
ตัวอย่าง response
{
  "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ข้อความ
10001SEAMLESS_USER_NOT_FOUND200ไม่พบผู้เล่นในระบบของ agent
10002SEAMLESS_INSUFFICIENT_BALANCE200ยอดเงินไม่พอสำหรับรายการหักเงิน (debit)balance < bet_amount เฉพาะ single-state
20002SEAMLESS_DUPLICATE_TXN200รายการซ้ำ (txn_id เคยประมวลแล้ว)
30002SEAMLESS_INVALID_SIGNATURE401X-Signature ไม่ถูกต้อง
40003SEAMLESS_FORBIDDEN200ปฏิเสธการเข้าถึง (api-key/IP)
50001SEAMLESS_INTERNAL_ERROR200ข้อผิดพลาดภายในระบบของ agent