Skip to content

กระทบยอด X/V/A และส่งออก ​

หน้านี้เป็นเครื่องมือปฏิบัติการใน Back Office สำหรับหาเงินที่ยังไม่ลงบัญชีตรงกัน และส่งออก snapshot เดิมไปตรวจต่อ โดยไม่เปิดเผยข้อมูลบัญชีธนาคาร ผู้ให้บริการ เส้นทางสภาพคล่อง หรือที่อยู่ object storage

พร้อมสำหรับขั้นตอน deploy

สัญญา DB, HTTP, UI และ worker ของ reconciliation.read, export.create และ export.auth.step-up ผ่าน release gates ใน repository และตั้งเป็น serverBacked: true พร้อมกันแล้ว เมนูจะปรากฏเฉพาะหลังผู้ดูแล deploy ชุดนี้และ authoritative bootstrap ให้ capability/API contract ครบ; สถานะนี้ไม่ได้หมายความว่ามีการ deploy remote แล้ว

ใครเห็นข้อมูลอะไร ​

Scope ปัจจุบันselfsubtree
White Labelตัวเองตัวเองและสายภายใต้ White Label เดียวกัน
Agentตัวเองตัวเองและ Merchant ของ Agent นั้น
Merchantตัวเองไม่อนุญาต

สิทธิ์หน้าอ่านคือ reconciliation:read พร้อม API contract reconciliation ส่วนการสร้างไฟล์ต้องมี exports:create, contract exports และสิทธิ์อ่าน dataset ต้นทางด้วย การมีเมนูหรือ role label ใน browser ไม่ใช่หลักฐานอนุญาต; ฐานข้อมูลตรวจสมาชิก, hierarchy, environment และ scope ซ้ำทุก request และคืน 404 แบบเดียวกันเมื่อ target ไม่อยู่ในสาย

ความหมายของ X, V และ A ​

text
X = ordered_minor       ยอดที่สร้างรายการ
V = transferred_minor   ยอดโอนจริงจากหลักฐานที่เชื่อถือได้
A = accepted_minor      ยอดที่ระบบรับ
net = A - fee
กรณีกติกา
โอนตรงV=X, รับ A=X
โอนไม่ถึงรับตามยอดจริง A=V
โอนเกินรับไม่เกินยอดที่สร้าง A=X, ปิดงาน และติด action_required=contact_support
ยังไม่มีหลักฐานV=null, A=fee=net=0 และคงสถานะ pending
ต้องตัดสินโดยเจ้าหน้าที่แสดง manual review โดยไม่ตีความว่า balanced

ส่วนเกินจาก overpayment ไม่สร้างเครดิตอัตโนมัติ ผู้ใช้งานต้องติดต่อ Support หลังบ้านตาม flag ของรายการนั้น

balanced หมายถึงยอด accepted, fee และ net ตรงกับ immutable ledger ทั้งหมด ไม่ได้หมายถึงแค่ V=X ส่วน variance ต้องมีผลต่าง ledger อย่างน้อยหนึ่งค่า ระบบตรวจสมการเงินซ้ำใน response adapter และใช้ decimal string หน่วยสตางค์เพื่อไม่เสีย precision

Snapshot และหน้าถัดไป ​

หน้าแรกเรียก:

http
GET /v1/bo/reconciliation?scope_id={scope}&livemode=true&currency=THB&view=self&from={UTC}&to={UTC}&limit=50
X-PG-BO-Client: 1

ช่วงเวลาต้องมากกว่า 0 ไม่เกิน 31 วัน และไม่เป็นอนาคต หน้าแรกห้ามส่ง cursor หรือ as_of; PostgreSQL เป็นผู้ตรึง as_of หลังตรวจสิทธิ์แล้ว หน้าถัดไปต้องส่งทั้ง cursor และ as_of เดิม การเปลี่ยน scope, mode, ช่วงเวลา, status, resolution หรือ limit ทำให้ cursor เดิมใช้ไม่ได้

ลำดับคงที่คือ (occurred_at DESC, reconciliation_ref DESC) และข้อมูลที่เกิดหลัง as_of จะไม่แทรกเข้ามาใน snapshot เดิม

สร้าง CSV แบบ asynchronous ​

ปุ่มส่งออกสร้าง snapshot ของ dataset ปัจจุบันหนึ่งชุด:

  • reconciliation — X/V/A, fee, net และผลต่าง ledger;
  • statement — posting จาก immutable ledger; หรือ
  • financial_report — volume และ economics ตาม scope

column set เป็นแบบตายตัวและ row_limit สูงสุด 100,000 แถว ถ้าเกินจะจบด้วย row_limit_exceeded; ระบบไม่สร้างไฟล์ที่ตัดข้อมูลเงียบ ๆ ไฟล์อยู่ใน dedicated private R2_EXPORTS ที่ bind เฉพาะ Money และมี bucket-wide lifecycle ไม่เกิน 7 วัน จึงไม่แชร์ capability กับ Edge Web/QR/statement และไม่มีชื่อ, อีเมล, เบอร์โทร, เลขบัญชี, raw evidence, metadata หรือข้อมูล routing ภายใน

การสร้างไฟล์เปิด OIDC popup ซึ่งส่ง callback ชนิด paygate:export-step-up และ proof ผูกกับ method, path, scope, livemode, body digest, idempotency digest, query_digest และ column_set_hash หลังยืนยันแล้ว browser ส่งคำสั่งเดิมไปที่:

http
POST /v1/bo/exports
If-Match: "0"
Idempotency-Key: {stable-key}
X-PG-Step-Up-Token: pgsea1.{opaque}
X-PG-BO-Client: 1
Content-Type: application/json; charset=utf-8

คำตอบ queued หรือ processing เป็นสถานะจริง ไม่ใช่ fake success การส่ง idempotency key เดิมพร้อม body เดิมใช้ดู job เดิมได้โดยไม่สร้าง snapshot ซ้ำ

ดาวน์โหลดโดยไม่ให้ grant หลุดเข้า HTTP metadata ​

job ที่ ready คืน handoff อายุไม่เกิน 5 นาที:

json
{
  "scheme": "pg_opaque_grant_v1",
  "method": "POST",
  "path": "/v1/bo/export-downloads:consume",
  "one_time": true,
  "grant": "{opaque-base64url}",
  "issued_at": "{canonical-UTC}",
  "expires_at": "{canonical-UTC}"
}

UI ล้าง handoff ออกจาก global/reactive state ก่อนเรียก download helper และห้ามนำ grant ไปใส่ href, URL, query หรือ header จากนั้น helper ส่ง body bytes เพียงรูปแบบเดียว:

http
POST /v1/bo/export-downloads:consume
Accept: text/csv
Content-Type: application/json
X-PG-BO-Client: 1

{"grant":"{opaque-base64url}"}

request ใช้ same-origin cookie, Origin และ Fetch Metadata เดิม และห้ามตาม redirect คำตอบสำเร็จต้องเป็น 200, text/csv; charset=utf-8, gzip, attachment filename ลงท้าย .csv, private, no-store, nosniff, no-referrer และ CSP default-src 'none'; base-uri 'none'; frame-ancestors 'none' เท่านั้น ไม่มี ETag, Digest, R2 locator หรือ redirect

grant ใช้ได้ครั้งเดียว 404 ครอบคลุมกรณีใช้แล้ว, หมดอายุ, ผิดผู้ใช้, ผิด scope หรือ session ไม่ active โดยไม่บอกว่ากรณีใด 502 คือ integrity/header mismatch และ UI ไม่ retry 404 หรือ 502 อัตโนมัติ

ก่อนเปิด feature ​

ต้องผ่าน fresh migration replay และ pgTAP ของ 0083/0084, DB/API/worker/Money/Admin tests, checksum/expiry ของ bucket ส่วนตัว R2_EXPORTS ซึ่ง bind เฉพาะ Money, one-time consume race, Tail native Workers Logs redaction, contract/OpenAPI drift, UI tests/build/ZIP และ staging smoke พร้อมกัน หลังผ่านแล้วจึงเปลี่ยน readiness ทั้งสาม operation เป็น true และ rebuild White Label artifacts

เอกสารชุดนี้อิงสัญญา API เวอร์ชัน 2026-08-01