ข้างใน QR พร้อมเพย์ และ QR บนสลิปที่ไม่มียอดเงิน
ทดลองอะไร
สร้าง QR พร้อมเพย์ของหน้า /support เองทั้งเส้นตามมาตรฐาน Thai QR Payment โดยไม่ผ่าน gateway แล้วถอดมันออกทีละช่องในใบนี้ · ข้อความใน QR คือช่องแบบ TLV ต่อกัน (เลข tag 2 หลัก ความยาว 2 หลัก แล้วตามด้วยค่า) ปิดท้ายด้วย CRC16 · ตารางในใบแตกตัวอย่างทดสอบออกเป็นแถว ชี้แถวไหนก็เห็นว่าช่องนั้นอยู่ตรงไหนของข้อความ และแก้ข้อความเองได้ · ครึ่งหลังทำแบบเดียวกันกับ QR เล็กมุมสลิปโอนเงิน เลือกภาพสลิปของตัวเองมาถอดในเครื่องได้ แล้วส่งเฉพาะข้อความใน QR ให้เซิร์ฟเวอร์ตรวจ
QR พร้อมเพย์
ข้อความใน QR
00020101021129370016A000000677010111011300668123456785802TH530376463045D82
| tag | ยาว | ค่า | |
|---|---|---|---|
| 00 | 02 | 01รุ่นของรูปแบบข้อมูล — 01 เสมอ | รุ่นของรูปแบบข้อมูล — 01 เสมอ |
| 01 | 02 | 1111 = QR ใช้ซ้ำได้ · 12 = ใช้ครั้งเดียว ล็อกยอด | 11 = QR ใช้ซ้ำได้ · 12 = ใช้ครั้งเดียว ล็อกยอด |
| 29 | 37 | 0016A00000067701011101130066812345678บัญชีผู้รับแบบพร้อมเพย์โอนเงิน — ค่าข้างในเป็น TLV ซ้อนอีกชั้น | บัญชีผู้รับแบบพร้อมเพย์โอนเงิน — ค่าข้างในเป็น TLV ซ้อนอีกชั้น |
| 29.00 | 16 | A000000677010111รหัสแอปพลิเคชันของพร้อมเพย์โอนเงิน — ค่าตายตัวจาก ธปท. | รหัสแอปพลิเคชันของพร้อมเพย์โอนเงิน — ค่าตายตัวจาก ธปท. |
| 29.01 | 13 | 0066812345678เบอร์มือถือ: 0066 แทน 0 ตัวหน้า | เบอร์มือถือ: 0066 แทน 0 ตัวหน้า |
| 58 | 02 | THประเทศ | ประเทศ |
| 53 | 03 | 764สกุลเงิน — 764 คือบาท | สกุลเงิน — 764 คือบาท |
| 63 | 04 | 5D82CRC16 ของทุกตัวอักษรก่อนหน้า รวม 6304 ของตัวเอง | CRC16 ของทุกตัวอักษรก่อนหน้า รวม 6304 ของตัวเอง |
CRC ตรง — คำนวณจากทุกตัวอักษรก่อนหน้าได้ 5D82 ตรงกับที่เขียนไว้
ลองแก้ตัวเลขสักตัว แล้วดูบรรทัด CRC ด้านล่าง
QR บนสลิป
QR เล็กมุมสลิปโอนเงินมีแค่ธนาคารผู้โอนกับเลขอ้างอิง — ไม่มียอด ไม่มีชื่อผู้รับ ไม่มีเวลา · เลือกภาพสลิปของตัวเองมาถอดได้ ภาพถูกอ่านในเครื่องนี้ ไม่ถูกส่งไปไหน
ตัวอย่างจากเอกสารอ้างอิง (ธนาคาร 002)
ข้อความใน QR
004000060000010103002021900021231231212000115102TH91049C30
| tag | ยาว | ค่า | |
|---|---|---|---|
| 00 | 40 | 0006000001010300202190002123123121200011ข้อมูลสลิป — ค่าข้างในเป็น TLV ซ้อน | ข้อมูลสลิป — ค่าข้างในเป็น TLV ซ้อน |
| 00.00 | 06 | 000001รหัส API ตรวจสลิป — 000001 | รหัส API ตรวจสลิป — 000001 |
| 00.01 | 03 | 002 → BBLรหัสธนาคารผู้โอนตามทะเบียน ธปท. | รหัสธนาคารผู้โอนตามทะเบียน ธปท. |
| 00.02 | 19 | 0002123123121200011เลขอ้างอิงรายการ — มีไว้ให้ไปถามธนาคาร ไม่ได้บอกยอด | เลขอ้างอิงรายการ — มีไว้ให้ไปถามธนาคาร ไม่ได้บอกยอด |
| 51 | 02 | THประเทศ | ประเทศ |
| 91 | 04 | 9C30CRC16 สูตรเดียวกับ tag 63 ของพร้อมเพย์ | CRC16 สูตรเดียวกับ tag 63 ของพร้อมเพย์ |
CRC ตรง — คำนวณจากทุกตัวอักษรก่อนหน้าได้ 9C30 ตรงกับที่เขียนไว้
ส่งตัวอย่างนี้ให้เซิร์ฟเวอร์ตรวจไม่ได้ — ตัวตรวจกันเลขอ้างอิงซ้ำ ใครกดก่อนก็เผาเลขของตัวอย่างทิ้ง · ลองกับสลิปของตัวเองแทน
ได้เรียนรู้อะไร
ข้อแรกมาจากเลขที่ไม่ตรงกัน · ค่าทดสอบในเอกสารอ้างอิงของ QR ไม่ระบุยอดลงท้ายด้วย CRC 823E แต่ตัวสร้างของเว็บนี้ได้ 5D82 จากเบอร์เดียวกัน · ไล่ดูแล้วไม่มีใครผิด: ไลบรารี promptparse วางช่องสกุลเงิน (53) ก่อนช่องประเทศ (58) ส่วน promptpay-qr กับเว็บนี้วางกลับกัน มาตรฐานไม่บังคับลำดับ แต่ CRC คำนวณจากตัวอักษรเรียงตามที่วางจริง ลำดับต่างจึงได้ CRC ต่าง แล้วถูกทั้งคู่ · ตัวอย่างยอด 30 ในใบก็เป็นแบบนั้น (C3C0 กับ 42EB) ถอดออกมาได้ค่าเดียวกันทุกช่อง ⇒ การเทียบ QR ต้องเทียบหลังแตกช่อง ไม่ใช่เทียบสตริง · ข้อสองคือ QR บนสลิปไม่มียอดเงิน ไม่มีชื่อผู้รับ ไม่มีเวลา มีแค่รหัสธนาคารผู้โอนกับเลขอ้างอิง การตรวจเองจึงไปได้สุดแค่ "รูปแบบถูก" ซึ่งใครก็ปลอมได้เพราะสูตร CRC เปิด แผงตรวจสลิปจึงย้ายออกจากหน้ารับเงินมาอยู่ที่นี่ · ข้อสามคือการปิดเลขผู้รับบนจอเป็นแค่หน้าตา QR ต้องฝังเลขเต็มเสมอ ใครสแกนก็เห็น เลขที่ตั้งให้หน้ารับเงินจึงต้องเป็นเลขที่ยอมให้คนเห็นได้ตั้งแต่แรก · ยันด้วยการแคป QR จากหน้า /support จริงแล้วถอดภาพกลับด้วย jsQR ได้เบอร์ทดสอบครบและ CRC ผ่าน ส่วน QR ยอด 30 ที่หน้าสร้างตรงกับผลของ promptpay-qr ทุกตัวอักษร
ที่ยังไม่ถึง
ยังไม่ได้สแกนด้วยแอปธนาคารจริงแม้แต่แอปเดียว — สิ่งที่ยันได้คือข้อความใน QR ตรงกับไลบรารีอ้างอิงสองตัว ไม่ใช่ว่าแอปธนาคารรับมันจริง · ระดับ "ธนาคารยืนยัน" ของตัวตรวจสลิปยังไม่เคยทำงานจริง เพราะต้องมีคีย์ของบริการตรวจสลิปแบบเสียเงิน ทางนั้นมีอยู่ในโค้ดแต่ทดสอบกับคำตอบปลอมเท่านั้น · บุคคลทั่วไปยังยืนยันเงินเข้าเองฟรีด้วยโค้ดไม่ได้ (API ของธนาคารเปิดให้นิติบุคคล) · และ QR สลิปของแต่ละธนาคารอาจหน้าตาต่างกัน เช่นตัวอย่างของ SCB ที่ CRC มีแค่ 3 หลัก โค้ดเติม 0 ข้างหน้าให้แล้วบอกว่าซ่อม แต่ทดสอบกับตัวอย่างสังเคราะห์เท่านั้น ยังไม่ได้ลองกับสลิปจริงครบทุกธนาคาร