Ringkasan
API iPay memungkinkan pengembang untuk mengintegrasikan pemrosesan pembayaran, faktur, dan transaksi keuangan secara terprogram. API ini menggunakan otentikasi OAuth 2.0 dan kunci API, endpoint RESTful untuk pembayaran, pengembalian dana, transaksi, dan rekonsiliasi, dengan persyaratan kepatuhan PCI DSS dan batas laju standar industri. Panduan ini mencakup pengaturan otentikasi, pemrosesan pembayaran, integrasi webhook, kepatuhan keamanan, dan strategi penerapan produksi.
Pendahuluan
Pemrosesan pembayaran digital menangani lebih dari $8 triliun setiap tahun di seluruh dunia. Untuk pengembang yang membangun platform e-commerce, aplikasi SaaS, atau marketplace, integrasi API pembayaran sangat krusial agar pembayaran pelanggan dapat diterima secara aman dan sesuai regulasi.
Bisnis dapat kehilangan 5-10% pendapatan akibat pembayaran gagal, rekonsiliasi manual, dan penipuan. Integrasi API pembayaran yang baik mengotomatiskan proses pembayaran, mengurangi kegagalan dengan retry cerdas, mengaktifkan rekonsiliasi otomatis, dan mendeteksi penipuan secara real-time.
Panduan ini membahas langkah implementasi otentikasi, pemrosesan pembayaran, pengembalian dana, webhook, PCI DSS, keamanan, dan strategi deployment produksi. Dengan mengikuti langkah-langkah berikut, Anda akan mendapatkan integrasi pembayaran siap produksi.
π‘ Tips:
Apidog memudahkan pengujian API pembayaran: uji endpoint di sandbox, validasi webhook, periksa respons transaksi, dan debug masalah integrasi dalam satu workspace. Impor spesifikasi API, buat mock response, dan share skenario pengujian ke tim.
Catatan: Panduan ini menggunakan pola integrasi API pembayaran umum untuk iPay dan gateway serupa. URL endpoint dan detail otentikasi dapat bervariasiβpastikan cek dokumentasi resmi iPay saat implementasi.
Apa itu API iPay?
API pembayaran seperti iPay menyediakan antarmuka RESTful untuk transaksi keuangan:
- Otorisasi dan penangkapan pembayaran
- Pengembalian dana dan chargeback
- Riwayat transaksi serta pelaporan
- Tokenisasi pelanggan (vault)
- Langganan dan penagihan berulang
- Pembuatan/manajemen faktur
- Rekonsiliasi dan settlement
- Deteksi serta pencegahan penipuan
Fitur Utama
| Fitur | Deskripsi |
|---|---|
| API RESTful | Endpoint berbasis JSON |
| OAuth 2.0 + Kunci API | Otentikasi aman |
| Webhooks | Notifikasi pembayaran real-time |
| Tokenisasi | Penyimpanan kartu aman |
| 3D Secure | Kepatuhan SCA |
| PCI DSS | Kepatuhan Level 1 wajib |
| Multi-Mata Uang | 100+ mata uang |
| Alat Penipuan | Penilaian risiko, rate check |
Gambaran Umum Alur Pembayaran
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β Pelanggan βββββΆβ Pedagang βββββΆβ Gerbang β
β (Peramban)β β (Server) β β Pembayaran β
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β β β
β 1. Masukkan Kartu β β
βββββββββββββββββββββΆβ β
β β β
β 2. Tokenisasi β β
βββββββββββββββββββββΆβ 3. Buat Niat β
β βββββββββββββββββββββΆβ
β β β
β β 4. Konfirmasi Pembayaranβ
β βββββββββββββββββββββΆβ
β β β
β β 5. Hasil β
β ββββββββββββββββββββββ
β β β
β 6. Resi β β
ββββββββββββββββββββββ β
Lingkungan API
| Lingkungan | URL | Kasus Penggunaan |
|---|---|---|
| Sandbox | https://sandbox.ipay.com/api |
Pengembangan, pengujian |
| Produksi | https://api.ipay.com/api |
Transaksi live |
Memulai: Pengaturan Otentikasi
Langkah 1: Buat Akun iPay
- Daftar merchant iPay
- Verifikasi bisnis (KYB)
- Upload dokumen:
- Registrasi bisnis
- Rekening bank
- ID pemerintah
- Tunggu approval (1-3 hari kerja)
Langkah 2: Dapatkan Kredensial API
- Login ke dashboard merchant iPay
- Navigasi ke Pengaturan > Kunci API
- Generate kunci API baru
- Simpan kredensial dengan aman
# file .env (tidak boleh di-commit)
IPAY_API_KEY="live_xxxxxxxxxxxxxxxxxxxx"
IPAY_API_SECRET="secret_xxxxxxxxxxxxxxxxxxxx"
IPAY_WEBHOOK_SECRET="whsec_xxxxxxxxxxxxxxxxxxxx"
Tips keamanan: Gunakan kunci terpisah untuk sandbox dan produksi.
Langkah 3: Pilih Metode Otentikasi
| Metode | Rekomendasi | Keamanan |
|---|---|---|
| Otentikasi Dasar | Server-ke-server | Tinggi |
| OAuth 2.0 | Multi-tenant apps | Sangat tinggi |
| JWT | Mikroservis | Tinggi |
Langkah 4: Panggil API Terotentikasi
Buat klien API reusable untuk semua request:
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;
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)}`;
}
// Contoh pemakaian
const account = await ipayRequest('/account');
console.log(`Merchant: ${account.business_name}`);
Pemrosesan Pembayaran
Membuat Niat Pembayaran
Inisialisasi pembayaran:
const createPayment = async (paymentData) => {
const payment = {
amount: paymentData.amount, // dalam sen
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', // 'automatic' atau 'manual'
statement_descriptor: paymentData.statementDescriptor || 'MYCOMPANY'
};
const response = await ipayRequest('/payments', {
method: 'POST',
body: JSON.stringify(payment),
idempotencyKey: paymentData.idempotencyKey
});
return response;
};
// Contoh penggunaan
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(`Status pembayaran: ${payment.status}`);
console.log(`ID Pembayaran: ${payment.id}`);
Alur Status Pembayaran
membutuhkan_metode_pembayaran β membutuhkan_konfirmasi β membutuhkan_tindakan
β memproses β membutuhkan_penangkapan β berhasil
β gagal
β dibatalkan
Metode Pembayaran
| Metode | Tipe | Kasus Penggunaan |
|---|---|---|
kartu |
Kredit/Debit | Pembayaran standar |
transfer_bank |
ACH, SEPA | Transfer biaya rendah |
dompet_digital |
ApplePay, GPay | Checkout mobile |
beli_sekarang_bayar_nanti |
Klarna, Afterpay | Pembayaran cicilan |
Membuat Token Detail Kartu
Gunakan tokenisasi sisi klien, jangan pernah proses data kartu mentah di server:
const tokenizeCard = async (cardData) => {
// Sisi klien (browser/mobile)
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; // Kirim token.id ke server
};
// Server: Buat metode pembayaran dari token
const createPaymentMethod = async (tokenId, customerId) => {
const response = await ipayRequest('/payment_methods', {
method: 'POST',
body: JSON.stringify({
type: 'card',
token: tokenId,
customer: customerId
})
});
return response;
};
Otentikasi 3D Secure
Implementasi SCA (Strong Customer Authentication):
const createPaymentWith3DS = async (paymentData) => {
const payment = await createPayment({
...paymentData,
confirmation_token: true // Mengembalikan client secret untuk 3DS
});
if (payment.status === 'requires_action') {
// Klien harus menyelesaikan tantangan 3DS
return {
requiresAction: true,
clientSecret: payment.client_secret,
nextAction: payment.next_action
};
}
return { success: true, payment };
};
// Sisi klien: gunakan SDK iPay.js atau mobile untuk tantangan 3DS
Manajemen Pengembalian Dana
Pengembalian Dana Penuh
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;
};
// Contoh penggunaan
const refund = await refundPayment('pay_12345', 'duplicate');
console.log(`Status pengembalian dana: ${refund.status}`);
console.log(`ID Pengembalian Dana: ${refund.id}`);
Pengembalian Dana Sebagian
const partialRefund = async (paymentId, amount, reason = null) => {
const refund = {
payment: paymentId,
amount: amount, // sen
reason: reason || 'requested_by_customer'
};
const response = await ipayRequest('/refunds', {
method: 'POST',
body: JSON.stringify(refund),
idempotencyKey: `refund_${paymentId}_${amount}_${Date.now()}`
});
return response;
};
// Contoh: Refund $15.00 dari $29.99
const refund = await partialRefund('pay_12345', 1500, 'partial_ship');
console.log(`Dikembalikan: $${refund.amount / 100}`);
Alasan Pengembalian Dana
| Kode Alasan | Deskripsi |
|---|---|
duplikat |
Biaya duplikat |
penipuan |
Transaksi penipuan |
diminta_oleh_pelanggan |
Permintaan pelanggan |
pesanan_dibatalkan |
Order dibatalkan |
produk_belum_diterima |
Barang belum diterima |
produk_tidak_sesuai_deskripsi |
Barang tidak sesuai deskripsi |
Manajemen Pelanggan
Membuat Pelanggan
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;
};
// Contoh
const customer = await createCustomer({
email: 'customer@example.com',
name: 'John Doe',
phone: '+1-555-0123',
internalId: 'USR-12345',
tier: 'premium'
});
console.log(`Pelanggan dibuat: ${customer.id}`);
Melampirkan Metode Pembayaran ke Pelanggan
const attachPaymentMethod = async (paymentMethodId, customerId) => {
const response = await ipayRequest(`/payment_methods/${paymentMethodId}/attach`, {
method: 'POST',
body: JSON.stringify({
customer: customerId
})
});
return response;
};
// Contoh
await attachPaymentMethod('pm_67890', 'cus_12345');
Mencantumkan Metode Pembayaran Pelanggan
const getCustomerPaymentMethods = async (customerId) => {
const response = await ipayRequest(`/customers/${customerId}/payment_methods`);
return response;
};
// Contoh
const methods = await getCustomerPaymentMethods('cus_12345');
methods.data.forEach(method => {
console.log(`${method.card.brand} berakhir di ${method.card.last4}`);
console.log(`Kedaluwarsa: ${method.card.exp_month}/${method.card.exp_year}`);
});
Webhook
Konfigurasi Webhook
- Login ke dashboard iPay
- Navigasi ke Pengembang > Webhooks
- Klik Tambahkan Endpoint
- Masukkan URL HTTPS endpoint
- Pilih event yang ingin di-subscribe
Event Webhook
| Event | Trigger |
|---|---|
payment.succeeded |
Pembayaran selesai |
payment.failed |
Pembayaran gagal |
payment.refunded |
Refund diproses |
payment.disputed |
Chargeback diajukan |
customer.created |
Pelanggan baru |
customer.subscription.updated |
Langganan diubah |
Handler Webhook (Express.js)
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;
// Verifikasi tanda tangan webhook
const isValid = verifyWebhookSignature(payload, signature, process.env.IPAY_WEBHOOK_SECRET);
if (!isValid) {
console.error('Tanda tangan webhook tidak valid');
return res.status(401).send('Tidak Sah');
}
const event = JSON.parse(payload.toString());
// Route event ke handler
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('Jenis acara tidak tertangani:', 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(`Pembayaran berhasil: ${data.id}`);
// Perbarui status order di DB
await db.orders.update(data.metadata.orderId, {
status: 'paid',
paymentId: data.id,
paidAt: new Date()
});
// Kirim email konfirmasi ke pelanggan
await sendOrderConfirmation(data.metadata.orderId);
}
async function handlePaymentFailed(data) {
console.log(`Pembayaran gagal: ${data.id} - ${data.failure_code}`);
// Notifikasi ke pelanggan
await sendPaymentFailedEmail(data.customer, data.failure_message);
// Tandai pesanan gagal di DB
await db.orders.update(data.metadata.orderId, {
status: 'payment_failed',
failureReason: data.failure_message
});
}
Keamanan dan Kepatuhan
Persyaratan PCI DSS
Integrasi pembayaran harus memenuhi PCI DSS:
| Persyaratan | Implementasi |
|---|---|
| Jaringan Aman | HTTPS, firewall, konfigurasi aman |
| Perlindungan Data Pemegang | Jangan simpan CVV, enkripsi PAN |
| Manajemen Kerentanan | Patch rutin, anti-virus |
| Kontrol Akses | Privilege minimum, MFA, ID unik |
| Pemantauan | Logging, deteksi intrusi |
| Kebijakan Keamanan | Dokumentasi & pelatihan rutin |
Praktik Terbaik Keamanan
// 1. Gunakan tokenisasi - jangan pernah proses data kartu mentah
const token = await tokenizeCard(cardData); // Sisi klien
// 2. Terapkan idempotensi pada pembayaran
const idempotencyKey = `pay_${orderId}_${Date.now()}`;
// 3. Validasi amount di server
if (req.body.amount !== calculatedAmount) {
throw new Error('Ketidaksesuaian jumlah - kemungkinan manipulasi');
}
// 4. Logging transaksi tanpa data sensitif
logger.info('Upaya pembayaran', {
orderId,
amount,
currency,
customerId,
timestamp: new Date().toISOString()
// Jangan log: nomor kartu, CVV, detail lengkap
});
// 5. Gunakan environment variable untuk rahasia
const apiKey = process.env.IPAY_API_KEY;
// 6. Rate limit endpoint pembayaran
const paymentLimiter = rateLimit({
windowMs: 60000,
max: 10 // 10 transaksi per menit
});
Daftar Periksa Produksi
Sebelum live, pastikan:
- [ ] Lengkapi Kuesioner Penilaian Mandiri PCI DSS
- [ ] Semua endpoint pakai HTTPS
- [ ] Kunci API disimpan di secret manager
- [ ] Verifikasi tanda tangan webhook aktif
- [ ] Idempotensi diterapkan pada pembayaran
- [ ] Logging komprehensif (tanpa data sensitif)
- [ ] Aturan deteksi penipuan dikonfigurasi
- [ ] Uji refund dan dispute flow
- [ ] Ada runbook untuk kegagalan pembayaran
- [ ] Monitoring & alerting aktif
- [ ] Ada fallback payment processor
Kasus Penggunaan Dunia Nyata
Checkout E-commerce
- Tantangan: Proses manual, abandonment tinggi
- Solusi: Checkout satu halaman + tokenisasi kartu
- Hasil: Konversi +35%, pembayaran instan
Penagihan Langganan SaaS
- Tantangan: Invoice & koleksi manual
- Solusi: Pembayaran recurring + retry otomatis
- Hasil: Pembayaran tepat waktu 95%, hemat waktu admin 80%
Escrow Marketplace
- Tantangan: Pembayaran split antar vendor
- Solusi: Niat pembayaran + penjadwalan transfer
- Hasil: Pembayaran vendor otomatis, penipuan berkurang
Kesimpulan
Integrasi API pembayaran harus memperhatikan keamanan, kepatuhan, dan penanganan error:
- Jangan pernah proses data kartu mentahβgunakan tokenisasi
- Terapkan idempotensi pada semua pembayaran
- Verifikasi tanda tangan webhook untuk cegah fraud
- Patuhi PCI DSS
- Uji menyeluruh di sandbox sebelum live
- Apidog memudahkan pengujian API & kolaborasi tim
Bagian FAQ
Bagaimana cara melakukan otentikasi dengan API iPay?
Gunakan otentikasi Dasar (kunci API & rahasia), atau OAuth 2.0 untuk aplikasi multi-tenant.
Bisakah saya menyimpan detail kartu pelanggan?
Bisa, asalkan patuh PCI DSS. Gunakan tokenisasi agar kartu tersimpan aman di vault iPay.
Bagaimana menangani pembayaran gagal?
Implementasikan retry dengan backoff eksponensial, notifikasi pelanggan, dan sediakan metode pembayaran alternatif.
Apa itu idempotensi dan mengapa penting?
Idempotensi memastikan permintaan duplikat dengan kunci sama tidak menyebabkan biaya dobel.
Bagaimana menguji pembayaran tanpa charge ke kartu?
Gunakan mode sandbox dengan nomor kartu test dari dokumentasi iPay.
Apa itu tanda tangan webhook?
Tanda tangan kriptografi yang memverifikasi webhook benar-benar dikirim iPay, bukan pihak lain.
Top comments (0)