Sebelum memulai integrasi, pastikan Anda sudah memiliki beberapa hal berikut:
- Akun Midtrans (daftar di midtrans.com)
- Laravel versi 8 atau lebih baru sudah terinstall
- Composer untuk manajemen dependency
- Server Key dan Client Key dari dashboard Midtrans
Setelah mendaftar di Midtrans, Anda akan mendapatkan akses ke dashboard Sandbox untuk testing. Ambil Server Key dan Client Key dari menu Settings → Access Keys.
Langkah 1: Install Package Midtrans
Midtrans menyediakan package official untuk PHP yang bisa kita install melalui Composer. Jalankan perintah berikut di terminal:
composer require midtrans/midtrans-php
Tunggu hingga proses instalasi selesai. Package ini akan memudahkan kita dalam berkomunikasi dengan API Midtrans.
Langkah 2: Konfigurasi Environment
Tambahkan konfigurasi Midtrans di file .env Anda:
MIDTRANS_SERVER_KEY=your-server-key
MIDTRANS_CLIENT_KEY=your-client-key
MIDTRANS_IS_PRODUCTION=false
MIDTRANS_IS_SANITIZED=true
MIDTRANS_IS_3DS=true
Ganti your-server-key dan your-client-key dengan key yang Anda dapatkan dari dashboard Midtrans. Set MIDTRANS_IS_PRODUCTION menjadi true saat aplikasi sudah siap production.
Selanjutnya, buat file konfigurasi baru di config/midtrans.php:
<?php
return [
'server_key' => env('MIDTRANS_SERVER_KEY'),
'client_key' => env('MIDTRANS_CLIENT_KEY'),
'is_production' => env('MIDTRANS_IS_PRODUCTION', false),
'is_sanitized' => env('MIDTRANS_IS_SANITIZED', true),
'is_3ds' => env('MIDTRANS_IS_3DS', true),
];
Langkah 3: Membuat Model dan Migration
Kita perlu membuat tabel untuk menyimpan data transaksi. Buat migration dengan perintah:
php artisan make:migration create_transactions_table
Edit file migration yang baru dibuat di folder database/migrations:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateTransactionsTable extends Migration
{
public function up()
{
Schema::create('transactions', function (Blueprint $table) {
$table->id();
$table->string('order_id')->unique();
$table->decimal('gross_amount', 10, 2);
$table->string('payment_type')->nullable();
$table->string('transaction_status')->default('pending');
$table->string('transaction_id')->nullable();
$table->text('snap_token')->nullable();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('transactions');
}
}
Jalankan migration:
php artisan migrate
Kemudian buat model Transaction:
php artisan make:model Transaction
Edit file app/Models/Transaction.php:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Transaction extends Model
{
protected $fillable = [
'order_id',
'gross_amount',
'payment_type',
'transaction_status',
'transaction_id',
'snap_token'
];
}
Langkah 4: Membuat Controller Payment
Buat controller untuk menangani proses payment:
php artisan make:controller PaymentController
Edit file app/Http/Controllers/PaymentController.php:
<?php
namespace App\Http\Controllers;
use App\Models\Transaction;
use Illuminate\Http\Request;
use Midtrans\Config;
use Midtrans\Snap;
class PaymentController extends Controller
{
public function __construct()
{
// Set konfigurasi Midtrans
Config::$serverKey = config('midtrans.server_key');
Config::$isProduction = config('midtrans.is_production');
Config::$isSanitized = config('midtrans.is_sanitized');
Config::$is3ds = config('midtrans.is_3ds');
}
public function checkout(Request $request)
{
$request->validate([
'gross_amount' => 'required|numeric|min:1',
]);
// Generate unique order ID
$orderId = 'ORDER-' . time();
// Siapkan parameter transaksi
$params = [
'transaction_details' => [
'order_id' => $orderId,
'gross_amount' => $request->gross_amount,
],
'customer_details' => [
'first_name' => auth()->user()->name ?? 'Customer',
'email' => auth()->user()->email ?? '[email protected]',
],
];
try {
// Dapatkan Snap Token
$snapToken = Snap::getSnapToken($params);
// Simpan transaksi ke database
Transaction::create([
'order_id' => $orderId,
'gross_amount' => $request->gross_amount,
'snap_token' => $snapToken,
'transaction_status' => 'pending',
]);
return response()->json([
'snap_token' => $snapToken,
'order_id' => $orderId
]);
} catch (\Exception $e) {
return response()->json([
'error' => $e->getMessage()
], 500);
}
}
public function callback(Request $request)
{
$serverKey = config('midtrans.server_key');
$hashed = hash("sha512", $request->order_id . $request->status_code .
$request->gross_amount . $serverKey);
// Verifikasi signature key
if ($hashed == $request->signature_key) {
$transaction = Transaction::where('order_id', $request->order_id)->first();
if ($transaction) {
$transaction->update([
'transaction_status' => $request->transaction_status,
'transaction_id' => $request->transaction_id,
'payment_type' => $request->payment_type,
]);
}
}
return response()->json(['status' => 'success']);
}
}
Langkah 5: Setup Routes
Tambahkan routes untuk payment di file routes/web.php:
<?php
use App\Http\Controllers\PaymentController;
use Illuminate\Support\Facades\Route;
Route::get('/payment', function () {
return view('payment');
})->name('payment.page');
Route::post('/payment/checkout', [PaymentController::class, 'checkout'])
->name('payment.checkout');
Route::post('/payment/callback', [PaymentController::class, 'callback'])
->name('payment.callback');
Langkah 6: Membuat View Payment
Buat file view di resources/views/payment.blade.php:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Payment Gateway</title>
<script src="https://app.sandbox.midtrans.com/snap/snap.js"
data-client-key="{{ config('midtrans.client_key') }}"></script>
</head>
<body>
<div class="container">
<h1>Checkout Payment</h1>
<form id="payment-form">
<label>Jumlah Pembayaran:</label>
<input type="number" id="amount" name="amount" required>
<button type="submit">Bayar Sekarang</button>
</form>
</div>
<script>
document.getElementById('payment-form').addEventListener('submit', function(e) {
e.preventDefault();
const amount = document.getElementById('amount').value;
fetch('{{ route("payment.checkout") }}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify({
gross_amount: amount
})
})
.then(response => response.json())
.then(data => {
snap.pay(data.snap_token, {
onSuccess: function(result) {
alert('Pembayaran berhasil!');
console.log(result);
},
onPending: function(result) {
alert('Menunggu pembayaran Anda');
console.log(result);
},
onError: function(result) {
alert('Pembayaran gagal!');
console.log(result);
},
onClose: function() {
alert('Anda menutup popup tanpa menyelesaikan pembayaran');
}
});
})
.catch(error => {
console.error('Error:', error);
});
});
</script>
</body>
</html>
Langkah 7: Konfigurasi Notification URL
Agar Midtrans dapat mengirimkan notifikasi status pembayaran ke aplikasi Anda, masuk ke dashboard Midtrans dan setting Notification URL ke:
https://yourdomain.com/payment/callback
Pastikan URL ini dapat diakses secara public. Jika masih dalam tahap development, Anda bisa menggunakan tools seperti ngrok untuk expose localhost Anda.
Langkah 8: Testing Integrasi
Untuk melakukan testing di environment sandbox, Midtrans menyediakan beberapa nomor kartu test:
- Kartu Kredit Sukses: 4811 1111 1111 1114
- CVV: 123
- Expired Date: 01/25 (atau tanggal yang akan datang)
Jalankan aplikasi Laravel Anda dan akses halaman payment. Masukkan jumlah pembayaran dan klik tombol bayar. Popup Snap Midtrans akan muncul dengan berbagai pilihan metode pembayaran.
Tips dan Best Practices
Beberapa hal yang perlu diperhatikan dalam implementasi payment gateway:
- Keamanan: Jangan pernah expose Server Key di frontend. Semua komunikasi dengan Midtrans API harus dilakukan di backend.
- Validasi Callback: Selalu validasi signature key yang dikirim Midtrans untuk memastikan request berasal dari server Midtrans.
- Handle Status: Midtrans memiliki beberapa status transaksi (pending, settlement, expire, cancel). Pastikan aplikasi Anda handle semua status dengan baik.
- Logging: Simpan semua response dari Midtrans untuk keperluan audit dan debugging.
- Testing Menyeluruh: Test berbagai skenario pembayaran termasuk success, pending, dan failed sebelum go live.
Kesimpulan
Integrasi Midtrans dengan Laravel cukup straightforward dengan bantuan package official yang disediakan. Dengan mengikuti langkah-langkah di atas, Anda sudah bisa menerima pembayaran melalui berbagai metode yang disediakan Midtrans. Jangan lupa untuk melakukan testing menyeluruh di environment sandbox sebelum mengaktifkan mode production.
Untuk dokumentasi lebih lengkap dan fitur-fitur advanced seperti subscription, tokenization, atau 3D Secure, Anda bisa mengunjungi dokumentasi official Midtrans.
...