Lewati ke konten
Integrasi API QRIS

API QRIS untuk WHMCS

Untuk penyedia hosting, domain, dan VPS yang ingin pelanggan bayar QRIS tanpa konfirmasi manual.

Halaman ini bagian dari layanan API QRIS gratis APIQris: pakai QRIS milik Anda sendiri, tanpa potongan dari kami, dana langsung ke rekening Anda.

  • 0% fee APIQris
  • Dana langsung ke Anda
  • Webhook HMAC

Jawaban singkatModul gateway WHMCS yang memakai API QRIS membuat tagihan QRIS sesuai jumlah invoice, lalu memanggil addInvoicePayment saat webhook lunas diterima. Layanan pelanggan aktif otomatis tanpa admin memeriksa mutasi.

Ingin tahu gambaran besarnya dulu? Baca juga pengertian QRIS API dan bagaimana API QRIS gratis APIQris menghubungkan QRIS Anda ke website, aplikasi, dan chatbot.

Rp0potongan dari APIQris
24/7konfirmasi otomatis
100%dana ke rekening Anda
Masalah

Tanpa API QRIS WHMCS, ini yang biasa terjadi

Pesanan menumpuk malam hari

Pembeli bayar jam 11 malam, pesanan baru diproses pagi karena menunggu admin.

Plugin gateway mahal

Biaya per transaksi plus biaya penarikan menggerus margin yang sudah tipis.

Konfirmasi manual di chat

Admin harus membalas "sudah masuk kak" satu per satu.

Data tersebar

Status bayar ada di aplikasi merchant, pesanan ada di sistem, rekap jadi kerja dua kali.

Solusinya: API QRIS WHMCS dari APIQris mengotomatiskan semuanya, tanpa mengganti QRIS yang sudah Anda punya.

Panduan

Memahami API QRIS WHMCS secara lengkap

01

Kenapa penting untuk bisnis hosting

Pelanggan hosting sering membayar di malam hari. Tanpa konfirmasi otomatis, layanan baru aktif keesokan pagi dan pelanggan kecewa. Dengan API QRIS, aktivasi berjalan dalam hitungan detik.

02

Fitur modul

Yang ditangani modul gateway:

  • Tombol bayar QRIS di halaman invoice
  • Callback dengan checkCbTransID agar tidak dobel
  • Log gateway untuk audit
  • Mendukung invoice perpanjangan otomatis
03

Margin lebih utuh

Margin bisnis hosting tipis. Menghapus fee gateway 0,7% sampai 1% per transaksi berarti keuntungan bersih langsung naik.

Cara kerja

Alur API QRIS WHMCS dari scan sampai lunas

Dana dan data berjalan di jalur berbeda. Uang pembeli langsung ke QRIS Anda, APIQris hanya mengurus QRIS dinamis, pencocokan, dan webhook.

Infografis cara kerja API QRIS APIQris Dana pembeli mengalir dari pembeli ke penyedia QRIS lalu langsung ke rekening Anda. Jalur data terpisah: notifikasi dari HP merchant Anda dibaca APIQris lalu dikirim sebagai webhook ke website atau bot Anda. Rp Rp bayar dana langsung notifikasi kirim mutasi webhook buat tagihan → tampilkan QRIS dinamis ke pembeli Pembeli Scan & bayar Penyedia QRISAnda Bank / e-wallet Rekening Anda Langsung ke Anda HP MerchantAnda Notif dana masuk APIQris Cocokkan tagihan Website /Bot Anda Webhook lunas APIQris tidak menyentuh dana
Jalur dana: pembeli → penyedia QRIS → rekening Anda Jalur data: notifikasi → APIQris → webhook ke sistem Anda
  1. 1

    Daftar gratis

    Buat akun APIQris dengan email, tanpa biaya dan tanpa dokumen perusahaan.

  2. 2

    Upload QRIS Anda

    Unggah gambar QRIS merchant dari bank atau e-wallet Anda. Sistem membaca data QRIS secara otomatis.

  3. 3

    Pasang aplikasi pendamping

    Pasang aplikasi APIQris di HP Android yang menerima notifikasi dana masuk, lalu pindai kode pairing.

  4. 4

    Pakai API key

    Salin API key, buat tagihan QRIS dinamis dari website atau chatbot, dan terima webhook saat lunas.

Contoh skenario

Sebelum dan sesudah memakai API QRIS WHMCS

UMKM kuliner yang menerima pesanan lewat website dan WhatsApp. Ilustrasi alur kerja, bukan testimoni pelanggan.

Sebelum

Pembeli mengirim foto bukti bayar, admin mengecek mutasi, lalu mengubah status pesanan secara manual.

Sesudah

Lewat API QRIS WHMCS, QRIS bernominal dikirim otomatis. Status berubah lunas sendiri dan dapur langsung menerima pesanan.

Perbandingan

QRIS statis manual vs API QRIS WHMCS vs payment gateway

AspekQRIS statis manualAPI QRIS WHMCS (APIQris)Payment gateway
NominalDiketik pembeliTerkunci otomatisTerkunci otomatis
Konfirmasi bayarCek mutasi manualWebhook otomatisWebhook otomatis
Penerima danaRekening AndaRekening AndaRekening gateway
Potongan perantaraRp0Rp0±0,7% + biaya tarik
Bekerja 24 jamTergantung adminYaYa
Contoh kode

Buat tagihan dengan API QRIS WHMCS

Kirim nominal dan order ID, terima QR dan total yang sudah ditambah kode unik.

Buat tagihan QRIS
<?php
$ch = curl_init('https://api.apiqris.com/v1/invoices');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('APIQRIS_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'amount'   => 50000,
        'order_id' => 'INV-1024',
    ]),
]);
$qris = json_decode(curl_exec($ch), true);
echo $qris['qr_image_url']; // tampilkan ke pembeli
curl -X POST https://api.apiqris.com/v1/invoices \
  -H "Authorization: Bearer AQ_LIVE_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"amount":50000,"order_id":"INV-1024"}'
use Illuminate\Support\Facades\Http;

$qris = Http::withToken(config('services.apiqris.key'))
    ->post('https://api.apiqris.com/v1/invoices', [
        'amount'   => $order->total,
        'order_id' => $order->number,
    ])
    ->throw()
    ->json();

return view('checkout.qris', ['qris' => $qris]);
const res = await fetch('https://api.apiqris.com/v1/invoices', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.APIQRIS_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ amount: 50000, order_id: 'INV-1024' }),
});
const qris = await res.json();
console.log(qris.total_amount, qris.qr_image_url);
import os, requests

r = requests.post(
    "https://api.apiqris.com/v1/invoices",
    headers={"Authorization": f"Bearer {os.environ['APIQRIS_KEY']}"},
    json={"amount": 50000, "order_id": "INV-1024"},
    timeout=15,
)
r.raise_for_status()
qris = r.json()
print(qris["total_amount"], qris["qr_image_url"])
body := strings.NewReader(`{"amount":50000,"order_id":"INV-1024"}`)
req, _ := http.NewRequest("POST", "https://api.apiqris.com/v1/invoices", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("APIQRIS_KEY"))
req.Header.Set("Content-Type", "application/json")

res, err := http.DefaultClient.Do(req)
if err != nil {
    log.Fatal(err)
}
defer res.Body.Close()
Webhook

Verifikasi kabar lunas

Hitung HMAC SHA-256 dari timestamp dan body mentah, bandingkan secara constant-time.

Verifikasi webhook
<?php
$body = file_get_contents('php://input');
parse_str(str_replace(',', '&', $_SERVER['HTTP_X_APIQRIS_SIGNATURE'] ?? ''), $sig);
$expected = hash_hmac('sha256', $sig['t'] . '.' . $body, getenv('APIQRIS_SECRET'));

if (!hash_equals($expected, $sig['v1'] ?? '') || abs(time() - (int) $sig['t']) > 300) {
    http_response_code(401);
    exit;
}
$event = json_decode($body, true);
if ($event['event'] === 'invoice.paid') {
    tandai_lunas($event['order_id']); // fungsi milik aplikasi Anda
}
http_response_code(200);
# Header yang dikirim APIQris ke callback_url Anda
X-APIQris-Signature: t=1760670000,v1=5f2b...e9
Content-Type: application/json

{"event":"invoice.paid","id":"qr_9KX2T7","order_id":"INV-1024","total_amount":50123,"status":"paid"}
Route::post('/webhook/qris', function (Request $request) {
    parse_str(str_replace(',', '&', $request->header('X-APIQris-Signature')), $sig);
    $expected = hash_hmac('sha256', $sig['t'].'.'.$request->getContent(), config('services.apiqris.secret'));
    abort_unless(hash_equals($expected, $sig['v1'] ?? ''), 401);

    if ($request->input('event') === 'invoice.paid') {
        Order::where('number', $request->input('order_id'))->update(['status' => 'paid']);
    }
    return response()->noContent();
});
import crypto from 'node:crypto';
import express from 'express';

const app = express();
app.post('/webhook/qris', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = Object.fromEntries(req.get('X-APIQris-Signature').split(',').map((p) => p.split('=')));
  const expected = crypto.createHmac('sha256', process.env.APIQRIS_SECRET)
    .update(`${sig.t}.${req.body}`).digest('hex');
  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig.v1 ?? ''))) return res.sendStatus(401);

  const event = JSON.parse(req.body);
  if (event.event === 'invoice.paid') markPaid(event.order_id);
  res.sendStatus(200);
});
import hmac, hashlib, os
from flask import Flask, request, abort

app = Flask(__name__)

@app.post("/webhook/qris")
def webhook():
    sig = dict(p.split("=", 1) for p in request.headers["X-APIQris-Signature"].split(","))
    msg = f"{sig['t']}.".encode() + request.get_data()
    expected = hmac.new(os.environ["APIQRIS_SECRET"].encode(), msg, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, sig.get("v1", "")):
        abort(401)
    event = request.get_json()
    if event["event"] == "invoice.paid":
        mark_paid(event["order_id"])
    return "", 200
func webhook(w http.ResponseWriter, r *http.Request) {
    body, _ := io.ReadAll(r.Body)
    sig := map[string]string{}
    for _, p := range strings.Split(r.Header.Get("X-APIQris-Signature"), ",") {
        if k, v, ok := strings.Cut(p, "="); ok {
            sig[k] = v
        }
    }
    mac := hmac.New(sha256.New, []byte(os.Getenv("APIQRIS_SECRET")))
    mac.Write([]byte(sig["t"] + "." + string(body)))
    if !hmac.Equal([]byte(hex.EncodeToString(mac.Sum(nil))), []byte(sig["v1"])) {
        http.Error(w, "invalid signature", http.StatusUnauthorized)
        return
    }
    w.WriteHeader(http.StatusOK)
}
Keamanan

Aman sejak baris kode pertama

HTTPS di semua endpoint

Data tagihan dan API key selalu terenkripsi saat dikirim.

API key bisa dirotasi

Kunci bocor? Buat kunci baru dari dashboard, kunci lama langsung mati.

Webhook HMAC SHA-256

Setiap callback ditandatangani agar server Anda bisa menolak yang palsu.

Dana tidak lewat kami

Tidak ada saldo yang bisa dibekukan, karena uang langsung ke QRIS Anda.

Sebelum go-live

Checklist API QRIS WHMCS

  • QRIS merchant resmi sudah diupload dan terbaca benar
  • Aplikasi pendamping di HP Android berstatus online
  • Optimasi baterai dimatikan untuk aplikasi merchant & pendamping
  • Uji bayar Rp1.000 berhasil terdeteksi lunas
  • URL webhook memakai HTTPS dan membalas 200
  • Tanda tangan HMAC diverifikasi sebelum memproses pesanan
  • Proses webhook idempoten berdasarkan order_id
  • API key disimpan di server, tidak di frontend
Istilah

Glosarium singkat

QRIS
Quick Response Code Indonesian Standard, standar QR pembayaran nasional dari Bank Indonesia.
QRIS dinamis
QRIS yang membawa nominal untuk satu transaksi, berbeda dengan QRIS statis tanpa nominal.
NMID
National Merchant ID, nomor identitas merchant yang tertanam di QRIS Anda.
MDR
Merchant Discount Rate, biaya yang dipotong penyedia QRIS atas transaksi sesuai ketentuan.
Kode unik
Angka kecil yang ditambahkan ke nominal agar setiap tagihan bisa dibedakan.
Webhook
HTTP POST otomatis dari APIQris ke server Anda saat status tagihan berubah.
FAQ

Pertanyaan umum tentang API QRIS WHMCS

Versi WHMCS apa yang didukung?

Modul ditulis untuk WHMCS 8.x dengan PHP 8.

Bagaimana dengan kode unik?

Selisih kode unik dicatat sebagai bagian pembayaran sehingga invoice tetap lunas penuh.

Apakah dana dari API QRIS WHMCS ditampung APIQris?

Tidak. Pembeli membayar ke QRIS milik Anda sendiri, sehingga dana langsung masuk ke rekening atau saldo merchant Anda.

Berapa biaya memakai APIQris?

Daftar gratis dan APIQris tidak memotong fee per transaksi. MDR dari penyedia QRIS Anda (bila ada) mengikuti ketentuan penyedia.

Apakah perlu HP khusus?

Cukup satu HP Android yang terpasang aplikasi merchant penerbit QRIS Anda dan aplikasi pendamping APIQris. HP lama pun bisa selama notifikasinya stabil.

Mulai API QRIS WHMCS hari ini

Gratis, tanpa potongan per transaksi, dana langsung ke rekening Anda. Pelajari dulu API QRIS selengkapnya atau langsung daftar.