Bot Jualan dengan Payment Gateway
Cara integrasi bot jualan WhatsApp dengan payment gateway. Midtrans, Xendit, Duitku. Auto payment link, verifikasi otomatis!
Manual konfirmasi transfer? Kuno!
Integrasi payment gateway membuat proses pembayaran 100% otomatis - customer bayar, sistem verify, order langsung diproses.
Kenapa Payment Gateway?
📊 MANUAL vs PAYMENT GATEWAY:
MANUAL TRANSFER:
❌ Kirim rekening manual
❌ Customer screenshot bukti
❌ Cek mutasi satu-satu
❌ Human error (salah nominal)
❌ Delay verifikasi
PAYMENT GATEWAY:
✅ Auto-generate payment link
✅ Multiple payment options
✅ Real-time verification
✅ Auto update order status
✅ 24/7 processingPayment Gateway Options
💳 POPULAR DI INDONESIA:
MIDTRANS:
- Bank transfer, VA, e-wallet
- Fee: 0.7% - 2.9%
- Trusted by Tokopedia, Gojek
XENDIT:
- VA, e-wallet, retail outlet
- Fee: 0.6% - 2.5%
- Good API documentation
DUITKU:
- Affordable fees
- Fee: 0.5% - 2%
- SME friendly
IPAYMU:
- Local option
- Fee: 1% - 2.5%
- Easy integration
FLIP:
- Bank transfer focus
- Fee: Rp 2,500 flat
- Good for B2BFlow dengan Payment Gateway
📱 CUSTOMER JOURNEY:
1. Customer order via bot
"Mau pesan Produk A 2 pcs"
2. Bot generate payment link
"Total Rp 200.000, bayar di sini: [LINK]"
3. Customer klik & pilih metode
VA, GoPay, OVO, QRIS, etc.
4. Customer bayar
Langsung di app mereka
5. Payment gateway notify bot
Webhook: "Payment received!"
6. Bot update customer
"Pembayaran diterima! Pesanan diproses."
7. Order auto-fulfilled
Langsung masuk sistem!Template Messages
Payment Link:
💳 PEMBAYARAN
Order: #ORD-20260217-001
📋 Ringkasan:
━━━━━━━━━━━━━━━━━━━━
- Produk A x 2 - Rp 150.000
- Produk B x 1 - Rp 50.000
━━━━━━━━━━━━━━━━━━━━
Subtotal: Rp 200.000
Ongkir: Rp 15.000
TOTAL: Rp 215.000
💳 BAYAR SEKARANG:
👉 [PAYMENT LINK]
Metode tersedia:
- Transfer Bank (VA)
- GoPay, OVO, DANA
- QRIS
- Indomaret/Alfamart
⏰ Link berlaku 24 jam
Sudah bayar? Otomatis terverifikasi!VA Instructions:
🏦 VIRTUAL ACCOUNT
Order: #ORD-20260217-001
Total: Rp 215.000
Pilih bank untuk VA:
1️⃣ BCA VA
2️⃣ Mandiri VA
3️⃣ BNI VA
4️⃣ BRI VA
5️⃣ Permata VA
Ketik angka untuk dapat nomor VA!
Atau bayar via:
6️⃣ E-Wallet (GoPay/OVO/DANA)
7️⃣ QRIS
8️⃣ Retail (Indomaret/Alfa)VA Number Generated:
🏦 NOMOR VIRTUAL ACCOUNT
Order: #ORD-20260217-001
Bank: BCA
━━━━━━━━━━━━━━━━━━━━
VA Number: 7007081234567890
Nominal: Rp 215.000 (exact)
━━━━━━━━━━━━━━━━━━━━
⏰ Bayar sebelum:
18 Feb 2026, 14:30 WIB
CARA BAYAR:
📱 M-Banking:
1. Login BCA mobile
2. Menu Transfer > Virtual Account
3. Masukkan no VA di atas
4. Konfirmasi & bayar
🏧 ATM:
1. Pilih Transaksi Lainnya
2. Transfer > Virtual Account
3. Masukkan no VA
4. Konfirmasi nominal
✅ Pembayaran otomatis terverifikasi!E-Wallet (QRIS):
📱 BAYAR VIA QRIS
Order: #ORD-20260217-001
Total: Rp 215.000
[QRIS IMAGE]
Scan QR di atas dengan:
- GoPay
- OVO
- DANA
- ShopeePay
- LinkAja
- Semua e-wallet QRIS
⏰ QR berlaku: 30 menit
Setelah bayar, otomatis terverifikasi!Payment Success:
✅ PEMBAYARAN BERHASIL!
Order: #ORD-20260217-001
Terima kasih! Pembayaran diterima 🎉
📋 Detail:
━━━━━━━━━━━━━━━━━━━━
Nominal: Rp 215.000
Metode: BCA Virtual Account
Waktu: 17 Feb 2026, 14:25 WIB
━━━━━━━━━━━━━━━━━━━━
📦 Status Order: DIPROSES
Estimasi kirim: Hari ini!
Kami akan kirim no resi
setelah paket dijemput kurir.
Terima kasih sudah belanja! 💕Payment Expired:
⚠️ PEMBAYARAN EXPIRED
Order: #ORD-20260217-001
Maaf, waktu pembayaran sudah habis 😔
Pesanan otomatis dibatalkan.
Mau order ulang?
Ketik ORDER ULANG untuk
generate link pembayaran baru!
Stok produk yang kakak pesan
masih tersedia kok! 😊Implementation
Create Payment (Midtrans):
javascript
const midtransClient = require('midtrans-client');
const snap = new midtransClient.Snap({
isProduction: false,
serverKey: process.env.MIDTRANS_SERVER_KEY,
clientKey: process.env.MIDTRANS_CLIENT_KEY
});
async function createPayment(order) {
const parameter = {
transaction_details: {
order_id: order.id,
gross_amount: order.total
},
customer_details: {
first_name: order.customerName,
phone: order.customerPhone
},
item_details: order.items.map(item => ({
id: item.productId,
price: item.price,
quantity: item.quantity,
name: item.name
})),
expiry: {
unit: 'hours',
duration: 24
}
};
const transaction = await snap.createTransaction(parameter);
return {
paymentUrl: transaction.redirect_url,
token: transaction.token
};
}Create VA (Xendit):
javascript
const Xendit = require('xendit-node');
const xendit = new Xendit({ secretKey: process.env.XENDIT_SECRET });
async function createVirtualAccount(order, bankCode) {
const { VirtualAcc } = xendit;
const va = new VirtualAcc({});
const virtualAccount = await va.createFixedVA({
externalID: order.id,
bankCode: bankCode, // BCA, MANDIRI, BNI, BRI
name: order.customerName,
expectedAmt: order.total,
expirationDate: new Date(Date.now() + 24 * 60 * 60 * 1000)
});
return {
vaNumber: virtualAccount.account_number,
bankCode: virtualAccount.bank_code,
expectedAmount: virtualAccount.expected_amount,
expirationDate: virtualAccount.expiration_date
};
}Webhook Handler:
javascript
// Handle payment notification
app.post('/webhook/payment', async (req, res) => {
const notification = req.body;
// Verify signature (important!)
const isValid = verifySignature(notification);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
const orderId = notification.order_id;
const status = notification.transaction_status;
if (status === 'settlement' || status === 'capture') {
// Payment successful
await db.orders.updateOne(
{ id: orderId },
{
$set: {
paymentStatus: 'paid',
paidAt: new Date(),
paymentMethod: notification.payment_type
}
}
);
// Notify customer
const order = await db.orders.findOne({ id: orderId });
await sendPaymentSuccessMessage(order);
// Trigger fulfillment
await startFulfillment(order);
}
if (status === 'expire') {
// Payment expired
await db.orders.updateOne(
{ id: orderId },
{ $set: { paymentStatus: 'expired', status: 'cancelled' } }
);
const order = await db.orders.findOne({ id: orderId });
await sendPaymentExpiredMessage(order);
}
res.status(200).send('OK');
});Payment Options
Let Customer Choose:
javascript
async function handlePaymentChoice(phone, orderId, choice) {
const order = await db.orders.findOne({ id: orderId });
switch (choice) {
case '1': // BCA VA
const bcaVA = await createVirtualAccount(order, 'BCA');
await sendVAMessage(phone, bcaVA, 'BCA');
break;
case '6': // E-Wallet
const ewalletLink = await createEwalletPayment(order);
await sendEwalletMessage(phone, ewalletLink);
break;
case '7': // QRIS
const qris = await createQRIS(order);
await sendQRISMessage(phone, qris);
break;
default:
await sendPaymentOptionsMenu(phone, orderId);
}
}Best Practices
DO ✅
- Multiple payment options
- Clear instructions per method
- Real-time status updates
- Handle expiry gracefully
- Retry payment option
- Secure webhook verificationDON'T ❌
- Single payment method only
- No timeout handling
- Manual verification
- Ignore failed payments
- No payment confirmation
- Skip signature verificationFAQ
Payment gateway mana yang terbaik?
Tergantung kebutuhan. Midtrans untuk fitur lengkap, Xendit untuk API bagus, Duitku untuk biaya murah.
Berapa fee payment gateway?
0.5% - 3% tergantung metode. VA biasanya flat Rp 4,000-5,000. E-wallet sekitar 1.5-2%.
Perlu verifikasi manual juga?
Tidak! Payment gateway handle semua. Tapi siapkan fallback untuk edge cases.
Kesimpulan
Payment gateway = Autopilot payments!
| Manual Transfer | Payment Gateway |
|---|---|
| Screenshot bukti | Auto verify |
| Cek mutasi manual | Real-time |
| Human error | Accurate |
| Delay processing | Instant |