Misteri Dibalik Anehnya Ongkos Kirim Barang Jika Belanja di Bhinneka

Di zaman e-commerce gini, sudah banyak banget orang Indonesia yang belanja online, kita sudah terbiasa dengan cara tersebut. Ketika membeli suatu barang maka otomatis kita sudah mengetahui bahwa kita akan dikenakan biaya tambahan untuk pengiriman barang, biasanya disebut ongkir atau ongkos kirim. Nah biaya pengiriman ini berbeda-beda tergantung lokasi asal dan tujuan barang.

Mungkin kita juga sudah tahu berapa biaya kirim 1kg barang dari suatu tempat ke tempat lain, terutama ke lokasi tujuan kita. Misalnya kalo kirim barang dari Jakarta ke Bandung pake JNE Reguler bakal dikenai biaya Rp 10.000. Tapi selain ongkir, ada juga biaya tambahan lainnya. Kalo kita belanja di BukaLap*k atau Tok*pedia, maka ada nomor unik yang ditambahkan ke total biaya. Angkanya sangat kecil (gak nyampe seribu perak) karena memang tujuannya hanya sebagai identifier transaksi, biar gampang ditelusuri gitu lah.

Namun satu hal yang cukup berbeda jika kita belanja di Bhinneka. Coba perhatikan gambar berikut.

Coba lihat ongkos kirimnya. Gw beli barang yang gak nyampe 1 kg masa ongkir ke Jakarta Rp 11.650. Aneh kan? Kalo gw sebagai orang teknik (padahal kuliahnya bukan jurusan teknik, tapi gelarnya sarjana teknik #abaikan), gw penasaran angka itu dari mana. Emang sih, angka unik yang diberikan Bh*nneka nantinya akan negatif, artinya total belanja akan lebih kecil sedikit. Seperti dijelaskan pada halaman ini.

Pertama yang gw harus lakukan ialah mencari tahu sebenarnya biaya asli ongkir ini berapa, karena gw yakin ongkir dalam kota yang sama harusnya gak sampe ceban. Nah kalo kita klik tombol search untuk mencari kota tujuan, maka akan muncul halaman berikut.

Halaman ini digunakan untuk mencari kecamatan atau kota pengiriman.

Setelah muncul kota yang dicari, jangan klik tombol select dulu, kita lihat kode html nya dulu. Dan kita cari berapa ongkirnya. Dan ternyata ongkir awalnya Rp 9000!

Artinya ongkir yang harus gw bayar ada kelebihan Rp 2645. Nah ini yang menarik. Oleh Bh*nneka ongkirnya dinaikkan sekian ribu sementara disisi lain angka unik yang diberikan nilainya minus. Lalu dari mana nilai Rp 2645 itu berasal?

Cara Pertama: Pendekatan Matematis

Cara yang paling gampang mengetahui kelebihan itu ialah kita hitung Rp2645 itu berapa persen. Bisa persentase terhadap ongkir awal atau persentase terhadap harga barang. Kalo persentase terhadap ongkir awal maka persentasenya ialah 29,39%. Dan kalo persentasenya terhadap harga barang maka persentasenya ialah tepat 0.25%. Mana yang benar? Kita lanjutkan pencariannya…

Cara Kedua: Debugging Kode

Dengan cara yang pertama kita masih belum tau mana yang bener, 29 sekian persen atau 0.25 persen. Nah cara yang kedua ini ialah cara yang eksak, dengan melakukan debugging terhadap kode sumber. Logikanya, setiap kita ganti kota pengiriman maka ongirnya juga berubah. Karena itu kita lihat kode sumber halaman pencarian kota yang tadi. Dari gambar sebelumnya juga sudah bisa dilihat kalo tombol select di klik maka akan memanggil fungsi setPengiriman.

Di dalam fungsi setPengiriman terdapat bagian ini

Artinya setiap kali kota pengiriman berubah maka fungsi calculate() akan dijalankan. Setelah sedikit pencarian maka fungsi calculate() berada di file shopping-cart.min.js. Biar enak bacanya kita unminify dulu kode tersebut.

Cara debugging yang gw lakukan ialah pertama, gw bikin versi unminify dari shopping-cart.min.js. Terus gw copy ke localhost. Begitu juga dengan kode sumber dari halaman shopping cart. Sehingga gw punya dua file, index.html (kode sumber) dan shopping-cart.js. Nah untuk debugging, gw modif kode sumbernya sehingga yang dipake ialah shopping-cart.js punya gw, bukan lagi shopping-cart.min.js.

Setelah dicari-cari, hasilnya ialah bahwa Bhinneka memiliki rate besar tambahan ongkir tersebut yakni sebesar 0.25% dari total harga barang (yakni harga barang x jumlah barang) jika menggunakan JNE dan 0,22% jika menggunakan Tiki. Namun jika tambahan tersebut kurang dari Rp 2500 maka tambahan yang digunakan Rp 2500 (minimum tambahan).

Gw gak tau apa tujuan dari penambahan ini. Menurut gw sih mungkin saja biaya ini merupakan biaya handling atau packaging barang dan biaya buat jaga-jaga kalo ada force major dari suatu pengiriman. Bisa juga Bhinneka mencoba membuat keuntungan dengan margin sebesar Rp 2500 atau 0.25% atau 0.22% dari tiap transaksi. Tapi masa iya margin 0.25%? Wkwkwk

Cara Back-up Website dari Shared Hosting ke Dropbox Secara Otomatis

Data merupakan salah satu aset berharga bagi para pemilik web, apalagi bagi Anda yang memiliki data yang begitu besar. Jika suatu waktu terjadi crash atau masalah pada server sehingga data-data yang Anda miliki lenyap maka bisa-bisa Anda nangis darah. Oleh karena itu, back-up, back-up, dan back-up sebelum petaka terjadi. Umumnya data dalam database dan file-file website lah yang perlu di back-up.

Dalam tulisan kali ini gw ingin berbagi gimana caranya back-up data dalam database dan file-file website (file yang terletak pada folder public_html) secara berkala dan otomatis ke akun Dropbox kita. Cara ini bisa digunakan untuk website aplikasi maupun wordpress/CMS pada shared hosting. Cara yang gw gunakan tanpa plugin (wordpress) dan menggunakan bahasa pemrograman PHP.

Catatan: file-file website sebenarnya lebih bagus dibackup melalui version control seperti git karena perubahannya relatif jarang.

Perlengkapan

Sebelum memulai, beberapa kebutuhan yang harus diperlukan antara lain:

  • Akses ssh ke server Anda (catatan: Jika tidak punya mintalah ke penyedia hosting, namun beberapa penyedia hosting memang tidak memberikan akses ssh)
  • Akses cpanel
  • Akun Dropbox

Langkah-langkah

Secara ringkas langkah-langkah yang akan ditempuh ialah sebagai berikut:

  • Membuat Aplikasi pada Dropbox untuk Mengakses API
  • Meng-install Dropbox PHP Client
  • Membuat script PHP untuk mengupload data
  • Membuat cron job yang menjalankan script PHP

Membuat Aplikasi pada Dropbox untuk Mengakses API

  • Buatlah sebuah app baru melalui halaman ini.
  • Isi form sesuai kebutuhan. Disini karena gw cuma mau back-up file maka gw pilih jenis Dropbox API dengan tipe aksesnya App folder.
    dropbox_createnewapp
  • Klik tombol ‘Create app
  • Maka akan muncul informasi detil aplikasi yang dibuat. Pada bagian OAuth 2 klik tombol generate untuk membuat access token.
    dropbox_generateaccesstoken
  • Simpan App key, App Secret, dan Access Token (copy ke text editor). App key, App Secret, dan Access Token inilah yang akan kita gunakan.
    dropbox_savekeysecrettoken
  • Coba buka direktori Dropbox Anda maka akan ada sebuah folder baru bernama Apps

Menginstall Dropbox PHP Client

Sebenarnya Dropbox sudah menyediakan SDK API dalam berbagai bahasa.  Karena gw pake shared hosting maka akan lebih gampang kalo pake bahasa PHP. Sayang oh sayang, Dropbox belum menyediakan SDK untuk bahasa pemrograman PHP. Sebagai alternatif, kita bisa gunakan SDK yang unofficial, namanya Dropbox PHP Client.

  • Lakukan ssh ke server Anda. Kemudian cek apakah composer sudah ter-install dengan mengetik command:
    composer
  • Jika composer telah ter-install maka tampilannya akan seperti gambar berikut
    dropbox_checkingcomposer
  • Jika composer belum ter-install maka install dulu composer nya dengan mengikuti tutorial disini, atau dengan menjalankan command berikut:
    cd /
    /usr/bin/php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
    /usr/bin/php -r "if (hash_file('SHA384', 'composer-setup.php') === 'aa96f26c2b67226a324c27919f1eb05f21c248b987e6195cad9690d5c1ff713d53020a02ac8c217dbf90a7eacc9d141d') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
    /usr/bin/php composer-setup.php
    /usr/bin/php -r "unlink('composer-setup.php');"
  • Jika composer sudah ter-install, maka selanjutnya jalankan command berikut untuk meng-install Dropbox PHP Client:
    composer require kunalvarma05/dropbox-php-sdk
  • Hasillnya jika berhasil:
    dropbox_dropboxphpclientinstalled

Membuat script PHP untuk mengupload data ke Dropbox

Sebelum kita membuat script untuk mengupload data ke Dropbox kita persiapkan dulu data yang mau diupload. Data-data ini terdiri dari data pada database dan data-data yang terletak dalam folder public_html. Anda bisa menyesuaikan data apa saja yang mau diupload.

  • Buatlah sebuah folder baru khusus untuk menyimpan sementara file yang ingin diupload. Letak foldernya di luar folder_html, misalnya kita namakan ‘backup’ sehingga lokasinya: /home/<user>/backup.
  • Buatlah sebuah script PHP dalam folder tersebut sebut saja DoBackup.php yang isinya:
    <?
    //Setting Akun Database, sesuaikan dengan akun Anda
    $db_host       = "localhost";
    $db_username   = "siganteng";             //username untuk mengakses database
    $db_password   = 'm4k1nGant3n9';
    $db_name       = "databaseku";            //nama database yang ingin di-backup
    
    //Setting Akun Dropbox, sesuaikan dengan akun Anda
    $app_key       = 'k0ax1b4ml7bisk2';       //App Key
    $app_secret    = '82ahvmqyp98kx05';       //App Secret
    $access_token  = 'Wzm67iy-k2jAAAAAAAABpjs33Avbt99Uachh8MkO212jkw30sPKI_vs2I0IUV2O'; //Access Token
    
    //file database
    //$file_name   = $db_name.'_'.date("Y-m-d").'.sql.gz'; // output: 'databaseku_2016-12-08.sql.gz'
    $file_name     = $db_name.'.sql.qz';                   // output: 'databaseku.sql.gz'
    $file_dir      = dirname(__FILE__);                    // output: '/home//backup'
    
    //Mengekspor database dan dikompres
    system("mysqldump -h $db_host -u $db_username -p'$db_password' $db_name | gzip > $file_name");
    
    //Kompres folder public_html
    $public_dir    = '/home/siganteng/public_html' //ganti dengan direktori public html Anda
    //$public_name  = 'public_'.date("Y-m-d");     //nama untuk file hasil kompresi, output: 'public_2016-12-08'
    $public_name   = 'public';
    
    $phar = new PharData($public_name.'.tar');      //kompres folder menjadi .tar
    $phar->buildFromDirectory($public_dir);         //file yang sama akan di overwrite
    
    file_put_contents($public_name.'.tar.gz' , gzencode(file_get_contents($public_name.'.tar'))); //kompres .tar menjadi .tar.gz (supaya ukuran file lebih kecil)
    
    //upload file ke Dropbox
    //---------------------------------
    //import dependency
    require '../vendor/autoload.php';
    use Kunnu\Dropbox\Dropbox;
    use Kunnu\Dropbox\DropboxApp;
    use Kunnu\Dropbox\DropboxFile;
    
    //Konfigurasi koneksi aplikasi Dropbox
    $app = new DropboxApp($app_key, $app_secret, $access_token);
    
    //Menyiapkan file yang diupload
    $dropbox = new Dropbox($app);
    $dropboxFile_db = new DropboxFile(__DIR__.'/'.$file_name);
    $dropboxFile_public = new DropboxFile(__DIR__.'/'.$public_name.'.tar.gz');
    
    //Delete file saat ini, karena tidak bisa overwrite otomatis
    $deletedFile = $dropbox->delete('/'.$file_name);
    $deletedFile = $dropbox->delete('/'.$public_name.'.tar.gz');
    //Upload ke Dropbox
    $file = $dropbox->upload($dropboxFile_db, '/' . $file_name);
    $file = $dropbox->upload($dropboxFile_public, '/'.$public_name.'.tar.gz');
    ?>
    

Membuat Cron Job yang menjalankan script PHP

  • Masuklah ke layanan cron job dengan mengklik icon cron job pada Cpanel.
  • Atur preferensi waktu atau pengulangan backup seperti 1 x seminggu, 1 x sebulan, dsb. Lama pengulangan ini sangat tergantung pada kecepatan perubahan data yang masuk dan resource yang tersedia karena back-up akan menggunakan memory dan I/O.
  • Pada bagian command, tulis command berikut:
    /usr/bin/php -q /home/<user>/backup/DoBackup.php
  • Command tersebut akan menjalankan script PHP yang sudah kita buat sebelumnya dan command ini akan dijalankan secara berkala dan otomatis.
    dropbox_uploaded
  • Tips 1: untuk melihat secara langsung apakah cron job tersebut berjalan dengan baik dan proses backup ke Dropbox juga berhasil, set waktu cron job dengan waktu sekarang + 1-2 menit. Misalnya sekarang tanggal 8 Desember 2016 pukul 11.30, maka set Minute: 31, Hour: 11, Day: 8, Month: December (12), dan Weekday: Everyday (*)
    Tips 2:  pada kode diatas nama file yang gw pake untuk upload sama jadi file yang sebelumnya akan di-overwrite. Jika ingin membuat versi, Anda bisa tambahin tanggal dibelakang nama filenya jadi file yang lama gak dihapus.

 

Iris Tutorial: Hello, World!

Iris is one of Golang frameworks and claims as the fastest backend web framework for Go. Unfortunately, the documentation doesn’t provide easy-enough learning step so that a new comer like me will face some difficulties. In this tutorial I’m going to documenting my journey in learning Iris and Go.

Requirements

  • Go 1.7+
    Download Go installer here and follow installation instructions in this page.
  • Iris 5
    Run this command in your terminal to install iris

    go get -u github.com/kataras/iris/iris

Go “Hello, World!”

In your $GOPATH/src/github.com/<username>/ make a new directory for this project, for example “goapp“. Then, let’s start writing our code by creating a new Go file called app.go (goapp/app.go) which contains:

package main

import "github.com/kataras/iris"

func main() {
    app := iris.New()
    app.Get("/", index)
    app.Listen(":8080")
}

func index(ctx *iris.Context){
   ctx.Write("Hello, world!")
}

Explanation

  • iris.New() will create new iris application, we name it app
  • app.Get is used to handle HTTP Method GET
  • iris.Context is an object to handle incoming request. We will use this object for many activities such as to set cookie, getting current session, forcing file download to user, render a html page, etc.
  • ctx.Write will writes a string to the client, something like fmt.Printf but for the web
  • app.Listen will starts the standalone http server which listens to the addr parameter which as the form of host:port, in this case 0.0.0.0:8080

We need to build/run that file to show it in the browser. Just go to goapp directory via terminal and execute this command:

go run app.go

If the code is successfully compiled, open your browser and go to

http://0.0.0.0:8080
Hello, world!
Hello, world!

Considering Technology Stack

Today’s web technology is growing fast. There are numerous technology stack you can choose, both for back-end and front-end. But this also means you have to consider which technology is more appropriate for your project. And yap, sometimes choosing the technology itself can be confusing. I have been struggling with this stuff, and eventually I decide I will be using this tech stack for my next project (i.e. Edufia).

Back-end

Previosly I use Python (Flask + Restless) for building web service. It was great, simple, fast dev time, with fairly little effort. The major drawback is the performance. I feel it takes much more time for rendering a page. I don’t know exactly whether it comes from the back-end or the front-end. But after reading several articles and benchmark that involves Python, I might think Python will not be suitable for what I want in terms of performance.

Regardless of what framework I am using in the front-end, I will go for Go for my back-end. Why? First, by looking at benchmark result, it’s good in terms of performance. So I hope it will serve all requests coming faster than Python. On the top of that, Indonesian users is speed-sensitive (or maybe all users generally). Second, the code structure of Go is very similar to C and more ‘simple’ compared to similar languages like Elixir, Erlang, or Clojure. Third, Go is supported by Google. But Go is not mature yet. I mean only small number of library/framework that already exist. We may need to working without simply importing package/library, it might take more time to develop.

Font-end

Rather than creating full-stack website, I will separate back-end and front-end for my web. So, my attention will goes to Single-Page Application. Unfortunately, there are many JS SPA framework and for a novice like me it will be confusing in picking the right one. React is fast-growing, its community members is large, and the framework support server-side rendering which makes rendering a page become faster (this is my major focus). But React is only a V in MV*, you need another kind of tech to make it works.

In a nutshell, I choose Ember.js for my front-end. I have used it before for initial version of Edufia. But I think I have performance issue there. I’m not satisfied with the speed, in which the loading time is quite high. But now, there is Glimmer which I can say to be ‘a React way’ to render a page. Plus, it has FastBoot.js to make Ember.js more faster. Another reason why I choose Ember.js is its “convention over configuration”. I know that the learning curve is very hard, but you will be more productive later on.

After all, the next step is how to combine Go and Ember.js. To be honest I don’t have any idea and cannot figuring out how it will be. For now, I just trying to focus to make simple API using Go that comply with Ember Data. Once done, let me decide whether to continue with this stack or rearrange it.

Update

After struggling with golang and ember.js I think I won’t continue to adopt that tech stack. I would rather pick React as front-end, so maybe my tech stack will be like this: Golang + React + Redux + React-router + Webpack