Berikut adalah langkah-langkah detail untuk menambahkan fitur ongkos kirim menggunakan API dari RajaOngkir ke dalam web e-commerce Laravel yang telah kita buat sebelumnya.
Langkah 1: Daftar dan Dapatkan API Key RajaOngkir
- Daftar akun di RajaOngkir.
- Pilih paket yang sesuai (Starter sudah cukup untuk testing).
- Salin API Key yang diberikan di dashboard RajaOngkir.
Langkah 2: Install Guzzle HTTP Client
RajaOngkir memerlukan HTTP request untuk mengambil data. Install Guzzle:
composer require guzzlehttp/guzzle
Langkah 3: Buat File Config untuk RajaOngkir
Buat file config di config/rajaongkir.php:
<?php
return [
'api_key' => env('RAJAONGKIR_API_KEY'),
'base_url' => env('RAJAONGKIR_BASE_URL', 'https://api.rajaongkir.com/starter/'),
];
Tambahkan API Key ke file .env:
RAJAONGKIR_API_KEY=your_api_key
RAJAONGKIR_BASE_URL=https://api.rajaongkir.com/starter/
Langkah 4: Tambahkan Service untuk RajaOngkir
Buat service di config/service.php dan tambahkan config berikut:
'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
'rajaongkir' => [
'api_key' => env('RAJAONGKIR_API_KEY'),
'base_url' => 'https://api.rajaongkir.com/starter/',
],
Langkah 5: Buat Controller
Buat controller untuk menangani ongkos kirim:
php artisan make:controller ShippingController
Tambahkan ke ShippingController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
class ShippingController extends Controller
{
public function getProvinces()
{
try {
$response = Http::withHeaders([
'key' => config('services.rajaongkir.api_key'),
])->get(config('services.rajaongkir.base_url') . 'province');
if ($response->successful()) {
return response()->json($response->json()['rajaongkir']['results']);
}
return response()->json(['error' => $response->json()], $response->status());
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
public function getCities(Request $request)
{
$provinceId = $request->province_id;
// Panggil API RajaOngkir untuk mendapatkan data kota
$response = Http::withHeaders([
'key' => config('services.rajaongkir.api_key'),
])->get(config('services.rajaongkir.base_url') . 'city', [
'province' => $provinceId,
]);
// Periksa jika response sukses
if ($response->successful()) {
return response()->json($response->json()['rajaongkir']['results']);
} else {
return response()->json(['error' => $response->json()], $response->status());
}
}
public function getShippingCost(Request $request)
{
$total = $request->total; // Total produk dari frontend
$validated = $request->validate([
'city' => 'required|integer',
'weight' => 'required|integer|min:1',
'courier' => 'required|string',
]);
try {
// Panggil API RajaOngkir
$response = Http::withHeaders([
'key' => config('services.rajaongkir.api_key'),
])->post('https://api.rajaongkir.com/starter/cost', [
'origin' => 114,
'destination' => $validated['city'],
'weight' => $validated['weight'],
'courier' => $validated['courier'],
]);
$data = $response->json();
if (isset($data['rajaongkir']['results'][0]['costs'])) {
$shippingCost = $response->json()['rajaongkir']['results'][0]['costs'][0]['cost'][0]['value']; // Ongkos kirim
$grandTotal = $total + $shippingCost; // Total keseluruhan
return response()->json([
'cost' => $data['rajaongkir']['results'][0]['costs'][0]['cost'][0]['value'],
'estimate' => $data['rajaongkir']['results'][0]['costs'][0]['cost'][0]['etd'],
'grandTotal' =>$grandTotal,
]);
}else if ($response->failed()) {
return response()->json([
'error' => 'Failed to calculate shipping cost: ' . $response->json()['rajaongkir']['status']['description'] ?? 'Unknown error'
], 400);
}
return response()->json(['error' => 'Failed to calculate shipping cost'], 400);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
}
Langkah 6: Tambahkan Routes
Tambahkan route di routes/web.php:
Route::get('/provinces', [ShippingController::class, 'getProvinces'])->name('provinces');
Route::get('/cities', [ShippingController::class, 'getCities'])->name('cities');
Route::post('/calculate-shipping', [ShippingController::class, 'getShippingCost'])->name('calculate.shipping');
Langkah 7: Update Halaman Checkout
Di resources/views/frontend/checkout.blade.php, tambahkan form untuk memilih provinsi, kota, dan kurir:
@extends('layouts.frontend')
@section('content')
<div class="container">
<h2>Checkout</h2>
<form action="{{ route('checkout.process') }}" method="POST" id="paymentForm">
<!-- Address Fields -->
<h4>Billing Address</h4>
<div class="mb-3">
<label for="address" class="form-label">Address</label>
<textarea class="form-control" name="address" id="address" rows="3" required>{{ old('address') }}</textarea>
</div>
<div class="mb-3">
<label for="province">Province</label>
<select class="form-control" id="province" name="province" value="{{ old('state') }}" required>
<option value="">Select Province</option>
</select>
</div>
<div class="mb-3">
<label for="city">City</label>
<select class="form-control" id="city" name="city" value="{{ old('city') }}" required>
<option value="">Select City</option>
</select>
</div>
<div class="mb-3">
<label for="zip" class="form-label">ZIP Code</label>
<input type="text" class="form-control" name="zip" id="zip" value="{{ old('zip') }}" required>
</div>
<div class="mb-3">
<label for="courier">Courier</label>
<select class="form-control" id="courier" name="courier">
<option value="jne">JNE</option>
<option value="pos">POS</option>
<option value="tiki">TIKI</option>
</select>
</div>
<div class="mb-3">
<label for="weight">Weight (gram)</label>
<input class="form-control" type="number" id="weight" name="weight" value="1000">
</div>
<div id="shippingResult"></div>
<input class="form-control" type="hidden" id="total" name="total" value="{{ $total }}">
<h4>Order Summary</h4>
<ul>
@foreach ($cart as $item)
<li>{{ $item['name'] }} - {{ $item['quantity'] }} x ${{ $item['price'] }}</li>
@endforeach
</ul>
<div id="grandtotal"><strong>Total: </strong> ${{ number_format($total, 2) }}</div>
<button type="submit" class="btn btn-primary btn-space">Place Order</button>
</form>
</div>
@endsection
@section('script')
<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const provinceDropdown = document.getElementById('province');
const cityDropdown = document.getElementById('city');
// Fetch provinces
fetch('{{ route('provinces') }}')
.then(response => response.json())
.then(data => {
data.forEach(province => {
const option = document.createElement('option');
option.value = province.province_id;
option.textContent = province.province;
provinceDropdown.appendChild(option);
});
});
$('#province').change(function () {
let provinceId = $(this).val();
if (provinceId) {
$.ajax({
url: '/cities',
type: 'GET',
data: { province_id: provinceId },
dataType: 'json',
success: function (data) {
let cityDropdown = $('#city');
cityDropdown.empty();
cityDropdown.append('<option value="">Select City</option>');
$.each(data, function (key, city) {
cityDropdown.append(`<option value="${city.city_id}">${city.city_name}</option>`);
});
},
error: function (xhr) {
alert('Error fetching city data');
},
});
}
});
});
</script>
<script>
$(document).ready(function () {
// Setup CSRF token for AJAX requests
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
},
});
// Event listener untuk city
$(document).on('change', '#city', function () {
let city = $(this).val();
console.log('Selected city:', city); // Debugging
let weight = $('#weight').val();
let courier = $('#courier').val();
let total = $('#total').val();
if (city && weight && courier) {
calculateShipping(city, weight, courier, total);
}
});
// Function untuk menghitung ongkir
function calculateShipping(city, weight, courier, total) {
let token = $("meta[name='csrf-token']").attr("content");
$.ajax({
url: '/calculate-shipping',
type: 'POST',
data: {
city: city,
weight: weight,
courier: courier,
_token: token,
total: total,
},
success: function (response) {
$('#shippingResult').html(`
<p>Shipping Cost: ${response.cost}</p>
<p>Estimated Delivery Time: ${response.estimate}</p>
<p>Grand Total: ${response.grandTotal}</p>
`);
$('#grandtotal').html(`Total:
${response.grandTotal}
`);
},
error: function (xhr, status, error) {
alert('Error calculating shipping cost: ' + xhr.responseText);
},
});
}
});
</script>
@endsection('script')
Langkah 8: Uji Fitur Ongkos Kirim
Silahkan check out salah satu produk. Kemudian jika berhasil, untuk Provinsi dan City otomatis ketika diklik akan memanggil API Rajaongkir untuk get province dan city. Dan ketika province dipilih, akan memunculkan dropdown bertingkat untuk city sebagai berikut:
Lalu otomatis akan menghitung biaya ongkos kirim seperti berikut:
Selamat mencoba!!! Silahkan tinggalkan komentar jika belum berhasil