อธิบายฟิลด์ทั้งหมดของโมเดลมาตรฐานของข้อมูลธุรกรรมที่ ReceiptRoller จัดการ คือ PosTransactionDto ข้อมูลธุรกรรมของแต่ละผู้ให้บริการ POS(スマレジ, Square, และอื่น ๆ)จะถูกแปลงเป็นโมเดลนี้ทั้งหมด แล้วนำไปใช้ผ่านฐานข้อมูล・แดชบอร์ด・REST API・เครื่องมือ MCP
โปรดใช้เป็นข้อมูลอ้างอิงเมื่ออ่านเขียนธุรกรรมผ่าน API จากระบบภายนอก หรือเมื่อต้องการเข้าใจว่าฟิลด์ฝั่งผู้ให้บริการปรากฏบน ReceiptRoller อย่างไร
ภาพรวม
PosTransactionDto แทน 1 ธุรกรรม(1 การชำระเงิน)รายการ(ระดับสินค้า)เก็บเป็นอาร์เรย์ในชื่อ LineItems และภายในถูกทำให้คงอยู่เป็น JSON ใน LineItemsJson
- จำนวนเงินอยู่ในสกุลที่ระบุด้วย
Currency(ค่าเริ่มต้น JPY)และหากไม่ได้ระบุเป็นอย่างอื่น จะเป็นราคารวมภาษี
- วันเวลาทั้งหมดเก็บเป็น UTC และแปลงเป็น JST ตอนแสดงผล
- คีย์: มี 2 ตัวคือ
TransactionId(ID ภายในของ ReceiptRoller)และ ExternalTransactionId(ID ฝั่งผู้ให้บริการ POS)
- การชำระเงินรองรับหลาย tender(แยกบิล)เก็บเป็นอาร์เรย์
Payments(ยังคงเหลือ PaymentMethod ที่เป็นสตริงเดี่ยวไว้เพื่อความเข้ากันได้ย้อนหลัง)
- ขยายให้รองรับข้อมูลที่ผู้ให้บริการส่งมาโดยไม่ตกหล่น เช่น การคืนเงิน・ID เชื่อมต่อภายนอก・ข้อมูลบัตร・ข้อมูลดิบ
ตัวระบุ
| ฟิลด์ | ชนิด | คำอธิบาย |
TransactionId | string | ID ธุรกรรมภายในของ ReceiptRoller หลายกรณีใช้ ID ฝั่ง POS ตามเดิม(เป็นคีย์ของ idempotent upsert) |
ExternalTransactionId | string | ID ธุรกรรมฝั่งผู้ให้บริการ POS スマレジ: transactionHeadId, Square: Payment.Id |
OrganizationId | string (Guid) | ID ของบัญชีธุรกิจ |
StoreId | string (Guid) | ID ร้านค้า |
TerminalId | string (Guid) | ID ของเครื่อง POS(เครื่องเก็บเงิน) |
วันเวลา
| ฟิลด์ | ชนิด | คำอธิบาย |
TransactionDateTime | DateTime (UTC) | เวลาที่การชำระเงินเกิดขึ้น แปลงจาก Square created_at, スマレジ transactionDateTime |
CreatedAt | DateTime (UTC) | เวลาสร้างเรกคอร์ดฝั่ง ReceiptRoller(สำหรับการตรวจสอบ) |
UpdatedAt | DateTime (UTC) | เวลาอัปเดตเรกคอร์ดฝั่ง ReceiptRoller(สำหรับการตรวจสอบ) |
จำนวนเงิน
| ฟิลด์ | ชนิด | คำอธิบาย |
Currency | string | รหัสสกุลเงินของจำนวนเงินทั้งหมด(ISO-4217, ค่าเริ่มต้น JPY)Square มาจาก money.currency, スマレジ ตรึงเป็น JPY |
TotalAmount | decimal | ยอดรวม(รวมภาษี) |
TaxAmount | decimal | ยอดภาษีบริโภค |
SubtotalAmount | decimal | ยอดย่อย(ไม่รวมภาษี)= TotalAmount - TaxAmount |
DiscountAmount | decimal | ยอดส่วนลด(เก็บเป็นค่าบวก ไม่ใช่ค่าลบ) |
TipAmount | decimal? | ทิป・ค่าบริการ เฉพาะกรณีที่ผู้ให้บริการส่งมาต่างหาก(Square tip_money)ถ้าไม่มีจะเป็น null |
รายการ
| ฟิลด์ | ชนิด | คำอธิบาย |
LineItems | List<PosTransactionLineItemDto> | อาร์เรย์รายการระดับสินค้า(พร็อพเพอร์ตีคำนวณ ตัวจริงคือ LineItemsJson) |
LineItemsJson | string (JSON) | รูปแบบ JSON ที่คงอยู่ของรายการ อย่าอ่านโดยตรง ให้ใช้ LineItems |
ItemCount | int | ผลรวมจำนวนของรายการ(LineItems.Sum(li => li.Quantity)) |
PosTransactionLineItemDto
| ฟิลด์ | ชนิด | คำอธิบาย |
ProductName | string | ชื่อสินค้า หากมีตัวเลือกย่อยจะเป็นรูปแบบ "ชื่อสินค้า (ชื่อตัวเลือกย่อย)" |
Quantity | int | จำนวนที่ขาย |
UnitPrice | decimal | ราคาต่อหน่วย(ไม่รวมภาษี) |
Subtotal | decimal | ยอดย่อย(รวมภาษี) |
TaxRate | decimal | อัตราภาษีที่แท้จริง(%)Square คำนวณอัตโนมัติจากรายการ, スマレジ ใช้ taxRate |
TaxAmount | decimal? | ยอดภาษีระดับรายการ Square total_tax_money, スマレジ tax สำหรับผู้ให้บริการ・ข้อมูลเก่าที่มีแต่อัตราภาษีจะเป็น null |
DiscountAmount | decimal? | ยอดส่วนลดระดับรายการ Square total_discount_money สำหรับผู้ให้บริการที่ไม่มีส่วนลดรายรายการจะเป็น null |
Category | string | หมวดหมู่สินค้า スマレジ คือ categoryName, Square ปัจจุบันว่าง |
Sku | string? | SKU / รหัสสินค้าของผู้ให้บริการ スマレジ คือ productCode ใช้ในการเทียบกับสินค้าใน PIM |
CostPriceAtSale | decimal? | สแนปช็อตต้นทุน PIM(ไม่รวมภาษี)ณ เวลาที่ขาย ใช้ในการคำนวณกำไรขั้นต้น ถ้ายังไม่ได้ตั้งต้นทุนจะเป็น null |
ProductId | string? | ID สินค้าฝั่ง ReceiptRoller(เมื่อระบุได้) |
CatalogObjectId | string? | catalog object ID ของผู้ให้บริการ(Square catalog_object_id, スマレジ productId)สำหรับการเชื่อมต่อระหว่างระบบ |
Unit | string? | หน่วยที่ขาย(「ชิ้น」「kg」ฯลฯ)เฉพาะกรณีที่ผู้ให้บริการมี |
Note | string? | หมายเหตุระดับรายการ |
Modifiers | List<PosLineItemModifierDto>? | ออปชัน・modifier ของรายการ(Square modifiers)มี Name และ Amount |
การชำระเงิน
ธุรกรรมสามารถมีหลาย tender(แยกบิล)ได้ รายละเอียดฉบับสมบูรณ์เก็บใน Payments(ตัวจริงคือ PaymentsJson)ส่วน PaymentMethod ที่เป็นสตริงเดี่ยวเก็บ「tender หลัก」ไว้เพื่อความเข้ากันได้ย้อนหลัง
| ฟิลด์ | ชนิด | คำอธิบาย |
PaymentMethod | string (enum) | ทำให้วิธีชำระเงินหลักเป็นรูปแบบมาตรฐาน:
Cash / CreditCard / QR / IC / Other |
Payments | List<PosPaymentDto> | รายละเอียด tender ฉบับสมบูรณ์(พร็อพเพอร์ตีคำนวณ ตัวจริงคือ PaymentsJson) |
PaymentsJson | string (JSON) | รูปแบบ JSON ที่คงอยู่ของรายละเอียด tender |
ReceiptNumber | string | เลขที่ใบเสร็จ(เลขที่ออกให้ฝั่ง POS) |
PosPaymentDto
| ฟิลด์ | ชนิด | คำอธิบาย |
Method | string | วิธีที่ทำให้เป็นรูปแบบมาตรฐาน(Cash / CreditCard / QR / IC / Other)หรือชื่อดิบของผู้ให้บริการหากไม่รองรับ |
Amount | decimal | จำนวนเงินของ tender นี้ |
TenderedAmount | decimal? | จำนวนเงินที่รับมา(กรณีที่ผู้ให้บริการรายงาน) |
ChangeAmount | decimal? | เงินทอน(กรณีที่ผู้ให้บริการรายงาน) |
Brand | string? | แบรนด์บัตร(VISA, Mastercard ฯลฯ)เฉพาะการชำระด้วยบัตร |
Last4 | string? | เลขบัตร 4 หลักท้าย แสดงได้(ไม่เก็บ PAN) |
ExternalId | string? | ID การชำระเงินฝั่งผู้ให้บริการ(กรณีต่างจาก ID ธุรกรรม) |
การคืนเงิน
รายละเอียดการคืนเงินของธุรกรรมที่ถูกคืน(บางส่วน)เก็บใน Refund(ตัวจริงคือ RefundJson)
| ฟิลด์ | ชนิด | คำอธิบาย |
Refund | PosRefundDto? | รายละเอียดการคืนเงิน(ถ้าไม่มีจะเป็น null) |
RefundJson | string (JSON) | รูปแบบ JSON ที่คงอยู่ของรายละเอียดการคืนเงิน |
PosRefundDto
| ฟิลด์ | ชนิด | คำอธิบาย |
Amount | decimal | ยอดคืนเงิน |
IsPartial | bool | เป็นการคืนเงินบางส่วนหรือไม่ |
Reason | string? | เหตุผลการคืนเงิน |
OriginalTransactionId | string? | ธุรกรรมต้นทางที่เป็นเป้าหมายการคืนเงิน |
RefundedAt | DateTime? | วันเวลาคืนเงิน |
หมายเหตุ: โมเดลและช่องทางของ API พร้อมแล้ว หากมีข้อมูลการคืนเงินจะถูกสะท้อนออกมา เนื่องจาก Square / スマレジ ส่งการคืนเงินเป็น Webhook อีเวนต์แยกต่างหาก การรับข้อมูลการคืนเงินแบบ end-to-end จึงรองรับด้วยกระบวนการซิงก์อีกส่วนหนึ่ง
การเชื่อมต่อภายนอก・URL ใบเสร็จ
เก็บ ID ต่าง ๆ ของ POS ต้นทางและ URL ใบเสร็จ เพื่อให้เทียบธุรกรรมกลับไปยังเรกคอร์ดต้นทางได้
| ฟิลด์ | ชนิด | คำอธิบาย |
ReceiptUrl | string | URL ใบเสร็จสำหรับลูกค้า(Square receipt_url)เป็นฟิลด์ที่มีโครงสร้าง(เดิมเคยเก็บใน Notes แต่ยกเลิกแล้ว) |
ExternalIds | PosExternalIdsDto? | ID ข้ามผู้ให้บริการ(พร็อพเพอร์ตีคำนวณ ตัวจริงคือ ExternalIdsJson) |
ExternalIdsJson | string (JSON) | รูปแบบ JSON ที่คงอยู่ของ ID ภายนอก |
PosExternalIdsDto
| ฟิลด์ | ชนิด | คำอธิบาย |
ProviderOrderId | string? | ID ออเดอร์ของผู้ให้บริการ(Square order_id) |
LocationId | string? | ID location ของผู้ให้บริการ(Square location_id) |
ProviderCustomerId | string? | ID ลูกค้าของผู้ให้บริการ(Square customer_id, スマレジ customerId) |
ข้อมูลดิบ
| ฟิลด์ | ชนิด | คำอธิบาย |
RawJson | string (JSON) | เพย์โหลดดิบของต้นทางตอนรับข้อมูล เก็บไว้เพื่อให้กู้คืนฟิลด์ที่ยังไม่ได้ทำเป็นโมเดล(เช่น card fingerprint)ได้ ใช้ภายในเซิร์ฟเวอร์เท่านั้น API จะไม่คืนค่านี้ |
สตาฟ
| ฟิลด์ | ชนิด | คำอธิบาย |
StaffName | string | ชื่อสตาฟผู้รับผิดชอบ(หากดึงไม่ได้จะว่าง) |
StaffId | string | ID สตาฟฝั่งผู้ให้บริการ POS(Square: team_member_id, スマレジ: staffId) |
สถานะ・ที่มา
| ฟิลด์ | ชนิด | คำอธิบาย |
Status | string (enum) | Completed / Voided / Refunded / Pending สำหรับแสดงผลใช้ StatusDisplayName |
Source | string (enum) | API(รับอัตโนมัติจาก POS)/ Webhook(แจ้งเตือนแบบพุชจาก POS)/ CSV(นำเข้าเป็นชุด)/ Manual(กรอกด้วยมือ) |
Notes | string | หมายเหตุ・บันทึก เนื่องจากย้าย URL ใบเสร็จไปที่ ReceiptUrl แล้ว ที่นี่จึงไม่เก็บอีกต่อไป |
การเชื่อม CRM
เมื่อธุรกรรมถูกผูกกับลูกค้า(ข้อมูลสมาชิกฝั่ง POS, ตรงกับเบอร์โทร・อีเมล ฯลฯ)ICrmCustomerResolver ของ ReceiptRoller จะเติมฟิลด์ต่อไปนี้
| ฟิลด์ | ชนิด | คำอธิบาย |
MembershipCode | string? | เลขที่สมาชิก ReceiptRoller หากผูกไม่ได้จะเป็น null |
CrmCustomerId | string? | ID ของเรกคอร์ดลูกค้า CRM หากผูกไม่ได้จะเป็น null |
ID ลูกค้าดิบฝั่งผู้ให้บริการอ้างอิงต่างหากได้ที่ ExternalIds.ProviderCustomerId
เฮลเปอร์สำหรับแสดงผล
เป็นพร็อพเพอร์ตีคำนวณสำหรับใช้ฝั่ง UI ไม่ได้บันทึกลง DB โดยตรง
PaymentMethodDisplayName — การเขียนวิธีชำระเงินเป็นภาษาญี่ปุ่น(ตัวอย่าง: 「クレジットカード」)
StatusDisplayName — การเขียนสถานะเป็นภาษาญี่ปุ่น(ตัวอย่าง: 「完了」「取消」)
StatusBadgeClass — CSS class สำหรับแบดจ์ Bootstrap
SourceDisplayName — ชื่อแสดงของที่มา
FormattedDateTime — วันเวลารูปแบบ 「yyyy/MM/dd HH:mm」
FormattedTotal — ยอดรวมแบบคั่นด้วยจุลภาค
ความเข้ากันได้ย้อนหลัง
ฟิลด์ส่วนขยายข้างต้นทั้งหมดเป็นฟิลด์ที่เพิ่มขึ้นและ nullable และถูกทำให้คงอยู่เป็นคอลัมน์ JSON ไม่จำเป็นต้อง migrate ของ Table Storage แถวเดิมและ LineItemsJson เดิมยังใช้ได้ตามเดิม ฟิลด์ใหม่จะถูกสะท้อนจากธุรกรรมที่รับเข้ามาใหม่(หากต้องการสะท้อนไปยังข้อมูลเก่าต้องซิงก์ซ้ำ)
การแมปปิงแยกตามผู้ให้บริการ
รายละเอียดว่าแต่ละผู้ให้บริการ POS เติมฟิลด์ใดอย่างไร โปรดดูบทความการแมปปิงแยกตามผู้ให้บริการต่อไปนี้
คู่มือที่เกี่ยวข้อง