ข้ามไปยังเนื้อหาหลัก

TrueMoney QR

รับชำระเงินผ่าน QR Code แบบออฟไลน์จากผู้ใช้ TrueMoney กว่า 30 ล้านคนในประเทศไทย ลูกค้าสแกน QR Code ด้วยแอป TrueMoney และเลือกแหล่งเงินสำหรับชำระได้หลากหลายรูปแบบ

ภาพรวม

TrueMoney QR เป็นวิธีการชำระเงินแบบออฟไลน์ที่สร้าง QR Code ที่สแกนได้สำหรับให้ลูกค้าชำระเงินโดยใช้แอปมือถือ TrueMoney ต่างจากขั้นตอนการเปลี่ยนเส้นทาง (redirect) ลูกค้าจะทำการชำระเงินให้เสร็จสมบูรณ์บนโทรศัพท์ของตนเองโดยสแกน QR Code ที่แสดงบนเว็บไซต์หรือระบบขายหน้าร้านของคุณ

คุณสมบัติหลัก:

  • การชำระเงินแบบออฟไลน์ - ไม่ต้องเปลี่ยนเส้นทาง ลูกค้าสแกน QR Code
  • แหล่งเงินหลากหลาย - กระเป๋าเงิน บัตร บัญชีธนาคาร Pay Next
  • ฐานผู้ใช้ขนาดใหญ่ - ผู้ใช้ TrueMoney กว่า 30 ล้านคนในประเทศไทย
  • ยอดขั้นต่ำที่ยืดหยุ่น - ต่ำสุดที่ ฿0.01 สำหรับวิธีการชำระเงินส่วนใหญ่
  • การโอนเงินรวดเร็ว - เร็วกว่าการธนาคารแบบดั้งเดิม
  • รองรับระบบขายหน้าร้าน - ใช้งานได้ทั้งการชำระเงินในร้านและออนไลน์

ภูมิภาคที่รองรับ

ภูมิภาคสกุลเงินยอดขั้นต่ำยอดสูงสุดหมายเหตุ
ประเทศไทยTHB฿0.01*฿50,000*ยอดขั้นต่ำแตกต่างกันตามแหล่งเงิน

ยอดขั้นต่ำตามแหล่งเงิน

ลูกค้าสามารถเลือกวิธีการชำระเงินที่ต้องการเมื่อสแกน QR Code โดยแต่ละวิธีมีข้อกำหนดขั้นต่ำที่แตกต่างกัน:

แหล่งเงินยอดขั้นต่ำหมายเหตุ
ยอดเงินในกระเป๋า฿0.01เงินในกระเป๋า TrueMoney
บัตรเครดิต/เดบิต฿0.01การชำระด้วยบัตรผ่าน TrueMoney
Pay Next (ชำระเต็มจำนวน)฿0.01ซื้อเลย จ่ายภายหลัง (ยอดเต็ม)
Pay Next Extra (ชำระเต็มจำนวน)฿0.01ตัวเลือก BNPL แบบขยาย (ยอดเต็ม)
บัญชีธนาคารแตกต่างกันตามธนาคารขั้นต่ำขึ้นอยู่กับธนาคารผู้ออกบัตร
การเลือกแหล่งเงิน

เมื่อลูกค้าสแกน QR Code พวกเขาจะเลือกแหล่งเงินสำหรับชำระเงินภายในแอป TrueMoney ร้านค้าไม่สามารถควบคุมได้ว่าลูกค้าจะเลือกแหล่งเงินใด โปรดตั้งค่ายอดธุรกรรมขั้นต่ำให้รองรับทุกแหล่งเงินหรือสื่อสารข้อกำหนดขั้นต่ำให้ชัดเจน

วิธีการทำงาน

ขั้นตอนการชำระเงิน

ขั้นตอนการชำระเงิน TrueMoney QR

ประสบการณ์ของลูกค้า:

  1. ลูกค้าเลือก TrueMoney QR ที่หน้าชำระเงิน
  2. ร้านค้าแสดง QR Code บนหน้าจอ
  3. ลูกค้าเปิดแอป TrueMoney
  4. ลูกค้าสแกน QR Code
  5. ลูกค้าเลือกแหล่งเงินสำหรับชำระ (กระเป๋า/บัตร/ธนาคาร/Pay Next)
  6. ลูกค้าอนุมัติการชำระเงิน
  7. ยืนยันการชำระเงินเสร็จสมบูรณ์

การติดตั้งและใช้งาน

ขั้นตอนที่ 1: สร้าง Source ของ TrueMoney QR

curl https://api.omise.co/sources \
-u skey_test_YOUR_SECRET_KEY: \
-d "type=truemoney_qr" \
-d "amount=50000" \
-d "currency=THB"

การตอบกลับ:

{
"object": "source",
"id": "src_test_5rt6s9vah5lkvi1rh9c",
"type": "truemoney_qr",
"flow": "offline",
"amount": 50000,
"currency": "THB"
}

ขั้นตอนที่ 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"

การตอบกลับรวม QR Code:

{
"object": "charge",
"id": "chrg_test_5rt6s9vah5lkvi1rh9d",
"amount": 50000,
"currency": "THB",
"status": "pending",
"source": {
"object": "source",
"type": "truemoney_qr",
"flow": "offline",
"scannable_code": {
"object": "barcode",
"type": "qr",
"image": {
"download_uri": "https://api.omise.co/charges/chrg_test_.../documents/docu_test_.../downloads/..."
}
}
}
}

ขั้นตอนที่ 3: แสดง QR Code

app.post('/create-truemoney-qr-payment', async (req, res) => {
try {
const { amount, order_id } = req.body;

// Validate amount
if (amount < 1 || amount > 5000000) {
return res.status(400).json({
error: 'Amount must be between ฿0.01 and ฿50,000'
});
}

// Create source
const source = await omise.sources.create({
type: 'truemoney_qr',
amount: amount,
currency: 'THB'
});

// 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
}
});

// Get QR code image URL
const qrCodeUrl = charge.source.scannable_code.image.download_uri;

// Return to frontend
res.json({
charge_id: charge.id,
qr_code_url: qrCodeUrl,
amount: amount
});

} catch (error) {
console.error('TrueMoney QR payment error:', error);
res.status(500).json({ error: error.message });
}
});

การแสดงผลส่วนหน้า:

<div class="payment-container">
<h2>สแกนเพื่อชำระเงินด้วย TrueMoney</h2>
<div class="qr-code-container">
<img id="qrCode" src="" alt="TrueMoney QR Code" />
</div>
<p class="amount">ยอดชำระ: <strong>฿<span id="amount"></span></strong></p>
<div class="instructions">
<h3>วิธีการชำระเงิน:</h3>
<ol>
<li>เปิดแอป TrueMoney บนโทรศัพท์ของคุณ</li>
<li>แตะปุ่ม "สแกน QR"</li>
<li>สแกนโค้ดด้านบน</li>
<li>เลือกวิธีการชำระเงิน (กระเป๋า/บัตร/ธนาคาร/Pay Next)</li>
<li>อนุมัติการชำระเงิน</li>
</ol>
</div>
</div>

<script>
async function createPayment(amount, orderId) {
const response = await fetch('/create-truemoney-qr-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount, order_id: orderId })
});

const data = await response.json();

// Display QR code
document.getElementById('qrCode').src = data.qr_code_url;
document.getElementById('amount').textContent = (data.amount / 100).toFixed(2);

// Start polling for payment status
pollPaymentStatus(data.charge_id);
}

async function pollPaymentStatus(chargeId) {
const interval = setInterval(async () => {
const response = await fetch(`/check-payment-status/${chargeId}`);
const data = await response.json();

if (data.status === 'successful') {
clearInterval(interval);
window.location.href = '/payment-success';
} else if (data.status === 'failed') {
clearInterval(interval);
window.location.href = '/payment-failed';
}
}, 3000); // Check every 3 seconds
}
</script>

ขั้นตอนที่ 4: จัดการ Webhook

app.post('/webhooks/omise', (req, res) => {
const event = req.body;

if (event.key === 'charge.complete' && event.data.source.type === 'truemoney_qr') {
const charge = event.data;

if (charge.status === 'successful') {
// Process order
processOrder(charge.metadata.order_id);
console.log(`TrueMoney QR payment successful: ${charge.id}`);
} else if (charge.status === 'failed') {
// Handle failure
handleFailedPayment(charge.metadata.order_id, charge.failure_message);
}
}

res.sendStatus(200);
});

ตัวอย่างการติดตั้งแบบสมบูรณ์

// Express.js server with TrueMoney QR
const express = require('express');
const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY
});

const app = express();
app.use(express.json());

// Create payment and get QR code
app.post('/checkout/truemoney-qr', async (req, res) => {
try {
const { amount, order_id } = req.body;

// Validate amount
if (amount < 1 || amount > 5000000) {
return res.status(400).json({
error: 'Amount must be between ฿0.01 and ฿50,000'
});
}

// Create source
const source = await omise.sources.create({
type: 'truemoney_qr',
amount: amount,
currency: 'THB'
});

// 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,
created_at: new Date().toISOString()
}
});

// Get QR code URL
const qrCodeUrl = charge.source.scannable_code.image.download_uri;

res.json({
success: true,
charge_id: charge.id,
qr_code_url: qrCodeUrl,
amount: amount
});

} catch (error) {
console.error('TrueMoney QR error:', error);
res.status(500).json({
success: false,
error: error.message
});
}
});

// Check payment status (for polling)
app.get('/check-payment-status/:chargeId', async (req, res) => {
try {
const charge = await omise.charges.retrieve(req.params.chargeId);
res.json({
status: charge.status,
paid: charge.paid,
amount: charge.amount
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});

// Webhook handler (primary method)
app.post('/webhooks/omise', (req, res) => {
const event = req.body;

if (event.key === 'charge.complete') {
const charge = event.data;

if (charge.source.type === 'truemoney_qr') {
if (charge.status === 'successful') {
updateOrderStatus(charge.metadata.order_id, 'paid');
sendConfirmation(charge.metadata.order_id);
} else {
updateOrderStatus(charge.metadata.order_id, 'failed');
}
}
}

res.sendStatus(200);
});

app.listen(3000);

การยกเลิกและคืนเงิน

การยกเลิก Charge

TrueMoney QR รองรับการยกเลิกในวันเดียวกันเท่านั้น:

// Void same-day (full amount only)
const refund = await omise.charges.refund('chrg_test_...', {
amount: 50000 // Must be full amount
});

if (refund.voided) {
console.log('Charge was voided (same-day)');
}
การยกเลิกในวันเดียวกันเท่านั้น

การยกเลิกสามารถทำได้เฉพาะในวันเดียวกันที่สร้าง charge หลังเที่ยงคืนแล้วจะต้องใช้การคืนเงินแทน

การคืนเงิน

การคืนเงินสามารถทำได้ภายใน 30 วัน การรองรับแตกต่างกันตามแหล่งเงิน:

// Full refund (all payment methods)
const refund = await omise.charges.refund('chrg_test_...', {
amount: 50000 // Full amount
});

// Partial refund (Wallet, Bank Account, Pay Next)
const partialRefund = await omise.charges.refund('chrg_test_...', {
amount: 25000 // Half amount
});

การรองรับการคืนเงินตามแหล่งเงิน:

วิธีการชำระเงินคืนเงินเต็มจำนวนคืนเงินบางส่วนระยะเวลา
ยอดเงินในกระเป๋า✅ ได้✅ ได้ภายใน 30 วัน
บัญชีธนาคาร✅ ได้✅ ได้ภายใน 30 วัน
Pay Next✅ ได้✅ ได้ภายใน 30 วัน
Pay Next Extra✅ ได้✅ ได้ภายใน 30 วัน
บัตรเครดิต/เดบิต✅ ได้ (วันถัดไป+)❌ ไม่ได้ภายใน 30 วัน
การคืนเงินบัตรเครดิต/เดบิต

การชำระด้วยบัตรรองรับเฉพาะการคืนเงินเต็มจำนวน และหลังวันทำธุรกรรม (วันถัดไปเป็นต้นไป) เท่านั้น ไม่รองรับการคืนเงินบัตรในวันเดียวกัน

ปัญหาที่พบบ่อยและการแก้ไข

ปัญหา: QR Code ไม่แสดงผล

สาเหตุ:

  • URL ของภาพไม่ถูกต้อง
  • ข้อจำกัดของ CORS
  • ปัญหาเครือข่าย

วิธีแก้ไข:

// Add error handling for QR code loading
<img
src={qrCodeUrl}
onError={(e) => {
console.error('QR code load failed');
e.target.src = '/images/qr-placeholder.png';
showRetryButton();
}}
alt="TrueMoney QR Code"
/>

ปัญหา: การชำระเงินหมดเวลา

สาเหตุ: ลูกค้าไม่ได้สแกน QR Code ภายในช่วงเวลาที่กำหนด

วิธีแก้ไข:

// Set reasonable timeout and allow regeneration
setTimeout(() => {
if (!paymentConfirmed) {
showExpiredMessage();
allowNewQRGeneration();
}
}, 15 * 60 * 1000); // 15 minutes

ปัญหา: ลูกค้าสแกนแล้วแต่การชำระเงินล้มเหลว

สาเหตุ:

  • ยอดเงินหรือเครดิตไม่เพียงพอ
  • ธนาคารปฏิเสธการทำธุรกรรม
  • เกินวงเงินรายวัน

วิธีแก้ไข:

  • แสดงข้อความแสดงข้อผิดพลาดอย่างชัดเจน
  • อนุญาตให้ลองใหม่ด้วยวิธีการชำระเงินอื่น
  • ให้ข้อมูลติดต่อฝ่ายบริการลูกค้า

ปัญหา: ไม่ได้รับ Webhook

สาเหตุ: ปัญหาเครือข่ายหรือการตั้งค่า webhook

วิธีแก้ไข:

// Implement polling as backup
function pollPaymentStatus(chargeId) {
const maxAttempts = 20; // 1 minute total
let attempts = 0;

const interval = setInterval(async () => {
attempts++;
const charge = await checkChargeStatus(chargeId);

if (charge.status !== 'pending' || attempts >= maxAttempts) {
clearInterval(interval);
handlePaymentResult(charge);
}
}, 3000);
}

แนวทางปฏิบัติที่ดีที่สุด

1. แสดง QR Code ที่ชัดเจน

.qr-code-container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
text-align: center;
}

.qr-code-container img {
max-width: 300px;
width: 100%;
height: auto;
}

2. แสดงคำแนะนำในการชำระเงิน

<div class="payment-instructions">
<h3>วิธีการชำระเงิน</h3>
<ol>
<li>เปิดแอป TrueMoney</li>
<li>แตะ "สแกน QR"</li>
<li>ชี้กล้องไปที่ QR Code</li>
<li>เลือกวิธีการชำระเงิน</li>
<li>ยืนยันการชำระเงิน</li>
</ol>

<div class="funding-sources">
<p>คุณสามารถชำระด้วย:</p>
<ul>
<li>💰 ยอดเงินในกระเป๋า TrueMoney</li>
<li>💳 บัตรเครดิต/เดบิต</li>
<li>🏦 บัญชีธนาคาร</li>
<li>📆 Pay Next (BNPL)</li>
</ul>
</div>
</div>

3. จัดการสถานะการชำระเงิน

// Use both webhook and polling
class PaymentMonitor {
constructor(chargeId) {
this.chargeId = chargeId;
this.resolved = false;
}

startMonitoring() {
// Primary: webhook
this.setupWebhookListener();

// Backup: polling
this.startPolling();

// Timeout: expire after 15 minutes
this.setupTimeout();
}

handleSuccess() {
if (!this.resolved) {
this.resolved = true;
this.stopPolling();
redirectToSuccess();
}
}
}

4. ตรวจสอบยอดเงินตามแหล่งเงิน

// Inform users of minimum requirements
function displayMinimumAmounts() {
return `
<div class="minimum-info">
<p>ยอดชำระขั้นต่ำ:</p>
<ul>
<li>กระเป๋า/บัตร/Pay Next: ฿0.01</li>
<li>บัญชีธนาคาร: แตกต่างกันตามธนาคาร</li>
</ul>
</div>
`;
}

5. ใช้ระบบลองใหม่อัตโนมัติ

function createPaymentWithRetry(amount, orderId, maxRetries = 3) {
let attempts = 0;

async function attempt() {
attempts++;
try {
return await createTrueMoneyQRPayment(amount, orderId);
} catch (error) {
if (attempts < maxRetries && error.recoverable) {
await delay(2000 * attempts); // Exponential backoff
return attempt();
}
throw error;
}
}

return attempt();
}

คำถามที่พบบ่อย (FAQ)

TrueMoney QR คืออะไร?

TrueMoney QR เป็นวิธีการชำระเงินแบบออฟไลน์ที่ลูกค้าสแกน QR Code ด้วยแอป TrueMoney เพื่อทำการชำระเงินให้เสร็จสมบูรณ์ ต่างจากวิธีการเปลี่ยนเส้นทาง (redirect) การชำระเงินจะเกิดขึ้นทั้งหมดภายในแอปมือถือของลูกค้า

ความแตกต่างระหว่าง TrueMoney QR และ TrueMoney Wallet คืออะไร?
  • TrueMoney QR: แบบออฟไลน์ ใช้ QR Code ลูกค้าสแกนโค้ดด้วยแอป
  • TrueMoney Wallet: การเปลี่ยนเส้นทางออนไลน์ การยืนยันตัวตนด้วยหมายเลขโทรศัพท์ + OTP

ทั้งสองวิธีเข้าถึงระบบนิเวศ TrueMoney เดียวกันแต่ใช้ขั้นตอนการชำระเงินที่แตกต่างกัน

แหล่งเงินใดบ้างที่รองรับการคืนเงินบางส่วน?

ยอดเงินในกระเป๋า บัญชีธนาคาร Pay Next และ Pay Next Extra รองรับการคืนเงินบางส่วน บัตรเครดิต/เดบิตรองรับเฉพาะการคืนเงินเต็มจำนวน (วันถัดไปเป็นต้นไป)

QR Code ใช้ได้นานเท่าไหร่?

QR Code มักจะหมดอายุหลังจากไม่มีการใช้งาน 15-20 นาที สร้าง QR Code ใหม่หากลูกค้าต้องการเวลาเพิ่มเติม

สามารถใช้ TrueMoney QR สำหรับการชำระเงินในร้านค้าได้หรือไม่?

ได้! TrueMoney QR ใช้งานได้ดีกับระบบขายหน้าร้าน (point-of-sale) แสดง QR Code บนหน้าจอ POS หรือพิมพ์บนใบเสร็จเพื่อให้ลูกค้าสแกน

จะเกิดอะไรขึ้นถ้าบัญชีธนาคารของลูกค้ามียอดเงินไม่เพียงพอ?

การชำระเงินจะล้มเหลว ลูกค้าสามารถ:

  • เติมเงินเข้ากระเป๋า TrueMoney
  • ใช้แหล่งเงินอื่น (บัตร บัญชีธนาคารอื่น)
  • ลองใช้ Pay Next หากมีสิทธิ์

การทดสอบ

โหมดทดสอบ

TrueMoney QR สามารถทดสอบในโหมดทดสอบโดยใช้ API Keys สำหรับทดสอบของคุณ:

ขั้นตอนการทดสอบ:

  1. สร้าง source และ charge โดยใช้ API keys สำหรับทดสอบ
  2. คุณจะได้รับ URL ของ QR Code สำหรับทดสอบ
  3. ในโหมดทดสอบ ทำเครื่องหมาย charge เป็นสำเร็จ/ล้มเหลวด้วยตนเองในแดชบอร์ด
  4. Webhook จะถูกส่งตามการเปลี่ยนแปลงสถานะ

การทดสอบการเปลี่ยนแปลงสถานะ:

// Create test charge
const charge = await omise.charges.create({
amount: 50000,
currency: 'THB',
source: testSourceId,
return_uri: 'https://example.com/callback'
});

// Get test QR code
console.log(charge.source.scannable_code.image.download_uri);

// In test mode, use Omise Dashboard to:
// 1. Navigate to the charge
// 2. Use "Actions" menu to mark as successful or failed
// 3. Verify webhook handling

สถานการณ์การทดสอบ:

  • การชำระเงินสำเร็จ: ตรวจสอบขั้นตอนการดำเนินการคำสั่งซื้อ
  • การชำระเงินล้มเหลว: ทดสอบการจัดการข้อผิดพลาดและการลองใหม่
  • หมดเวลา: ทดสอบสถานการณ์ QR Code หมดอายุ
  • การส่ง Webhook: ตรวจสอบให้แน่ใจว่าได้รับ webhook ทั้งหมดอย่างถูกต้อง
  • การคืนเงิน: ทดสอบการคืนเงินทั้งเต็มจำนวนและบางส่วน

หมายเหตุสำคัญ:

  • QR Code สำหรับทดสอบใช้สำหรับทดสอบการเชื่อมต่อเท่านั้น
  • Charge สำหรับทดสอบไม่เชื่อมต่อกับเซิร์ฟเวอร์ TrueMoney จริง
  • ใช้แดชบอร์ดเพื่อจำลองการทำธุรกรรมให้เสร็จสมบูรณ์
  • ทดสอบการจัดการ webhook ก่อนเริ่มใช้งานจริงเสมอ

สำหรับแนวทางการทดสอบอย่างครอบคลุม ดู เอกสารการทดสอบ

แหล่งข้อมูลที่เกี่ยวข้อง

ขั้นตอนถัดไป

  1. สร้าง Source ของ TrueMoney QR
  2. แสดง QR Code ให้กับลูกค้า
  3. จัดการ Webhook การชำระเงิน
  4. ทดสอบขั้นตอนการชำระเงิน
  5. เปิดใช้งานจริง