Pendahuluan
Sejak pertama kali serial Membuat Aplikasi E-Commerce Laravel 6 di-release, ada banyak permintaan untuk menerapkan fitur ongkos kirim, namun kendalanya, tidak satupun yang memiliki license ongkos kirim untuk digunakan secara public. Hal ini tentu saja menjadi kendala kami dalam menuliskan materi karena tidak adanya sumber untuk mengambil data ongkos kirim.
Kendala lainnya adalah license yang dimiliki jika tidak didonasikan ke public akan menjadi halangan bagi teman-teman pembaca lainnya dalam mengikuti serial tersebut, sehingga kami putuskan untuk tidak membahas terkait fitur ongkos kirim pada aplikasi ecommerce yang kita bangun.
Beruntungnya saat ini sudah tersedia RuangAPI, dimana kita bisa menggunakannya secara gratis untuk diterapkan pada project apapun yang membutuhkan data ongkos kirim. Berikut adalah materi bagaimana menerapkan fitur ongkos kirim pada Aplikasi E-Commerce Laravel 6.
Baca Juga: Membuat Aplikasi Ekspedisi NuxtJS #4: Manage Categories
Integrasi Data Ongkos Kirim RuangAPI
Proses integrasi untuk mengambil data ongkos kirim pada platform RuangAPI adalah dengan melakukan hit ke API yang sudah disediakan. Akan tetapi, agar bisa mendapatkan izin, maka kita wajib melakukan pendaftaran untuk mendapatkan API Key. Tenang saja, pendaftarannya gratis dan setelah proses pendaftaran selesai, kamu bisa mendapatkan API Key nya pada menu RuangAPI Key.
Adapun HTTP Client yang akan digunakan adalah Guzzle, install terlebih dahulu dengan command
composer require guzzlehttp/guzzle
Buka file Ecommerce/CartController.php
dan tambahkan method berikut
public function getCourier(Request $request)
{
$this->validate($request, [
'destination' => 'required',
'weight' => 'required|integer'
]);
//MENGIRIM PERMINTAAN KE API RUANGAPI UNTUK MENGAMBIL DATA ONGKOS KIRIM
//BACA DOKUMENTASI UNTUK PENJELASAN LEBIH LANJUT
$url = 'https://ruangapi.com/api/v1/shipping';
$client = new Client();
$response = $client->request('POST', $url, [
'headers' => [
'Authorization' => 'API KEY ANDA'
],
'form_params' => [
'origin' => 22, //ASAL PENGIRIMAN, 22 = BANDUNG
'destination' => $request->destination,
'weight' => $request->weight,
'courier' => 'jne,jnt' //MASUKKAN KEY KURIR LAINNYA JIKA INGIN MENDAPATKAN DATA ONGKIR DARI KURIR YANG LAIN
]
]);
$body = json_decode($response->getBody(), true);
return $body;
}
Masih dengan file yang sama, tambahkan use statement
use GuzzleHttp\Client;
Definisikan routing dari method di atas, buka file routes/api.php
dan tambahkan code
Route::post('cost', 'Ecommerce\CartController@getCourier');
Tiba saatnya bagi kita untuk meng-handle view halaman checkout, buka file ecommerce/checkout.blade.php
dan tambahkan tag berikut tepat di bawah tag kecamatan.
<div class="col-md-12 form-group p_star">
<label for="">Kurir</label>
<input type="hidden" name="weight" id="weight" value="{{ $weight }}">
<select class="form-control" name="courier" id="courier" required>
<option value="">Pilih Kurir</option>
</select>
<p class="text-danger">{{ $errors->first('courier') }}</p>
</div>
Kemudian modifikasi tag untuk menampilkan summary pesanan, masih dengan file yang sama, modifikasi bagian berikut
<ul class="list list_2">
<li>
<a href="#">Subtotal
<span>Rp {{ number_format($subtotal) }}</span>
</a>
</li>
<li>
<a href="#">Pengiriman
<span id="ongkir">Rp 0</span>
</a>
</li>
<li>
<a href="#">Total
<span id="total">Rp {{ number_format($subtotal) }}</span>
</a>
</li>
</ul>
Note: Bagian yang di-edit adalah menambahkan id ongkir dan total.
Bergeser pada bagian javascriptnya, tambahkan code berikut di dalam file yang sama
//JIKA KECAMATAN DIPILIH
$('#district_id').on('change', function() {
//MEMBUAT EFEK LOADING SELAMA PROSES REQUEST BERLANGSUNG
$('#courier').empty()
$('#courier').append('<option value="">Loading...</option>')
//MENGIRIM PERMINTAAN KE SERVER UNTUK MENGAMBIL DATA API
$.ajax({
url: "{{ url('/api/cost') }}",
type: "POST",
data: { destination: $(this).val(), weight: $('#weight').val() },
success: function(html){
//BERSIHKAN AREA SELECT BOX
$('#courier').empty()
$('#courier').append('<option value="">Pilih Kurir</option>')
//LOOPING DATA ONGKOS KIRIM
$.each(html.data.results, function(key, item) {
let courier = item.courier + ' - ' + item.service + ' (Rp '+ item.cost +')'
let value = item.courier + '-' + item.service + '-'+ item.cost
//DAN MASUKKAN KE DALAM OPTION SELECT BOX
$('#courier').append('<option value="'+value+'">' + courier + '</option>')
})
}
});
})
//JIKA KURIR DIPILIH
$('#courier').on('change', function() {
//UPDATE INFORMASI BIAYA PENGIRIMAN
let split = $(this).val().split('-')
$('#ongkir').text('Rp ' + split[2])
//UPDATE INFORMASI TOTAL (SUBTOTAL + ONGKIR)
let subtotal = "{{ $subtotal }}"
let total = parseInt(subtotal) + parseInt(split['2'])
$('#total').text('Rp' + total)
})
Bagian berikutnya adalah meng-handle data ongkos kirim yang dipilih untuk kemudian disimpan ke database. Buat migration baru dengan command
php artisan make:migration add_field_shipping_to_orders_table
Buka file migration yang baru saja di-generate dan modifikasi menjadi
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddFieldShippingToOrdersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('orders', function (Blueprint $table) {
$table->integer('cost')->after('subtotal')->default(0);
$table->string('shipping')->after('cost')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('cost');
$table->dropColumn('shipping');
});
}
}
Eksekusi migration diatas dengan command php artisan migrate
.
Saatnya untuk mengelola data ongkos kirim yang dipilih oleh pelangga, buka file Ecommerce/CartController.php
dan modifikasi beberapa bagian berikut pada method processCheckout()
. Bagian pertama adalah validasi di-ubah menjadi.
$this->validate($request, [
'customer_name' => 'required|string|max:100',
'customer_phone' => 'required',
'email' => 'required|email',
'customer_address' => 'required|string',
'province_id' => 'required|exists:provinces,id',
'city_id' => 'required|exists:cities,id',
'district_id' => 'required|exists:districts,id',
'courier' => 'required' //TAMBAHKAN VALIDASI KURIR
]);
Selanjutnya modifikasi query untuk menyimpan informasi pesanan menjadi
$shipping = explode('-', $request->courier); //EXPLODE DATA KURIR, KARENA FORMATNYA, NAMAKURIR-SERVICE-COST
$order = Order::create([
'invoice' => Str::random(4) . '-' . time(),
'customer_id' => $customer->id,
'customer_name' => $customer->name,
'customer_phone' => $request->customer_phone,
'customer_address' => $request->customer_address,
'district_id' => $request->district_id,
'subtotal' => $subtotal,
'cost' => $shipping[2], //SIMPAN INFORMASI BIAYA ONGKIRNYA PADA INDEX 2
'shipping' => $shipping[0] . '-' . $shipping[1], //SIMPAN NAMA KURIR DAN SERVICE YANG DIGUNAKAN
'ref' => $affiliate != '' && $explodeAffiliate[0] != auth()->guard('customer')->user()->id ? $affiliate:NULL
]);
Sampai pada tahap ini, proses integrasi berhasil dilakukan. Tapi sebelum melakukan proses uji coba, ada beberapa bagian yang perlu untuk dilakukan penyesuaian.
[BUG] Berat Produk Pesanan
Error pertama yang akan kita temukan adalah terkait berat pada produk yang dipilih atau yang dimasukkan ke dalam keranjang. Buka file Ecommerce/CartController.php
dan modifikasi method checkout()
menjadi
public function checkout()
{
$provinces = Province::orderBy('created_at', 'DESC')->get();
$carts = $this->getCarts();
$subtotal = collect($carts)->sum(function($q) {
return $q['qty'] * $q['product_price'];
});
//TAMBAHKAN FUNGSI UNTUK MENGHITUNG BERAT BARANG
$weight = collect($carts)->sum(function($q) {
return $q['qty'] * $q['weight'];
});
//JANGAN LUPA PASSING KE VIEW
return view('ecommerce.checkout', compact('provinces', 'carts', 'subtotal', 'weight'));
}
Masalah berikutnya yang akan kita temukan adalah berat pesanan ini tidak masuk ke dalam cookie atau keranjang belanja. Jadi buka di dalam file yang sama, modifikasi method addToCart()
menjadi
public function addToCart(Request $request)
{
$this->validate($request, [
'product_id' => 'required|exists:products,id',
'qty' => 'required|integer'
]);
$carts = $this->getCarts();
if ($carts && array_key_exists($request->product_id, $carts)) {
$carts[$request->product_id]['qty'] += $request->qty;
} else {
$product = Product::find($request->product_id);
$carts[$request->product_id] = [
'qty' => $request->qty,
'product_id' => $product->id,
'product_name' => $product->name,
'product_price' => $product->price,
'product_image' => $product->image,
'weight' => $product->weight //TAMBAHKAN BERAT KE DALAM COOKIE
];
}
$cookie = cookie('dw-carts', json_encode($carts), 2880);
//KITA JUGA MENAMBAHKAN FLASH MESSAGE UNTUK NOTIFIKASI PRODUK DIMASUKKAN KE KERANJANG
return redirect()->back()->with(['success' => 'Produk Ditambahkan ke Keranjang'])->cookie($cookie);
}
[BUG] Notifikasi Add to Cart
Ada yang memberikan masukan terkait UI/UX, dimana sebelumnya kita tidak memberikan feedback kepada pelanggan bahwa produk sudah ditambahkan ke dalam keranjang. Adapun fungsi flash message-nya sudah kita tambahkan, sehingga pada bagian ini, kita hanya akan menampilkan flash message tersebut.
Buka file ecommerce/show.blade.php
dan tambahkan tag berikut tepat di bawah tombol add to cart.
@if (session('success'))
<div class="alert alert-success mt-2">{{ session('success') }}</div>
@endif
Menampilkan Ongkos Kirim
Data ongkos kirim untuk setiap pesanan sudah tersedia, saatnya bagi kita untuk menyesuaikan pada beberapa bagian agar data tersebut ditampilkan. Buka file checkout_finish.blade.php
dan modifikasi tag berikut
<li>
<a href="#">
<span>Subtotal</span> : Rp {{ number_format($order->subtotal) }}
</a>
</li>
<li>
<a href="#">
<span>Ongkos Kirim</span> : Rp {{ number_format($order->cost) }}
</a>
</li>
<li>
<a href="#">
<span>Total</span> : Rp {{ number_format($order->total) }}
</a>
</li>
Note: Cukup tambahkan informasi ongkos kirim dan total.
Bagian selanjutnya adalah pada halaman list pesanan, buka file ecommerce/orders/index.blade.php
dan modifikasi baris untuk menampilkan subtotal menjadi total.
<td>{{ number_format($row->total) }}</td>
Objek total merupakan sebuah Accessor, sehingga buka file app/Order.php
dan tambahkan code berikut
public function getTotalAttribute()
{
return $this->subtotal + $this->cost;
}
Jangan lupa pada bagian property $appends
untuk menambahkan total
protected $appends = ['status_label', 'ref_status_label', 'commission', 'total'];
Baca Juga: Cara Membuat Sistem Komentar Dengan Laravel 7
Kesimpulan
Menambahkan fitur Ongkos kirim pada seri membuat aplikasi Ecommerce menggunakan Laravel 6, dimana kita membuat fitur integrasi data ongkos kirim dengan menggunakan API ongkos kirim dari RuangAPI.
Dokumentasi code dari materi ini bisa dilihat di Github.
Comments