3D Secure
ใช้การยืนยันตัวตน 3D Secure 2.0 เพื่อลดการฉ้อโกง เปลี่ยนความรับผิด และปฏิบัติตามข้อกำหนด Strong ลูกค้า Authentication (SCA) ในยุโรปและอื่นๆ
ภาพรวม
3D Secure (3DS) เป็นโปรโตคอลการยืนยันตัวตนที่เพิ่มชั้นความปลอดภัยเพิ่มเติมให้กับธุรกรรมบัตรออนไลน์ เมื่อเปิดใช้งาน ลูกค้าจะยืนยันตัวตนกับผู้ออกบัตรก่อนทำการชำระเงินให้เสร็จสิ้น
ประโยชน์หลัก:
- 🔒 ลดการฉ้อโกง - ขั้นตอนการยืนยันตัวตนเพิ่มเติม
- 🛡️ เปลี่ยนความรับผิด - ความรับผิดจากการฉ้อโกงเปลี่ยนไปที่ผู้ออกบัตร
- ✅ การปฏิบัติตาม SCA - จำเป็นสำหรับการชำระเงินในยุโรป
- 📈 อัตราการอนุมัติที่สูงขึ้น - ผู้ออกบัตร เชื่อถือธุรกรรมที่ผ่านการยืนยันตัวตน
- 💳 รองรับบัตรทั้งหมด - Visa, Mastercard, JCB
แบรนด์ 3D Secure:
- Visa: Visa Secure (เดิมคือ Verified by Visa)
- Mastercard: Mastercard Identity Check (เดิมคือ Mastercard SecureCode)
- JCB: J/Secure
3D Secure 1 เทียบกับ 3D Secure 2
| คุณสมบัติ | 3DS 1.0 (เก่า) | 3DS 2.0 (ปัจจุบัน) |
|---|---|---|
| ประสบการณ์ผู้ใช้ | ป๊อปอัป, ยุ่งยาก | ในแอป, ราบรื่น |
| รองรับมือถือ | แย่ | ยอดเยี่ยม |
| ข้อมูลที่แชร์ | จำกัด | บริบทที่สมบูรณ์ |
| ความยุ่งยาก | สูง | ต่ำ (มักไร้รอยต่อ) |
| การยืนยันตัวตน | รหัสผ่าน | ไบโอเมตริก, PIN, OTP |
| อัตราความสำเร็จ | ต่ำกว่า | สูงกว่า |
Omise รองรับ 3D Secure 2.0 โดยค่าเริ่มต้น ให้ประสบการณ์ผู้ใช้ที่ดีที่สุดและอัตราการอนุมัติสูงสุด
วิธีการทำงานของ 3D Secure
ประสบการณ์ของลูกค้า:
- ลูกค้ากรอกรายละเอียดบัตรที่เช็คเอาต์
- หาก 3DS จำเป็น เปลี่ยนเส้นทางไปยังหน้ายืนยันตัวตนของผู้ออกบัตร
- ลูกค้ายืนยันตัวตนด้วย:
- ไบโอเมตริก (ลายนิ้วมือ, Face ID)
- PIN หรือรหัสผ่าน
- รหัสผ่านแบบใช้ครั้งเดียว (SMS/แอป)
- กลับไปยังไซต์ผู้ค้า
- การชำระเงินเส ร็จสมบูรณ์หรือล้มเหลวตามการยืนยันตัวตน
เวลาที่ใช้: 10-30 วินาที (ราบรื่นด้วยไบโอเมตริก)
การใช้งาน
3DS อัตโนมัติ (แนะนำ)
Omise กระตุ้น 3DS โดยอัตโนมัติเมื่อจำเป็น:
- Node.js
- PHP
- Python
const omise = require('omise')({
publicKey: 'pkey_test_YOUR_PUBLIC_KEY',
secretKey: 'skey_test_YOUR_SECRET_KEY'
});
// สร้างการเรียกเก็บเงินด้วย card token
const charge = await omise.charges.create({
amount: 100000,
currency: 'THB',
card: cardToken, // จาก Omise.js
return_uri: 'https://yourdomain.com/payment/callback'
});
// ตรวจสอบว่า 3DS จำเป็นหรือไม่
if (charge.authorize_uri) {
// เปลี่ยนเส้นทางลูกค้าไปยังการยืนยันตัวตน 3DS
res.redirect(charge.authorize_uri);
} else if (charge.status === 'successful') {
// การชำระเงินสำเร็จโดยไม่มี 3DS
res.redirect('/success');
}
<?php
$charge = OmiseCharge::create(array(
'amount' => 100000,
'currency' => 'THB',
'card' => $cardToken,
'return_uri' => 'https://yourdomain.com/payment/callback'
));
if ($charge['authorize_uri']) {
// เปลี่ยนเส้นทางไปยัง 3DS
header('Location: ' . $charge['authorize_uri']);
} else if ($charge['status'] === 'successful') {
// สำเร็จโดยไม่มี 3DS
header('Location: /success');
}
?>
import omise
charge = omise.Charge.create(
amount=100000,
currency='THB',
card=card_token,
return_uri='https://yourdomain.com/payment/callback'
)
if charge.authorize_uri:
# เปลี่ยนเส้นทางไปยัง 3DS
return redirect(charge.authorize_uri)
elif charge.status == 'successful':
# สำเร็จโดยไม่มี 3DS
return redirect('/success')
จัดการการกลับมาจาก 3DS
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') {
// การยืนยันตัวตน 3DS สำเร็จ
await processOrder(charge.metadata.order_id);
res.redirect('/payment-success');
} else if (charge.status === 'failed') {
// การยืนยันตัวตนหรือการชำระเงินล้มเหลว
res.redirect(`/payment-failed?reason=${charge.failure_message}`);
} else {
// รอดำเนินการ (หายาก)
res.redirect('/payment-pending');
}
} catch (error) {
res.redirect('/payment-error');
}
});
เมื่อไหร่ที่ต้องใช้ 3DS
บังคับ (จำเป็นเสมอ)
เขตเศรษฐกิจยุโรป (EEA):
- การชำระเงินของผู้บริโภ คทั้งหมดต้องใช้ Strong ลูกค้า Authentication (SCA)
- ครอบคลุม EU + ไอซ์แลนด์, ลิกเตนสไตน์, นอร์เวย์
- ผู้ค้าต้องใช้ 3DS หรือเผชิญกับการปฏิเสธบัตร
บางธนาคาร/ภูมิภาค:
- อินเดีย (ข้อบังคับ RBI)
- บางส่วนของเอเชีย-แปซิฟิก
- แตกต่างกันตามนโยบายผู้ออกบัตร
ทางเลือก (ตามความเสี่ยง)
ผู้ออกบัตรอาจต้องการ 3DS สำหรับ:
- ธุรกรรมมูลค่าสูง
- ผู้ค้าความเสี่ยงสูง
- รูปแบบที่น่าสงสัย
- ธุรกรรมแรกของลูกค้ากับผู้ค้า
- การชำระเงินข้ามพรมแดน
ไร้รอยต่อ vs ท้าทาย:
- ไร้รอยต่อ: ผู้ออกบัตรอนุมัติโดยไม่ต้องให้ลูกค้าทำอะไร (80%+ ของ 3DS 2.0)
- ท้าทาย: ลูกค้าต้องยืนยันตัวตน (20%)
ตัวอย่างการใช้งานที่สมบูรณ์
const express = require('express');
const omise = require('omise')({
publicKey: process.env.OMISE_PUBLIC_KEY,
secretKey: process.env.OMISE_SECRET_KEY
});
const app = express();
app.use(express.json());
// ขั้นตอนที่ 1: สร้างการเรียกเก็บเงิน
app.post('/checkout', async (req, res) => {
try {
const { token, amount, currency, order_id } = req.body;
const charge = await omise.charges.create({
amount: amount,
currency: currency,
card: token, // จาก Omise.js
return_uri: `${process.env.BASE_URL}/payment/callback`,
metadata: {
order_id: order_id
}
});
if (charge.authorize_uri) {
// ต้องใช้ 3DS - คืนค่า URL เปลี่ยนเส้นทาง
res.json({
requires_authentication: true,
authorize_uri: charge.authorize_uri,
charge_id: charge.id
});
} else if (charge.status === 'successful') {
// สำเร็จโดยไม่มี 3DS
await processOrder(order_id);
res.json({
requires_authentication: false,
status: 'successful',
charge_id: charge.id
});
} else {
// ล้มเหลว
res.status(400).json({
error: charge.failure_message
});
}
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// ขั้นตอนที่ 2: จัดการการกลับมาจาก 3DS
app.get('/payment/callback', async (req, res) => {
try {
const charge = await omise.charges.retrieve(req.query.charge_id);
if (charge.status === 'successful') {
await processOrder(charge.metadata.order_id);
res.redirect(`/order-confirmation?order=${charge.metadata.order_id}`);
} else {
res.redirect(`/payment-failed?error=${charge.failure_code}`);
}
} catch (error) {
res.redirect('/payment-error');
}
});
// ขั้นตอนที่ 3: Webhook (แนะนำ)
app.post('/webhooks/omise', async (req, res) => {
const event = req.body;
if (event.key === 'charge.complete') {
const charge = event.data;
if (charge.status === 'successful') {
await processOrder(charge.metadata.order_id);
}
}
res.sendStatus(200);
});
app.listen(3000);
การทดสอบ 3D Secure
บัตรทดสอบ
| หมายเลขบัตร | พฤติกรรม 3DS | ผลลัพธ์ |
|---|---|---|
| 4242424242424242 | ไม่มี 3DS | สำเร็จ |
| 4000000000003220 | ต้องใช้ 3DS, สำเร็จ | สำเร็จ |
| 4000000000009235 | ต้องใช้ 3DS, ล้มเหลว | ปฏิเสธ |
| 4000008260003178 | 3DS, เงินไม่เพียงพอ | ปฏิเสธ |
ขั้นตอนการ ทดสอบ
- ใช้บัตรทดสอบ 3DS
- เปลี่ยนเส้นทางไปยังหน้าทดสอบ 3DS
- คลิกปุ่ม "Success" หรือ "Fail"
- กลับไปยัง return_uri พร้อมผลลัพธ์
ดูรายการทั้งหมดได้ที่คู่มือการทดสอบ
แนวทางปฏิบัติที่ดีที่สุด
1. ให้ return_uri เสมอ
// จำเป็นสำหรับการเปลี่ยนเส้นทาง 3DS
const charge = await omise.charges.create({
// ... พารามิเตอร์อื่นๆ
return_uri: 'https://yourdomain.com/payment/callback' // ต้องเป็น HTTPS
});
2. จัดการสถานะการเรียกเก็บเงินทั้งหมด
switch (charge.status) {
case 'successful':
// การชำระเงินเสร็จสมบูรณ์
break;
case 'failed':
// แสดงข้อผิดพลาด อนุญาตให้ลองใหม่
break;
case 'pending':
// รอ webhook (หายาก)
break;
case 'expired':
// ลูกค้าไม่ได้ทำ 3DS ให้เสร็จ
break;
}
3. ใช้ HTTPS
3DS ต้องการ HTTPS สำหรับ return_uri:
✅ https://yourdomain.com/callback
❌ http://yourdomain.com/callback
4. ใช้ Webhooks
อย่าพึ่งพา return_uri เพียงอย่างเดียว:
// Webhook คือแหล่งข้อมูลที่เชื่อถือได้
app.post('/webhooks/omise', handleWebhook);
// Return URI เพื่อ UX ของลูกค้าเท่านั้น
app.get('/payment/callback', showCustomerResult);
คำถามที่พบบ่อย
3D Secure เป็นข้อบังคับหรือไม่?
ใช่สำหรับ:
- การชำระเงินในเขตเศร ษฐกิจยุโรป (EEA) - ข้อกำหนด SCA
- อินเดีย - ข้อบังคับ RBI
- บางภูมิภาคในเอเชีย-แปซิฟิก
ทางเลือกสำหรับ:
- ภูมิภาคอื่นๆ (แต่แนะนำเพื่อการป้องกันการฉ้อโกง)
- ธุรกรรมความเสี่ยงสูง (ผู้ออกบัตรอาจต้องการ)
3DS ลด conversion หรือไม่?
3DS 1.0: ใช่ ลดลงอย่างมาก (10-20%) 3DS 2.0: ผลกระทบน้อยที่สุด (1-5%) เนื่องจาก:
- การยืนยันตัวตนแบบไร้รอยต่อ (80%+ ของกรณี)
- การยืนยันตัวตนด้วยไบโอเมตริก (รวดเร็วและง่าย)
- ประสบการณ์มือถือที่ดีกว่า
การเปลี่ยนความรับผิดคืออะไร?
เมื่อการยืนยันตัวตน 3DS สำเร็จ ความรับผิดจากการฉ้อโกงจะเปลี่ยนจากผู้ค้าไปยังผู้ออกบัตร หากไม่มี 3DS ผู้ค้าจะรับผิดชอบต่อการฉ้อโกง
ลูกค้าสามารถข้าม 3DS ได้หรือไม่?
ไม่ได้ เมื่อ 3DS จำเป็น (โดยกฎระเบียบหรือผู้ออกบัตร) จะไม่สามารถข้ามได้ การชำระเงินจะล้มเหลวหากลูกค้าไม่ทำการยืนยันตัวตนให้เสร็จสิ้น
แหล่งข้อมูลที่เกี่ยวข้อง
- การเรียกเก็บเงินจากบัตร - คู่มือการชำระเงินด้วยบัตร
- การเก็บรวบรวมบัตร - การเก็บรวบรวมบัตรที่ปลอดภัย
- การป้องกันการฉ้อโกง - เครื่องมือป้องกันการฉ้อโกงเพิ่มเติม
- การทดสอบ - บัตรทดสอบ 3DS
- Webhooks - จัดก ารการแจ้งเตือนการชำระเงิน
ขั้นตอนถัดไป
- ใช้ 3DS อัตโนมัติในการบูรณาการของคุณ
- เพิ่ม return_uri ให้กับการเรียกเก็บเงินจากบัตรทั้งหมด
- จัดการ 3DS redirect และ return flow
- ทดสอบด้วยบัตรทดสอบ 3DS
- ตั้งค่าการจัดการ webhook
- ตรวจสอบอัตราความสำเร็จของ 3DS
- เข้าสู่การผลิต