Menerima Pembayaran Midtrans di Laravel: Hal yang Perlu Dibenahi Sejak Awal

Saya sudah membangun beberapa produk dengan Midtrans di Laravel: toko e-book, platform belajar, situs tiket event, toko roti online, dan toko kecantikan multi-peran. Halaman checkout selalu terlihat seperti bagian tersulit. Padahal bukan. Bagian yang menentukan apakah uang dan pesanan saling cocok justru lebih sunyi.

Browser bukan sumber kebenaran

Setelah membayar, pelanggan dikembalikan ke situs Anda. Godaan terbesarnya menandai pesanan sebagai lunas di situ. Jangan. Pelanggan bisa menutup tab, kehilangan sinyal, atau menekan kembali sebelum redirect terjadi, dan redirect bisa dipalsukan siapa saja. Status pembayaran harus datang dari Midtrans yang memberi tahu server Anda langsung, lewat endpoint notifikasi (webhook).

Verifikasi notifikasinya

Siapa pun bisa mengirim permintaan ke URL notifikasi Anda. Midtrans menyertakan signature_key, yaitu hash SHA-512 dari order id, status code, gross amount, dan server key Anda. Hitung ulang dan bandingkan sebelum memercayai apa pun di dalam permintaan itu. Kalau tidak cocok, abaikan. Sebagai pemeriksaan tambahan, Anda bisa menanyakan status transaksi ke Midtrans dengan order id dan membandingkannya.

Siap menerima notifikasi yang sama lebih dari sekali

Notifikasi bisa datang dua kali, terlambat, atau tidak berurutan. Handler Anda harus idempoten: dijalankan lagi tidak boleh mengirim paket kedua, menambah stok dua kali, atau mengirim dua email. Aturan sederhana yang berfungsi: hanya majukan pesanan ke status berikutnya (pending ke lunas, tidak pernah lunas kembali ke pending) dan catat bahwa efek sampingnya sudah dijalankan.

Buat order id dan nominal yang membosankan

Pakai order id yang unik per percobaan dan terhubung ke catatan pesanan Anda sendiri. Simpan nominal dalam rupiah utuh dan hitung di server, jangan pernah dari kolom form tersembunyi. Kalau pelanggan mencoba bayar ulang pada pesanan yang sama, putuskan lebih dulu apakah itu membuat order id Midtrans baru.

Uji jalur yang tidak menyenangkan

Sandbox membuat jalur yang lancar mudah. Habiskan waktu untuk jalur lainnya: pembayaran kedaluwarsa, pembayaran dibatalkan, tab ditutup, notifikasi yang tiba sebelum pelanggan dialihkan, dan webhook yang mati semenit. Itulah kasus yang ditemui toko sungguhan pada minggu pertamanya.

Pisahkan kunci dan lingkungan

Server key ada di file environment, bukan di repositori atau di front end. Pisahkan kunci sandbox dan produksi dengan jelas, dan periksa kembali mana yang dipakai deployment sebelum hari peluncuran.

Tidak ada yang eksotis di sini. Ini daftar periksa singkat, dan itulah beda antara checkout yang tampak selesai dan yang diam-diam tetap benar.

← Semua tulisan