Pesanan menumpuk malam hari
Pembeli bayar jam 11 malam, pesanan baru diproses pagi karena menunggu admin.
Website custom, landing page, atau toko online: semua bisa menerima QRIS otomatis.
Halaman ini bagian dari layanan API QRIS gratis APIQris: pakai QRIS milik Anda sendiri, tanpa potongan dari kami, dana langsung ke rekening Anda.
Jawaban singkatUntuk memasang API QRIS di website, server Anda membuat tagihan lewat API saat pembeli checkout, lalu menampilkan QR atau mengarahkan pembeli ke halaman bayar APIQris. Status pesanan diperbarui otomatis lewat webhook ketika pembayaran masuk.
Ingin tahu gambaran besarnya dulu? Baca juga pengertian QRIS API dan bagaimana API QRIS gratis APIQris menghubungkan QRIS Anda ke website, aplikasi, dan chatbot.
Pembeli bayar jam 11 malam, pesanan baru diproses pagi karena menunggu admin.
Biaya per transaksi plus biaya penarikan menggerus margin yang sudah tipis.
Admin harus membalas "sudah masuk kak" satu per satu.
Status bayar ada di aplikasi merchant, pesanan ada di sistem, rekap jadi kerja dua kali.
Solusinya: API QRIS website dari APIQris mengotomatiskan semuanya, tanpa mengganti QRIS yang sudah Anda punya.
Pilih sesuai kemampuan teknis:
Pembeli melihat total, QR, hitung mundur, dan instruksi singkat. Begitu lunas, halaman langsung berubah tanpa pembeli perlu mengunggah bukti transfer.
Gambar QR ringan dan halaman bayar dioptimalkan untuk HP. Pembeli yang membuka dari HP bisa menyimpan gambar QR lalu membayar dari aplikasi pilihannya.
Dana dan data berjalan di jalur berbeda. Uang pembeli langsung ke QRIS Anda, APIQris hanya mengurus QRIS dinamis, pencocokan, dan webhook.
Buat akun APIQris dengan email, tanpa biaya dan tanpa dokumen perusahaan.
Unggah gambar QRIS merchant dari bank atau e-wallet Anda. Sistem membaca data QRIS secara otomatis.
Pasang aplikasi APIQris di HP Android yang menerima notifikasi dana masuk, lalu pindai kode pairing.
Salin API key, buat tagihan QRIS dinamis dari website atau chatbot, dan terima webhook saat lunas.
UMKM kuliner yang menerima pesanan lewat website dan WhatsApp. Ilustrasi alur kerja, bukan testimoni pelanggan.
Pembeli mengirim foto bukti bayar, admin mengecek mutasi, lalu mengubah status pesanan secara manual.
Lewat API QRIS website, QRIS bernominal dikirim otomatis. Status berubah lunas sendiri dan dapur langsung menerima pesanan.
| Aspek | QRIS statis manual | API QRIS website (APIQris) | Payment gateway |
|---|---|---|---|
| Nominal | Diketik pembeli | Terkunci otomatis | Terkunci otomatis |
| Konfirmasi bayar | Cek mutasi manual | Webhook otomatis | Webhook otomatis |
| Penerima dana | Rekening Anda | Rekening Anda | Rekening gateway |
| Potongan perantara | Rp0 | Rp0 | ±0,7% + biaya tarik |
| Bekerja 24 jam | Tergantung admin | Ya | Ya |
Kirim nominal dan order ID, terima QR dan total yang sudah ditambah kode unik.
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);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"}'<?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 pembeliuse 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]);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()Hitung HMAC SHA-256 dari timestamp dan body mentah, bandingkan secara constant-time.
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);
});# 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"}<?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);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 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 "", 200func 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)
}Data tagihan dan API key selalu terenkripsi saat dikirim.
Kunci bocor? Buat kunci baru dari dashboard, kunci lama langsung mati.
Setiap callback ditandatangani agar server Anda bisa menolak yang palsu.
Tidak ada saldo yang bisa dibekukan, karena uang langsung ke QRIS Anda.
Bisa dengan link pembayaran. Untuk konfirmasi otomatis ke sistem Anda, dibutuhkan backend penerima webhook.
Dengan API penuh, Anda bebas mendesain halaman bayar sendiri.
Tidak. Pembeli membayar ke QRIS milik Anda sendiri, sehingga dana langsung masuk ke rekening atau saldo merchant Anda.
Daftar gratis dan APIQris tidak memotong fee per transaksi. MDR dari penyedia QRIS Anda (bila ada) mengikuti ketentuan penyedia.
Cukup satu HP Android yang terpasang aplikasi merchant penerbit QRIS Anda dan aplikasi pendamping APIQris. HP lama pun bisa selama notifikasinya stabil.
Semua panduan berinduk ke halaman utama API QRIS gratis tanpa fee.
Gratis, tanpa potongan per transaksi, dana langsung ke rekening Anda. Pelajari dulu API QRIS selengkapnya atau langsung daftar.