NercPay API

v1.0

Integrasikan QRIS payment ke bot Telegram, WhatsApp, website, atau aplikasi kamu dengan mudah.

Base URL: https://nercpay.vercel.app/api/v1

Autentikasi

Semua endpoint API memerlukan API key yang dikirim lewat salah satu cara berikut:

Header (direkomendasikan)

http
x-api-key: NercPay_Wanzie_9f3a1b7c2e4d5f6a7b8c9d0e1f2a3b4c5d6e7f8a

Authorization Bearer

http
Authorization: Bearer NercPay_Wanzie_9f3a1b7c2e4d5f6a7b8c9d0e1f2a3b4c5d6e7f8a

Query param (tidak disarankan untuk produksi)

http
GET /api/v1/qris/status?qris_id=RO123&api_key=NercPay_Wanzie_xxx
⚠️ Jangan expose API key di sisi client/frontend. Selalu panggil API ini dari backend atau server bot kamu.

Generate API Key

QR

QRIS

Error Codes

HTTP StatusArtiSolusi
200OKRequest berhasil.
400Bad RequestParameter salah atau nominal tidak valid. Cek pesan error.
401UnauthorizedAPI key salah atau tidak disertakan.
405Method Not AllowedSalah HTTP method. Cek docs.
429Too Many RequestsRate limit. Tunggu beberapa detik.
500Server ErrorError di server NercPay. Hubungi support.
json
// Semua error response memiliki format:
{
  "success": false,
  "error": "Pesan error detail di sini"
}

Contoh: Bot Telegram (Node.js)

Contoh flow lengkap: user ketik /qris 10000 → bot kirim QR → bot polling status → notif saat lunas.

javascript
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.');
  }
});