Tags:
Node Thumbnail

เมื่อวานนี้ธนาคารแห่งประเทศไทยเปิดตัว PromptPay QR แต่การใช้งานก็ยังจำกัดบางพื้นที่โดยต้องใช้แอปพลิเคชั่นของธนาคารในการสร้างตัว QR อย่างไรก็ดี PromptPay QR นี้เป็นมาตรฐานเปิดของ EMVco ที่เปิดให้อ่านฟรีโดยไม่ต้องเป็นหน่วยงานที่เกี่ยวข้องแต่อย่างใด เอกสารฉบับนี้คือ "EMVCo QR Code Specification for Payment Systems: Merchant-Presented Mode" หรือสเปคสำหรับการสร้าง QR จากฝั่งผู้ขายเพื่อขอรับเงินจากผู้รับ

ตอนนี้เราจะมาดูกันว่าข้อมูลใน QR นี้มีข้อมูลอะไรบ้าง อย่างไรก็ดีบทความนี้ข้ามข้อมูลที่ยังไม่สามารถหาได้ จากการดู QR ที่เปิดเผยออกมา

No Description

หากเราสแกน QR ที่ใช้จ่ายเงินตอนนี้ด้วยแอปพลิเคชั่นสแกน QR โดยเฉพาะ ไม่ใช่แอปของธนาคาร จะเห็นตัวเลขและข้อความยาวๆ เป็นชุดเดียว เช่นตัวอย่าง "00020101021129370016A000000677010111011300660000000005802TH530376463048956" (ตัวอย่างนี้ใช้ข้อมูลหลอก ด้วยหมายเลขโทรศัพท์ 000-000-0000)

แนวทางการอ่านข้อมูลของมาตรฐาน EMVco คือ หมายเลขประจำฟิลด์ข้อมูล (เป็น 00-99), ความยาวของข้อมูลในฟิลด์นั้น (เป็น 01-99), และตัวข้อมูลจริงๆ การอ่านข้อมูลตัวอย่างจะทำเป็นขั้นได้ดังนี้

  • หมายเลขเวอร์ชั่น ฟิลด์ 00 ความยาว 02 ข้อมูลตอนนี้คือ 01 เสมอ ดังนั้นข้อมูลชุดแรกคือ "000201"
  • ประเภทของ QR ฟิลด์ 01 ความยาว 02 ข้อมูล "11" แปลว่า QR นี้สร้างขึ้นเพื่อใช้สำหรับการขายหลายครั้ง เช่นระบุผู้ขาย หรือระบุราคาสินค้า ถ้าเป็น 12 คือ QR สร้างขึ้นเพื่อใช้ครั้งเดียว เช่น เป็นการจ่ายสำหรับใบเสร็จใบเดียว
  • ข้อมูลผู้ขาย (merchant account information) ฟิลด์ 29 ความยาว 37 ข้อมูล "0016A00000067701011101130066000000000" โดยข้อมูลนี้แบ่งออกเป็นสองฟิลด์ย่อย
    • หมายเลขแอปพลิเคชั่น (application ID - AID) เป็นหมายเลขที่ปกติแล้วใช้อ้างอิงประเภทบัตรสมาร์ตการ์ดแบบต่างๆ ตั้งแต่บัตรประชาชนไปจนถึงบัตรเครดิตทั้งหลาย ในกรณีนี้มีการนำหมายเลขนี้มาใช้ใน QR เพื่อระบุว่า QR นี้เป็น PromptPay หมายเลขฟิลด์ย่อย 00 ความยาว 16 ข้อมูล "A000000677010111"
    • หมายเลขบัญชี เป็นหมายเลข PromptPay โดยตรง ตอนนี้มีหมายเลขฟิลด์ เช่น
    • 01 หมายเลขโทรศัพท์ ความยาว 13 นำหน้าด้วย 00 แล้วตามด้วยรหัสประเทศ 66 แล้วจึงเป็นหมายเลขโทรศัพท์ตัดศูนย์นำหน้าออก 00-000-0000
    • 02 หมายเลขบัตรประชาชนไม่มีขีดคั่น
  • ประเทศ ฟิลด์ 58 ความยาว 02 ข้อมูล "TH" หมายถึงประเทศไทย
  • สกุลเงินที่ใช้งาน ฟิลด์ 53 ความยาว 03 ข้อมูล "764" โดยหมายเลข 764 เป็นหมายเลขประจำค่าเงินบาทตาม ISO 4217
  • ค่า check sum ฟิลด์ 63 ความยาว 04 ข้อมูล "8956" ข้อมูลนี้ต้องอยู่ท้ายสุดเสมอ โดยค่า check sum เป็นการคำนวณจากข้อมูลทั้งหมด รวมถึงหมายเลขฟิลด์ของ check sum และความยาวของฟิลด์ check sum เอง กระบวนการหาค่า check sum ใช้ CRC-16 และ ค่าคงที่ polynomial 0x1021 (XMODEM) พร้อมกับค่าเริ่มต้น 0xFFFF (อันนี้ต้องระวังเพราะไลบรารีส่วนมากมักใส่ค่าเริ่มต้นเป็น 0x0000) ตัวไลบรารีสามารถใช้ pycrc16 ได้โดยตรง

ตัวอย่างการหาค่า check sum ด้วย crc16pure.py เช่น

In [7]: hex(crc16pure.crc16xmodem("00020101021129370016A000000677010111011300660000000005802TH53037646304",0xffff))
Out[7]: '0x8956'

สังเกตว่าหมายเลขฟิลด์กระโดดจาก 01 ซึ่งเป็นฟิลด์บังคับ ไปยัง 29 ทันที เพราะหมายเลข 02-25 นั้นสงวนไว้สำหรับผู้ให้บริการบัตรเครดิตโดยเฉพาะ เช่น 02-03 สำหรับ VISA, 04-05 สำหรับ Mastercard, 06-08, 11-12 สำหรับ Amex, 13-14 สำหรับ JCB, และ 15-16 สำหรับ UnionPay ที่เหลือทาง EMVco ก็ให้เว้นไว้สำหรับการใช้งานในอนาคต

เราได้ข้อมูลหลายอย่างจากการดูว่ามีข้อมูลอยู่ใน QR เช่น

  • ตัว QR ยังคงแสดงข้อมูลหมายเลข PromptPay เช่นเดิม ซึ่งอาจจะหมายถึงหมายเลขโทรศัพท์หรือหมายเลขบัตรประชาชน หากใครมีความไม่สะดวกใจที่จะให้หมายเลขทั้งสองกับผู้ซื้อก็อาจจะต้องระวัง
  • QR เหล่านี้ไม่มีกระบวนการยืนยันว่าสร้างโดยใคร ที่จริงแล้วตอนนี้ทาง Digio ก็เปิดเว็บสร้าง QR PromptPay แล้ว เท่าที่ทดสอบสามารถใช้ได้กับ PromptPay ทุกธนาคาร ความเสี่ยงมีอยู่บ้างคือธนาคารเองก็ไม่สามารถตรวจสอบได้ว่ามีการสร้าง QR ไปแปะทับเพื่อขโมยเงินกันหรือไม่ ดังนั้นการจ่ายเงินควรตรวจสอบชื่อบัญชีของผู้รับเสมอว่าตรงกับคนที่เราต้องการจ่ายไป
  • มีความเป็นไปได้ที่จะสร้าง QR เหล่านี้โดยอัตโนมัติ ในเร็วๆ นี้เราคงได้เห็นไลบรารีโอเพนซอร์ส หรือบริการต่างๆ เพื่อสร้าง QR ทั้งระบุและไม่ระบุจำนวนเงิน ความเป็นไปได้อื่นๆ ของบริการนี้คงมีอีกมาก เช่นร้านค้าออนไลน์อาจจะเริ่มรับเงินผ่าน PromptPay กันมากขึ้นเพราะสามารถส่ง QR ระบุจำนวนเงินไปในแชตหรือเว็บอีคอมเมิร์ชได้โดยตรง

ข้อมูลเปิดเผย: Digio เป็นผู้ลงประกาศหางานบน Blognone แบบเด่นพิเศษ แต่บทความนี้เขียนโดยไม่ได้มีการติดต่อกันมาก่อน (ผมพบโพสประกาศหลังเริ่มเขียนบทความไปแล้ว) อย่างไรก็ดี QR ตัวอย่างสร้างโดยเว็บของ Digio เพื่อปิดบัง QR จริงที่ผมใช้แกะข้อมูล

Get latest news from Blognone

Comments

By: ShiRaTo
Android
on 31 August 2017 - 05:41 #1004859

อยากลองถกเหมือนกัน ว่าทำไมต้องสร้าง CRC ใน QR อีก
ในเมื่อ QR ก็มี CRC ในตัวมันเองอยู่แล้ว. ใครมีไอเดียมุมไหนบ้างครับ

By: iamfalan
iPhoneAndroidWindows
on 31 August 2017 - 07:35 #1004865 Reply to:1004859

ไว้กันกรณีคนแอบเปลี่ยน id บัตรคนรับเงินมั้งครับ
แต่คงกันไม่ได้เท่าไหร่

By: Hadakung
iPhoneWindows PhoneAndroidWindows
on 31 August 2017 - 07:46 #1004866 Reply to:1004859

น่าจะเอาไว้เช็คกันผิดพลาดระดับแอพพิเคชั่นนะครับคงคิดว่าข้อมูลอาจจะผิดพลาดระหว่างกระบวนการไหนก็ได้เลยต้องใส่ไปจนระดับ end to end เลย

By: bungbui
ContributorAndroidWindows
on 1 September 2017 - 23:43 #1005220 Reply to:1004859
bungbui's picture

QR มี error correction อยู่แล้ว
และรายละเอียดผู้รับเงินปลายทาง คนจ่ายควรจะเช็คก่อนอยู่แล้ว ว่ากำลังโอนเงินไปไหน
หากมีการ fraud ก็ใส่ CRC มาเองได้อยู่ดี ไม่ได้ช่วยยืนยันอะไร
ผมคิดว่าไม่จำเป็นต้องมีนะครับ

By: lew
FounderJusci's WriterMEconomicsAndroid
on 2 September 2017 - 00:06 #1005226 Reply to:1005220
lew's picture

ผมคิดว่า CRC มีไว้เพื่อยืนยันว่ามันเป็น QR ของ EMVco ครับ ไม่ใช่ QR อื่นๆ ที่บังเอิญ parse ผ่านพอดี


lewcpe.com, @public_lewcpe

By: foizy
AndroidUbuntuWindows
on 2 September 2017 - 03:24 #1005240 Reply to:1005220

ใน Paper

The CRC (ID "63") is the last object under the root and
allows the mobile application to check the integrity of the data scanned without having to parse all of the data objects.

หลักๆแล้วผมว่าเค้าอาจจะมองว่า
QR-CRC มันทำให้รู้ล่ะ ว่าสแกนมาถูกแน่ๆ แต่การแสกนถูก ไม่ได้บอกว่าเป็น EMV QR ที่ถูกต้อง เลยสร้าง EMV-CRC ซ้ำมาอีกที เพื่อให้เช็คได้เลยตั้งแต่เห็น Message ว่าข้อความที่สแกนมา เป็น EMVQR .. ถ้า Field นี้ผิดก็ผิด

ออกแนวเป็น Validation(Hash-Check) มากกว่า error detection(CRC) นะครับ ..

อาจจะเพราะว่ามันเป็นตัวเลขเกือบๆล้วนๆ(ALNUM) มีโอกาสที่การ Parse แล้วเช็คยาก
เช่นตัวอย่างในโพสต์นี่ ถ้าไม่มี CRC ให้เช็คก่อน เราก็จะไม่รู้เลยจนกว่าจะ Parse ครบหมด ว่า string ที่สแกนมาได้นั้นถูกหรือผิด

00020101021129370016A00000067701011101130
0660000000005802TH530376463048956

หรือไม่ก็จริงๆมันอาจจะมีโอกาสเจอตัวเลขที่คล้ายคลึงกับ [Type][Length][Data] ในเรื่องอื่นๆเยอะล่ะมั๊ง

SCAN + QR ECC PROCESS = RAWCODE

IF (CHECKCRC == Pass) THEN
..Parse Code
ELSE
..Reject
END

By: MaylinZ
Contributor
on 31 August 2017 - 07:15 #1004863

ต่อไปคงไม่มีแล้วขอทงขอทาน อยากได้ตังก็ปริ๊นสติกเกอร์ QR ไปติดข้างเสาไฟฟ้าดื้อๆเลย บริจาคตามกำลังศรัทธา

By: gosol
AndroidWindows
on 31 August 2017 - 09:20 #1004879 Reply to:1004863
gosol's picture

ติดเสาไฟเฉยๆคงไม่มีใครให้ ขอทานจีนเขาเดินไปยื่น QR code ให้สแกนบริจาคเลยครับ จะได้มี impact แต่พวกขอทานต่างด้าว,ขอทานฝรั่งคงยังรับเศษเงินอยู่

By: impascetic
Android
on 31 August 2017 - 09:54 #1004889 Reply to:1004863

วณิพก 4.0

By: Floating Rotten Dog
iPhoneWindows PhoneAndroidWindows
on 1 September 2017 - 02:13 #1005076 Reply to:1004889
Floating Rotten Dog's picture

วณิพก ไม่ได้ขอเฉยๆ แต่มีการแสดงแลกเงินครับ อาจจะเพิ่มคิวอาร์โค้ดสำหรับลิ้งก์ให้เข้าไปฟังเพลงออนไลน์

By: raykichi
AndroidSymbianWindows
on 31 August 2017 - 08:16 #1004867

02 หมายเลขบัตรประชาชน ความยาว 15 นำหน้าด้วย 00 เช่นกัน และไม่มีขีดคั่น

02 มีความยาวแค่ 13 หลัก และไม่มี 00 นำหน้า

By: azpirin
AndroidUbuntuWindows
on 31 August 2017 - 16:06 #1004989

สรุปข้อมูลข้างในก็คือ รหัสบัตรประชาชน/เบอร์โทร สินะ นึกว่าจะได้ตัวเลือกที่ 3 เพิ่มมาให้ใช้ซะอีก

By: gd_ab
ContributorAndroidUbuntuWindows
on 1 September 2017 - 08:55 #1005093 Reply to:1004989
gd_ab's picture

หมายเลขประจำตัวผู้เสียภาษีใช้ 02 เหมือนกันกับเลขประจำตัวประชาชนครับ

ลองมาแล้ว

By: lew
FounderJusci's WriterMEconomicsAndroid
on 1 September 2017 - 15:40 #1005173 Reply to:1004989
lew's picture

ตัวเลือกอื่นจะมี eWallet ID เพิ่มมาครับ ตอนนี้ยังไม่รู้ว่าจะเป็นเบอร์โทรผม (แต่ผมเชื่อว่าไม่ใช่นะ เพราะ LINE ก็ไม่ได้ผูกกับเบอร์โทรเดียว)


lewcpe.com, @public_lewcpe

By: bioice on 2 September 2017 - 03:01 #1005229

พยายามเขียนอธิบายคนอื่น
ลิงค์สอน

By: EThaiZone
ContributorAndroidUbuntuWindows
on 2 September 2017 - 15:37 #1005288
EThaiZone's picture

อยากให้มีข้อมูลมากกว่านี้แฮะ เช่น callback หรือ product

/me กำลังเมาโค้ด


มันไม่ง่ายเลยที่จะทำ GIF ให้มีขนาดน้อยกว่า 20kB

By: lew
FounderJusci's WriterMEconomicsAndroid
on 4 September 2017 - 11:27 #1005495 Reply to:1005288
lew's picture

จริงๆ มีข้อมูลสินค้าแบบเดียวกับบัตรเครดิตครับ พวก merchant type ทั้งหลาย แต่ผมยังไม่เห็นว่ามีใครเอาไปใช้อะไร


lewcpe.com, @public_lewcpe

By: 444poon on 21 March 2019 - 00:27 #1096056

Tag29 สามารถพ่วง Ref เข้าไปได้บ้างไหมครับ นอกจากใช้ระบบเศษสตางค์

By: gift099
Windows PhoneAndroidWindowsIn Love
on 11 February 2019 - 09:02 #1096058

เรื่องเบอร์โทร กับ เลขบัตรประชาชนก็เรื่องนึง

อีกเรื่องคือ คนขาย ก็เห็นชื่อ นามสกุลของเรา ตอนที่เราจ่ายด้วย อันนี้ผมไม่ค่อยชอบนะ