Integrasikan QRIS payment ke bot Telegram, WhatsApp, website, atau aplikasi kamu dengan mudah.
Semua endpoint API memerlukan API key yang dikirim lewat salah satu cara berikut:
Header (direkomendasikan)
x-api-key: NercPay_Wanzie_9f3a1b7c2e4d5f6a7b8c9d0e1f2a3b4c5d6e7f8a
Authorization Bearer
Authorization: Bearer NercPay_Wanzie_9f3a1b7c2e4d5f6a7b8c9d0e1f2a3b4c5d6e7f8a
Query param (tidak disarankan untuk produksi)
GET /api/v1/qris/status?qris_id=RO123&api_key=NercPay_Wanzie_xxx
| HTTP Status | Arti | Solusi |
|---|---|---|
| 200 | OK | Request berhasil. |
| 400 | Bad Request | Parameter salah atau nominal tidak valid. Cek pesan error. |
| 401 | Unauthorized | API key salah atau tidak disertakan. |
| 405 | Method Not Allowed | Salah HTTP method. Cek docs. |
| 429 | Too Many Requests | Rate limit. Tunggu beberapa detik. |
| 500 | Server Error | Error di server NercPay. Hubungi support. |
// Semua error response memiliki format:
{
"success": false,
"error": "Pesan error detail di sini"
}Contoh flow lengkap: user ketik /qris 10000 → bot kirim QR → bot polling status → notif saat lunas.
const TelegramBot = require('node-telegram-bot-api');
const bot = new TelegramBot('TELEGRAM_BOT_TOKEN', { polling: true });
const API_BASE = 'https://nercpay.vercel.app/api/v1';
const API_KEY = 'NercPay_Wanzie_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const headers = {
'x-api-key': API_KEY,
'Content-Type': 'application/json',
};
// Command: /qris <nominal>
bot.onText(/\/qris (\d+)/, async (msg, match) => {
const chatId = msg.chat.id;
const amount = parseInt(match[1]);
if (amount < 1000) {
return bot.sendMessage(chatId, '❌ Minimal nominal Rp 1.000');
}
bot.sendMessage(chatId, '⏳ Membuat QRIS...');
try {
// 1. Buat QRIS
const res = await fetch(`${API_BASE}/qris/create`, {
method: 'POST',
headers,
body: JSON.stringify({ amount }),
});
const data = await res.json();
if (!data.success) {
return bot.sendMessage(chatId, '❌ ' + data.error);
}
const { qris_id, qr_image, amount_received, fee, expired_at } = data.data;
const expiredMin = Math.round((expired_at - Date.now()) / 60000);
// 2. Kirim gambar QR
await bot.sendPhoto(chatId, qr_image, {
caption: `✅ *QRIS Siap*\n\n`
+ `💰 Nominal: Rp ${amount_received.toLocaleString('id-ID')}\n`
+ `💸 Fee: Rp ${fee.toLocaleString('id-ID')}\n`
+ `⏰ Berlaku: ${expiredMin} menit\n\n`
+ `Scan dengan GoPay, OVO, DANA, atau mobile banking.`,
parse_mode: 'Markdown',
});
// 3. Polling status tiap 5 detik (max 20 menit)
let attempts = 0;
const poll = setInterval(async () => {
attempts++;
if (attempts > 240) {
clearInterval(poll);
return bot.sendMessage(chatId, '⌛ QRIS expired.');
}
const statusRes = await fetch(
`${API_BASE}/qris/status?qris_id=${qris_id}`,
{ headers }
);
const statusData = await statusRes.json();
if (statusData.data?.status === 'success') {
clearInterval(poll);
bot.sendMessage(chatId,
`🎉 *Pembayaran Diterima!*\n`
+ `Nominal: Rp ${amount_received.toLocaleString('id-ID')}`,
{ parse_mode: 'Markdown' }
);
} else if (statusData.data?.status === 'cancel') {
clearInterval(poll);
bot.sendMessage(chatId, '❌ QRIS dibatalkan.');
}
}, 5000);
} catch (err) {
bot.sendMessage(chatId, '❌ Terjadi kesalahan. Coba lagi.');
}
});