Menu dokumentasi

Webhook

Notifikasi perubahan status pembayaran ke callback_url project, dan cara memverifikasinya.

Saat status pembayaran berubah, Aulaa mengirim HTTP POST ke callback_url project Anda — diatur sekali di Dashboard → Projects dan berlaku untuk semua transaksi project itu (tidak bisa diganti per transaksi, demi keamanan).

Payload bersifat flat (tanpa pembungkus event); bedakan jenis notifikasi dari field status — biasanya paid atau expired.

Contoh payload

{
  "order_id": "INV-20260627-001",
  "amount": 50000,
  "currency": "IDR",
  "country_code": "ID",
  "status": "paid",
  "payment_method": "qris",
  "formatted_amount": "Rp 50.000",
  "paid_at": "2026-06-27T07:15:32Z"
}

Verifikasi signature

Setiap request menyertakan header X-Webhook-Signature: HMAC-SHA256 (hex, tanpa prefix) dari raw body, ditandatangani dengan Webhook Secret project Anda. Selalu verifikasi sebelum memproses.

const crypto = require('crypto');
const express = require('express');
const app = express();

// PENTING: signature dihitung dari RAW body (byte mentah), jadi
// gunakan express.raw — bukan express.json — di endpoint webhook.
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-webhook-signature'];

  const expected = crypto
    .createHmac('sha256', process.env.AULAA_WEBHOOK_SECRET)
    .update(req.body)            // req.body = Buffer (raw)
    .digest('hex');             // hex, TANPA prefix "sha256="

  const valid = signature && crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );

  if (!valid) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const event = JSON.parse(req.body.toString());
  if (event.status === 'paid') {
    // Verifikasi order_id & amount sesuai data Anda, lalu update order
    console.log('Pembayaran lunas:', event.order_id);
  }

  res.status(200).json({ received: true });
});

Webhook Secret bersifat per project. Temukan dan rotasi di Dashboard → Projects → bagian Webhook. Merotasi secret tidak butuh review ulang. Namun mengganti callback URL pada project yang sudah approved memicu review ulang (project turun ke revision dan Live dimatikan sementara), karena URL webhook ikut ditinjau untuk anti-abuse.

Endpoint Anda harus menjawab 2xx. Jika gagal, Aulaa mencoba ulang hingga 4 kali total (percobaan awal + 3 ulangan) dengan jeda +1 menit, +5 menit, +30 menit. Pastikan handler Anda idempoten terhadap order_id.

Terakhir diperbarui 23 Oktober 2026