Refunds
ออก refund เต็มจำนวนหรือบางส่วนให้กับลูกค้าได้อย่างรวดเร็วและง่ายดายผ่าน Omise API หรือ dashboard
ภาพรวม
Omise อนุญาตให้คุณ refund การชำระเงินที่ทำผ่านวิธีการชำระเงินส่วนใหญ่ Refunds สามารถเป็นแบบเต็มจำนวน (ทั้งหมด) หรือบางส่วน (ส่วนหนึ่งของจำนวน) ขึ้นอยู่กับวิธีการชำระเงินที่ใช ้
คุณสมบัติหลัก:
- การประมวลผล refund แบบทันที
- รองรับ refund เต็มจำนวนและบางส่วน (สำหรับวิธีที่รองรับ)
- ช่วงเวลา refund สูงสุด 365 วัน
- หักจากยอดโอนอัตโนมัติ
- การแจ้งเตือน Webhook
วิธีการชำระเงินที่รองรับ
รองรับ Refund เต็มจำนวนและบางส่วน
- ✅ Credit/Debit Cards - เต็มจำนวนและบางส่วน (สูงสุด 15 ครั้งต่อ charge)
- ✅ DuitNow - เต็มจำนวนและบางส่วนภายใน 180 วัน
- ✅ PayNow - เต็มจำนวนและบางส่วนภายใน 6 เดือน
- ✅ GrabPay - เต็มจำนวนและบางส่วนภายใน 3 เดือน
- ✅ ShopeePay - เต็มจำนวนและบางส่วนภายใน 180 วัน
Refund เต็มจำนวนเท่านั้น
- ⚠️ Installments - refund เต็มจำนวนเท่านั้น (ช่วงเวลาแตกต่างกันตามธนาคาร: 30 วันถึง 1 ปี)
- ⚠️ TrueMoney - refund เต็มจำนวนเท่านั้นภายใน 30 วัน
ไม่รองรับ Refund
- ❌ PromptPay - ไม่สามารถ refund ได้
- ❌ Mobile Banking (ไทย) - ไม่สามารถ refund ได้
- ❌ Internet Banking (ไทย) - ไม่สามารถ refund ได้
- ❌ Konbini/Pay-easy (ญี่ปุ่น) - ไม่สามารถ refund ได้
- ❌ Online Direct Debit - ไม่สามารถ refund ได้
ตรวจสอบเอกสารวิธีการชำระเงิน
ตรวจสอบนโยบาย refund ของวิธีการชำระเงินเฉพาะก่อนการใช้งานเสมอ การรองรับ refund และช่วงเวลาแตกต่างกันอย่างมาก
Refunds ทำงานอย่างไร
การสร้าง Refunds
Refund เต็มจำนวน
- cURL
- Node.js
- PHP
- Python
curl https://api.omise.co/charges/chrg_test_5rt6s9vah5lkvi1rh9c/refunds \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=10025"
const omise = require('omise')({
secretKey: 'skey_test_YOUR_SECRET_KEY'
});
// Full refund
const refund = await omise.charges.refund('chrg_test_...', {
amount: 10025
});
console.log(refund.status); // 'pending'
<?php
$charge = OmiseCharge::retrieve('chrg_test_5rt6s9vah5lkvi1rh9c');
$refund = $charge->refund(array(
'amount' => 10025
));
echo $refund['status']; // 'pending'
?>
import omise
omise.api_secret = 'skey_test_YOUR_SECRET_KEY'
charge = omise.Charge.retrieve('chrg_test_5rt6s9vah5lkvi1rh9c')
refund = charge.refund(amount=10025)
print(refund.status) # 'pending'
Refund บางส่วน
// Refund ส่วนหนึ่งของ charge (เช่น THB 50 จาก THB 100.25)
const partialRefund = await omise.charges.refund('chrg_test_...', {
amount: 5000 // THB 50.00 (ในหน่วยที่เล็กที่สุด)
});
// ลูกค้าได้รับเงินคืน THB 50
// ผู้ขายเก็บ THB 50.25
Refunds บางส่วนหลายครั้ง
// Refund บางส่วนครั้งแรก (THB 30)
await omise.charges.refund(chargeId, { amount: 3000 });
// Refund บางส่วนครั้งที่สอง (THB 20)
await omise.charges.refund(chargeId, { amount: 2000 });
// Refund บางส่วนครั้งที่สาม (THB 50)
await omise.charges.refund(chargeId, { amount: 5000 });
// รวม refund: THB 100
// สูงสุด: 15 ครั้งต่อ charge
ข้อจำกัดของ Refund
ช่วงเวลา
| วิธีการชำระเงิน | ช่วงเวลา Refund |
|---|---|
| Credit/Debit Cards | 365 วัน |
| DuitNow | 180 วัน |
| ShopeePay | 180 วัน |
| PayNow | 6 เดือน |
| GrabPay | 3 เดือน |
| Atome | 60 วัน |
| TrueMoney | 30 วัน (voids เท่านั้น) |
| WeChat Pay | 90 วัน |
| PayPay | 1 ปี |
ข้อจำกัด Refund บางส่วน
- สูงสุดต่อ charge: 15 ครั้ง
- จำนวนขั้นต่ำ: แตกต่างกันตามวิธีการชำระเงิน
- รวมไม่สามารถเกิน: จำนวน charge เดิม
Voiding เทียบกับ Refunding
Voiding เกิดขึ้นเมื่อ refund ถูกประมวลผลก่อนการโอน:
- ยังไม่มีการโอนจริง
- Charge ถูกยก เลิก
- ประมวลผลเร็วขึ้น
- ตั้งค่า
voidflag เป็นtrueใน response
Refunding เกิดขึ้นหลังการโอน:
- เงินโอนไปยังผู้ขายแล้ว
- สร้างธุรกรรม refund จริง
- หักจากยอดเงินผู้ขาย
- ตั้งค่า
voidflag เป็นfalse
const refund = await omise.charges.refund(chargeId, { amount: 10000 });
if (refund.voided) {
console.log('Charge ถูก void (ก่อนการโอน)');
} else {
console.log('Refund ถูกประมวลผล (หลังการโอน)');
}
สถานะและไทม์ไลน์ของ Refund
สถานะ Refund
pending- สร้าง Refund แล้ว กำลังประมวลผลsuccessful- Refund เสร็จสมบูรณ์failed- Refund ล้มเหลว (หายาก)
ไทม์ไลน์การประมวลผล
| วิธีการชำระเงิน | ลูกค้าได้รับ Refund |
|---|---|
| Credit Cards | 5-10 วันทำการ (ขึ้นอยู่กับธนาคาร) |
| Debit Cards | 1-7 วันทำการ |
| QR Payments | ทันทีถึง 1 วันทำการ |
| E-Wallets | ทันทีถึง 3 วันทำการ |
| ธนาคาร Transfers | 1-3 วันทำการ |
เวลาประมวลผลของธนาคาร
เวลา refund ขึ้นอยู่กับธนาคารของลูกค้า Omise ประมวลผล refunds ทันที แต่ธนาคารอาจใช้เวลาหลายวันในการเครดิตบัญชีลูกค้า
ตรวจสอบสถานะ Refund
ดึง Refund เฉพาะ
const refund = await omise.charges.retrieveRefund(
'chrg_test_...',
'rfnd_test_...'
);
console.log(refund.status);
console.log(refund.amount);
console.log(refund.created_at);
แสดงรายการ Refunds ทั้งหมดสำหรับ Charge
const refunds = await omise.charges.listRefunds('chrg_test_...');
refunds.data.forEach(refund => {
console.log(`Refund ${refund.id}: ${refund.amount/100} ${refund.currency}`);
});
ตรวจสอบสถานะ Refund ของ Charge
const charge = await omise.charges.retrieve('chrg_test_...');
console.log('Refundable:', charge.refundable);
console.log('Refunded amount:', charge.refunded_amount);
console.log('Net amount:', charge.net - charge.refunded_amount);
การจัดการ Webhooks ของ Refund
app.post('/webhooks/omise', (req, res) => {
const event = req.body;
if (event.key === 'refund.create') {
const refund = event.data;
const chargeId = refund.charge;
// อัพเดทสถานะคำสั่งซื้อ
updateOrderStatus(chargeId, 'refunded');
// แจ้งเตือนลูกค้า
sendRefundConfirmation(refund);
// อัพเดทสินค้าคงคลังถ้าจำเป็น
restockItems(chargeId);
}
res.sendStatus(200);
});
กรณีการใช้งานทั่วไป
1. การยกเลิกคำสั่งซื้อ
async function cancelOrder(orderId) {
const order = await getOrder(orderId);
if (order.omise_charge_id && order.status === 'paid') {
// ออก refund เต็มจำนวน
const refund = await omise.charges.refund(order.omise_charge_id, {
amount: order.amount,
metadata: {
order_id: orderId,
reason: 'customer_request'
}
});
// อัพเดทสถานะคำสั่งซื้อ
await updateOrder(orderId, {
status: 'refunded',
refund_id: refund.id
});
// แจ้งเตือนลูกค้า
await sendCancellationEmail(order.customer_email, refund);
}
}
2. Refund บางส่วนสำหรับการคืนสินค้า
async function processPartialReturn(orderId, returnedItems) {
const order = await getOrder(orderId);
let refundAmount = 0;
// คำนวณจำนวน refund
returnedItems.forEach(item => {
refundAmount += item.price * item.quantity;
});
// ออก refund บางส่วน
const refund = await omise.charges.refund(order.omise_charge_id, {
amount: refundAmount,
metadata: {
order_id: orderId,
reason: 'partial_return',
items: JSON.stringify(returnedItems)
}
});
return refund;
}
3. แก้ไขการชำระเงินเกิน
async function correctOverpayment(chargeId, correctAmount) {
const charge = await omise.charges.retrieve(chargeId);
const overpayment = charge.amount - correctAmount;
if (overpayment > 0) {
// Refund ส่วนต่าง
const refund = await omise.charges.refund(chargeId, {
amount: overpayment,
metadata: {
reason: 'overpayment_correction'
}
});
return refund;
}
}