การแมปข้อมูลการขายของ Square กับข้อมูลการขายของ Receipt Roller

Square การเชื่อมต่อ POS การแมปข้อมูล รายละเอียดทางเทคนิค ข้อมูลการขาย API

คำอธิบายทางเทคนิคเกี่ยวกับกลไกที่ดึงข้อมูลการขายจาก Square API แล้วแมปเข้าสู่โมเดลข้อมูลการขายของ Receipt Roller บทความนี้จัดทำขึ้นสำหรับนักพัฒนาและผู้ดูแลระบบที่ต้องการทำความเข้าใจข้อกำหนดภายใน ครอบคลุมตารางเทียบฟิลด์ การแปลงรหัสสถานะ การปรับมาตรฐานวิธีการชำระเงิน การระบุข้อมูลรายละเอียด/ลูกค้า/พนักงาน การจัดการโซนเวลาและความคงเส้นคงวา

บทความนี้สรุปพฤติกรรมของ SquarePaymentMapper ในฝั่ง Receipt Roller สำหรับขั้นตอนทั่วไปอย่าง "การเชื่อมต่อกับ Square" หรือ "เกิดอะไรขึ้นเมื่อซิงค์" ดูได้ที่ การตั้งค่าเชื่อมต่อ POS ของ Square สำหรับข้อกำหนดโมเดลมาตรฐานแยกตามฟิลด์ ดูได้ที่ ข้อกำหนด PosTransactionDto (ฟิลด์อ้างอิง)

โครงสร้างพื้นฐาน

Square และ Receipt Roller มีความละเอียดของข้อมูลการขายที่แตกต่างกัน

  • ฝั่ง Square แบ่งออกเป็น Payment(การชำระเงิน)และ Order(คำสั่งซื้อ)Payment มีข้อมูลการชำระเงิน ส่วน Order มีข้อมูลรายละเอียด
  • ฝั่ง Receipt Roller รวบรวมการชำระเงิน + รายละเอียด + ลูกค้า + พนักงานไว้ใน PosTransactionDto รายการเดียว
  • เมื่อดึงข้อมูล จะเริ่มจาก Payment แล้วดึง Order / TeamMember / Customer ที่เกี่ยวข้องเพิ่มเติม

ตารางเทียบฟิลด์หลัก

ฝั่ง Receipt Rollerฝั่ง Squareหมายเหตุ
TransactionIdPayment.idใช้ ID การชำระเงินของ Square ตามเดิม เป็นคีย์สำหรับการ upsert แบบคงเส้นคงวา
ExternalTransactionIdPayment.idเช่นเดียวกับข้างต้น(เก็บซ้ำไว้สำหรับการอ้างอิงภายนอก)
TransactionDateTimePayment.created_atแปลงจากสตริง ISO 8601 เป็น DateTime แบบ UTC
CurrencyPayment.amount_money.currencyรหัสสกุลเงิน ค่าเริ่มต้นคือ JPY
TotalAmountPayment.amount_money.amountJPY ใช้ค่าตามเดิม สกุลเงินอื่นแปลงจากหน่วยที่เล็กที่สุด (cents) เป็นหน่วยหลัก
TaxAmountPayment.tax_money.amountเช่นเดียวกับข้างต้น
SubtotalAmountค่าที่คำนวณamount - tax
DiscountAmountPayment.discount_money.amountเช่นเดียวกับข้างต้น
TipAmountPayment.tip_money.amountทิป มีเฉพาะกรณีที่มี
PaymentMethodตรวจสอบว่ามี Payment.card_details หรือไม่หากมีข้อมูลบัตรจะเป็น CreditCard หากไม่มีจะเป็น Other(ผู้ให้บริการหลัก รายละเอียดดูใน Payments ด้านล่าง)
Payments[]Payment 1 รายการ + card_details.cardรายละเอียดผู้ให้บริการชำระเงิน Method / Amounttotal_money)/ Brand(card_brand)/ Last4(last_4)
StatusPayment.statusดู "ตารางเทียบรหัสสถานะ" ด้านล่าง
ReceiptNumberPayment.receipt_numberออกโดย Square
ReceiptUrlPayment.receipt_urlURL ใบเสร็จสำหรับลูกค้า บันทึกในฟิลด์ที่มีโครงสร้าง(เดิมเก็บไว้ใน Notes แต่ยกเลิกแล้ว)
ExternalIdsorder_id / location_id / customer_idID สำหรับอ้างอิงข้ามผู้ให้บริการ(ProviderOrderId / LocationId / ProviderCustomerId
StaffIdPayment.team_member_idเป็นค่าว่างหากยังไม่ได้กำหนด
StaffNameTeamMember.display_nameระบุแยกต่างหากผ่าน TeamMembers API
Sourceค่าคงที่ "API" หรือ "Webhook"ตามเส้นทางที่ดึงข้อมูล
RawJsonPayload ดิบของ Payment + Orderเก็บฟิลด์ที่ไม่ได้แปลงเป็นโมเดล(เช่น card fingerprint)ไว้เพื่อให้สามารถกู้คืนได้ ไม่ส่งคืนผ่าน API
LineItemsOrder.line_items[]ระบุแยกต่างหากผ่าน Orders API ดู "การแมปข้อมูลรายละเอียด" ด้านล่าง

ตารางเทียบรหัสสถานะ

Square Payment.statusReceipt Roller Statusความหมาย
COMPLETEDCompletedบันทึกบัญชีเสร็จสมบูรณ์
CANCELEDVoidedยกเลิก
FAILEDVoidedล้มเหลว(ไม่รวมอยู่ในยอดขาย)
อื่นๆPendingกำลังดำเนินการ/ยังไม่ยืนยัน

การแปลงสกุลเงินของจำนวนเงิน

อ็อบเจ็กต์ Money ของ Square มีวิธีจัดการหน่วยที่เล็กที่สุดแตกต่างกันไปตามสกุลเงิน

  • JPY: 1 เยนเป็นหน่วยที่เล็กที่สุด ใช้ค่า amount ตามเดิม
  • USD・EUR เป็นต้น: 1 เซ็นต์เป็นหน่วยที่เล็กที่สุด แปลงเป็นหน่วยหลักด้วย amount / 100

ฝั่ง Receipt Roller จะเก็บทุกค่าเป็นหน่วยหลัก (decimal) และเก็บรหัสสกุลเงินไว้ใน Currency

การแมปข้อมูลรายละเอียด

เนื่องจาก Payment ของ Square ไม่มีข้อมูลรายละเอียดรวมอยู่ด้วย ระบบจะดึง Order ที่เกี่ยวข้องแยกต่างหากเพื่อขยายเป็นรายละเอียด หากไม่สามารถดึง Order ได้(สิทธิ์ไม่เพียงพอ, API error, OAuth token หมดอายุ ฯลฯ)รายการขายจะถูกบันทึกโดยไม่มีรายละเอียด และสามารถเติมเต็มได้ในภายหลังผ่านการซิงค์ซ้ำ

Receipt Roller LineItemSquare Order.line_items[]หมายเหตุ
ProductNamename + variation_nameหากมี variation จะเป็นรูปแบบ "ชื่อสินค้า (ชื่อ variation)"
Quantityquantityแปลงสตริงเป็นจำนวนเต็ม หากล้มเหลวจะเป็น 1
UnitPricebase_price_money.amountมีการแปลงสกุลเงิน
Subtotaltotal_money.amountหากดึงไม่ได้จะใช้ UnitPrice × Quantity
TaxRateค่าที่คำนวณคำนวณจาก (total_tax_money / (total_money - total_tax_money)) × 100 แล้วปัดเศษทศนิยมตำแหน่งที่ 1
TaxAmounttotal_tax_money.amountจำนวนภาษีระดับรายละเอียด เก็บเป็นจำนวนเงินไม่ใช่แค่อัตราภาษี
DiscountAmounttotal_discount_money.amountจำนวนส่วนลดระดับรายละเอียด
CatalogObjectIdcatalog_object_idID สำหรับเชื่อมโยงกับแคตตาล็อกของ Square
Modifiersmodifiers[]ตัวเลือก/รายการปรับแต่ง(name + total_price_money
Categoryปัจจุบันเป็นค่าว่างเสมอ การระบุผ่าน Square Catalog API อยู่ระหว่างการพิจารณาในอนาคต

การดึงคีย์จับคู่ลูกค้า

เพื่อส่งต่อไปยังไปป์ไลน์การกระจายอัตโนมัติของ Receipt Roller(การเชื่อมต่อ CRM)ระบบจะดึงตัวระบุลูกค้าฝั่ง Square ออกมา

  • คีย์หลัก: Payment.customer_id(ID ลูกค้าใน Square Customer Directory)เก็บไว้เป็น ExternalIds.ProviderCustomerId ในรายการขายด้วย
  • สำรอง: Payment.card_details.card.fingerprint(แฮชของหมายเลขบัตร ไม่ใช่ PAN แต่เป็นตัวระบุที่เสถียรซึ่ง Square สร้างขึ้น เก็บไว้ใน RawJson ไม่ส่งคืนผ่าน API)

เนื่องจาก Square Payment ไม่มีหมายเลขโทรศัพท์หรืออีเมลรวมอยู่ด้วย จึงจำเป็นต้องเรียก API เพิ่มเติมไปยัง Customer Directory ปัจจุบันมักละเว้นขั้นตอนนี้เนื่องจาก fingerprint ของบัตรสามารถจับคู่ได้เพียงพอในกรณีส่วนใหญ่

การรีเฟรช OAuth token อัตโนมัติ

Access token ของ Square OAuth จะหมดอายุภายในประมาณ 30 วัน สำหรับเส้นทางผ่าน Webhook ระบบจะตรวจสอบวันหมดอายุของ terminal.AccessToken ก่อนดึงข้อมูลรายละเอียด/ชื่อพนักงาน หากเหลือเวลาน้อยกว่า 60 วินาที จะอัปเดตอัตโนมัติด้วย RefreshToken(หลังอัปเดตจะบันทึกลงในเรคคอร์ดของเครื่องแบบถาวร)วิธีนี้ช่วยป้องกันไม่ให้เกิดการดึงรายละเอียดไม่สำเร็จในร้านค้าที่ขับเคลื่อนด้วย webhook เป็นระยะเวลานาน

ความคงเส้นคงวา (Idempotency)

แม้รายการขายเดียวกันจะมาถึงหลายครั้ง(เช่น การซิงค์ด้วยตนเองซ้ำในฝั่ง Square หรือ Webhook ซ้ำซ้อน)ระบบจะบันทึกซ้ำได้อย่างปลอดภัยด้วยการ upsert โดยใช้ Payment.id เป็นคีย์ จะไม่มีการออกใบเสร็จซ้ำในฝั่ง Receipt Roller

บทความที่เกี่ยวข้อง

เผยแพร่เมื่อ: 2569-05-29 อัปเดตเมื่อ: 2569-07-02
บทความที่เกี่ยวข้อง