WeChat Pay
รับชำระเงินจาก WeChat Pay ซึ่งรวมเข้ากับแอป WeChat ที่มีผู้ใช้ 1.3 พันล้านคน โดย WeChat Pay เป็นหนึ่งในแพลตฟอร์มการชำระเงินผ่านมือถือที่โดดเด่นที่สุดในจีน มีการรวมเข้ากับระบบนิเวศ WeChat อย่างราบรื่น
สำหรับการเชื่อมต่อ POS ที่ร้านค้าแสดง QR code ดู WeChat Pay MPM สำหรับการสแกนบาร์โค้ดที่ร้านค้าสแกนรหัสชำระเงินของลูกค้า ดู WeChat Pay UPM
ภาพรวม
WeChat Pay (เรียกว่า Weixin Pay ในจีน) เป็นโซลูชันการชำระเงินผ่านมือถือของ Tencent ที่รวมเข้าโดยตรงในแอป WeChat Messaging ด้วยการรวมเข้ากับ WeChat messaging (มีผู้ใช้ 1.3 พันล้านคน) WeChat Pay เป็นหนึ่งในแพลตฟอร์มการชำระเงินที่โดดเด่นที่สุดในจีน เป็นหนึ่งในสองวิธีการชำระเงินที่ใหญ่ที่สุดในจีนพร้อมกับ Alipay WeChat Pay ช่วยให้การชำระเงินทันทีผ่านรหัส QR การซื้อในแอป และมินิโปรแกรมได้
คุณสมบัติหลัก:
- ✅ รวมเข้ากับ WeChat - เข้าถึงผ ู้ใช้ 1.3 พันล้าน+ คนทั่วจีนและชุมชนจีนต่างประเทศ
- ✅ การรวมเข้า WeChat - การชำระเงินแบบราบรื่นภายในระบบนิเวศแอป WeChat
- ✅ การชำระเงินผ่านรหัส QR - ประสบการณ์การชำระเงินที่รวดเร็วและไม่ต้องสัมผัส
- ✅ รองรับข้ามพรมแดน - รับชำระเงินจากนักท่องเที่ยวชาวจีนทั่วโลก
- ✅ หลายสกุลเงิน - ชำระเงินเป็น THB, SGD, MYR, JPY, USD
- ✅ มินิโปรแกรม - สร้างประสบการณ์อีคอมเมิร์ซภายใน WeChat
ภูมิภาคที่รองรับ
| Region | Currency | Min Amount | Max Amount | API Version |
|---|---|---|---|---|
| Thailand | THB | ฿20.00 | ฿150,000.00 | 2017-11-02 |
WeChat Pay มีค่ามากโดยเฉพาะสำหรับผู้ค้าที่มุ่งเน้นนักท่องเที่ยวชาวจีนหรืออีคอมเมิร์ซข้ามพรมแดน ลูกค้าชำระเงินเป็น CNY คุณได้รับชำระเงินเป็นสกุลเงินท้องถิ่นของคุณ
วิธีการทำงาน
ประสบการณ์ลูกค้า:
- ลูกค้าเลือก "WeChat Pay" ที่หน้าชำระเงิน
- รหัส QR ถูกแสดงบนหน้าจอ
- ลูกค้าเปิดแอป WeChat และสแกนรหัส QR
- ตรวจสอบรายละเอียดการทำรายการใน WeChat
- ยืนยันการชำระเงินด้วยรหัสผ่าน WeChat Pay หรือลายนิ้วมือ
- กลับไปยังเว็บไซต์ผู้ค้า
- รับการยืนยันการชำระเงิน
เวลาในการทำรายการโดยทั่วไป: 30-90 วินาที
การใช้งาน
ขั้นตอนที่ 1: สร้าง WeChat Pay Source
- cURL
- Node.js
- PHP
- Python
- Ruby
- Go
- Java
- C#
curl https://api.omise.co/sources \
-u skey_test_YOUR_SECRET_KEY: \
-d "type=wechat_pay" \
-d "amount=10000" \
-d "currency=THB"
const omise = require('omise')({
secretKey: 'skey_test_YOUR_SECRET_KEY'
});
const source = await omise.sources.create({
type: 'wechat_pay',
amount: 10000, // THB 100.00
currency: 'THB'
});
<?php
$source = OmiseSource::create(array(
'type' => 'wechat_pay',
'amount' => 10000,
'currency' => 'THB'
));
?>
import omise
omise.api_secret = 'skey_test_YOUR_SECRET_KEY'
source = omise.Source.create(
type='wechat_pay',
amount=10000,
currency='THB'
)
require 'omise'
Omise.api_key = 'skey_test_YOUR_SECRET_KEY'
source = Omise::Source.create({
type: 'wechat_pay',
amount: 10000,
currency: 'THB'
})
source, err := client.Sources().Create(&operations.CreateSource{
Type: "wechat_pay",
Amount: 10000,
Currency: "THB",
})
Source source = client.sources().create(new Source.CreateParams()
.type("wechat_pay")
.amount(10000L)
.currency("THB"));
var source = await client.Sources.Create(new CreateSourceRequest
{
Type = "wechat_pay",
Amount = 10000,
Currency = "THB"
});
การตอบสนอง:
{
"object": "source",
"id": "src_test_5rt6s9vah5lkvi1rh9c",
"type": "wechat_pay",
"flow": "redirect",
"amount": 10000,
"currency": "THB",
"scannable_code": {
"type": "qr",
"image": {
"uri": "https://omise.co/qr/...",
"download_uri": "https://api.omise.co/..."
}
}
}
ขั้นตอนที่ 2: สร้าง Charge
curl https://api.omise.co/charges \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=10000" \
-d "currency=THB" \
-d "source=src_test_5rt6s9vah5lkvi1rh9c" \
-d "return_uri=https://yourdomain.com/payment/callback"
ขั้นตอนที่ 3: แสดงรหัส QR
app.post('/checkout/wechat-pay', async (req, res) => {
try {
const { amount, order_id } = req.body;
// ตรวจสอบจำนวนเงิน
if (amount < 100 || amount > 10000000) {
return res.status(400).json({
error: 'Amount must be between ฿1 and ฿100,000'
});
}
// สร้าง source
const source = await omise.sources.create({
type: 'wechat_pay',
amount: amount,
currency: 'THB'
});
// สร้าง 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
}
});
// ส่งกลับ URL รหัส QR เพื่อแสดง
res.json({
qr_code_url: charge.source.scannable_code.image.uri,
charge_id: charge.id,
expires_at: new Date(Date.now() + 5 * 60 * 1000) // 5 นาที
});
} catch (error) {
console.error('WeChat Pay error:', error);
res.status(500).json({ error: error.message });
}
});
ขั้นตอนที่ 4: แสดง UI รหัส QR
<!DOCTYPE html>
<html>
<head>
<title>WeChat Pay Checkout</title>
<style>
.wechat-pay-container {
max-width: 400px;
margin: 50px auto;
text-align: center;
padding: 30px;
border: 1px solid #e0e0e0;
border-radius: 10px;
}
.qr-code {
width: 300px;
height: 300px;
margin: 20px auto;
border: 1px solid #ddd;
padding: 10px;
background: white;
}
.wechat-logo {
width: 60px;
height: 60px;
margin-bottom: 15px;
}
.countdown {
font-size: 18px;
color: #666;
margin-top: 15px;
}
.instructions {
color: #666;
margin: 20px 0;
line-height: 1.6;
}
</style>
</head>
<body>
<div class="wechat-pay-container">
<img src="/images/wechat-logo.svg" class="wechat-logo" alt="WeChat Pay">
<h2>Scan to Pay with WeChat</h2>
<div class="qr-code">
<img id="qr-image" src="" alt="WeChat Pay QR Code" style="width: 100%; height: 100%;">
</div>
<div class="instructions">
<ol style="text-align: left;">
<li>Open WeChat app on your phone</li>
<li>Tap the "+" icon and select "Scan QR Code"</li>
<li>Scan the QR code above</li>
<li>Confirm payment in WeChat</li>
</ol>
</div>
<div class="countdown">
Time remaining: <span id="timer">5:00</span>
</div>
<p style="color: #999; font-size: 14px; margin-top: 20px;">
Payment amount: <strong id="amount"></strong>
</p>
</div>
<script>
// Countdown timer
let timeLeft = 300; // 5 นาที
const timerElement = document.getElementById('timer');
const countdown = setInterval(() => {
timeLeft--;
const minutes = Math.floor(timeLeft / 60);
const seconds = timeLeft % 60;
timerElement.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
if (timeLeft <= 0) {
clearInterval(countdown);
alert('QR code expired. Please try again.');
window.location.href = '/checkout';
}
}, 1000);
// Poll for payment status
const chargeId = new URLSearchParams(window.location.search).get('charge_id');
const checkStatus = setInterval(async () => {
try {
const response = await fetch(`/api/check-payment-status/${chargeId}`);
const data = await response.json();
if (data.status === 'successful') {
clearInterval(checkStatus);
clearInterval(countdown);
window.location.href = '/payment-success';
} else if (data.status === 'failed') {
clearInterval(checkStatus);
clearInterval(countdown);
window.location.href = '/payment-failed';
}
} catch (error) {
console.error('Status check error:', error);
}
}, 3000); // ตรวจสอบทุก 3 วินาที
// Load QR code
fetch('/api/create-wechat-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
amount: 10000,
order_id: 'ORD-12345'
})
})
.then(res => res.json())
.then(data => {
document.getElementById('qr-image').src = data.qr_code_url;
document.getElementById('amount').textContent = `฿${(data.amount / 100).toFixed(2)}`;
});
</script>
</body>
</html>
ขั้นตอนที่ 5: จัดการ Webhook
app.post('/webhooks/omise', (req, res) => {
const event = req.body;
if (event.key === 'charge.complete' && event.data.source.type === 'wechat_pay') {
const charge = event.data;
if (charge.status === 'successful') {
processOrder(charge.metadata.order_id);
sendConfirmationEmail(charge.metadata.customer_email);
} else if (charge.status === 'failed') {
handleFailedPayment(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());
// สร้างการชำระเงิน WeChat Pay
app.post('/api/create-wechat-payment', async (req, res) => {
try {
const { amount, order_id, customer_email } = req.body;
// ตรวจสอบจำนวนเงิน (฿1 - ฿100,000)
if (amount < 100 || amount > 10000000) {
return res.status(400).json({
error: 'Amount must be between ฿1 and ฿100,000'
});
}
// สร้าง source
const source = await omise.sources.create({
type: 'wechat_pay',
amount: amount,
currency: 'THB'
});
// สร้าง 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_email: customer_email,
payment_method: 'wechat_pay'
}
});
// ส่งกลับรหัส QR
res.json({
charge_id: charge.id,
qr_code_url: charge.source.scannable_code.image.uri,
amount: charge.amount,
expires_at: new Date(Date.now() + 5 * 60 * 1000)
});
} catch (error) {
console.error('WeChat Pay error:', error);
res.status(500).json({ error: error.message });
}
});
// ตรวจสอบสถานะการชำระเงิน (สำหรับการสอบถาม)
app.get('/api/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
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// ตัวจัดการ webhook (วิธีการแจ้งเตือนหลัก)
app.post('/webhooks/omise', (req, res) => {
const event = req.body;
if (event.key === 'charge.complete') {
const charge = event.data;
if (charge.source.type === 'wechat_pay') {
if (charge.status === 'successful') {
updateOrderStatus(charge.metadata.order_id, 'paid');
sendConfirmationEmail(charge.metadata.customer_email);
// บันทึกการชำระเงินที่สำเร็จ
console.log(`WeChat Pay payment successful: ${charge.id}`);
} else {
updateOrderStatus(charge.metadata.order_id, 'failed');
// บันทึกการชำระเงินที่ล้มเหลว
console.log(`WeChat Pay payment failed: ${charge.id}, reason: ${charge.failure_message}`);
}
}
}
res.sendStatus(200);
});
// ฟังก์ชันวิธีการช่วยเหลือ
async function updateOrderStatus(orderId, status) {
// อัปเดตคำสั่งซื้อในฐานข้อมูล
await db.orders.update({ id: orderId }, { status: status });
}
async function sendConfirmationEmail(email) {
// ส่งการยืนยันอีเมล
// การใช้งานขึ้นอยู่กับบริการอีเมล
}
app.listen(3000, () => {
console.log('Server running on port 3000');
});
การรองรับการคืนเงิน
WeChat Pay รองรับ การคืนเงินแบบเต็มและบางส่วน ภายใน 90 วัน:
// การคืนเงินแบบเต็ม
const fullRefund = await omise.charges.refund('chrg_test_...', {
amount: 10000
});
// การคืนเงินบางส่วน
const partialRefund = await omise.charges.refund('chrg_test_...', {
amount: 5000 // การคืนเงินครึ่งหนึ่ง
});
- การคืนเงินจะประมวลผลภายใน 1-3 วันธุรกิจ
- ลูกค้าได้รับการคืนเงินในกระเป๋า WeChat ของพวกเขา
- รองรับภายใน 90 วันของการทำรายการเดิม
หน้าต่างการคืนเงินและนโยบายอาจมีการเปลี่ยนแปลง ตรวจสอบความสามารถในการคืนเงินปัจจุบันเสมอผ่านเอกสาร API ของ Omise หรือแดชบอร์ดผู้ค้าของคุณ
ปัญหาทั่วไปและการแก้ไขปัญหา
ปัญหา: ไม่สามารถสแกนรหัส QR
สาเหตุ: ลูกค้าใช้เครื่องสแกน QR ที่ไม่เข้ากันหรือรหัสที่หมดอายุ
วิธีแก้:
// ตรวจสอบให้แน่ใจว่ารหัส QR ใหม่และถูกต้อง
function displayQRCode(qrCodeUrl, expiresAt) {
const qrImage = document.getElementById('qr-code');
qrImage.src = qrCodeUrl;
// แสดงการเตือนเรื่องการหมดอายุ
const timeUntilExpiry = new Date(expiresAt) - Date.now();
if (timeUntilExpiry < 60000) { // น้อยกว่า 1 นาที
showWarning('QR code expiring soon! Please scan now.');
}
}
// ให้ตัวเลือกในการรีเฟรช
function refreshQRCode() {
// สร้างรหัส QR ใหม่
createNewPayment();
}
ปัญหา: หมดเวลาการชำระเงิน
สาเหตุ: ลูกค้าไม่ได้ทำการชำระเงินให้เสร็จสิ้นภายใน 5 นาที
วิธีแก้:
// ตั้งค่าเวลาที่เหมาะสม
const QR_EXPIRY_TIME = 5 * 60 * 1000; // 5 นาที
setTimeout(() => {
if (!paymentConfirmed) {
showMessage('Payment session expired. Please create a new payment.');
enableRetry();
}
}, QR_EXPIRY_TIME);
ปัญหา: แอป WeChat ไม่เปิดบนมือถือ
สาเหตุ: ปัญหา Deep link บนเบราว์เซอร์มือถือ
วิธีแก้:
function isMobileDevice() {
return /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
}
if (isMobileDevice()) {
// พยายามเปิดแอป WeChat โดยตรง
window.location = `weixin://dl/business/?t=${encodeURIComponent(qrCodeData)}`;
// กลับไปที่การแสดงรหัส QR
setTimeout(() => {
if (document.hidden === false) {
displayQRCodeFallback();
}
}, 2000);
} else {
// เดสก์ท็อป: แสดงรหัส QR
displayQRCode();
}
ปัญหา: ความสับสนในการแปลงเงินตรา
สาเหตุ: ลูกค้าเห็น CNY ผู้ค้าเห็น THB
วิธีแก้:
// แสดงสกุลเงินทั้งสองอย่างชัดเจน
function displayPaymentAmount(amountTHB, exchangeRate) {
const amountCNY = amountTHB * exchangeRate;
return `
<div class="payment-amount">
<p>You pay: ¥${amountCNY.toFixed(2)} CNY</p>
<p class="small">ร้านค้า receives: ฿${(amountTHB / 100).toFixed(2)} THB</p>
<p class="small">Exchange rate: 1 THB = ${exchangeRate.toFixed(4)} CNY</p>
</div>
`;
}
ปัญหา: การชำระเงินติดอยู่ในสถานะค้างอยู่
สาเหตุ: ปัญหาเครือข่ายหรือการแจ้งเตือนที่ล่าช้าจาก WeChat
วิธีแก้:
// ใช้การตรวจสอบสถานะที่มั่นคง
async function checkPaymentStatus(chargeId, maxAttempts = 10) {
let attempts = 0;
const checkInterval = setInterval(async () => {
attempts++;
try {
const charge = await omise.charges.retrieve(chargeId);
if (charge.status === 'successful') {
clearInterval(checkInterval);
handleSuccess(charge);
} else if (charge.status === 'failed') {
clearInterval(checkInterval);
handleFailure(charge);
} else if (attempts >= maxAttempts) {
clearInterval(checkInterval);
handleTimeout(charge);
}
} catch (error) {
console.error('Status check error:', error);
}
}, 3000); // ตรวจสอบทุก 3 วินาที
}