Bantuan
Documentation
Integrasi REST API Malawali Payment: project, API key, order, status, dan webhook.
Malawali Payment · REST API v1
Integrasi Pembayaran QRIS
Buat order dari server Anda, tampilkan QR ke pelanggan, lalu terima callback
order.paid setelah pembayaran terdeteksi otomatis. API Key dibuat per Project
dan hanya aktif selama langganan berjalan.
Base URL
http://localhost:3001/api
Autentikasi
Header
x-api-key: pk_live_…
Format
JSON (request & response)
Webhook
HMAC-SHA256, retry maksimal 3×, timeout 10 detik
Webhook
Malawali Payment mengirim event ke URL webhook project saat status order berubah. Setiap request ditandatangani dengan HMAC-SHA256 agar dapat diverifikasi.
Header
Signature
x-malawali-timestampTimestamp pengiriman (detik/detik-ISO).
x-malawali-signature
v1=<hex> hasil HMAC_SHA256(secret, timestamp + "." + raw_body).Prioritas URL
order.webhook_url → Webhook Project → notify_url akun.RetryMaksimal 3× dengan timeout 10 detik per percobaan.
# Verifikasi signature webhook (Node.js)
const crypto = require("crypto");
const ts = req.headers["x-malawali-timestamp"];
const raw = JSON.stringify(req.body);
const expected = crypto
.createHmac("sha256", process.env.MALAWALI_WEBHOOK_SECRET)
.update(ts + "." + raw)
.digest("hex");
const ok = req.headers["x-malawali-signature"] === "v1=" + expected;
app.post("/webhook/malawali", express.json(), (req, res) => {
const ts = req.headers["x-malawali-timestamp"];
const raw = JSON.stringify(req.body);
const expected = crypto
.createHmac("sha256", process.env.MALAWALI_WEBHOOK_SECRET)
.update(ts + "." + raw)
.digest("hex");
if (req.headers["x-malawali-signature"] !== "v1=" + expected) {
return res.status(401).end();
}
const { event, data } = req.body;
if (event === "order.paid") {
// aktifkan pesanan {data.id}
}
res.json({ ok: true });
});
<?php
$ts = $_SERVER["HTTP_X_MALAWALI_TIMESTAMP"];
$raw = file_get_contents("php://input");
$expected = hash_hmac("sha256", $ts . "." . $raw, getenv("MALAWALI_WEBHOOK_SECRET"));
if (($_SERVER["HTTP_X_MALAWALI_SIGNATURE"] ?? "") !== "v1=" . $expected) {
http_response_code(401);
exit;
}
$payload = json_decode($raw, true);
if ($payload["event"] === "order.paid") {
// aktifkan pesanan
}
echo json_encode(["ok" => true]);
import hmac, hashlib, os
from flask import Flask, request, abort
app = Flask(__name__)
@app.post("/webhook/malawali")
def malawali_webhook():
ts = request.headers["x-malawali-timestamp"]
raw = request.get_data(as_text=True)
expected = hmac.new(
os.environ["MALAWALI_WEBHOOK_SECRET"].encode(),
f"{ts}.{raw}".encode(),
hashlib.sha256,
).hexdigest()
if request.headers.get("x-malawali-signature") != f"v1={expected}":
abort(401)
payload = request.get_json()
return {"ok": True}
Contoh Payload
order.paid
JSON
{
"event": "order.paid",
"created_at": "2026-09-27T09:30:11.000Z",
"data": {
"id": "ord_7f3k9d2m",
"status": "paid",
"base_amount": 25000,
"pay_amount": 25000,
"reference_id": "INV-2026-0001",
"paid_at": "2026-09-27T09:30:10.000Z"
}
}