TrueMoney Wallet
รับชำระเงินออนไลน์จากหนึ่งใน e-wallet ที่ได้รับความนิยมมากที่สุดในไทย มีผู้ใช้งานมากกว่า 30 ล้านคน ลูกค้าจะถูก redirect ไปกรอกเบอร์โทรศัพท์และยืนยันตัวตนด้วย OTP
- การเปลี่ยนเส้นทางแบบแอปต่อแอป: สำหรับแอปมือถือที่มี deep link ไปยัง TrueMoney ดู TrueMoney Jump App
- การชำระเงินด้วย QR code: สำหรับการชำระเงินแบบออฟไลน์ผ่าน QR code ดู TrueMoney QR
หน้านี้อธิบายเกี่ยวกับขั้นตอนการ redirect แบบออนไลน์ที่ใช้ OTP
ขั้นตอนการชำระเงิน

ภาพด้านบนแสดงขั้นตอนการชำระเงินแบบ redirect ที่สมบูรณ์โดยใช้การยืนยันตัวตนด้วย OTP (one-time password)
ภาพรวม
จำนวนผู้ใช้เป็นค่าประมาณและอิงจากข้อมูลที่เปิดเผยต่อสาธารณะ จำนวนผู้ใช้งานจริงอาจแตกต่างกันไป
TrueMoney Wallet เป็นโซลูชันการชำระเงินผ่านมือถือชั้นนำในไทย มีผู้ใช้งานมากกว่า 30 ล้านคน กระเป๋าเงินนี้ช่วยให้ลูกค้าสามารถชำระเงินโดยใช้หมายเลขโทรศัพท์มือถือพร้อมการยืนยันตัวตนด้วย OTP เพื่อความปลอดภัยที่เพิ่มขึ้น
คุณสมบัติหลัก:
- ✅ ฐานผู้ใช้ขนาดใหญ่ - ผู้ใช้งานมากกว่า 30 ล้านคนในไทย
- ✅ ขั้นตอนที่เรียบง่าย - หมายเลขโทรศัพท์ + การยืนยันตัวตนด้วย OTP
- ✅ การชำระบัญชีที่รวดเร็ว - เร็วกว่าธนาคารแบบดั้งเดิม
- ✅ มือถือเป็นหลัก - ปรับแต่งสำหรับผู้ใช้สมาร์ทโฟน
- ✅ แบรนด์ที่เชื่อถือได้ - เป็นส่วนหนึ่งของ Ascend Group (กลุ่มซีพี)
ภูมิภาคที่รองรับ
| Region | Currency | Min Amount | Max Amount | API Version |
|---|---|---|---|---|
| Thailand | THB | ฿20.00 | ฿100,000.00 | 2017-11-02 |
ข้อจำกัดการทำรายการตามระดับการยืนยันตัวตน
| ระดับการยืนยันตัวตน | ต่อรายการ | วงเงินต่อวัน | วงเงินต่อเดือน |
|---|---|---|---|
| Basic (เบอร์โทรศัพท์อย่างเดียว) | ฿100,000 | ฿40,000 | ฿200,000 |
| Plus (บัตรประชาชน) | ฿100,000 | ฿100,000 | ฿500,000 |
| Premium (บัญชีธนาคาร) | ฿100,000 | ฿200,000 | ไม่จำกัด |
วิธีการทำงาน
ประสบการณ์ลูกค้า:
- ลูกค้าเลือก TrueMoney ที่หน้าชำระเงิน
- กรอกหมายเลขโทรศัพท์มือถือ
- รับ OTP ผ่าน SMS
- กรอก OTP เพื่ออนุมัติ
- ยืนยันจำนวนเงินที่ชำระ
- กลับไปยังเว็บไซต์ผู้ค้า
การใช้งาน
ขั้นตอนที่ 1: สร้าง TrueMoney Source
- cURL
- Node.js
- PHP
- Python
curl https://api.omise.co/sources \
-u skey_test_YOUR_SECRET_KEY: \
-d "type=truemoney" \
-d "amount=50000" \
-d "currency=THB" \
-d "phone_number=+66876543210"
const omise = require('omise')({
secretKey: 'skey_test_YOUR_SECRET_KEY'
});
const source = await omise.sources.create({
type: 'truemoney',
amount: 50000, // THB 500.00
currency: 'THB',
phone_number: '+66876543210'
});
<?php
$source = OmiseSource::create(array(
'type' => 'truemoney',
'amount' => 50000,
'currency' => 'THB',
'phone_number' => '+66876543210'
));
?>
import omise
omise.api_secret = 'skey_test_YOUR_SECRET_KEY'
source = omise.Source.create(
type='truemoney',
amount=50000,
currency='THB',
phone_number='+66876543210'
)
ผลลัพธ์:
{
"object": "source",
"id": "src_test_5rt6s9vah5lkvi1rh9c",
"type": "truemoney",
"flow": "redirect",
"amount": 50000,
"currency": "THB",
"phone_number": "+66876543210"
}
ขั้นตอนที่ 2: สร้าง Charge
curl https://api.omise.co/charges \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=50000" \
-d "currency=THB" \
-d "source=src_test_5rt6s9vah5lkvi1rh9c" \
-d "return_uri=https://yourdomain.com/payment/callback"
ขั้นตอนที่ 3: Redirect ลูกค้า
app.post('/create-truemoney-payment', async (req, res) => {
// Create source
const source = await omise.sources.create({
type: 'truemoney',
amount: req.body.amount,
currency: 'THB',
phone_number: req.body.phone_number
});
// Create charge
const charge = await omise.charges.create({
amount: req.body.amount,
currency: 'THB',
source: source.id,
return_uri: 'https://yourdomain.com/payment/callback',
metadata: {
order_id: req.body.order_id
}
});
// Redirect customer
res.redirect(charge.authorize_uri);
});
ขั้นตอนที่ 4: จัดการ Return
app.get('/payment/callback', async (req, res) => {
const chargeId = req.query.charge_id;
// Retrieve charge status
const charge = await omise.charges.retrieve(chargeId);
if (charge.status === 'successful') {
// Payment successful
await processOrder(charge.metadata.order_id);
res.redirect('/payment-success');
} else if (charge.status === 'failed') {
// Payment failed
res.redirect('/payment-failed?reason=' + charge.failure_message);
} else {
// Still pending
res.redirect('/payment-pending');
}
});
ขั้นตอนที่ 5: จัดการ Webhook
app.post('/webhooks/omise', (req, res) => {
const event = req.body;
if (event.key === 'charge.complete' && event.data.source.type === 'truemoney') {
const charge = event.data;
if (charge.status === 'successful') {
processOrder(charge.metadata.order_id);
}
}
res.sendStatus(200);
});
ตัวอย่างการใช้งานแบบสมบูรณ์
// Express.js server
const express = require('express');
const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY
});
const app = express();
app.use(express.json());
// Checkout page
app.post('/checkout/truemoney', async (req, res) => {
try {
const { amount, phone_number, order_id } = req.body;
// Validate phone number format
if (!/^\+66\d{9}$/.test(phone_number)) {
return res.status(400).json({
error: 'Invalid phone number. Use format: +66876543210'
});
}
// Check amount limits
if (amount < 2000 || amount > 10000000) {
return res.status(400).json({
error: 'Amount must be between ฿20 and ฿100,000'
});
}
// Create source
const source = await omise.sources.create({
type: 'truemoney',
amount: amount,
currency: 'THB',
phone_number: phone_number
});
// Create charge
const charge = await omise.charges.create({
amount: amount,
currency: 'THB',
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/callback`,
metadata: {
order_id: order_id,
customer_phone: phone_number
}
});
// Return authorization URL
res.json({
authorize_uri: charge.authorize_uri,
charge_id: charge.id
});
} catch (error) {
console.error('TrueMoney payment error:', error);
res.status(500).json({ error: error.message });
}
});
// Callback handler
app.get('/payment/callback', async (req, res) => {
try {
const chargeId = req.query.charge_id;
const charge = await omise.charges.retrieve(chargeId);
if (charge.status === 'successful') {
res.redirect(`/order-success?order=${charge.metadata.order_id}`);
} else {
res.redirect(`/payment-failed?charge=${chargeId}`);
}
} catch (error) {
res.redirect('/payment-error');
}
});
// Webhook handler
app.post('/webhooks/omise', (req, res) => {
const event = req.body;
if (event.key === 'charge.complete') {
const charge = event.data;
if (charge.source.type === 'truemoney') {
if (charge.status === 'successful') {
// Process order
updateOrderStatus(charge.metadata.order_id, 'paid');
sendConfirmation(charge.metadata.customer_phone);
} else {
// Handle failure
updateOrderStatus(charge.metadata.order_id, 'failed');
}
}
}
res.sendStatus(200);
});
app.listen(3000);
การรองรับ Void และการคืนเงิน
การยกเลิก Charge
TrueMoney รองรับการยกเลิกภายใน 24 ชั่วโมง หลังจากสร้าง charge:
// Void immediately (full or partial)
const refund = await omise.charges.refund('chrg_test_...', {
amount: 50000 // Full amount
});
if (refund.voided) {
console.log('Charge was voided (within 24 hours)');
}
การคืนเงิน
คืนเงินเต็มจำนวนเท่านั้น ภายใน 30 วัน:
// Full refund only
const refund = await omise.charges.refund('chrg_test_...', {
amount: 50000 // Must be full amount
});
TrueMoney Wallet ไม่รองรับการคืนเงินบางส่วน อนุญาตเฉพาะการคืนเงินเต็มจำนวนภายใน 30 วันเท่านั้น
ปัญหาทั่วไปและการแก้ไข
ปัญหา: "หมายเลขโทรศัพท์ไม่ถูกต้อง"
สาเหตุ:
- รูปแบบไม่ถูกต้อง
- ไม่มีรหัสประเทศ
- หมายเลขต่างประเทศ
วิธีแก้:
function validateThaiPhone(phone) {
// Accept formats: +66876543210, 0876543210
let normalized = phone.replace(/\s/g, '');
if (normalized.startsWith('0')) {
normalized = '+66' + normalized.substring(1);
}
if (!/^\+66\d{9}$/.test(normalized)) {
throw new Error('Invalid Thai phone number');
}
return normalized;
}
ปัญหา: ลูกค้าเกินวงเงินต่อวัน
ข้อผิดพลาด: รายการถูกปฏิเสธ
วิธีแก้:
- ลูกค้าต้องอัปเกรดการยืนยันตัวตนบัญชี TrueMoney
- แบ่งการชำระเงินเป็นหลายวัน
- ใช้วิธีการชำระเงินทางเลือก
ปัญหา: การชำระเงินค้างนานเกินไป
สาเหตุ: ลูกค้าไม่ได้ทำการยืนยัน OTP ให้เสร็จสิ้น
วิธีแก้:
- ตั้งค่าหมดเวลา 15-20 นาที
- อนุญาตให้ลูกค้าลองใหม่ด้วย charge ใหม่
- แสดงคำแนะนำที่ชัดเจน
ปัญหา: Return URI ไม่ถูกเรียก
สาเหตุ: ลูกค้าปิดเบราว์เซอร์
วิธีแก้:
- ใช้งานการจัดการ webhook (เชื่อถือได้มากกว่า)
- จัดให้มีหน้าตรวจสอบสถานะคำสั่งซื้อ
- ส่ง SMS ยืนยันให้ลูกค้า
แนวทางปฏิบัติที่ดีที่สุด
1. ตรวจสอบหมายเลขโทรศัพท์
const phoneRegex = /^\+66[0-9]{9}$/;
if (!phoneRegex.test(phoneNumber)) {
return res.status(400).json({
error: 'Please enter a valid Thai phone number (e.g., +66876543210)'
});
}
2. แสดงคำแนะนำที่ชัดเจน
<div class="truemoney-instructions">
<h3>ชำระเงินด้วย TrueMoney Wallet</h3>
<ol>
<li>กรอกหมายเลขโทรศัพท์ที่ลงทะเบียนกับ TrueMoney</li>
<li>คุณจะได้รับ OTP ผ่าน SMS</li>
<li>กรอก OTP เพื่ออนุมัติการชำระเงิน</li>
<li>ยืนยันจำนวนเงิน</li>
</ol>
<p>ตรวจสอบให้แน่ใจว่าคุณมียอดเงินเพียงพอใน TrueMoney Wallet ของคุณ</p>
</div>
3. จัดการหมดเวลา
// Set reasonable timeout
setTimeout(() => {
if (!paymentConfirmed) {
showTimeoutMessage();
allowRetry();
}
}, 15 * 60 * 1000); // 15 minutes
4. ใช้ Webhook
อย่าพึ่งพา redirect callback เพียงอย่างเดียว:
// Webhook is more reliable
app.post('/webhooks/omise', handleWebhook);
// Callback is backup
app.get('/payment/callback', handleCallback);