Lewati ke konten
Integrasi API QRIS

API QRIS untuk WooCommerce dan WordPress

Toko WordPress Anda menerima QRIS dengan konfirmasi otomatis.

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 singkatIntegrasi API QRIS di WooCommerce dilakukan lewat payment gateway plugin yang membuat tagihan QRIS saat checkout dan menerima webhook di endpoint wc-api. Setelah webhook lunas terverifikasi, plugin memanggil $order->payment_complete() sehingga status berubah menjadi Processing.

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 WooCommerce, 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 WooCommerce dari APIQris mengotomatiskan semuanya, tanpa mengganti QRIS yang sudah Anda punya.

Panduan

Memahami API QRIS WooCommerce secara lengkap

01

Alur checkout

Pembeli memilih metode "QRIS", menekan pesan, lalu diarahkan ke halaman bayar yang menampilkan QR bernominal dan hitung mundur. Halaman otomatis berpindah ke halaman terima kasih setelah lunas.

02

Kompatibilitas

Pendekatan ini mendukung:

  • WooCommerce HPOS (High-Performance Order Storage)
  • Checkout klasik maupun blok
  • Mata uang IDR
  • Plugin cache, dengan halaman bayar dikecualikan
03

Tanpa biaya plugin bulanan

Plugin gateway dapat diunduh dari dashboard. Anda tidak membayar fee per transaksi kepada kami.

Cara kerja

Alur API QRIS WooCommerce 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 WooCommerce

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 WooCommerce, QRIS bernominal dikirim otomatis. Status berubah lunas sendiri dan dapur langsung menerima pesanan.

Perbandingan

QRIS statis manual vs API QRIS WooCommerce vs payment gateway

AspekQRIS statis manualAPI QRIS WooCommerce (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 WooCommerce

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 WooCommerce

  • 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 WooCommerce

Apakah bisa dipakai bersama metode bayar lain?

Bisa. QRIS tampil sebagai salah satu pilihan di halaman checkout.

Bagaimana jika memakai LiteSpeed Cache?

Kecualikan halaman bayar dan endpoint webhook dari cache.

Apakah dana dari API QRIS WooCommerce 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 WooCommerce hari ini

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