KursusOtomasi WhatsApp untuk Bisnis
ModulPembayaran dan produksi
Durasi12 min
Progress0/7
Materi Pelajaran0/7 · 0%
  1. 1Apa yang kita bangun, dan setup proyeknya8 min
  2. 2Menyambung ke WhatsApp Cloud API12 min
  3. 3Session dan state machine alur pesanan12 min
  4. 4Mini CRM: kontak, order, dan label10 min
  5. 5Pembayaran dalam chat dengan sandbox Midtrans12 min
  6. 6Hardening: dedup, retry, dan pengambilalihan manusia10 min
  7. 7Deploy dengan Docker, lepas dari laptop selamanya12 min

Lesson 5 / 7 · 12 min

Pembayaran dalam chat dengan sandbox Midtrans

Buat invoice, kirim link, verifikasi signature webhook pembayaran, konfirmasi otomatis. Checkpoint: order lunas penuh, end to end.

Daftar akun Midtrans gratis dan alihkan dashboard ke mode Sandbox: API sungguhan, uang tes. Salin Server Key sandbox ke MIDTRANS_SERVER_KEY di .env. Kita pakai Snap, halaman pembayaran hosted mereka yang menerima QRIS, virtual account, e-wallet, dan kartu, jadi kita tidak pernah menyentuh data kartu sendiri.

Langkah 1: buat invoice (pay.js)

export async function createInvoice(orderId, amount) {
  const auth = Buffer
    .from(process.env.MIDTRANS_SERVER_KEY + ":")
    .toString("base64");

  const res = await fetch(
    "https://app.sandbox.midtrans.com/snap/v1/transactions",
    {
      method: "POST",
      headers: {
        Authorization: "Basic " + auth,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        transaction_details: {
          order_id: orderId,
          gross_amount: amount,
        },
      }),
    },
  );
  const data = await res.json();
  return data.redirect_url; // the hosted payment page
}
Satu POST, satu URL kembali. Di produksi Anda hanya mengganti domain (hapus .sandbox) dan key-nya.

Langkah 2: kirim link dari alur

// server.js: after step(), handle the action from CONFIRM
import { createInvoice } from "./pay.js";

const { reply, action } = step(session, msg.text.body);
saveSession(session);
if (reply) await sendText(msg.from, reply);

if (action === "create_invoice") {
  const link = await createInvoice(
    session.data.orderId,
    session.data.total,
  );
  await sendText(
    msg.from,
    "Total Rp " + session.data.total.toLocaleString("id-ID") +
    ". Silakan bayar di sini ya: " + link,
  );
}
Alur memutuskan APA yang terjadi; server memutuskan BAGAIMANA. Menjauhkan aksi dari flow.js menjaganya tetap bisa dites.

Langkah 3: webhook pembayaran, dengan verifikasi signature

// server.js
import crypto from "crypto";
import { db, addLabel } from "./db.js";

app.post("/payment/notify", async (req, res) => {
  res.sendStatus(200);
  const n = req.body;

  // Midtrans signs: sha512(order_id + status_code + gross_amount + ServerKey)
  const expected = crypto
    .createHash("sha512")
    .update(
      n.order_id + n.status_code + n.gross_amount +
      process.env.MIDTRANS_SERVER_KEY,
    )
    .digest("hex");
  if (expected !== n.signature_key) {
    return console.error("BAD SIGNATURE for", n.order_id);
  }

  if (n.transaction_status === "settlement" ||
      n.transaction_status === "capture") {
    // idempotent: only flips once, no matter how many callbacks arrive
    const r = db.prepare(
      "UPDATE orders SET status='paid', paid_at=unixepoch() " +
      "WHERE id = ? AND status != 'paid'",
    ).run(n.order_id);

    if (r.changes === 1) {
      const o = db.prepare("SELECT phone FROM orders WHERE id = ?")
        .get(n.order_id);
      addLabel(o.phone, "customer");
      await sendText(o.phone,
        "Pembayaran diterima. Pesanan Anda sedang diproses ya, terima kasih!");
    }
  }
});
Tiga hal tak bisa ditawar dalam satu handler: verifikasi signature, update idempoten, konfirmasi ke pelanggan.

Langkah 4: beri tahu Midtrans harus memanggil ke mana

Di dashboard sandbox Midtrans, isi Payment Notification URL dengan alamat ngrok Anda plus /payment/notify. Lalu buat pesanan dari ponsel, buka link-nya, dan bayar dengan salah satu metode tes sandbox yang tercantum di docs Midtrans (kartu tes dan simulasi QRIS atau virtual account).

Checkpoint: pesan dari ponsel, bayar di sandbox, dan lihat bot mengonfirmasi sendiri, dengan order berbalik jadi paid di database dan label customer tertempel. Loop itu, permintaan ke uang ke konfirmasi tanpa satu pun sentuhan manusia, adalah jantung otomasi perdagangan.

Yang Anda dapatkan

  • Snap memberi halaman pembayaran hosted; Anda tidak pernah memegang data kartu
  • Verifikasi signature sha512 di setiap notifikasi, tanpa kecuali
  • Update lunas idempoten: WHERE status != 'paid' menjaga callback ganda
  • Sandbox membuktikan loop penuh dengan uang tes sebelum rupiah sungguhan bergerak

Sumber terkurasi

Referensi pilihan untuk mendalami lebih jauh, direview oleh tim kami.

Layanan Etzal terkaitChatbot WhatsApp AIMau dikerjakan untuk Anda? Lihat caranya.
Pembayaran dalam chat dengan sandbox Midtrans - Otomasi WhatsApp untuk Bisnis | Etzal Academy | Etzal Group