สรุปแบบย่อ
iPay API ช่วยให้นักพัฒนาสามารถผสานรวมการประมวลผลการชำระเงิน การออกใบแจ้งหนี้ และการทำธุรกรรมทางการเงินเข้ากับระบบได้โดยตรง รองรับการยืนยันตัวตนด้วย OAuth 2.0 และ API key, RESTful endpoints ครอบคลุมทั้งการชำระเงิน การคืนเงิน การทำธุรกรรม และการกระทบยอด ปฏิบัติตามมาตรฐาน PCI DSS และ rate limit คู่มือนี้เน้นขั้นตอนการตั้งค่าการยืนยันตัวตน การประมวลผลการชำระเงิน การเชื่อม Webhook การรักษาความปลอดภัย และเทคนิคการ deploy ใช้งานจริง
บทนำ
การประมวลผลการชำระเงินดิจิทัลทั่วโลกมีมูลค่าสูงมาก นักพัฒนาที่สร้างแพลตฟอร์มอีคอมเมิร์ซ SaaS หรือ marketplace จำเป็นต้องผสานรวม Payment API เพื่อรองรับการรับเงินและความปลอดภัย
ธุรกิจส่วนใหญ่สูญเสียรายได้จากการชำระเงินที่ไม่สำเร็จ การกระทบยอดด้วยตนเอง และการฉ้อโกง การผสาน Payment API ที่ดีจะช่วยอัตโนมัติขั้นตอน ลดความผิดพลาด และรองรับการตรวจจับการฉ้อโกง
คู่มือนี้จะนำเสนอขั้นตอนการผสานรวม Payment API แบบครบวงจร ตั้งแต่การยืนยันตัวตน การชำระเงิน การคืนเงิน การจัดการ Webhook ปฏิบัติตาม PCI DSS ความปลอดภัย และกลยุทธ์ deploy ในสภาพแวดล้อมจริง เพื่อให้ระบบพร้อมใช้งานจริง
💡Apidog ช่วยให้นักพัฒนาทดสอบ Payment API ได้ง่ายขึ้น ทดสอบ endpoint ใน Sandbox, ตรวจสอบลายเซ็น Webhook, วิเคราะห์ response และแก้ไขปัญหาการอินทิเกรตในที่เดียว นำเข้า spec API, สร้าง mock response และแชร์ test case กับทีม
หมายเหตุ: คู่มือนี้ครอบคลุม pattern การอินทิเกรต Payment API ทั่วไปที่ใช้กับ iPay และ payment processor อื่นๆ รายละเอียด endpoint และ auth อาจแตกต่างกัน ควรอ้างอิงเอกสารของ iPay เสมอ
iPay API คืออะไร?
Payment API เช่น iPay มีอินเทอร์เฟซ RESTful สำหรับธุรกรรมทางการเงิน API นี้จัดการ:
- การอนุมัติและเรียกเก็บเงิน
- การคืนเงินและ chargeback
- ประวัติ transaction และรายงาน
- การสร้างโทเคนข้อมูลบัตร (secure card storage)
- Subscription/recurring billing
- การออกและจัดการ invoice
- การกระทบยอด/settlement
- การตรวจจับและป้องกัน fraud
คุณสมบัติหลัก
| คุณสมบัติ | คำอธิบาย |
|---|---|
| RESTful API | Endpoints ที่ใช้ JSON |
| OAuth 2.0 + API Keys | การยืนยันตัวตนที่ปลอดภัย |
| Webhooks | การแจ้งเตือนการชำระเงินแบบเรียลไทม์ |
| การสร้างโทเคน | การจัดเก็บข้อมูลบัตรอย่างปลอดภัย |
| 3D Secure | การปฏิบัติตามข้อกำหนด SCA |
| PCI DSS | ต้องปฏิบัติตามระดับ 1 |
| หลายสกุลเงิน | รองรับมากกว่า 100 สกุลเงิน |
| เครื่องมือป้องกันการฉ้อโกง | การให้คะแนนความเสี่ยง, การตรวจสอบความเร็ว |
ภาพรวมขั้นตอนการชำระเงิน
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Customer │───▶│ Merchant │───▶│ Payment │
│ (Browser) │ │ (Server) │ │ Gateway │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
│ 1. Enter Card │ │
│───────────────────▶│ │
│ │ │
│ 2. Tokenize │ │
│───────────────────▶│ 3. Create Intent │
│ │───────────────────▶│
│ │ │
│ │ 4. Confirm Payment│
│ │───────────────────▶│
│ │ │
│ │ 5. Result │
│ │◀───────────────────│
│ │ │
│ 6. Receipt │ │
│◀───────────────────│ │
สภาพแวดล้อม API
| สภาพแวดล้อม | URL | กรณีการใช้งาน |
|---|---|---|
| Sandbox | https://sandbox.ipay.com/api |
การพัฒนา, การทดสอบ |
| Production | https://api.ipay.com/api |
ธุรกรรมจริง |
เริ่มต้นใช้งาน: การตั้งค่าการยืนยันตัวตน
ขั้นตอนที่ 1: สร้างบัญชี iPay
- ลงทะเบียนผู้ค้ากับ iPay
- ยืนยันตัวตนธุรกิจ (KYB)
- ส่งเอกสาร: หนังสือรับรองบริษัท, รายละเอียดบัญชีธนาคาร, บัตรประชาชน
- รออนุมัติ (1-3 วันทำการ)
ขั้นตอนที่ 2: รับข้อมูลรับรอง API
- เข้าสู่ระบบ iPay Merchant Dashboard
- ไปที่ การตั้งค่า > API Keys
- สร้าง API key ใหม่
- เก็บข้อมูลรับรองอย่างปลอดภัย
# .env (ห้าม commit เข้า git)
IPAY_API_KEY="live_xxxxxxxxxxxxxxxxxxxx"
IPAY_API_SECRET="secret_xxxxxxxxxxxxxxxxxxxx"
IPAY_WEBHOOK_SECRET="whsec_xxxxxxxxxxxxxxxxxxxx"
Security Tip: ใช้คีย์แยกสำหรับ Sandbox/Production
ขั้นตอนที่ 3: ทำความเข้าใจวิธีการยืนยันตัวตน
| วิธีการ | เหมาะสำหรับ | ระดับความปลอดภัย |
|---|---|---|
| Basic Auth | เซิร์ฟเวอร์ต่อเซิร์ฟเวอร์ | สูง |
| OAuth 2.0 | Multi-tenant app | สูงกว่า |
| JWT | Microservices | สูง |
ขั้นตอนที่ 4: เรียกใช้ API ที่มีการยืนยันตัวตน
สร้าง client สำหรับเรียก API พร้อม auth header:
const IPAY_BASE_URL = process.env.IPAY_SANDBOX
? 'https://sandbox.ipay.com/api'
: 'https://api.ipay.com/api';
const ipayRequest = async (endpoint, options = {}) => {
const apiKey = process.env.IPAY_API_KEY;
const apiSecret = process.env.IPAY_API_SECRET;
// Basic Auth (Base64)
const authHeader = Buffer.from(`${apiKey}:${apiSecret}`).toString('base64');
const response = await fetch(`${IPAY_BASE_URL}${endpoint}`, {
...options,
headers: {
'Authorization': `Basic ${authHeader}`,
'Content-Type': 'application/json',
'Idempotency-Key': options.idempotencyKey || generateIdempotencyKey(),
...options.headers
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`iPay API Error: ${error.message}`);
}
return response.json();
};
function generateIdempotencyKey() {
return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
// ตัวอย่างการใช้งาน
const account = await ipayRequest('/account');
console.log(`ผู้ค้า: ${account.business_name}`);
การประมวลผลการชำระเงิน
การสร้าง Payment Intent
เริ่มต้นการชำระเงินใหม่:
const createPayment = async (paymentData) => {
const payment = {
amount: paymentData.amount, // หน่วยย่อย เช่น เซ็นต์
currency: paymentData.currency || 'USD',
customer: paymentData.customerId,
payment_method: paymentData.paymentMethodId,
confirm: true,
description: paymentData.description,
metadata: {
orderId: paymentData.orderId,
customerId: paymentData.customerId
},
capture_method: paymentData.captureMethod || 'automatic',
statement_descriptor: paymentData.statementDescriptor || 'MYCOMPANY'
};
const response = await ipayRequest('/payments', {
method: 'POST',
body: JSON.stringify(payment),
idempotencyKey: paymentData.idempotencyKey
});
return response;
};
// ตัวอย่าง
const payment = await createPayment({
amount: 2999, // $29.99
currency: 'USD',
customerId: 'cus_12345',
paymentMethodId: 'pm_67890',
description: 'Order #ORD-001',
orderId: 'ORD-001',
statementDescriptor: 'MYCOMPANY INC'
});
console.log(`สถานะการชำระเงิน: ${payment.status}`);
console.log(`รหัสการชำระเงิน: ${payment.id}`);
แผนผังสถานะการชำระเงิน
requires_payment_method → requires_confirmation → requires_action
→ processing → requires_capture → succeeded
→ failed
→ canceled
วิธีการชำระเงิน
| วิธีการ | ประเภท | กรณีการใช้งาน |
|---|---|---|
card |
บัตรเครดิต/เดบิต | การชำระเงินมาตรฐาน |
bank_transfer |
ACH, SEPA | โอนเงินค่าธรรมเนียมต่ำ |
digital_wallet |
Apple Pay, Google Pay | ชำระผ่านมือถือ |
buy_now_pay_later |
Klarna, Afterpay | ชำระแบบผ่อนชำระ |
การสร้างโทเคนข้อมูลบัตร
จัดเก็บข้อมูลบัตรอย่างปลอดภัย (ฝั่ง client เท่านั้น):
const tokenizeCard = async (cardData) => {
// ควรทำบน client เท่านั้น!
const response = await fetch(`${IPAY_BASE_URL}/tokens`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${CLIENT_PUBLISHABLE_KEY}`
},
body: JSON.stringify({
card: {
number: cardData.number,
exp_month: cardData.expMonth,
exp_year: cardData.expYear,
cvc: cardData.cvc
}
})
});
const token = await response.json();
return token; // ส่ง token.id ไป server
};
// server: ใช้ token เพื่อสร้าง payment method
const createPaymentMethod = async (tokenId, customerId) => {
const response = await ipayRequest('/payment_methods', {
method: 'POST',
body: JSON.stringify({
type: 'card',
token: tokenId,
customer: customerId
})
});
return response;
};
การยืนยันตัวตน 3D Secure
รองรับ SCA (Strong Customer Authentication):
const createPaymentWith3DS = async (paymentData) => {
const payment = await createPayment({
...paymentData,
confirmation_token: true // ส่งคืน client secret สำหรับ 3DS
});
if (payment.status === 'requires_action') {
// ไคลเอนต์ต้องทำ 3DS
return {
requiresAction: true,
clientSecret: payment.client_secret,
nextAction: payment.next_action
};
}
return { success: true, payment };
}
// ฝั่งไคลเอนต์: ใช้ iPay.js หรือ mobile SDK เพื่อแสดงหน้าการยืนยันตัวตน
การจัดการการคืนเงิน
การประมวลผลการคืนเงินเต็มจำนวน
const refundPayment = async (paymentId, reason = null) => {
const refund = {
payment: paymentId,
reason: reason || 'requested_by_customer'
};
const response = await ipayRequest('/refunds', {
method: 'POST',
body: JSON.stringify(refund),
idempotencyKey: `refund_${paymentId}_${Date.now()}`
});
return response;
};
// ตัวอย่าง
const refund = await refundPayment('pay_12345', 'duplicate');
console.log(`สถานะการคืนเงิน: ${refund.status}`);
console.log(`รหัสการคืนเงิน: ${refund.id}`);
การประมวลผลการคืนเงินบางส่วน
const partialRefund = async (paymentId, amount, reason = null) => {
const refund = {
payment: paymentId,
amount: amount, // หน่วยย่อย เช่น เซ็นต์
reason: reason || 'requested_by_customer'
};
const response = await ipayRequest('/refunds', {
method: 'POST',
body: JSON.stringify(refund),
idempotencyKey: `refund_${paymentId}_${amount}_${Date.now()}`
});
return response;
};
// ตัวอย่าง คืนเงิน $15.00 จาก $29.99
const refund = await partialRefund('pay_12345', 1500, 'partial_ship');
console.log(`คืนเงิน: $${refund.amount / 100}`);
เหตุผลในการคืนเงิน
| รหัสเหตุผล | คำอธิบาย |
|---|---|
duplicate |
การเรียกเก็บเงินซ้ำ |
fraudulent |
ธุรกรรมฉ้อโกง |
requested_by_customer |
ลูกค้าร้องขอ |
order_canceled |
การยกเลิกคำสั่งซื้อ |
product_not_received |
ไม่ได้รับสินค้า |
product_not_as_described |
สินค้าไม่ตรงตามที่แจ้ง |
การจัดการลูกค้า
การสร้างลูกค้า
const createCustomer = async (customerData) => {
const customer = {
email: customerData.email,
name: customerData.name,
phone: customerData.phone,
metadata: {
internalId: customerData.internalId,
tier: customerData.tier
}
};
const response = await ipayRequest('/customers', {
method: 'POST',
body: JSON.stringify(customer)
});
return response;
};
// ตัวอย่าง
const customer = await createCustomer({
email: 'customer@example.com',
name: 'John Doe',
phone: '+1-555-0123',
internalId: 'USR-12345',
tier: 'premium'
});
console.log(`สร้างลูกค้าแล้ว: ${customer.id}`);
การผูกวิธีการชำระเงินกับลูกค้า
const attachPaymentMethod = async (paymentMethodId, customerId) => {
const response = await ipayRequest(`/payment_methods/${paymentMethodId}/attach`, {
method: 'POST',
body: JSON.stringify({
customer: customerId
})
});
return response;
};
// ตัวอย่าง
await attachPaymentMethod('pm_67890', 'cus_12345');
การแสดงรายการวิธีการชำระเงินของลูกค้า
const getCustomerPaymentMethods = async (customerId) => {
const response = await ipayRequest(`/customers/${customerId}/payment_methods`);
return response;
};
// ตัวอย่าง
const methods = await getCustomerPaymentMethods('cus_12345');
methods.data.forEach(method => {
console.log(`${method.card.brand} ลงท้ายด้วย ${method.card.last4}`);
console.log(`หมดอายุ: ${method.card.exp_month}/${method.card.exp_year}`);
});
Webhooks
การกำหนดค่า Webhooks
- เข้าสู่ระบบ iPay Dashboard
- ไปที่ นักพัฒนา > Webhooks
- เพิ่ม endpoint (URL ที่เป็น HTTPS)
- เลือก event ที่ต้องการ subscribe
เหตุการณ์ Webhook
| เหตุการณ์ | ตัวกระตุ้น |
|---|---|
payment.succeeded |
การชำระเงินสำเร็จ |
payment.failed |
การชำระเงินถูกปฏิเสธ |
payment.refunded |
การคืนเงินถูกดำเนินการ |
payment.disputed |
Chargeback |
customer.created |
ลูกค้าใหม่ |
customer.subscription.updated |
เปลี่ยนแปลง subscription |
การจัดการ Webhooks
const express = require('express');
const crypto = require('crypto');
const app = express();
app.post('/webhooks/ipay', express.raw({ type: 'application/json' }), async (req, res) => {
const signature = req.headers['ipay-signature'];
const payload = req.body;
// ตรวจสอบลายเซ็น
const isValid = verifyWebhookSignature(payload, signature, process.env.IPAY_WEBHOOK_SECRET);
if (!isValid) {
console.error('ลายเซ็น Webhook ไม่ถูกต้อง');
return res.status(401).send('ไม่ได้รับอนุญาต');
}
const event = JSON.parse(payload.toString());
// Dispatch event
switch (event.type) {
case 'payment.succeeded':
await handlePaymentSucceeded(event.data);
break;
case 'payment.failed':
await handlePaymentFailed(event.data);
break;
case 'payment.refunded':
await handlePaymentRefunded(event.data);
break;
case 'payment.disputed':
await handlePaymentDisputed(event.data);
break;
default:
console.log('ประเภทเหตุการณ์ที่ไม่ได้จัดการ:', event.type);
}
res.status(200).send('OK');
});
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
);
}
async function handlePaymentSucceeded(data) {
console.log(`การชำระเงินสำเร็จ: ${data.id}`);
await db.orders.update(data.metadata.orderId, {
status: 'paid',
paymentId: data.id,
paidAt: new Date()
});
await sendOrderConfirmation(data.metadata.orderId);
}
async function handlePaymentFailed(data) {
console.log(`การชำระเงินล้มเหลว: ${data.id} - ${data.failure_code}`);
await sendPaymentFailedEmail(data.customer, data.failure_message);
await db.orders.update(data.metadata.orderId, {
status: 'payment_failed',
failureReason: data.failure_message
});
}
ความปลอดภัยและการปฏิบัติตามข้อกำหนด
ข้อกำหนด PCI DSS
ต้องปฏิบัติตาม PCI DSS:
| ข้อกำหนด | การใช้งาน |
|---|---|
| เครือข่ายที่ปลอดภัย | ใช้ HTTPS, firewall, config ที่ปลอดภัย |
| ป้องกันข้อมูลบัตร | ห้ามเก็บ CVV, เข้ารหัส PAN |
| จัดการช่องโหว่ | อัปเดต security, มี antivirus |
| ควบคุม access | Least privilege, MFA, unique code |
| เฝ้าระวัง | logging, intrusion detection |
| นโยบายความปลอดภัย | policy, training |
แนวทางปฏิบัติที่ดีที่สุดด้านความปลอดภัย
// 1. ใช้ tokenization ห้ามจัดการ card data ดิบ
const token = await tokenizeCard(cardData); // ฝั่ง client
// 2. ใช้ idempotency key กับทุกการชำระเงิน
const idempotencyKey = `pay_${orderId}_${Date.now()}`;
// 3. ตรวจสอบยอดเงินฝั่ง server
if (req.body.amount !== calculatedAmount) {
throw new Error('ยอดเงินไม่ตรงกัน - เสี่ยงถูกปลอมแปลง');
}
// 4. Logging (ไม่เก็บ card/CVV)
logger.info('Payment attempted', {
orderId,
amount,
currency,
customerId,
timestamp: new Date().toISOString()
// ห้าม log: หมายเลขบัตร, CVV, รายละเอียด sensitive
});
// 5. ใช้ env variable สำหรับ secret
const apiKey = process.env.IPAY_API_KEY;
// 6. Rate limit endpoint
const paymentLimiter = rateLimit({
windowMs: 60000,
max: 10 // 10 requests/นาที
});
รายการตรวจสอบการปรับใช้ในสภาพแวดล้อมจริง
ตรวจสอบก่อนเปิด production:
- [ ] กรอก PCI DSS self-assessment
- [ ] ใช้ HTTPS กับ endpoint ทุกตัว
- [ ] เก็บ API keys ใน secret manager
- [ ] ตรวจสอบ webhook signature
- [ ] ใช้ idempotency ทุก payment
- [ ] Logging ครบ แต่ไม่เก็บ sensitive data
- [ ] ตั้งกฎ fraud detection
- [ ] ทดสอบ refund/dispute flow
- [ ] มี playbook กรณีชำระเงินล้มเหลว
- [ ] ตั้ง monitoring/alert
- [ ] มี payment processor สำรอง
กรณีการใช้งานจริง
การชำระเงินของอีคอมเมิร์ซ
- ปัญหา: ชำระเงินด้วยตนเอง, abandon rate สูง
- แนวทาง: Checkout หน้าเดียว, บัตรโทเคน
- ผลลัพธ์: conversion rate +35%, จ่ายเงินทันที
การเรียกเก็บเงินค่าสมัครสมาชิก SaaS
- ปัญหา: ออก invoice/manual billing
- แนวทาง: Recurring payment, retry อัตโนมัติ
- ผล: 95% จ่ายตรงเวลา, ลด manual workload
Escrow ของ marketplace
- ปัญหา: แบ่งจ่ายหลายฝ่าย
- แนวทาง: Payment intent + schedule payout
- ผล: จ่ายผู้ขายอัตโนมัติ ลด fraud
บทสรุป
การผสาน Payment API ต้องโฟกัสความปลอดภัย, compliance และ error handling ประเด็นสำคัญ:
- ห้ามจัดการข้อมูลบัตรดิบ ให้ใช้ tokenization
- ใช้ idempotency กับทุก transaction
- ตรวจสอบ webhook signature
- ปฏิบัติตาม PCI DSS
- ทดสอบใน Sandbox ก่อน production
- Apidog ช่วยให้การทดสอบ API และ teamwork ง่ายขึ้น
คำถามที่พบบ่อย
ฉันจะยืนยันตัวตนกับ iPay API ได้อย่างไร?
ใช้ Basic Auth (API key + secret) หรือ OAuth 2.0 (multi-tenant app)
ฉันสามารถจัดเก็บรายละเอียดบัตรของลูกค้าได้หรือไม่?
ได้ แต่ต้องปฏิบัติตาม PCI DSS ใช้ tokenization เก็บข้อมูลบัตรบนระบบของ iPay
ฉันจะจัดการกับการชำระเงินที่ล้มเหลวได้อย่างไร?
ใช้ retry logic แบบ exponential backoff แจ้งลูกค้า และเสนอ payment method ทางเลือก
Idempotency คืออะไร และทำไมจึงสำคัญ?
Idempotency ทำให้การเรียกซ้ำด้วยคีย์เดียวกันได้ผลลัพธ์เดียวกัน ป้องกันการเรียกเก็บเงินซ้ำ
ฉันจะทดสอบการชำระเงินโดยไม่ต้องเรียกเก็บเงินจากบัตรได้อย่างไร?
ใช้โหมด Sandbox และหมายเลขบัตรทดสอบจากเอกสาร iPay
Webhook signatures คืออะไร?
ลายเซ็นที่ยืนยันว่า Webhook มาจาก iPay (ไม่ใช่ third party) เพื่อป้องกัน spoofing
บทความนี้เน้น implementation สำหรับ developer ที่ต้องการผสาน Payment API ใน production อย่างถูกต้อง ปลอดภัย และนำไปใช้ได้จริง
Top comments (0)