เช็คสลิปโอนเงินด้วย PHP ต่อ API ตรวจสลิปในร้านของคุณ

ร้านที่รับโอนเงินหลายสิบออเดอร์ต่อวัน เปิดแอปธนาคารเทียบสลิปทีละใบไม่ทัน บทความนี้พาต่อระบบหลังร้านที่เขียนด้วย PHP เข้ากับ Checkslip API ให้ระบบเช็คสลิปกับธนาคารเองทุกออเดอร์ ลูกค้าอัปโหลดสลิป ระบบได้ผลจากธนาคารภายในไม่กี่วินาที แล้วร้านตัดสินใจยืนยันออเดอร์จากข้อมูลนั้น

สิ่งที่ต้องมีก่อนเริ่ม
- PHP 7.4 ขึ้นไป ที่เปิด curl (เว็บโฮสติ้งทั่วไปเปิดไว้แล้ว)
- API key ของ Checkslip สมัครแล้วออก key ได้ที่หน้า API key ตาม เริ่มต้นใช้งาน บัญชีใหม่ได้เครดิตทดลองฟรี
- เก็บ key ไว้ในตัวแปรสภาพแวดล้อม CHECKSLIP_API_KEY บนเซิร์ฟเวอร์ ห้ามใส่ในโค้ดหน้าเว็บ
ขั้นที่ 1: ส่งรูปสลิปไปเช็คกับธนาคาร
ฟังก์ชันนี้รับไฟล์สลิปที่ลูกค้าอัปโหลด ส่งไปที่ API แล้วคืนคำตอบเป็น array
<?php
function checkslip_lookup(string $imagePath, string $idempotencyKey): array
{
$ch = curl_init('https://api.checkslip.com/api/slips/lookup');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CHECKSLIP_API_KEY'),
'Idempotency-Key: ' . $idempotencyKey,
],
CURLOPT_POSTFIELDS => ['image' => new CURLFile($imagePath)],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($body === false) {
throw new RuntimeException('เชื่อมต่อ API ไม่ได้ ให้ส่งซ้ำด้วย Idempotency-Key เดิม');
}
$data = json_decode($body, true) ?? [];
$data['_http_status'] = $status;
return $data;
}รูปที่ส่งต้องเป็น JPEG, PNG หรือ WebP ขนาดไม่เกิน 10 MB และไม่เกิน 50 ล้านพิกเซล รูป HEIC (ค่าเริ่มต้นของกล้อง iPhone), GIF และ PDF จะได้ 422 invalid-file และไม่หักเครดิต ส่วนรูปที่ใหญ่เกิน 10 MB ได้ 413 ถ้าลูกค้าส่งรูปจาก iPhone ให้แปลงเป็น JPEG ก่อนส่ง
ถ้าอ่านข้อความใน QR บนสลิปไว้แล้ว ส่ง QR แทนรูปได้ เปลี่ยน CURLOPT_POSTFIELDS เป็น json_encode(['qr' => $qrText]) และเพิ่ม header Content-Type: application/json
ขั้นที่ 2: ตัดสินจากผลที่ได้
ให้ดู outcome ใน body ไม่ใช่ HTTP status ผลที่ร้านใช้บ่อยมี 3 แบบ:
- FOUND: พบรายการ ธนาคารมีรายการโอนนี้ ระบบหัก 1 เครดิต
- NOT_FOUND: ไม่พบรายการ ณ เวลาที่ถาม ไม่หักเครดิต
- DUPLICATE: บัญชีของร้านเคยเช็คสลิปใบนี้แล้ว ไม่หักเครดิต
ผลอื่น เช่น PENDING (รอธนาคาร) และความหมายของทุกผล ดูได้ที่ ผลตรวจรายการโอน
ขั้นที่ 3: เทียบกับออเดอร์ก่อนยืนยัน
ผล FOUND บอกว่าธนาคารมีรายการนี้ ร้านยังต้องเทียบยอดเงินและบัญชีผู้รับกับออเดอร์เอง ยอดเงินมาเป็นสตางค์ (5000 = 50 บาท) และบัญชีผู้รับมาเป็นเลข 4 หลักท้าย
<?php
function decide_order(array $result, int $orderSatang, string $shopAccountLast4): string
{
switch ($result['outcome'] ?? '') {
case 'FOUND':
$slip = $result['slip'];
if ($slip['amount']['satang'] !== $orderSatang) {
return 'ยอดไม่ตรงกับออเดอร์';
}
if (($slip['receiver']['account'] ?? '') !== $shopAccountLast4) {
return 'โอนเข้าบัญชีอื่น';
}
return 'ยืนยันออเดอร์ได้';
case 'DUPLICATE':
return 'สลิปนี้เคยใช้กับร้านแล้ว ดูออเดอร์เดิมจาก duplicate_of.request_id';
case 'NOT_FOUND':
return 'ไม่พบรายการ ขอหลักฐานเพิ่มจากลูกค้า';
case 'PENDING':
return 'รอธนาคาร ระบบจะส่งผลทาง webhook';
default:
return 'เช็คไม่ได้ ดูรายละเอียดใน type ของคำตอบ';
}
}
$result = checkslip_lookup($_FILES['slip']['tmp_name'], 'order-1042-slip-1');
echo decide_order($result, 5000, '9681');ใช้ Idempotency-Key ให้ถูก
ตั้ง Idempotency-Key ให้ผูกกับออเดอร์และสลิปใบนั้น เช่น order-1042-slip-1 ถ้าเน็ตหลุดก่อนได้คำตอบ ส่งคำขอเดิมซ้ำด้วยคีย์เดิม จะได้คำตอบเดิมกลับมาและไม่หักเครดิตเพิ่ม ถ้าส่งซ้ำด้วยคีย์ใหม่ ครั้งที่สองจะได้ DUPLICATE แล้วโค้ดอาจเข้าใจผิดว่าลูกค้าใช้สลิปซ้ำ
ใช้กับ WordPress ได้ไหม?
ได้ ฟังก์ชันข้างบนเป็น PHP ธรรมดา วางในปลั๊กอินหรือ functions.php ของธีม แล้วเรียกตอนลูกค้าอัปโหลดสลิปในหน้าชำระเงิน ใช้ wp_handle_upload รับไฟล์ก่อน แล้วส่ง path ของไฟล์ให้ checkslip_lookup
ต่อจากนี้
- อ่านว่า API ทำงานยังไงทั้งระบบ: API ตรวจสลิปโอนเงินทำงานยังไง?
- ตัวอย่าง cURL, Node.js และ Python อยู่ใน เริ่มต้นใช้งาน
- ร้านที่ยังไม่ต่อระบบ อ่าน เช็คสลิปโอนเงินกับธนาคาร: คู่มือสำหรับร้านค้า