500 words
3 minutes
การทำระบบรับชำระเงินผ่าน True Money Wallet

ในบทความนี้ผมจะมาพูดถึงการทำระบบชำระเงินผ่าน True Money Wallet ซึ่งจะเป็นลักษณะ webhook โดยทาง truewallet จะส่งข้อมูลมาบอกเราทุกครั้งที่มีรายการเกิดขึ้น เช่น มีการเติมเงินเข้า truewallet, มีการโอนเข้า truewallet ไม่ว่าเป็นเป็นทาง truewallet เองหรือจะเป็น promptpay ก็จะส่งข้อมูลมาบอกเราทั้งหมด

ซึ่งบริการนี้ก็มีมาตั้งแต่ปี 2022 ละ อ้างอิงจาก มีผู้ใช้งาน TrueMoney Wallet พบว่ามีฟีเจอร์ใหม่ในแอพฯ ว่าถ้าหากมีรายการรับเงิน 100 ครั้งขึ้นไป นั้นแหละตอนนั้นผมก็ได้ลองใช้งานดูก็ถือว่าใช้งานได้ดีเลยทีเดียว แต่วิธีเข้าหน้าจัดการค่อยข้างยากตั้งแต่วันนั้นถึงวันนี้ ก็ยังเหมือนเดิม แต่ตอนนี้ก็มีฟีเจอร์อื่นๆเพิ่มเติมมาด้วย จากเดิมที่แค่ webhook เท่านั้น

image.png

เงื่อนไขการใช้งาน#

การที่จะใช้ฟีเจอร์ webhook หรือ inquiry service ได้นั้น บัญชีของเราจะต้องมีรายการรับเงิน 100 รายการ และ 10 บาทต่อรายการ (ถ้ามีรายการไม่ถึง 100 รายการก็แค่ปั้มเลยสิ โอนเข้ามา 100 ครั้ง ครั้งละ 10 บาท)

วิธีเข้าหน้าจัดการ#

  • เข้าไปที่ลิ้ง https://tmn.app.link/PFCCLT ลิ้งจะเปิดแอพ truewalletและเปิดหน้าจัดการให้เลย
  • Scan QR Code ตามลิ้งด้านล่าง ผ่านแอพ truewallet ก็ได้เหมือนกัน

image.png

เอกสารคู่มือการใช้งาน Webhook API#

เอกสารคู่มือการใช้งานนี้ก็เอามาจากทาง truewallet นั้นแหละ ถ้ามีการอัพเดตก็ต้องดูที่ทางแอพนะ จะได้เป็นตัวล่าสุดแต่ปัจจุบันตอนที่เขียนจะเป็นตามนี้

  1. ผู้ใช้จะได้รับข้อมูล Response Data เป็นแบบ Json
{
"message": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJldmVudF90eXBlIjoiUDJQIiwicmVjZWl2ZWRfdGltZSI6IjIwMjItMDEtMzFUMTM6MDI6MjMrMDcwMCIsImFtb3VudCI6MTAwMDAsInNlbmRlcl9tb2JpbGUiOiIwMTIzNDU2Nzg5IiwibWVzc2FnZSI6IiIsImlhdCI6MTY1MzUzODc5M30.wb-4vOY6ASVl3nVlALC0y1TIl-Gs0XEk5AqYdqtoFz0"
}
  1. ผู้ใช้งานสามารถนำข้อมูลของ message (JWT web token) ไปใช้ได้โดยการ Decode Base64
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJldmVudF90eXBlIjoiUDJQIiwicmVjZWl2ZWRfdGltZSI6IjIwMjItMDEtMzFUMTM6MDI6MjMrMDcwMCIsImFtb3VudCI6MTAwMDAsInNlbmRlcl9tb2JpbGUiOiIwMTIzNDU2Nzg5IiwibWVzc2FnZSI6IiIsImlhdCI6MTY1MzUzODc5M30.wb-4vOY6ASVl3nVlALC0y1TIl-Gs0XEk5AqYdqtoFz0

โดยข้อมูลแบ่งออกเป็น 3 ส่วนตามสี ดังนี้

HEADER (Decode ได้ด้วย Base64)

{
"alg": "HS256",
"typ": "JWT",
}

PAYLOAD (Decode ได้ด้วย Base64)

{
"event_type": "P2P",
"received_time": "2022-01-31T13:02:23+0700",
"amount": 10000,
"sender_mobile": "0123456789",
"message": "ค่าไอเทม",
"iat": 1653538793
}

VERIFY SIGNATURE (ALG HS256)

wb-4vOY6ASVl3nVlALC0y1TIl-Gs0XEk5AqYdqtoFz0

ด้วย Secret

018db5a1098fde137da6856eab3d26d7

หมายเหตุ*

สามารถนำ message ไปตรวจสอบได้ที่ URL : https://jwt.io/ และ JWT Verify Signature ของคุณสามารถดูได้จากรูปด้านล่าง ซึ่งจากข้อมูลตัวอย่างนี้ JWT Verify Signature คือ “018db5a1098fde137da6856eab3d26d7

Example Lib for work with Json web token https://www.npmjs.com/package/jsonwebtoken

รายละเอียดข้อมูล “รับเงิน”#

(โอนเงินจากวอลเล็ท, รับเงินจากลิงก์รับเงิน)

  1. ในกรณี รับเงินโอนเงินจากวอลเล็ท

PAYLOAD (Decode ได้ด้วย Base64)

{
"event_type": "P2P",
"received_time": "2022-01-31T13:02:23+0700",
"amount": 10000,
"sender_mobile": "",
"message": "ค่าไอเทม",
"channel": ""
}

ในกรณี รับเงินโอนเงินจากวอลเล็ท ข้อมูลในส่วนของ

  • received_time: เวลาที่ได้รับเงินโอนจากวอลเล็ท
  • amount: จำนวนเงินโดยมีหน่วยเป็นสตางค์
  • sender_mobile: ข้อมูลคนที่ส่งเงิน
  • message: ข้อความที่ทางผู้โอนเงินเขียนมาให้
  • channel: จะส่งข้อมูลเป็น empty string ไปให้
  1. ในกรณี รับเงินจากลิงก์รับเงิน

PAYLOAD (Decode ได้ด้วย Base64)

{
"event_type": "MONEY_LINK",
"received_time": "2022-01-31T13:02:23+0700",
"amount": 10000,
"sender_mobile": "0123456789",
"message": "",
"channel": ""
}

ในกรณี รับเงินจากลิงก์รับเงิน ข้อมูลในส่วนของ

  • received_time: เวลาที่ได้รับเงินโอนจากวอลเล็ท
  • amount: จำนวนเงินโดยมีหน่วยเป็นสตางค์
  • sender_mobile: ข้อมูลคนที่ส่งเงิน
  • message: จะส่งข้อมูลเป็น empty string ไปให้
  • channel: จะส่งข้อมูลเป็น empty string ไปให้

รายละเอียดข้อมูล “เติมเงิน”#

(เติมจากร้านค้า, ธนาคาร, พร้อมเพย์)

  1. ในกรณี เติมจากร้านค้า, ธนาคาร

PAYLOAD (Decode ได้ด้วย Base64)

{
"event_type": "DIRECT_TOPUP",
"received_time": "2022-01-31T13:02:23+0700",
"amount": 10000,
"sender_mobile": "0811111111",
"message": "",
"channel": "7-Eleven"
}

ในกรณี เติมจากร้านค้า, ธนาคาร ข้อมูลในส่วนของ

  • received_time: เวลาที่เติมจากร้านค้า, ธนาคาร
  • amount: จำนวนเงินโดยมีหน่วยเป็นสตางค์
  • sender_mobile: ข้อมูลคนที่ส่งเงิน
  • message: จะส่งข้อมูลเป็น empty string ไปให้
  • channel: ช่องทางการเติมเงิน ตัวอย่างข้อมูล “7-Eleven”
  1. ในกรณี เติมจากพร้อมเพย์

PAYLOAD (Decode ได้ด้วย Base64)

{
"event_type": "PROMPTPAY_IN",
"received_time": "2022-01-31T13:02:23+0700",
"amount": 10000,
"sender_mobile": "0123456789",
"message": "",
"channel": ""
}

ในกรณี พร้อมเพย์ ข้อมูลในส่วนของ

  • received_time: เวลาที่ได้รับเงินจากพร้อมเพย์
  • amount: จำนวนเงินโดยมีหน่วยเป็นสตางค์
  • sender_mobile: ข้อมูลคนที่ส่งเงิน
  • message: จะส่งข้อมูลเป็น empty string ไปให้
  • channel: จะส่งข้อมูลเป็น empty string ไปให้

Flow การทำงาน#

image.png

จากรูป flow ก็จะเห็นว่าเราไม่ได้ส่ง request ไปที่ truewallet เลย แต่จะเป็นทาง truewallet ที่จะส่งมาหาเราเอง ถ้ามี event เกิดขึ้น

ตัวอย่างโค้ด PHP#

ตรงนี้ก็จะเป็นแค่ตัวอย่างเท่านั้น โดยจะมีอยู่ 2 ไฟล์

  • index.php คือหน้า UI ที่จะแสดง QR CODE ให้ลูกค้าแสกน
  • webhook.php คือ url endpoint ที่จะเอาไปใส่ในแอพ เพื่อที่จะให้ truewallet ส่งข้อมูลมาให้เรา

library ที่จะใช้งาน

index.php

<script src="https://cdn.jsdelivr.net/npm/promptparse"></script>
<script>
;(function () {
// Generate QR code payload (use function from "promptparse" global)
const payload = promptparse.generate.trueMoney({
mobileNo: '08xxxxxxxx',
amount: 10.0,
message: 'INV1234',
})
// Quick & dirty way to show QR Code image
document.write(
`<img src="https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${payload}">`,
)
})()
</script>

webhook.php

<?php
require_once 'vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
header('Accept: application/json');
header('Content-Type: application/json');
try {
$key = 'fb7xxxxxxxxxxxxxxxxxxxxxxxxx'; // key ที่ได้หลังจากกรอก url endpoint
$request = json_decode(file_get_contents('php://input'), true);
$jwt = $request['message'];
$data = JWT::decode($jwt, new Key($key, 'HS256'));
$event_type = $data->event_type;
$invoice = $data->message;
$amount = $data->amount;
switch ($event_type) {
case 'P2P':
// if ($amount == $order_amount) {
// $sql = "UPDATE `orders` SET `status`='success' WHERE `invoice`='$invoice'"
// }
// ตรงนี้แล้วแต่จะเขียนเลยว่าอยากจะทำอะไรต่อ
break;
case 'MONEY_LINK':
// if ($amount == $order_amount) {
// $sql = "UPDATE `orders` SET `status`='success' WHERE `invoice`='$invoice'"
// }
// ตรงนี้แล้วแต่จะเขียนเลยว่าอยากจะทำอะไรต่อ
break;
case 'DIRECT_TOPUP':
// if ($amount == $order_amount) {
// $sql = "UPDATE `orders` SET `status`='success' WHERE `invoice`='$invoice'"
// }
// ตรงนี้แล้วแต่จะเขียนเลยว่าอยากจะทำอะไรต่อ
break;
case 'PROMPTPAY_IN':
// if ($amount == $order_amount) {
// $sql = "UPDATE `orders` SET `status`='success' WHERE `invoice`='$invoice'"
// }
// ตรงนี้แล้วแต่จะเขียนเลยว่าอยากจะทำอะไรต่อ
break;
default:
echo json_encode([
'message' => 'error'
]);
exit();
break;
}
echo json_encode([
'message' => 'complate'
]);
} catch (\Throwable $th) {
echo json_encode([
'message' => $th->getMessage()
]);
}
การทำระบบรับชำระเงินผ่าน True Money Wallet
https://blog.0x01code.me/posts/true-money-wallet-webhook/
Author
0x01code
Published at
2025-01-26
License
CC BY-NC-SA 4.0