GrabPay
รับชำระเงินจาก GrabPay กระเป๋าเงินดิจิทัลชั้นนำของเอเชียตะวันออกเฉียงใต้ ใช้งานได้ในสิงคโปร์และมาเลเซีย
ขั้นตอนการชำระเงิน

ภาพประกอบกระบวนการชำระเงินแบบ redirect ที่สมบูรณ์ รวมถึงการกรอกหมายเลขโทรศัพท์ การยืนยัน OTP การเลือกวิธีก ารชำระเงิน และการยืนยันขั้นสุดท้าย
ภาพรวม
GrabPay เป็นกระเป๋าเงินชำระเงินที่รวมอยู่ในแอปซูเปอร์ Grab ซึ่งให้บริการเรียกรถ จัดส่งอาหาร และบริการทางการเงินทั่วเอเชียตะวันออกเฉียงใต้ ลูกค้าสามารถชำระเงินโดยใช้ยอดเงิน GrabPay พร้อมการยืนยันทันที
คุณสมบัติหลัก:
- ✅ การเข้าถึงที่กว้างขวาง - ผู้ใช้ในสิงคโปร์และมาเลเซีย
- ✅ การยืนยันที่รวดเร็ว - การตรวจสอบการชำระเงินแบบเกือบเรียลไทม์ (โดยทั่วไปภายในไม่กี่วินาที)
- ✅ มือถือเป็นหลัก - ปรับแต่งสำหรับผู้ใช้สมาร์ทโฟน
- ✅ แบรนด์ที่เชื่อถือได้ - เป็นส่วนหนึ่งของระบบนิเวศ Grab
- ✅ ไม่มีความขัดแย้งในการชำระเงิน - การชำระเงินแบบแตะ เดียวในแอป Grab
- ✅ การครอบคลุมในภูมิภาค - รองรับสิงคโปร์และมาเลเซีย
ภูมิภาคที่รองรับ
| Region | Currency | Min Amount | Max Amount | API Version |
|---|---|---|---|---|
| Singapore | SGD | $1.00 | $5,000.00 | 2017-11-02 |
| Malaysia | MYR | RM1.00 | RM1,500.00 | 2017-11-02 |
ข้อจำกัดการทำรายการตามประเทศ
สิงคโปร์ (SGD)
| ระดับการยืนยันตัวตน | ต่อรายการ | วงเงินต่อวัน | วงเงินต่อเดือน |
|---|---|---|---|
| Basic (เบอร์โทรศัพท์อย่างเดียว) | $500 | $2,000 | $5,000 |
| Plus (ยืนยัน ID แล้ว) | $500 | $5,000 | $30,000 |
มาเลเซีย (MYR)
| ระดับการยืนยันตัวตน | ต่อรายการ | วงเงินต่อวัน | วงเงินต่อเดือน |
|---|---|---|---|
| Basic (เบอร์โทรศัพท์อย่างเดียว) | RM1,500 | RM1,500 | RM3,000 |
| Plus (ยืนยัน ID แล้ว) | RM1,500 | RM5,000 | RM10,000 |
วิธีการทำงาน
ประสบการณ์ลูกค้า:
- ลูกค้าเลือก GrabPay ที่หน้าชำระเงิน
- ถูก redirect ไปยังหน้าอนุมัติ GrabPay
- เปิดแอป Grab (deep link)
- ตรวจสอบรายละเอียดการชำระเงิน
- ยืนยันด้วย PIN/ชีวมิติ
- กลับไปยังเว็บไซต์ผู้ค้า
เวลาในการทำรายการโดยทั่วไป: 1-2 นาที
การใช้งาน
ขั้นตอนที่ 1: สร้าง GrabPay Source
- cURL
- Node.js
- PHP
- Python
- Ruby
- Go
- Java
- C#
curl https://api.omise.co/sources \
-u skey_test_YOUR_SECRET_KEY: \
-d "type=grabpay" \
-d "amount=10000" \
-d "currency=SGD"
const omise = require('omise')({
secretKey: 'skey_test_YOUR_SECRET_KEY'
});
const source = await omise.sources.create({
type: 'grabpay',
amount: 10000, // SGD 100.00
currency: 'SGD'
});
<?php
$source = OmiseSource::create(array(
'type' => 'grabpay',
'amount' => 10000,
'currency' => 'SGD'
));
?>
import omise
omise.api_secret = 'skey_test_YOUR_SECRET_KEY'
source = omise.Source.create(
type='grabpay',
amount=10000,
currency='SGD'
)
require 'omise'
Omise.api_key = 'skey_test_YOUR_SECRET_KEY'
source = Omise::Source.create({
type: 'grabpay',
amount: 10000,
currency: 'SGD'
})
source, err := client.Sources().Create(&operations.CreateSource{
Type: "grabpay",
Amount: 10000,
Currency: "SGD",
})
Source source = client.sources().create(new Source.CreateParams()
.type("grabpay")
.amount(10000L)
.currency("SGD"));
var source = await client.Sources.Create(new CreateSourceRequest
{
Type = "grabpay",
Amount = 10000,
Currency = "SGD"
});
ผลลัพธ์:
{
"object": "source",
"id": "src_test_5rt6s9vah5lkvi1rh9c",
"type": "grabpay",
"flow": "redirect",
"amount": 10000,
"currency": "SGD"
}
ขั้นตอนที่ 2: สร้าง Charge
curl https://api.omise.co/charges \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=10000" \
-d "currency=SGD" \
-d "source=src_test_5rt6s9vah5lkvi1rh9c" \
-d "return_uri=https://yourdomain.com/payment/callback"
ขั้นตอนที่ 3: Redirect ลูกค้า
app.post('/checkout/grabpay', async (req, res) => {
try {
const { amount, currency, order_id } = req.body;
// Validate currency
const supportedCurrencies = ['SGD', 'MYR'];
if (!supportedCurrencies.includes(currency)) {
return res.status(400).json({
error: 'GrabPay supports SGD and MYR only'
});
}
// Validate amount by currency
const limits = {
SGD: { min: 100, max: 500000 },
MYR: { min: 100, max: 150000 }
};
if (amount < limits[currency].min || amount > limits[currency].max) {
return res.status(400).json({
error: `Amount out of range for ${currency}`
});
}
// Create source
const source = await omise.sources.create({
type: 'grabpay',
amount: amount,
currency: currency
});
// Create charge
const charge = await omise.charges.create({
amount: amount,
currency: currency,
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/callback`,
metadata: {
order_id: order_id
}
});
// Redirect to GrabPay
res.redirect(charge.authorize_uri);
} catch (error) {
console.error('GrabPay error:', error);
res.status(500).json({ error: error.message });
}
});
ขั้นตอนที่ 4: จัดการ Return
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') {
// 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');
}
} catch (error) {
res.redirect('/payment-error');
}
});
ขั้นตอนที่ 5: จัดการ Webhook
app.post('/webhooks/omise', (req, res) => {
const event = req.body;
if (event.key === 'charge.complete' && event.data.source.type === 'grabpay') {
const charge = event.data;
if (charge.status === 'successful') {
processOrder(charge.metadata.order_id);
} 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());
// Amount limits by currency
const LIMITS = {
SGD: { min: 100, max: 500000 },
MYR: { min: 100, max: 150000 }
};
// Checkout page
app.post('/checkout/grabpay', async (req, res) => {
try {
const { amount, currency, order_id } = req.body;
// Validate currency
if (!['SGD', 'MYR'].includes(currency)) {
return res.status(400).json({
error: 'GrabPay only supports SGD and MYR'
});
}
// Validate amount
const { min, max } = LIMITS[currency];
if (amount < min || amount > max) {
return res.status(400).json({
error: `Amount must be between ${min} and ${max} ${currency}`
});
}
// Create source
const source = await omise.sources.create({
type: 'grabpay',
amount: amount,
currency: currency
});
// Create charge
const charge = await omise.charges.create({
amount: amount,
currency: currency,
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/callback`,
metadata: {
order_id: order_id,
payment_method: 'grabpay'
}
});
// Return authorization URL
res.json({
authorize_uri: charge.authorize_uri,
charge_id: charge.id
});
} catch (error) {
console.error('GrabPay 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 === 'grabpay') {
if (charge.status === 'successful') {
updateOrderStatus(charge.metadata.order_id, 'paid');
sendConfirmation(charge.metadata.customer_email);
} else {
updateOrderStatus(charge.metadata.order_id, 'failed');
}
}
}
res.sendStatus(200);
});
app.listen(3000);
การรองรับ Void และการคืนเงิน
การยกเลิก Charge
GrabPay รองรับการยกเลิกภายใน 24 ชั่วโมง หลังจากสร้าง charge:
// Void immediately (full amount only)
const refund = await omise.charges.refund('chrg_test_...', {
amount: 10000 // Full amount
});
if (refund.voided) {
console.log('Charge was voided (within 24 hours)');
}
การคืนเงิน
รองรับการคืนเงินเต็มจำนวนและบางส่วน ภายใน 30 วัน:
// Full refund
const fullRefund = await omise.charges.refund('chrg_test_...', {
amount: 10000
});
// Partial refund
const partialRefund = await omise.charges.refund('chrg_test_...', {
amount: 5000 // Half refund
});
GrabPay รองรับทั้งการคืนเงินเต็มจำนวนและบางส่วนภายใน 30 วันหลังจากทำรายการเดิม
ปัญหาทั่วไปและการแก้ไข
ปัญหา: ลูกค้าไม่มีแอป Grab
สาเหตุ: ลูกค้าเลือก GrabPay แต่ไม่ได้ติดตั้งแอป Grab
วิธีแก้:
- แสดงคำแนะนำที่ชัดเจนก่อนการชำระเงิน
- ตรวจสอบแพลตฟอร์ม (iOS/Android)
- จัดหาลิงก์ดาวน์โหลดแอป
function checkGrabApp() {
const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
const isAndroid = /Android/i.test(navigator.userAgent);
if (!isIOS && !isAndroid) {
alert('GrabPay requires the Grab mobile app. Please use a mobile device.');
return false;
}
return true;
}
ปัญหา: ยอดเงินไม่เพียงพอ
ข้อผิดพลาด: การชำระเงินถูกปฏิเสธ
วิธีแก้:
- แสดงข้อความแสดงข้อผิดพลาดที่ชัดเจน
- อนุญาตให้ลูกค้าเติมเงินกระเป๋าเงิน GrabPay
- เสนอวิธีการชำระเงินทางเลือก
if (charge.failure_code === 'insufficient_balance') {
showMessage('ยอดเงิน GrabPay ไม่เพียงพอ กรุณาเติมเงินหรือใช้วิธีการชำระเงินอื่น');
}
ปัญหา: สกุลเงินไม่ตรงกัน
ข้อผิดพลาด: สกุลเงินที่ไม่รองรับ
วิธีแก้:
function validateGrabPayCurrency(currency, country) {
const currencyMap = {
'SG': 'SGD',
'MY': 'MYR'
};
const expectedCurrency = currencyMap[country];
if (currency !== expectedCurrency) {
throw new Error(`Use ${expectedCurrency} for ${country}`);
}
}
ปัญหา: หมดเวลาการชำระเงิน
สาเหตุ: ลูกค้าไม่ทำการชำระเงินให้เสร็จสิ้นภายในเวลาที่กำหนด
วิธีแก้:
- ตั้งค่าหมดเวลา 15 นาที
- อนุญาตให้ลองใหม่ด้วย charge ใหม่
- ส่งคำเตือน
const TIMEOUT = 15 * 60 * 1000; // 15 minutes
setTimeout(() => {
if (!paymentConfirmed) {
showTimeoutMessage();
allowRetry();
}
}, TIMEOUT);
แนวทางปฏิบัติที่ดีที่สุด
1. แสดงคำแนะนำที่ชัดเจน
<div class="grabpay-instructions">
<h3>ชำระเงินด้วย GrabPay</h3>
<ol>
<li>ตรวจสอบให้แน่ใจว่าคุณมีแอป Grab ติดตั้งแล้ว</li>
<li>ตรวจสอบว่ามียอดเงินเพียงพอในกระเป๋าเงิน GrabPay ของคุณ</li>
<li>คุณจะถูก redirect ไปที่แอป Grab</li>
<li>ยืนยันตัวตนและยืนยันการชำระเงิน</li>
</ol>
<p>ยอดเงินไม่พอหรือ? <a href="https://grab.com/sg/pay/">เติมเงินเลย</a></p>
</div>
2. จัดการ Deep Link บนมือถือ
function openGrabApp(authorizeUri) {
if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
window.location = authorizeUri;
// Check if app opened
setTimeout(() => {
if (!document.hidden) {
showInstallAppMessage();
}
}, 2000);
} else {
alert('GrabPay ใช้งานได้เฉพาะบนอุปกรณ์มือถือเท่านั้น');
}
}
3. ตรวจสอบจำนวนเงินตามสกุลเงิน
function validateAmount(amount, currency) {
const limits = {
SGD: { min: 100, max: 500000, label: '$' },
MYR: { min: 100, max: 150000, label: 'RM' }
};
const { min, max, label } = limits[currency];
if (amount < min) {
return `จำนวนเงินขั้นต่ำคือ ${label}${min / 100}`;
}
if (amount > max) {
return `จำนวนเงินสูงสุดคือ ${label}${max / 100}`;
}
return null; // Valid
}
4. ใช้ Webhook
// Webhook is primary notification
app.post('/webhooks/omise', handleWebhook);
// Callback is backup
app.get('/payment/callback', handleCallback);
5. จัดการความแตกต่างในแต่ละภูมิภาค
const GRABPAY_CONFIG = {
SG: {
currency: 'SGD',
minAmount: 100,
maxAmount: 500000,
displayName: 'GrabPay (สิงคโปร์)'
},
MY: {
currency: 'MYR',
minAmount: 100,
maxAmount: 150000,
displayName: 'GrabPay (มาเลเซีย)'
}
};
คำถามที่พบบ่อย
GrabPay รองรับประเทศไหนบ้าง?
GrabPay ใช้งานได้ในสิงคโปร์และมาเลเซียผ่าน Omise
ลูกค้าต้องมีบัญชี Grab หรือไม่?
ใช่ ลูกค้าต้องติดตั้งแอป Grab และเปิดใช้งานกระเป๋าเงิน GrabPay แอปฟรีและใช้งานได้ทั้งบน iOS และ Android
ข้อจำกัดการทำรายการเป็นเท่าไร?
ข้อจำกัดแตกต่างกันตามประเทศ:
- สิงคโปร์: $1.00 - $5,000.00 ต่อรายการ
- มาเลเซีย: RM1.00 - RM1,500.00 ต่อรายการ
วงเงินต่อวันและต่อเดือนขึ้นอยู่กับระดับการยืนยันตัวตนของลูกค้า
การชำระบัญชีใช้เวลานานเท่าไร?
การชำระบัญชี GrabPay โดยทั่วไปเกิดขึ้นภายใน 1-3 วันทำการ ตรวจสอบแดชบอร์ด Omise ของคุณสำหรับกำหนดการชำระบัญชีเฉพาะสำหรับบัญชีของคุณ
สามารถคืนเงินการชำระเงิน GrabPay ได้หรือไม่?
ได้ GrabPay รองรับทั้งการคืนเงินเต็มจำนวนและบางส่วนภายใน 30 วันหลังจากทำรายการเดิม การยกเลิกใช้งานได้ภายใน 24 ชั่วโมง
ถ้าลูกค้ามียอดเงินไม่เพียงพอจะเกิดอะไรขึ้น?
การชำระเงินจะถูกปฏิเสธ ลูกค้าสามารถเติมเงินกระเป๋าเงิน GrabPay ผ่าน: