Main Menu

Tutorial Laravel Raja Ongkir V2 #6: Mendapatkan Biaya Ongkos Kirim


👍 0 ❤️ 0 💡 0 🔥 0 🙌 0 🥳 0
Tutorial Laravel Raja Ongkir V2 #6: Mendapatkan Biaya Ongkos Kirim

Halo teman-teman semuanya, setelah kita berhasil menampilkan data provinsi, kota/kabupaten, dan kecamatan menggunakan Ajax, sekarang saatnya masuk ke bagian yang paling ditunggu-tunggu, yaitu menghitung biaya ongkos kirim.

Pada tutorial kali ini, kita akan belajar bagaimana cara mengirim data destination, weight, dan courier ke API Raja Ongkir, lalu menampilkan hasil estimasi biaya pengiriman secara real-time di Laravel. Ini merupakan salah satu fitur yang sangat penting dalam sistem e-commerce atau aplikasi yang berkaitan dengan pengiriman barang.

Kita akan menggunakan Ajax jQuery untuk mengirim permintaan ke server Laravel tanpa perlu me-refresh halaman, dan hasilnya akan langsung ditampilkan kepada pengguna.

Langkah 1 - Mendapatkan Biaya Ongkos Kirim

Sekarang kita akan mendapatkan method baru di dalam controller, yang mana akan digunakan untuk melakukan proses perhitungan biaya ongkos kirim.

Silahkan buka file app/Http/Controllers/RajaOngkirController.php, kemudian ubah semua kode-nya menjadi seperti berikut ini.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

class RajaOngkirController extends Controller
{
    /**
     * Menampilkan daftar provinsi dari API Raja Ongkir
     *
     * @return \Illuminate\View\View
     */
    public function index()
    {
        // Mengambil data provinsi dari API Raja Ongkir
        $response = Http::withHeaders([

            //headers yang diperlukan untuk API Raja Ongkir
            'Accept' => 'application/json',
            'key' => config('rajaongkir.api_key'),

        ])->get('https://rajaongkir.komerce.id/api/v1/destination/province');

        // Memeriksa apakah permintaan berhasil
        if ($response->successful()) {

            // Mengambil data provinsi dari respons JSON
            // Jika 'data' tidak ada, inisialisasi dengan array kosong
            $provinces = $response->json()['data'] ?? [];
        }

        // returning the view with provinces data
        return view('rajaongkir', compact('provinces'));
    }

    /**
     * Mengambil data kota berdasarkan ID provinsi
     *
     * @param int $provinceId
     * @return \Illuminate\Http\JsonResponse
     */
    public function getCities($provinceId)
    {
        // Mengambil data kota berdasarkan ID provinsi dari API Raja Ongkir
        $response = Http::withHeaders([

            //headers yang diperlukan untuk API Raja Ongkir
            'Accept' => 'application/json',
            'key' => config('rajaongkir.api_key'),

        ])->get("https://rajaongkir.komerce.id/api/v1/destination/city/{$provinceId}");

        if ($response->successful()) {

            // Mengambil data kota dari respons JSON
            // Jika 'data' tidak ada, inisialisasi dengan array kosong
            return response()->json($response->json()['data'] ?? []);
        }
    }

    /**
     * Mengambil data kecamatan berdasarkan ID kota
     *
     * @param int $cityId
     * @return \Illuminate\Http\JsonResponse
     */
    public function getDistricts($cityId)
    {
        // Mengambil data kecamatan berdasarkan ID kota dari API Raja Ongkir
        $response = Http::withHeaders([

            //headers yang diperlukan untuk API Raja Ongkir
            'Accept' => 'application/json',
            'key' => config('rajaongkir.api_key'),

        ])->get("https://rajaongkir.komerce.id/api/v1/destination/district/{$cityId}");

        if ($response->successful()) {

            // Mengambil data kecamatan dari respons JSON
            // Jika 'data' tidak ada, inisialisasi dengan array kosong
            return response()->json($response->json()['data'] ?? []);
        }
    }

    /**
     * Menghitung ongkos kirim berdasarkan data yang diberikan
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function checkOngkir(Request $request)
    {
        $response = Http::withHeaders([

            //headers yang diperlukan untuk API Raja Ongkir
            'Accept' => 'application/json',
            'key'    => config('rajaongkir.api_key'),

        ])->withOptions([

            //query parameters untuk API Raja Ongkir
            'query' => [
                'origin'      => 3855, // ID kecamatan Diwek (ganti sesuai kebutuhan)
                'destination' => $request->input('district_id'), // ID kecamatan tujuan
                'weight'      => $request->input('weight'), // Berat dalam gram
                'courier'     => $request->input('courier'), // Kode kurir (jne, tiki, pos)
            ]
        ])->post('https://rajaongkir.komerce.id/api/v1/calculate/domestic-cost');

        if ($response->successful()) {

            // Mengambil data ongkos kirim dari respons JSON
            // Jika 'data' tidak ada, inisialisasi dengan array kosong
            return $response->json()['data'] ?? [];
        }
    }
}

Dari perubahan kode di atas, kita menambahkan method baru dengan nama checkOngkir.

public function checkOngkir(Request $request)
{

	//...
	
}

Di dalamnya, kita melakukan perhitungan biaya ongkos kirim menggunakan Raja Ongkir.

$response = Http::withHeaders([

    //headers yang diperlukan untuk API Raja Ongkir
    'Accept' => 'application/json',
    'key'    => config('rajaongkir.api_key'),

])->withOptions([

    //query parameters untuk API Raja Ongkir
    'query' => [
        'origin'      => 3855, // ID kecamatan Diwek (ganti sesuai kebutuhan)
        'destination' => $request->input('district_id'), // ID kecamatan tujuan
        'weight'      => $request->input('weight'), // Berat dalam gram
        'courier'     => $request->input('courier'), // Kode kurir (jne, tiki, pos)
    ]
    
])->post('https://rajaongkir.komerce.id/api/v1/calculate/domestic-cost');

Di atas, kita diwajibkan mengirimkan 4 data sebagai query parameter, yaitu

KEY VALUE KETERANGAN
origin 3855 ID kecamatan Diwek (ganti sesuai kebutuhan)
destination $request->input('district_id') ID kecamatan tujuan
weight $request->input('weight') Berat dalam gram
courier $request->input('courier') Kode kurir (jne, tiki, pos, dan lain-lain).

Dan endpoint untuk proses check ongkos kirim adalah:

https://rajaongkir.komerce.id/api/v1/calculate/domestic-cost

Jika berhasil, maka kita akan return ke dalam format JSON.

return $response->json()['data'] ?? [];

Langkah 2 - Membuat Route Check Ongkir

Sekarang kita lanjutkan membuat route-nya. Silahkan buka file routes/web.php, kemudian ubah kode-nya menjadi seperti berikut ini.

<?php

use Illuminate\Support\Facades\Route;

//index route for RajaOngkirController
Route::get('/', [App\Http\Controllers\RajaOngkirController::class, 'index']);

//route to get cities based on province ID
Route::get('/cities/{provinceId}', [App\Http\Controllers\RajaOngkirController::class, 'getCities']);

//route to get districts based on city ID
Route::get('/districts/{cityId}', [App\Http\Controllers\RajaOngkirController::class, 'getDistricts']);

//route to post shipping cost
Route::post('/check-ongkir', [App\Http\Controllers\RajaOngkirController::class, 'checkOngkir']);

Dari perubahan kode di atas, kita menambahkan route baru dengan path /check-ongkir dan method yang digunakan adalah POST.

Langkah 3 - Menampilkan Biaya Ongkos Kirim

Silahkan buka file resources/views/rajaongkir.blade.php, kemudian ubah semua kode-nya menjadi seperti berikut ini.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>Raja Ongkir V2 - SantriKoding.com</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.0/jquery.min.js"></script>
    <style>
        .loader{border:4px solid #f3f3f3;border-top:4px solid #4f46e5;border-radius:50%;width:30px;height:30px;animation:spin 1s linear infinite;margin:0 auto;display:none}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}
    </style>
</head>
<body class="bg-gray-200 min-h-screen flex items-center justify-center p-4">

    <div class="bg-white p-8 rounded-xl shadow w-full max-w-2xl">
        <h1 class="text-3xl font-bold text-center text-gray-800 mb-8">Kalkulator Ongkos Kirim (V2)</h1>

        <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">

            <!-- Dropdown Provinsi -->
            <div>
                <label for="province" class="block text-sm font-medium text-gray-700 mb-1">Provinsi Tujuan</label>
                <select id="province" name="province_id" class="mt-1 block w-full pl-3 pr-10 py-2 text-base bg-gray-200 border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md shadow">
                    <option value="">-- Pilih Provinsi --</option>
                    @foreach($provinces as $province)
                    <option value="{{ $province['id'] }}">{{ $province['name'] }}</option>
                    @endforeach
                </select>
            </div>

            <!-- Dropdown Kota / Kabupaten -->
            <div>
                <label for="city" class="block text-sm font-medium text-gray-700 mb-1">Kota / Kabupaten Tujuan</label>
                <select id="city" name="city_id" class="mt-1 block w-full pl-3 pr-10 py-2 text-base bg-gray-200 border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md shadow-sm disabled:bg-gray-50 disabled:cursor-not-allowed">
                    <option value="">-- Pilih Kota / Kabupaten --</option>
                </select>
            </div>

            <!-- Dropdown Kecamatan -->
            <div>
                <label for="district" class="block text-sm font-medium text-gray-700 mb-1">Kecamatan Tujuan</label>
                <select id="district" name="district_id" class="mt-1 block w-full pl-3 pr-10 py-2 text-base bg-gray-200 border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md shadow-sm disabled:bg-gray-50 disabled:cursor-not-allowed">
                    <option value="">-- Pilih Kecamatan --</option>
                </select>
            </div>

            <div>
                <label for="weight" class="block text-sm font-medium text-gray-700 mb-1">Berat Barang (gram)</label>
                <input type="number" name="weight" id="weight" min="1000" placeholder="Masukkan berat barang dalam gram" class="mt-1 block w-full pl-3 pr-3 py-2 text-base bg-gray-200 border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md shadow">
            </div>

        </div>

        <!-- Radio Box Kurir -->
        <div class="mb-8">
            <label class="block text-sm font-medium text-gray-700 mb-2">Pilih Kurir</label>
            <div class="grid grid-cols-2 sm:grid-cols-3 gap-4">
                
                <div class="flex items-center">
                    <input type="radio" name="courier" id="courier-1" value="sicepat" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300">
                    <label for="courier-1" class="ml-2 block text-sm text-gray-900">SICEPAT</label>
                </div>

                <div class="flex items-center">
                    <input type="radio" name="courier" id="courier-2" value="jnt" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300">
                    <label for="courier-2" class="ml-2 block text-sm text-gray-900">J&T</label>
                </div>

                <div class="flex items-center">
                    <input type="radio" name="courier" id="courier-3" value="ninja" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300">
                    <label for="courier-3" class="ml-2 block text-sm text-gray-900">Ninja Express</label>
                </div>

                <div class="flex items-center">
                    <input type="radio" name="courier" id="courier-4" value="jne" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300">
                    <label for="courier-4" class="ml-2 block text-sm text-gray-900">JNE</label>
                </div>

                <div class="flex items-center">
                    <input type="radio" name="courier" id="courier-5" value="anteraja" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300">
                    <label for="courier-5" class="ml-2 block text-sm text-gray-900">Anteraja</label>
                </div>

                <div class="flex items-center">
                    <input type="radio" name="courier" id="courier-6" value="pos" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300">
                    <label for="courier-6" class="ml-2 block text-sm text-gray-900">POS Indonesia</label>
                </div>

                <div class="flex items-center">
                    <input type="radio" name="courier" id="courier-7" value="tiki" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300">
                    <label for="courier-7" class="ml-2 block text-sm text-gray-900">Tiki</label>
                </div>

                <div class="flex items-center">
                    <input type="radio" name="courier" id="courier-8" value="wahana" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300">
                    <label for="courier-8" class="ml-2 block text-sm text-gray-900">Wahana</label>
                </div>

                <div class="flex items-center">
                    <input type="radio" name="courier" id="courier-9" value="lion" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300">
                    <label for="courier-9" class="ml-2 block text-sm text-gray-900">Lion Parcel</label>
                </div>

            </div>
        </div>

        <div class="flex justify-center mb-8 flex-col items-center">
            <button class="btn-check w-full md:w-auto px-6 py-3 border border-transparent text-base font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed">
                Hitung Ongkos Kirim
            </button>
            <div class="loader mt-4" id="loading-indicator"></div>
        </div>

        <!-- Hasil Perhitungan Ongkos Kirim -->
        <div class="mt-8 p-6 bg-indigo-50 border border-indigo-200 rounded-lg results-container hidden">
            <h2 class="text-xl font-semibold text-indigo-800 mb-4 text-center">Hasil Perhitungan Ongkos Kirim</h2>
            <div class="space-y-3" id="results-ongkir">
            </div>
        </div>

        <script>
            $(document).ready(function() {

                // Fungsi formatCurrency
                function formatCurrency(amount) {
                    return new Intl.NumberFormat('id-ID', {
                        style: 'currency',
                        currency: 'IDR',
                        minimumFractionDigits: 0,
                        maximumFractionDigits: 0
                    }).format(amount);
                }

                // Inisialisasi dropdown kota/kabupaten
                $('select[name="province_id"]').on('change', function() {
                    let provinceId = $(this).val();
                    if (provinceId) {
                        jQuery.ajax({
                            url: `/cities/${provinceId}`,
                            type: "GET",
                            dataType: "json",
                            success: function(response) {
                                $('select[name="city_id"]').empty();
                                $('select[name="city_id"]').append(`<option value="">-- Pilih Kota / Kabupaten --</option>`);
                                $.each(response, function(index, value) {
                                    $('select[name="city_id"]').append(`<option value="${value.id}">${value.name}</option>`);
                                });
                            }
                        });
                    } else {
                        $('select[name="city_id"]').append(`<option value="">-- Pilih Kota / Kabupaten --</option>`);
                    }
                });

                // Inisialisasi dropdown kecamatan
                $('select[name="city_id"]').on('change', function() {
                    let cityId = $(this).val();
                    if (cityId) {
                        jQuery.ajax({
                            url: `/districts/${cityId}`,
                            type: "GET",
                            dataType: "json",
                            success: function(response) {
                                $('select[name="district_id"]').empty();
                                $('select[name="district_id"]').append(`<option value="">-- Pilih Kecamatan --</option>`);
                                $.each(response, function(index, value) {
                                    $('select[name="district_id"]').append(`<option value="${value.id}">${value.name}</option>`);
                                });
                            }
                        });
                    } else {
                        $('select[name="district_id"]').append(`<option value="">-- Pilih Kecamatan --</option>`);
                    }
                });

                // ajax check ongkir
                let isProcessing = false;

                $('.btn-check').click(function (e) {
                    e.preventDefault();

                    if (isProcessing) return;

                    let token        = $("meta[name='csrf-token']").attr("content");
                    let district_id  = $('select[name=district_id]').val();
                    let courier      = $('input[name=courier]:checked').val();
                    let weight       = $('#weight').val();

                    // Validasi form
                    if (!district_id || !courier || !weight) {
                        alert('Harap lengkapi semua data terlebih dahulu!');
                        return;
                    }

                    isProcessing = true;
                    
                    // Tampilkan loading indicator
                    $('#loading-indicator').show();
                    $('.btn-check').prop('disabled', true);
                    $('.btn-check').text('Memproses...');

                    $.ajax({
                        url: "/check-ongkir",
                        type: "POST",
                        dataType: "JSON",
                        data: {
                            _token: token,
                            district_id: district_id,
                            courier: courier,
                            weight: weight,
                        },
                        beforeSend: function() {
                            // Sembunyikan hasil sebelumnya jika ada
                            $('.results-container').addClass('hidden').removeClass('block');
                        },
                        success: function (response) {
                            if (response) {
                                $('#results-ongkir').empty();
                                $('.results-container').removeClass('hidden').addClass('block');
                                $.each(response, function (index, value) {
                                    $('#results-ongkir').append(`
                                        <div class="flex justify-between items-center p-3 bg-white rounded-xl shadow border border-gray-200">
                                            <span class="text-lg font-medium text-gray-800">${value.service} - ${value.description} - (${value.etd})</span>
                                            <span class="text-lg font-bold text-indigo-700">${formatCurrency(value.cost)}</span>
                                        </div>
                                    `);
                                });
                            }
                        },
                        error: function (xhr, status, error) {
                            console.error("Gagal menghitung ongkir:", error);
                            alert("Terjadi kesalahan saat menghitung ongkir. Coba lagi.");
                        },
                        complete: function () {
                            // Sembunyikan loading indicator
                            $('#loading-indicator').hide();
                            $('.btn-check').prop('disabled', false);
                            $('.btn-check').text('Hitung Ongkos Kirim');
                            
                            // pastikan tombol bisa diklik kembali
                            isProcessing = false;
                        }
                    });
                });

            });
        </script>

    </body>
</html>

Dari perubahan kode di atas, pertama kita menambahkan input untuk weight atau berat.

<input type="number" name="weight" id="weight" min="1000" placeholder="Masukkan berat barang dalam gram" class="mt-1 block w-full pl-3 pr-3 py-2 text-base bg-gray-200 border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md shadow">

Setelah itu, kita tambahkan list data kurir menggunakan input dengan type radio.

<!-- Radio Box Kurir -->
<div class="mb-8">
    <label class="block text-sm font-medium text-gray-700 mb-2">Pilih Kurir</label>
    <div class="grid grid-cols-2 sm:grid-cols-3 gap-4">

        <!-- Kurir Sicepat -->
        <div class="flex items-center">
            <input type="radio" name="courier" id="courier-sicepat" value="sicepat" class="h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
            <label for="courier-sicepat" class="ml-2 text-sm text-gray-900">SICEPAT</label>
        </div>

        <!-- Kurir J&T -->
        <div class="flex items-center">
            <input type="radio" name="courier" id="courier-jnt" value="jnt" class="h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
            <label for="courier-jnt" class="ml-2 text-sm text-gray-900">J&T</label>
        </div>

        <!-- Kurir Ninja Express -->
        <div class="flex items-center">
            <input type="radio" name="courier" id="courier-ninja" value="ninja" class="h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
            <label for="courier-ninja" class="ml-2 text-sm text-gray-900">Ninja Express</label>
        </div>

        <!-- Kurir JNE -->
        <div class="flex items-center">
            <input type="radio" name="courier" id="courier-jne" value="jne" class="h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
            <label for="courier-jne" class="ml-2 text-sm text-gray-900">JNE</label>
        </div>

        <!-- Kurir Anteraja -->
        <div class="flex items-center">
            <input type="radio" name="courier" id="courier-anteraja" value="anteraja" class="h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
            <label for="courier-anteraja" class="ml-2 text-sm text-gray-900">Anteraja</label>
        </div>

        <!-- Kurir POS Indonesia -->
        <div class="flex items-center">
            <input type="radio" name="courier" id="courier-pos" value="pos" class="h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
            <label for="courier-pos" class="ml-2 text-sm text-gray-900">POS Indonesia</label>
        </div>

        <!-- Kurir Tiki -->
        <div class="flex items-center">
            <input type="radio" name="courier" id="courier-tiki" value="tiki" class="h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
            <label for="courier-tiki" class="ml-2 text-sm text-gray-900">Tiki</label>
        </div>

        <!-- Kurir Wahana -->
        <div class="flex items-center">
            <input type="radio" name="courier" id="courier-wahana" value="wahana" class="h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
            <label for="courier-wahana" class="ml-2 text-sm text-gray-900">Wahana</label>
        </div>

        <!-- Kurir Lion Parcel -->
        <div class="flex items-center">
            <input type="radio" name="courier" id="courier-lion" value="lion" class="h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
            <label for="courier-lion" class="ml-2 text-sm text-gray-900">Lion Parcel</label>
        </div>

    </div>
</div>

Selanjutnya, kita membuat button yang nanti digunakan untuk melakukan proses check ongkos kirim.

<button class="btn-check w-full md:w-auto px-6 py-3 border border-transparent text-base font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed">
    Hitung Ongkos Kirim
</button>

Di atas, kita tambahkan class btn-check dimana nantinya itu yang akan kita gunakan di jQuery untuk men-trigger Ajax saat button diklik.

Berikutnya, kita membuat sebuah div yang nanti digunakan untuk menampilkan hasil perhitungan biaya ongkos kirim.

<!-- Hasil Perhitungan Ongkos Kirim -->
    <div class="mt-8 p-6 bg-indigo-50 border border-indigo-200 rounded-lg results-container hidden">
        <h2 class="text-xl font-semibold text-indigo-800 mb-4 text-center">Hasil Perhitungan Ongkos Kirim</h2>
        <div class="space-y-3" id="results-ongkir">
    </div>
</div>

Di dalam JavaScript, pertama kita menambahkan function baru dengan nama formatCurrency. Fungsi tersebut akan kita gunakan untuk menampilkan harga pengiriman dengan format yang lebih baik.

// Fungsi formatCurrency
function formatCurrency(amount) {
    return new Intl.NumberFormat('id-ID', {
        style: 'currency',
        currency: 'IDR',
        minimumFractionDigits: 0,
        maximumFractionDigits: 0
    }).format(amount);
}

Selanjutnya, kita mendeklarasikan variabel isProcessing, yang berfungsi untuk mencegah klik ganda saat proses AJAX masih berlangsung.

// ajax check ongkir
let isProcessing = false;

Ketika tombol Hitung Ongkos Kirim ditekan, event click akan dijalankan. Fungsi e.preventDefault() digunakan untuk mencegah submit form secara default.

$('.btn-check').click(function (e) {
    e.preventDefault();

	//...

}

Jika proses sebelumnya masih berjalan (isProcessing == true), maka klik akan diabaikan. Ini mencegah request berulang yang bisa membebani server.

if (isProcessing) return;

Selanjutnya, kita mengambil data dari form:

  • token: CSRF token untuk keamanan Laravel.
  • district_id: ID kecamatan tujuan.
  • courier: Kurir yang dipilih user (misalnya jne, pos, dll).
  • weight: Berat barang dalam gram.
let token        = $("meta[name='csrf-token']").attr("content");
let district_id  = $('select[name=district_id]').val();
let courier      = $('input[name=courier]:checked').val();
let weight       = $('#weight').val();

Kemudian kita buat Validasi sederhana. Jika salah satu dari data di atas kosong, akan muncul alert dan proses dihentikan.

if (!district_id || !courier || !weight) {
    alert('Harap lengkapi semua data terlebih dahulu!');
    return;
}

Setelah validasi berhasil, status isProcessing diset ke true, lalu tampilkan loading indicator, nonaktifkan tombol, dan ubah teks tombol menjadi "Memproses...".

isProcessing = true;

// Tampilkan loading indicator
$('#loading-indicator').show();
$('.btn-check').prop('disabled', true);
$('.btn-check').text('Memproses...');

Berikutnya, kita mengirim request AJAX ke route Laravel /check-ongkir dengan method POST. Data yang dikirim sesuai dengan parameter yang dibutuhkan oleh API Raja Ongkir.

$.ajax({
    url: "/check-ongkir",
    type: "POST",
    dataType: "JSON",
    data: {
        _token: token,
        district_id: district_id,
        courier: courier,
        weight: weight,
    },

Sebelum request dikirim, hasil perhitungan sebelumnya disembunyikan agar tidak membingungkan pengguna.

beforeSend: function() {
    $('.results-container').addClass('hidden').removeClass('block');
},

Jika request berhasil, kosongkan hasil sebelumnya, kemudian tampilkan container hasil ongkir (.results-container).

success: function (response) {
    if (response) {
        $('#results-ongkir').empty();
        $('.results-container').removeClass('hidden').addClass('block');

Melakukan looping pada hasil response menggunakan $.each. Setiap item akan ditampilkan dalam bentuk box rapi dengan informasi:

  • Nama layanan (value.service)
  • Deskripsi layanan (value.description)
  • Estimasi waktu pengiriman (value.etd)
  • Harga (value.cost)

Fungsi formatCurrency() akan mengubah angka menjadi format rupiah seperti: Rp10.000.

$.each(response, function (index, value) {
    const html = `
        <div class="flex justify-between items-center p-3 bg-white rounded-xl shadow border border-gray-200">
            <span class="text-lg font-medium text-gray-800">
                ${value.service} - ${value.description} - (${value.etd})
            </span>
            <span class="text-lg font-bold text-indigo-700">
                ${formatCurrency(value.cost)}
            </span>
        </div>
    `;
    
    $('#results-ongkir').append(html);
});

Jika terjadi error saat request (misalnya koneksi internet terputus, server down, dsb), tampilkan pesan alert ke pengguna.

error: function (xhr, status, error) {
    console.error("Gagal menghitung ongkir:", error);
    alert("Terjadi kesalahan saat menghitung ongkir. Coba lagi.");
},

Setelah request selesai (sukses maupun gagal), kembalikan tombol ke kondisi semula:

  • Sembunyikan loading
  • Aktifkan tombol
  • Kembalikan teks tombol ke "Hitung Ongkos Kirim"
  • Izinkan klik berikutnya dengan isProcessing = false
complete: function () {
    $('#loading-indicator').hide();
    $('.btn-check').prop('disabled', false);
    $('.btn-check').text('Hitung Ongkos Kirim');
    isProcessing = false;
}

Langkah 4 - Uji Coba Mendapatkan Biaya Ongkos Kirim

Silahkan buka project-nya, jika berhasil maka teman-teman akan mendapatkan tampilkan seperti berikut ini.

Silahkan pilih data dan sesuaikan dengan keinginan dan jika berhasil maka kurang lebih hasilnya seperti berikut ini.

Kesimpulan

Pada artikel kali ini, semua semua telah belajar bagaimana cara mendapatkan Biaya Ongkos Kirim menggunakan Raja Ongkir V2 dengan metode Step-by-Step di dalam Laravel.

Jika teman-teman ada kendala saat belajar, silahkan bisa bertanya melalui kolom komentar atau ke group Telegram milik SantriKoding.

Terima Kasih


Fika Ridaul Maulayya
Full-Stack Developer, Content Creator and CO-Founder SantriKoding.com

Suka dengan tulisan di SantriKoding? Kamu bisa memberikan dukungan dengan berdonasi atau bagikan konten ini di sosial media. Terima kasih atas dukungan Anda!

KEBIJAKAN KOMENTAR

Saat memberikan komenatar silahkan memberikan informasi lengkap tentang error, seperti: screenshot, link kode, dll. Baca aturan komentar kami