การจัดการข้อผิดพลาด
ทำความเข้าใจข้อผิดพลาด Omise API และนำการ จัดการข้อผิดพลาดที่แข็งแกร่งมาใช้สำหรับการผสานการชำระเงินที่เชื่อถือได้ เรียนรู้เกี่ยวกับรหัสสถานะ HTTP รูปแบบการตอบกลับข้อผิดพลาด และแนวทางปฏิบัติที่ดีที่สุดสำหรับการดีบัก
ภาพรวม
Omise API ใช้รหัสตอบกลับ HTTP แบบเดิมเพื่อระบุความสำเร็จหรือความล้มเหลวของคำขอ API ข้อผิดพลาดส่งคืนการตอบกลับที่เข้ารหัส JSON พร้อมข้อมูลโดยละเอียดเพื่อช่วยคุณดีบักและจัดการความล้มเหลวอย่างสง่างาม
- รหัส 2xx → สำเร็จ
- รหัส 4xx → ข้อผิดพลาดฝั่งไคลเอนต์ (คำขอของคุณไม่ถูกต้อง)
- รหัส 5xx → ข้อผิดพลาดเซิร์ฟเวอร์ (เกิดปัญหาฝั่ง Omise)
- ข้อผิดพลาดทั้งหมดส่งคืน JSON พร้อม
object: "error"และฟิลด์อธิบาย
รูปแบบการตอบกลับข้อผิดพลาด
ข้อผิดพลาด API ทั้งหมดส่งคืนโครงสร้าง JSON ที่สอดคล้องกัน:
{
"object": "error",
"location": "https://www.omise.co/api-errors#authentication-failure",
"code": "authentication_failure",
"message": "authentication failed"
}
ฟิลด์ออบเจ็กต์ข้อผิดพลาด
| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
object | string | เป็น "error" เสมอสำหรับการตอบกลับข้อผิดพลาด |
location | string | URL ไปยังเอกสารสำหรับข้อผิดพลาดประเภทนี้ |
code | string | รหัสข้อผิดพลาดที่อ่านโดยเครื่อง (ตัวพิมพ์เล็กพร้อมขีดล่าง) |
message | string | ข้อความข้อผิดพลาดที่อ่านโดยมนุษย์เป็นภาษาอังกฤษ |
ข้อผิดพลาดบางประเภทอาจรวมฟิลด์เฉพาะบริบทเพิ่มเติม เช่น charge_id, customer_id หรือ validation_errors สำหรับการดีบักโดยละเอียด
รหัสสถานะ HTTP
2xx สำเร็จ
200 OK
ความหมาย: คำขอสำเร็จ
{
"object": "charge",
"id": "chrg_test_5xuy4w91xqz7d1w9u0t",
"amount": 100000,
"status": "successful"
}
เมื่อเกิดขึ้น:
- ✅ คำขอ GET ส่งคืนข้อมูลสำเร็จ
- ✅ คำขอ POST/PATCH เสร็จสมบูรณ์สำเร็จ
- ✅ คำขอ DELETE ลบทรัพยากรสำเร็จ
201 สร้างแล้ว
ความหมาย: สร้างทรัพยากรสำเร็จ
เมื่อเกิดขึ้น:
- ✅ คำขอ POST สร้างทรัพยากรใหม่ (หายาก โดยปกติส่งคืน 200)
4xx ข้อผิดพลาดฝั่งไคลเอนต์
ข้อผิดพลาดฝั่งไคลเอนต์ระบุปัญหากับคำขอที่คุณส่ง แก้ไขคำขอและลองใหม่
400 คำขอไม่ถูกต้อง
ความหมาย: คำขอมีรูปแบบผิดหรือมีพารามิเตอร์ไม่ถูกต้อง
{
"object": "error",
"location": "https://www.omise.co/api-errors#bad-request",
"code": "bad_request",
"message": "amount must be at least 2000 (in subunits)"
}
สาเหตุทั่วไป:
- ❌ พารามิเตอร์ที่จำเป็นหายไป
- ❌ ค่าพารามิเตอร์ไม่ถูกต้อง
- ❌ จำนวนเงินต่ำกว่าเกณฑ์ขั้นต่ำ
- ❌ สกุลเงินที่ไม่รองรับ
- ❌ JSON payload มีรูปแบบผิด
- ❌ ประเภทพารามิเตอร์ไม่ถูกต้อง
สถานการณ์ตัวอย่าง:
# พารามิเตอร์ที่จำเป็นหายไป
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "currency=thb"
# ข้อผิดพลาด: amount is required
# จำนวนเงินน้อยเกินไป
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "amount=100" \
-d "currency=thb"
# ข้อผิดพลาด: amount must be at least 2000 (20 THB)
วิธีแก้ไข:
- ✅ ตรวจสอบเอกสาร API สำหรับพารามิเตอร์ที่จำเป็น
- ✅ ตรวจสอบค่าพารามิเตอร์ก่อนส่ง
- ✅ ให้แน่ใจว่าประเภทข้อมูลถูกต้อง (ตัวเลขเป็นตัวเลข ไม่ใช่สตริง)
- ✅ ยืนยันจำนวนเงินขั้นต่ำเฉพาะสกุลเงิน
401 ไม่ได้รับอนุญาต
ความหมาย: การยืน ยันตัวตนล้มเหลว - คีย์ API ไม่ถูกต้องหรือหายไป
{
"object": "error",
"location": "https://www.omise.co/api-errors#authentication-failure",
"code": "authentication_failure",
"message": "authentication failed"
}
สาเหตุทั่วไป:
- ❌ ไม่มีคีย์ API ที่ให้มา
- ❌ รูปแบบคีย์ API ไม่ถูกต้อง
- ❌ คีย์ API ถูกเพิกถอนหรือหมดอายุ
- ❌ คีย์ผิดสำหรับสภาพแวดล้อม (คีย์ทดสอบในการผลิต)
- ❌ คีย์ API ไม่ได้เข้ารหัสอย่างเหมาะสมใน header Authorization
สถานการณ์ตัวอย่าง:
# คีย์ API หายไป
curl https://api.omise.co/account
# ข้อผิดพลาด: authentication failed
# คีย์ API ไม่ถูกต้อง
curl https://api.omise.co/account \
-u invalid_key:
# ข้อผิดพลาด: authentication failed
# ใช้คีย์สาธารณะสำหรับการดำเนินการคีย์ลับ
curl https://api.omise.co/charges \
-X POST \
-u pkey_test_...: \
-d "amount=100000" \
-d "currency=thb"
# ข้อผิดพลาด: authentication failed
วิธีแก้ไข:
- ✅ ยืนยันว่าคีย์ API ถูกต้อง (คัดลอกจาก Dashboard)
- ✅ ตรวจสอบช่อง ว่างหรืออักขระพิเศษ
- ✅ ใช้คีย์ลับสำหรับการดำเนินการฝั่งเซิร์ฟเวอร์
- ✅ ใช้คีย์สาธารณะเฉพาะสำหรับโทเค็น/แหล่งที่มา
- ✅ ให้แน่ใจว่าคีย์ไม่ถูกเพิกถอน
- ✅ ยืนยันว่าคีย์ทดสอบ vs จริงตรงกับสภาพแวดล้อม
เรียนรู้เพิ่มเติมเกี่ยวกับการยืนยันตัวตน →
402 ต้องชำระเงิน
ความหมาย: บัตรหรือวิธีการชำระเงินถูกปฏิเสธ
{
"object": "error",
"location": "https://www.omise.co/api-errors#payment-declined",
"code": "payment_declined",
"message": "Your card was declined",
"charge_id": "chrg_test_5xuy4w91xqz7d1w9u0t"
}
สาเหตุทั่วไป:
- ❌ เงินไม่เพียงพอ
- ❌ บัตรหมดอายุ
- ❌ รายละเอียดบัตรไม่ถูกต้อง (CVV, วันหมดอายุ)
- ❌ ผู้ออกบัตรปฏิเสธ (สงสัยการฉ้อโกง)
- ❌ บัตรไม่เปิดใช้งานสำหรับการชำระเงินออนไลน์
- ❌ เกินขีดจำกัดธุรกรรม
รหัสข้อผิดพลาดเฉพาะการชำระเงิน:
| รหัส | ความหมาย | การดำเนินการ |
|---|---|---|
insufficient_fund | เงินไม่เพียงพอในบัตร | ขอให้ลูกค้าใช้บัตรอื่น |
invalid_card | หมายเลขบัตรไม่ถูกต้อง | ยืนยันหมายเลขบัตร |
stolen_or_lost_card | บัตรถูกรายงานว่าถูกขโมย/สูญหาย | ขอให้ลูกค้าติดต่อธนาคาร |
failed_processing | การประมวลผลล้มเหลว | ลองใหม่หรือใช้บัตรอื่น |
payment_cancelled | ลูกค้ายกเลิกการชำระเงิน | การดำเนินการของลูกค้า ไม่ต้องแก้ไข |
payment_expired | หมดเวลาชำระเงิน | สร้างการ เรียกเก็บเงินใหม่ |
สถานการณ์ตัวอย่าง:
# พยายามเรียกเก็บเงินที่มียอดไม่เพียงพอ
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "amount=1000000" \
-d "currency=thb" \
-d "card=tokn_test_..."
# ข้อผิดพลาด: insufficient_fund
วิธีแก้ไข:
- ✅ แสดงข้อความข้อผิดพลาดที่ชัดเจนแก่ลูกค้า
- ✅ ขอให้ลูกค้าลองวิธีการชำระเงินอื่น
- ✅ อย่าลองบัตรเดียวกันหลายครั้ง (หลีกเลี่ยงการบล็อกบัตร)
- ✅ แนะนำให้ลูกค้าติดต่อธนาคาร
- ✅ บันทึกเหตุผลการปฏิเสธสำหรับการ วิเคราะห์
การพยายามบัตรที่ถูกปฏิเสธซ้ำๆ สามารถทริกเกอร์การแจ้งเตือนการฉ้อโกงและทำให้บัตรถูกบล็อก แทนที่จะเป็นเช่นนั้น ขอให้ลูกค้ายืนยันรายละเอียดการชำระเงินหรือใช้วิธีการชำระเงินทางเลือก
404 ไม่พบ
ความหมาย: ทรัพยากรที่ร้องขอไม่มีอยู่
{
"object": "error",
"location": "https://www.omise.co/api-errors#not-found",
"code": "not_found",
"message": "charge chrg_test_invalid was not found"
}
สาเหตุทั่วไป:
- ❌ ID ทรัพยากร ไม่ถูกต้อง
- ❌ ทรัพยากรถูกลบ
- ❌ URL ปลายทาง API ผิด
- ❌ พิมพ์ผิดใน ID ทรัพยากร
- ❌ ใช้ ID ทดสอบในโหมดจริง (หรือในทางกลับกัน)
สถานการณ์ตัวอย่าง:
# ID การเรียกเก็บเงินไม่ถูกต้อง
curl https://api.omise.co/charges/chrg_invalid \
-u skey_test_...:
# ข้อผิดพลาด: not found
# ปลายทางผิด
curl https://api.omise.co/charge/chrg_test_... \
-u skey_test_...:
# ข้อผิดพลาด: not found (ควรเป็น /charges ไม่ใช่ /charge)
วิธีแก้ไข:
- ✅ ยืนยันว่า ID ทรัพยากรถูกต้อง
- ✅ ตรวจสอบว่าทรัพยากรไม่ถูกลบ
- ✅ ให้แน่ใจว่าโหมดทดสอบ/จริงตรงกับคีย์
- ✅ ยืนยันการสะกดคำ URL ปลายทาง
- ✅ ค้นหาทรัพยากรโดยใช้ปลายทางรายการ
422 Unprocessable Entity
ความหมาย: คำขอมีรูปแบบที่ดี แต่มีข้อผิดพลาดทางความหมาย
{
"object": "error",
"location": "https://www.omise.co/api-errors#invalid-charge",
"code": "invalid_charge",
"message": "charge has already been captured"
}
สาเหตุทั่วไป:
- ❌ พยายามเปลี่ยนสถานะที่ไม่ถูกต้อง
- ❌ การละเมิดตรรกะธุรกิจ
- ❌ ทรัพยากรได้รับการประมวลผลแล้ว
- ❌ การรวมพารามิเตอร์ที่ไม่ถูกต้อง
สถานการณ์ตัวอย่าง:
# เรียกเก็บการเรียกเก็บเงินที่เรียกเก็บแล้ว
curl https://api.omise.co/charges/chrg_test_.../capture \
-X POST \
-u skey_test_...:
# ข้อผิดพลาด: charge has already been captured
# คืนเงินมากกว่าจำนวนการเรียกเก็บเงิน
curl https://api.omise.co/charges/chrg_test_.../refunds \
-X POST \
-u skey_test_...: \
-d "amount=200000"
# ข้อผิดพลาด: refund amount exceeds available amount
วิธีแก้ไข:
- ✅ ตรวจสอบสถานะทรัพยากรก่อนการดำเนินการ
- ✅ ยืนยันข้อจำกัดตรรกะธุรกิจ
- ✅ อย่าลองการดำเนินการเดียวกันซ้ำ (อาจสำเร็จแล้ว)
- ✅ เรียกข้อมูลทรัพยากรเพื่อตรวจสอบสถานะปัจจุบัน
429 Too Many Requests
ความหมาย: คุณเกินขีดจำกัดอัตรา
{
"object": "error",
"location": "https://www.omise.co/api-errors#rate-limit-exceeded",
"code": "rate_limit_exceeded",
"message": "too many requests, please try again later"
}
การตอบกลับ headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1612137600
Retry-After: 60
วิธีแก้ไข:
- ✅ นำ exponential backoff มาใช้
- ✅ ตรวจสอบ header
Retry-After - ✅ ลดความถี่ของคำขอ
- ✅ รวมการดำเนินการเมื่อเป็นไปได้
- ✅ แคชการตอบกลับเม ื่อเหมาะสม
เรียนรู้เพิ่มเติมเกี่ยวกับการจำกัดอัตรา →
5xx ข้อผิดพลาดเซิร์ฟเวอร์
ข้อผิดพลาดเซิร์ฟเวอร์ระบุปัญหาฝั่ง Omise หายากแต่ควรได้รับการจัดการอย่างสง่างาม
500 ข้อผิดพลาดภายในเซิร์ฟเวอร์
ความหมาย: เกิดปัญหาบนเซิร์ฟเวอร์ของ Omise
{
"object": "error",
"location": "https://www.omise.co/api-errors#internal-server-error",
"code": "internal_server_error",
"message": "An internal server error occurred"
}
เมื่อเกิดขึ้น:
- ⚠️ ข้อผิดพลาดฝั่งเซิร์ฟเวอร์ที่ไม่คาดคิด
- ⚠️ การหยุดชะงักของบริการชั่วคราว
- ⚠️ ปัญหาการเชื่อมต่อฐานข้อมูล
วิธีจัดการ:
- ✅ ลองคำขอซ้ำด้วย exponential backoff
- ✅ ตรวจสอบ status.omise.co สำหรับเหตุการณ์
- ✅ ติดต่อฝ่ายสนับสนุนหากยังคงเกิดขึ้น
- ✅ บันทึกรายละเอียดข้อผิดพลาดสำหรับการดีบัก
503 บริการไม่พร้อมใช้งาน
ความหมาย: บริการไม่พร้อมใช้งานชั่วคราว
{
"object": "error",
"location": "https://www.omise.co/api-errors#service-unavailable",
"code": "service_unavailable",
"message": "Service temporarily unavailable"
}
เมื่อเกิดขึ้น:
- ⚠️ การบำรุงรักษาตามกำหนดการ
- ⚠️ โอเวอร์โหลดบริการ
- ⚠️ ปัญหาผู้ให้บริการ upstream
วิธีจัดการ:
- ✅ ลองใหม่หลังจากหน่วง (ตรวจสอบ header
Retry-After) - ✅ แสดงข้อความบำรุงรักษาแก่ผู้ใช้
- ✅ จัดคิวคำขอสำหรับการประมวลผลภายหลัง
- ✅ ตรวจสอบหน้าสถานะ
รหัสข้อผิดพลาดทั่วไป
ข้อผิดพลาดการยืนยันตัวตน
| รหัส | สถานะ HTTP | คำอธิบาย | วิธีแก้ไข |
|---|---|---|---|
authentication_failure | 401 | คีย์ API ไม่ถูกต้องหรือหายไป | ยืนยันว่าคีย์ API ถูกต้อง |
forbidden | 403 | คีย์ขาดสิทธิ์ที่จำเป็น | ใช้คีย์ลับสำหรับการดำเนินการนี้ |
ข้อผิดพลาดคำขอ
| รหัส | สถานะ HTTP | คำอธิบาย | วิธีแก้ไข |
|---|---|---|---|
bad_request | 400 | พารามิเตอร์คำขอไม่ถูกต้อง | ตรวจสอบพารามิเตอร์และรูปแบบที่จำเป็น |
invalid_charge | 422 | สถานะการเรียกเก็บเงินไม่อนุญาตให้ดำเนินการ | ยืนยันสถานะการเรียกเก็บเงินก่อน |
invalid_customer | 422 | ไม่อนุญาตให้ดำเนินการกับลูกค้า | ตรวจสอบสถานะลูกค้า |
not_found | 404 | ทรัพยากรไม่มีอยู่ | ยืนยัน ID ทรัพยากร |
ข้อผิดพลาดการชำระเงิน
| รหัส | สถานะ HTTP | คำอธิบาย | วิธีแก้ไข |
|---|---|---|---|
payment_declined | 402 | การชำระเงินถูกปฏิเสธ | ขอให้ลูกค้าใช้บัตรอื่น |
insufficient_fund | 402 | ยอดเงินไม่เพียงพอ | ขอวิธีการชำระเงินอื่น |
invalid_card | 402 | รายละเอียดบัตรไม่ถูกต้อง | ยืนยันหมายเลขบัตรและ CVV |
stolen_or_lost_card | 402 | บัตรถูกรายงานว่าถูกขโมย/สูญหาย | ลูกค้าต้องติดต่อธนาคาร |
failed_processing | 402 | การประมวลผลการชำระเงินล้มเหลว | ลองใหม่หรือใช้บัตรอื่น |
payment_cancelled | 402 | ลูกค้ายกเลิกการชำระเงิน | การดำเนินการของลูกค้า |
payment_expired | 402 | หมดเวลาชำระเงิน | สร้างการเรียกเก็บเงินใหม่ |
ข้อผิดพลาดระบบ
| รหัส | สถานะ HTTP | คำอธิบาย | วิธีแก้ไข |
|---|---|---|---|
internal_server_error | 500 | ข้อผิดพลาดฝั่งเซิร์ฟเวอร์ | ลองใหม่ด้วย backoff |
service_unavailable | 503 | บริการหยุดชั่วคราว | รอและลองใหม่ |
rate_limit_exceeded | 429 | คำขอมากเกินไป | นำการจำกัดอัตรามาใช้ |
การจัดการข้อผิดพลาด แนวทางปฏิบัติที่ดีที่สุด
1. ตรวจสอบสถานะ HTTP ก่อนเสมอ
# ✅ ดี - ตรวจสอบรหัสสถานะ
require 'omise'
begin
charge = Omise::Charge.create({
amount: 100000,
currency: 'thb',
card: params[:token]
})
# สำเร็จ
render json: charge
rescue Omise::Error => e
# จัดการข้อผิดพลาดตามประเภท
case e.http_status
when 400
render json: { error: 'คำขอไม่ถูกต้อง' }, status: 400
when 401
render json: { error: 'การยืนยันตัวตนล้มเหลว' }, status: 401
when 402
render json: { error: 'การชำระเงินถูกปฏิเสธ', code: e.code }, status: 402
when 404
render json: { error: 'ไม่พบทรัพยากร' }, status: 404
when 422
render json: { error: 'การดำเนินการไม่ถูกต้อง', message: e.message }, status: 422
when 429
render json: { error: 'เกินขีดจำกัดอัตรา' }, status: 429
when 500, 503
render json: { error: 'บริการไม่พร้อมใช้งานชั่วคราว' }, status: 503
else
render json: { error: 'เกิดข้อผิดพลาด' }, status: 500
end
end
2. แยก วิเคราะห์รายละเอียดข้อผิดพลาด
# ✅ ดี - แยกรายละเอียดข้อผิดพลาด
import omise
try:
charge = omise.Charge.create(
amount=100000,
currency='thb',
card=token
)
return charge
except omise.errors.BaseError as e:
error_code = e.code
error_message = e.message
# บันทึกสำหรับการดีบัก
logger.error(f"การเรียกเก็บเงินล้มเหลว: {error_code} - {error_message}")
# ส่งคืนข้อความที่เป็นมิตรกับผู้ใช้
if error_code == 'insufficient_fund':
return {'error': 'เงินไม่เพียงพอ กรุณาลองบัตรอื่น'}
elif error_code == 'invalid_card':
return {'error': 'รายละเอียดบัตรไม่ถูกต้อง กรุณาตรวจสอบและลองใหม่'}
else:
return {'error': 'การชำระเงินล้มเหลว กรุณาลองใหม่'}
3. นำตรรกะการลองใหม่สำหรับข้อผิดพลาดเซิร์ฟเวอร์มาใช้
// ✅ ดี - ลองใหม่ด้วย exponential backoff
const omise = require('omise')({ secretKey: process.env.OMISE_SECRET_KEY });
async function createChargeWithRetry(chargeData, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const charge = await omise.charges.create(chargeData);
return { success: true, charge };
} catch (error) {
const isServerError = error.statusCode >= 500;
const isLastAttempt = attempt === maxRetries - 1;
if (isServerError && !isLastAttempt) {
// Exponential backoff: 1s, 2s, 4s
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
// อย่าลองข้อผิดพลาดฝั่งไคลเอนต์หรือความพยายามสุดท้าย
return {
success: false,
error: {
code: error.code,
message: error.message,
statusCode: error.statusCode
}
};
}
}
}
4. ตรวจสอบก่อนส่งคำขอ
<?php
// ✅ ดี - ตรวจสอบก่อนเรียก API
function createCharge($amount, $currency, $token) {
// ตรวจสอบจำนวนเงิน
$minAmounts = [
'thb' => 2000, // 20 THB
'jpy' => 50, // 50 JPY
'sgd' => 100, // 1 SGD
];
if ($amount < $minAmounts[$currency]) {
return [
'error' => 'จำนวนเงินต่ำกว่าขั้นต่ำสำหรับ ' . strtoupper($currency),
'min_amount' => $minAmounts[$currency]
];
}
// ตรวจสอบสกุลเงิน
$supportedCurrencies = ['thb', 'jpy', 'sgd', 'myr', 'usd'];
if (!in_array($currency, $supportedCurrencies)) {
return [
'error' => 'สกุลเงินไม่รองรับ',
'supported' => $supportedCurrencies
];
}
// ตรวจสอบรูปแบบโทเค็น
if (!preg_match('/^tokn_test_[a-z0-9]+$/', $token) &&
!preg_match('/^tokn_[a-z0-9]+$/', $token)) {
return ['error' => 'รูปแบบโทเค็นไม่ถูกต้อง'];
}
try {
$charge = OmiseCharge::create([
'amount' => $amount,
'currency' => $currency,
'card' => $token
]);
return ['success' => true, 'charge' => $charge];
} catch (Exception $e) {
return [
'error' => $e->getMessage(),
'code' => $e->getCode()
];
}
}
5. แสดงข้อความที่เป็นมิตรกับผู้ใช้
// ✅ ดี - แปลรหัสข้อผิดพลาดเป็นข้อความผู้ใช้
package main
import (
"github.com/omise/omise-go"
)
func getUserMessage(err error) string {
if omiseErr, ok := err.(*omise.Error); ok {
switch omiseErr.Code {
case "authentication_failure":
return "เกิดข้อผิดพลาดของระบบ กรุณาลองใหม่ภายหลัง"
case "insufficient_fund":
return "บัตรของคุณมีเงินไม่เพียงพอ กรุณาใช้บัตรอื่น"
case "invalid_card":
return "รายละเอียดบัตรไม่ถูกต้อง กรุณาตรวจสอบและลองใหม่"
case "stolen_or_lost_card":
return "ไม่สามารถใช้บัตรนี้ได้ กรุณาติดต่อธนาคารของคุณ"
case "payment_cancelled":
return "การชำระเงินถูกยกเลิก คุณสามารถลองใหม่เมื่อพร้อม"
case "payment_expired":
return "เซสชันการชำระเงินหมดอายุ กรุณาเริ่มการชำระเงินใหม่"
case "rate_limit_exceeded":
return "พยายามหลายครั้งเกินไป กรุณารอสักครู่แล้วลองใหม่"
case "service_unavailable":
return "บริการชำระเงินไม่พร้อมใช้งานชั่วคราว กรุณาลองใหม่ภายหลัง"
default:
return "การชำระเงินล้มเหลว กรุณาลองใหม่หรือใช้วิธีการชำระเงินอื่น"
}
}
return "เกิดข้อผิดพลาดที่ไม่คาดคิด กรุณาลองใหม่"
}
func createCharge(amount int64, currency string, token string) (string, error) {
client, _ := omise.NewClient(
os.Getenv("OMISE_PUBLIC_KEY"),
os.Getenv("OMISE_SECRET_KEY"),
)
charge, err := client.CreateCharge(&omise.ChargeParams{
Amount: amount,
Currency: currency,
Card: token,
})
if err != nil {
userMessage := getUserMessage(err)
return userMessage, err
}
return "การชำระเงินสำเร็จ!", nil
}
6. บันทึกข้อผิดพลาดสำหรับการดีบัก
# ✅ ดี - บันทึกข้อผิดพลาดที่ครอบคลุม
require 'logger'
logger = Logger.new('omise_errors.log')
begin
charge = Omise::Charge.create({
amount: 100000,
currency: 'thb',
card: token
})
rescue Omise::Error => e
# บันทึกข้อมูลข้อผิดพลาดโดยละเอียด
logger.error({
timestamp: Time.now.iso8601,
error_type: 'omise_api_error',
http_status: e.http_status,
error_code: e.code,
error_message: e.message,
request_id: e.request_id,
charge_params: {
amount: 100000,
currency: 'thb',
token: token[0..10] + '...' # โทเค็นบางส่วนเพื่อความปลอดภัย
},
backtrace: e.backtrace.first(5)
}.to_json)
# raise ต่อหรือจัดการ
raise
end
7. อย่าเปิดเผยรายละเอียดข้อผิดพลาดที่ละเอียดอ่อน
// ❌ ไม่ดี - เปิดเผยรายละเอียดภายใน
app.post('/charge', async (req, res) => {
try {
const charge = await omise.charges.create(req.body);
res.json(charge);
} catch (error) {
// อย่าทำแบบนี้ - เปิดเผยคีย์ API, เส้นทางภายใน ฯลฯ
res.status(500).json({ error: error.toString() });
}
});
// ✅ ดี - ข้อความข้อผิดพลาดที่ปลอดภัย
app.post('/charge', async (req, res) => {
try {
const charge = await omise.charges.create({
amount: req.body.amount,
currency: req.body.currency,
card: req.body.token
});
res.json({ success: true, charge_id: charge.id });
} catch (error) {
// บันทึกข้อผิดพลาดทั้งหมดฝั่งเซิร์ฟเวอร์
console.error('การเรียกเก็บเงินล้มเหลว:', error);
// ส่งคืนข้อความที่ปลอดภัยแก่ไคลเอนต์
const safeMessage = {
success: false,
error: {
code: error.code || 'unknown',
message: getUserFriendlyMessage(error.code)
}
};
res.status(error.statusCode || 500).json(safeMessage);
}
});