~ We are changing the world with technology. ~

Matt Mullenweg

Aplikasi E-Commerce Laravel 6 #18: Membuat Fitur Afiliasi

Aplikasi E-Commerce Laravel 6 #18: Membuat Fitur Afiliasi

1826 Dilihat

Pendahuluan

Beragam cara atau teknik penjualan dilakukan guna mendongkrak transaksi pada sebuah bidang usaha, termasuk salah satu teknik marketing yang banyak digunakan adalah afiliasi. Teknik ini mengundang banyak orang untuk membantu mempromosikan usaha dengan memberikan komisi sebagai imbalan atas bantuan tersebut.

Serial aplikasi e-commerce Laravel 6 kali ini akan membahas bagaimana membuat fitur afiliasi dengan imbalan komisi sebesar 10% dari total transaksi dan tidak lebih dari Rp 10.000. Setiap transaksi yang terjadi dibawah link afiliasi customer tertentu, maka customer tersebut akan diberikan imbalannya setelah status transaksi terkait selesai.

Baca Juga: Aplikasi E-Commerce Laravel 6 #17: Laporan Periode Date Range

Membuat Fitur Afiliasi

Ada beberapa tahapan dalam merealisasikan fitur ini, berikut adalah langkah yang kita perlukan

  1. Menampilkan link afiliasi pada halaman product.
  2. Redirect link afiliasi kembali ke halaman product dengan menyimpan cookie.
  3. Membuat migration baru untuk menambahkan column ref dan ref_status
  4. Mengambil cookie ketika customer melakukan checkout, jika ada dan bukan dirinya sendiri maka informasi afiliasi akan disimpan pada order-an terkait.
  5. Menampilkan list komisi yang didapatkan oleh pemilik referal code.

Untuk menyelesaikan tahapan pertama, buka file ecommerce/show.blade.php dan tambahkan tag berikut di atas tag form pada quantity product.

<p>
  @if (auth()->guard('customer')->check())
  <label>Afiliasi Link</label>
  <input type="text" 
    value="{{ url('/product/ref/' . auth()->guard('customer')->user()->id . '/' . $product->id) }}" 
    readonly class="form-control">
  @endif
</p>

Kemudian untuk meng-handle redirect link dari link afiliasi di atas, buka file Ecommerce/FrontController.php dan tambahkan method.

public function referalProduct($user, $product)
{
    $code = $user . '-' . $product; //KITA MERGE USERID DAN PRODUCTID
    $product = Product::find($product); //FIND PRODUCT BERDASARKAN PRODUCTID
    $cookie = cookie('dw-afiliasi', json_encode($code), 2880); //BUAT COOKIE DENGAN NAMA DW-AFILIASI DAN VALUENYA ADALAH CODE YANG SUDAH DI-MERGE
    //KEMUDIAN REDIRECT KE HALAMAN SHOW PRODUCT DAN MENGIRIMKAN COOKIE KE BROWSER
    return redirect(route('front.show_product', $product->slug))->cookie($cookie);
}

Definisikan routing dari url di atas, buka file routes/web.php dan tambahkan route berikut di luar dari block code route group manapun.

Route::get('/product/ref/{user}/{product}', 'Ecommerce\[email protected]')->name('front.afiliasi');

Langkah pertama dan kedua telah kita selesaikan, maka langkah selanjutnya adalah berkaitan dengan database, pada command line, jalankan command

php artisan make:migration add_field_ref_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 AddFieldRefToOrdersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('orders', function (Blueprint $table) {
            $table->string('ref')->nullable()->after('tracking_number');
            $table->boolean('ref_status')->default(false)->after('ref');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('orders', function (Blueprint $table) {
            $table->dropColumn('ref');
            $table->dropColumn('ref_status');
        });
    }
}

Eksekusi migration di atas dengan command

php artisan migrate

Saatnya untuk menyimpan informasi cookie ke pesanan terkait jika customer datang dari link afiliasi, buka file Ecommerce/CartController.php dan modifikasi method processCheckout() menjadi

public function processCheckout(Request $request)
    {
        $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'
        ]);

        DB::beginTransaction();
        try {
            //TAMBAHKAN DUA BARI CODE INI
            //GET COOKIE DARI BROWSER
            $affiliate = json_decode(request()->cookie('dw-afiliasi'), true);
            //EXPLODE DATA COOKIE UNTUK MEMISAHKAN USERID DAN PRODUCTID
            $explodeAffiliate = explode('-', $affiliate);

            $customer = Customer::where('email', $request->email)->first();
            if (!auth()->guard('customer')->check() && $customer) {
                return redirect()->back()->with(['error' => 'Silahkan Login Terlebih Dahulu']);
            }

            $carts = $this->getCarts();
            $subtotal = collect($carts)->sum(function($q) {
                return $q['qty'] * $q['product_price'];
            });

            if (!auth()->guard('customer')->check()) {
                $password = Str::random(8);
                $customer = Customer::create([
                    'name' => $request->customer_name,
                    'email' => $request->email,
                    'password' => $password,
                    'phone_number' => $request->customer_phone,
                    'address' => $request->customer_address,
                    'district_id' => $request->district_id,
                    'activate_token' => Str::random(30),
                    'status' => false
                ]);
            }

            $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,
                'ref' => $affiliate != '' && $explodeAffiliate[0] != auth()->guard('customer')->user()->id ? $affiliate:NULL
            ]);
            //CODE DIATAS MELAKUKAN PENGECEKAN JIKA USERID NYA BUKAN DIRINYA SENDIRI, MAKA AFILIASINYA DISIMPAN

            foreach ($carts as $row) {
                $product = Product::find($row['product_id']);
                OrderDetail::create([
                    'order_id' => $order->id,
                    'product_id' => $row['product_id'],
                    'price' => $row['product_price'],
                    'qty' => $row['qty'],
                    'weight' => $product->weight
                ]);
            }

            DB::commit();

            $carts = [];
            $cookie = cookie('dw-carts', json_encode($carts), 2880);
            //KEMUDIAN HAPUS DATA COOKIE AFILIASI
            Cookie::queue(Cookie::forget('dw-afiliasi'));

            if (!auth()->guard('customer')->check()) {
                Mail::to($request->email)->send(new CustomerRegisterMail($customer, $password));
            }
            return redirect(route('front.finish_checkout', $order->invoice))->cookie($cookie);
        } catch (\Exception $e) {
            DB::rollback();
            return redirect()->back()->with(['error' => $e->getMessage()]);
        }
    }

Jangan lupa menambahkan use statement di dalam file yang sama.

use Cookie;

Menampilkan List Komisi

Setiap komisi transaksi harus ada transparansi antara pemilik aplikasi dan user yang turut serta memasarkan product, maka pada seri ini kita akan belajar bagaimana menampilkan data tersebut. Buka file Ecommerce/FrontController.php dan tambahkan method

public function listCommission()
{
    $user = auth()->guard('customer')->user(); //AMBIL DATA USER YANG LOGIN
    //QUERY BERDASARKAN ID USER DARI DATA REF YANG ADA DIORDER DENGAN STATUS 4 ATAU SELESAI
    $orders = Order::where('ref', $user->id)->where('status', 4)->paginate(10);
    //LOAD VIEW AFFILIATE.BLADE.PHP DAN PASSING DATA ORDERS
    return view('ecommerce.affiliate', compact('orders'));
}

Dan tambahkan use statement

use App\Order;

Sediakan view-nya untuk menampilkan data tersebut, buat file baru dengan nama affiliate.blade.php di dalam folder resources/views/ecommerce dan tambahkan code

@extends('layouts.ecommerce')

@section('title')
    <title>Daftar Komisi - DW Ecommerce</title>
@endsection

@section('content')
    <!--================Home Banner Area =================-->
	<section class="banner_area">
		<div class="banner_inner d-flex align-items-center">
			<div class="container">
				<div class="banner_content text-center">
					<h2>Daftar Komisi</h2>
					<div class="page_link">
            <a href="{{ url('/') }}">Home</a>
            <a href="{{ route('customer.affiliate') }}">Daftar Komisi</a>
					</div>
				</div>
			</div>
		</div>
	</section>
	<!--================End Home Banner Area =================-->

	<!--================Login Box Area =================-->
	<section class="login_box_area p_120">
		<div class="container">
			<div class="row">
				<div class="col-md-3">
					@include('layouts.ecommerce.module.sidebar')
				</div>
				<div class="col-md-9">
          <div class="row">
						<div class="col-md-12">
							<div class="card">
                <div class="card-header">
                    <h4 class="card-title">Komisi Afiliasi</h4>
                </div>
<div class="card-body">

                    @if (session('error'))
                        <div class="alert alert-danger">{{ session('error') }}</div>
                    @endif

                    @if (session('success'))
                    <div class="alert alert-success">{{ session('success') }}</div>
                    @endif

  <div class="table-responsive">
                        <table class="table table-hover table-bordered">
                            <thead>
                                <tr>
                                    <th>Invoice</th>
                                    <th>Penerima</th>
                                    <th>Komisi</th>
                                    <th>Status</th>
                                    <th>Tanggal</th>
                                </tr>
                            </thead>
                            <tbody>
                                @forelse ($orders as $row) 
                                <tr>
                                    <td>
                                        <strong>{{ $row->invoice }}</strong><br>
                                        @if ($row->return_count == 1)
                                        <small>Return: {!! $row->return->status_label !!}</small>
                                        @endif
                                    </td>
                                    <td>{{ $row->customer_name }}</td>
                                    <td>Rp {{ number_format($row->commission) }}</td>
                                    <td>{!! $row->ref_status_label !!}</td>
                                    <td>{{ $row->created_at }}</td>
                                </tr>
                                @empty
                                <tr>
                                    <td colspan="6" class="text-center">Tidak ada komisi</td>
                                </tr>
                                @endforelse
                            </tbody>
                        </table>
                    </div>
                    <div class="float-right">
                        {!! $orders->links() !!}
                    </div>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</section>
@endsection

Note: Tidak ada yang perlu dijelaskan pada code di atas karena sama dengan view data order.

Kemudian definisikan routing-nya, buka file routes/web.php dan tambahkan route di dalam route group dengan middleware customer

Route::get('/afiliasi', '[email protected]')->name('customer.affiliate');

Kita juga harus menyediakan Accessor untuk kalkulasi komisi dan status komisinya, buka file Order.php dan tambahkan kedua method berikut

public function getRefStatusLabelAttribute()
{
    if ($this->ref_status == 0) {
        return '<span class="badge badge-secondary">Pending</span>';
    }
    return '<span class="badge badge-success">Dicairkan</span>';
}

public function getCommissionAttribute()
{
    //KOMISINYA ADALAH 10% DARI SUBTOTAL
    $commission = ($this->subtotal * 10) / 100;
    //TAPI JIKA LEBIH DARI 10.000 MAKA YANG DIKEMBALIKAN ADALAH 10.000
    return $commission > 10000 ? 10000:$commission;
}

Jangan lupa property $appends di modifikasi menjadi

protected $appends = ['status_label', 'ref_status_label', 'commission'];

Langkah terakhir adalah membuat sidebar menu untuk halaman afiliasi, buka file layouts/ecommerce/module/sidebar.blade.php dan tambahkan menu

<li class="icon-customers"><a href="{{ route('customer.affiliate') }}">Afiliasi</a></li>

Baca Juga: Aplikasi E-Commerce Laravel 6 #16: Integrasi Telegram Bot

Kesimpulan

Sepanjang artikel ini kita sudah belajar bagaimana memainkan peran cookie untuk membantu kita dalam membuat fitur afiliasi pada aplikasi e-commerce Laravel 6. Challenge-nya adalah teman-teman bisa mencoba bagaimana mengubah status afiliasi apabila customer meminta untuk withdraw komisinya. Selamat mencoba!

Adapun dokumentasi code dari artikel ini bisa dilihat di Github.

Full Stack Developer & Remote Worker salah satu perusahaan asal Australia. Senang dengan teknologi baru. Laravel addict yang tidak fanatik. Merekam jejak dengan menulis

Cara Upload File ke Amazon S3 Menggunakan Laravel 7 Laravel

Cara Upload File ke Amazon S3 Menggunaka...

Mengelola data dengan format file umumnya menjadi bagian yang sering kali ditemukan pada sebuah aplikasi, sebut saja avatar atau file gambar untuk setiap users, pdf, video dan lain sebagainya. Berikut...

Laravel Multiple Database MySql & MongoDB Laravel

Laravel Multiple Database MySql & MongoD...

Mengelola lebih dari satu database di Laravel akan menjadi bahan pembahasan kita dimana engine database yang akan digunakan adalah MySQL dan MongoDB, persoalannya adalah bagaimana menggunakan kedua da...

Mengenal & Mengimplementasikan Laravel Airlock Laravel

Mengenal & Mengimplementasikan Laravel A...

Salah satu fitur yang menarik perhatian dari Laravel 7 adalah Airlock. Fitur ini melengkapi sederet fitur lainnya yang serupa dalam menciptakan fungsi authentication, sebut saja yang lebih dahulu dike...

Komentar