2020年5月19日 星期二

Shopify 開店筆記 - 跨境電商、依重量計算運費、依地區限制購物

google SHOP stock 2020/05/16

約莫協助公司維運自家電商已經有五年多。

通常電商的成績不佳,大部分會被認為是電商平台的設計問題,像是購物流程是否可以改善、網站配色是否不夠精美等等。因此,我們也開始研究是否朝向知名的網購平台 Shopify 來維運。Shopify 是一個體質非常好的電商平台,非常適合小試身手的平台,而這波疫情也讓 Shopify 股價扶搖直上。

其實,公司維運的電商平台老早就有用 Shopify 幾年了,如幫其他客戶經營副牌、白牌等。對我而言是一個熟悉又陌生的平台,因為整體上的維運都已經不需要透過工程師。趁這次把品牌電商遷移到 Shopify 上,順手記錄碰到的課題,主要分成收錢(金流)、寄貨(物流)、買家交易過程和其他需求等筆記,而 Shopify 其實有不錯的 Shopify App Store,可以自行添購(通常是訂閱式,每月支付),有些真的滿夠用,十分方便。

收錢/金流:

提供常見的 Paypal 支付,以及 Shopify Payment 機制,而這兩點都恰好因為已有 Paypal 帳號跟有香港辦公室的關係無痛打通。這兩個金流的使用都有地緣限制,像 Shopify Payment 還可以有 Google pay / Apple Pay ,只是不見得買家的地方可以使用。

金流上當客戶在網站上完成支付後,Shopify 便會立即發信給 商店聯絡電子郵件,就是在 "後台 -> 設定 -> 一般 -> 商店聯絡電子郵件" 設定。

此外 Paypal 帳號也是只限制 PayPal 商業帳戶,不能用個人的。

寄貨/物流:

Shopify 的物流可以簡單到自己寄送即可,單純把訂單標記成已出貨,並且可以填寫 tracking code 及查詢的方式(使用的物流),就完成了!

而物流的複雜度其實可大可小,我認為比較重要的是運送費率的設計,Shopify 支援設定多個倉儲位置,假設設定了兩個處(香港和台灣),那必須替這兩個倉儲分別設定運送策略。假設只對香港設定寄送到全世界而台灣倉庫沒有任何運送設定,這時有一位台灣用戶下單時,他會被默認靠近台灣而使用台灣倉庫的寄送策略,但台灣倉庫沒設定運送到台灣的運費規則,而導致使用者無法完成下單(會顯示類似無法寄送的錯誤訊息)。

另外,若設計以重量方式計算運費時,假設以 0.5kg 為間隔單位,分別設定了 "小於0.5kg"、"0.5kg到1.0kg"、"1.0kg到1.5kg",1.5kg到2.0kg",這時若使用者買的東西總重落在 2.0kg 以下是可以的,且有運費合併計算的美意,但如果使用者買的總重量超過 2.0kg 時,一樣會落入無法寄送的錯誤訊息,因為沒有大於 2.0kg 的運費規則。

另外,也要留意裝箱的箱子重量,定義了依重量計費時,結果不如預期時,可能是箱子重量影響。

買家交易過程:

如果沒有調整過預設設定時,客戶在下單過程時,可以選用手機門號簡訊完成認證,快速驗身完就可以下單了,非常貼心。而訂單狀態會用簡訊通知對方。然而,若是在做跨境電商時,碰到訂單問題時,就得走電話聯繫,推論會十分痛苦。另一方面,快遞都會要求填寫聯絡電話,若客戶訂購時沒留下電話資訊也會很苦的。

因此,將會到 "後台 -> 設定 -> 結帳",在 "客戶聯絡" 方面,改成限定用 email 結帳。表單資訊,會要求填寫 "運送地址電話號碼"。作為跨境電商的訂單管理機制。

其他項目 - 賣樣品給客人:

Shopify 建立訂單草稿 是非常好用的項目!若業務想要銷售樣品給客人時,透過訂單草稿,可以自行打包幾個商品、給予折扣,再透過寄送電子發票,便直接通報客戶直接到 Shopify 付款,整個過程非常方便。讓業務很快地辦完事,負責金流物流的同事也只是例行處理自己的職責。十分完美。

可以多多參考 Shopify 的說明:訂單草稿

其他項目 - 提醒未完成結帳項目:

當用戶在 Shopify 平台下單時,未完成結帳的訂單,一樣在後台可以看到。Shopify 可以在 "後台 -> 設定 -> 結帳 -> 未完成結帳作業" ,設定幾小時後傳送提醒信件。如此可以設法拉回一些潛在用戶。

其他項目 - 跨境電商 - 依照地區給予不同價格:

這個應數主要是總代理跟代理之間的關係,如果某個地區有代理商了,總代理賣的價格通常不能低於代理商,不然代理商都賣不出貨了。面對這個需求有兩種解法,第一種就是故意在電商上不銷售到有代理商的區域,可以靠 運費費率 的設定,讓有代理商地區沒有運費規則,這樣用戶就不能下單。另一種要花點錢的機制,使用 Multi-Country-Pricing 等類似服務,依照地區給予不同價格,但 Shopify 的核心只有收一個幣別,就算透過 Multi-Country-Pricing 的機制能夠給予當地使用者觀看當地的幣值,最終在收費時,還是會轉回原先 Shopify 商店所規範的價格(如美金為單位)


其他項目 - 信件通知:

Shopify 會用 "後台 -> 設定 -> 一般 -> 商店詳細資訊 -> 客戶電子郵件" 當作 mail sender 發送。通常 Shopify 發送到自己管理的 mail server 時,可以透過 SPF record 來允許,增加信件不被規範到垃圾信中。只有時很慘的,自家 mail server 阻擋了 Shopify 寄來的信時,只能設法靠不同的 mail domain 來避開。


在不同 mail domain 避開的機制下,例如現在用 [email protected] 作為 商店聯絡電子郵件 ,只好再用 [email protected] 當作 客戶電子郵件 。此時必須記得去修改信件通知的資訊,避免信件通知信一直請客人寄信給 [email protected] 尋求客服。而 [email protected] 最好也在設定個自動轉寄到 [email protected] ,避免漏掉客戶的重要信件。願意花錢可以靠 AWS WorkMail 單一帳號一個月四美金頂著用,不願意花錢可以試試免錢的 Yandex.Mail 。

2020年5月8日 星期五

[Python] 使用 http.server.BaseHTTPRequestHandler 製作簡易 Proxy 機制 @ macOS, python 3

學會用 curl / wget 模仿一些 request 後,在一些特殊情境上,還是得弄個 proxy 出來,雖然有 man-in-the-middle Proxy: mitmproxy 可以使用,但有時就是想要單純一點,寫點小程式自娛一下 XD

故事的情境:

- 想用 VLC 播放一些 Streaming 來源,但該 streaming 在存取時要求多塞一些request header,直接播會收到 40X 回應
- VLC 預設只吃 OS Level 的 proxy 設定

基於上述情境,雖然靠 curl/wget 添加 request header 可以搞定,但 VLC 這類就無法達成播放指定來源時多添加 request header。

因此,除了靠 OS Level 的 Proxy server 添加 reader header,就剩寫一隻代抓資料,邊抓邊輸出 stream 的小小程式,程式碼:

import http.server
import urllib.parse
import requests
import time

class ProxyHTTPRequestHandler(http.server.BaseHTTPRequestHandler):
	protocol_version = 'HTTP/1.0'

	def do_GET(self, body=True):
		try:
			target_url = urllib.parse.parse_qs(urllib.parse.urlparse(self.path).query).get('url', None)
			print("[INFO] target_url: "+str(target_url))
			if target_url != None:
				target_url = target_url[0]
				req_header = self.parse_headers()
				#resp = requests.get(target_url, headers=req_header, verify=False, stream=True)
				resp = requests.get(target_url, headers=req_header, verify="certs.pem", stream=True)
				print("[INFO] resp.status_code: %d " % resp.status_code)
				if resp.status_code == 404:
					self.send_response(404)
					self.send_header('Content-Type','text/html')
					self.end_headers()
					self.wfile.write("NOT FOUND".encode())
				else:
					self.send_response(resp.status_code)
					for k in resp.headers.keys():
						print("[INFO] resp.headers: [%s][%s]" % (k, resp.headers[k]) )
						self.send_header(k, resp.headers[k])
					self.end_headers()
					for chunk in resp.iter_content(chunk_size=1024):
						if chunk:
							self.wfile.write(chunk)
							self.wfile.flush()
						else:
							time.sleep(0.05)
				
			else:
				self.send_response(404)
				self.send_header('Content-Type','text/html')
				self.end_headers()
				self.wfile.write("NOT FOUND".encode())
		finally:
			pass

	def parse_headers(self):
		req_header = {}
		for line in self.headers:
			line_parts = [o.strip() for o in line.split(':', 1)]
			if len(line_parts) == 2:
				req_header[line_parts[0]] = line_parts[1]
		return self.inject_header(req_header)
    
	def inject_header(self, headers):
		headers['Referer'] = 'https://example.com/'
       
		return headers
	

if __name__ == '__main__':
	server_address = ('0.0.0.0', 8081)
	httpd = http.server.HTTPServer(server_address, ProxyHTTPRequestHandler)
	print('http server is running')
	httpd.serve_forever()

如此跑起來後,就可以用 http://localhost:8081/?url=https://exmaple.com/streaming 機制,例如 VLC 軟體直接輸入 http://localhost:8081/?url=https://exmaple.com/streaming 位置來嘗試播放。

2020年5月7日 星期四

Raspberry Pi 3 + RetroPie = 電視遊樂器 - 超任為例 @ macOS

Pi 3 + SNES

之前為了研究音控買了個 Pi 3 搭配 Google AIY Projects Voice Kit ,結果研究完就晾在那邊一年多了吧?反而音控設備已買了成品 Google Home mini 和 小愛音箱。最近無聊就想研究一下樹莓派怎樣玩遊戲,實在是已經不只一次看到什麼月光寶盒再賣,還是嘗試一下好了。

果真有個 RetroPie 就是專門做了超級多的電玩模擬器,裝下就搞定了!有幾件事要留意一下:
  • Pi 3 內建無線網卡,但安裝完卻沒法設定,連 ifconfig 都看不到
    • 解法:裝完 RetroPie 系統後,需要先設定 WI-FI Country ,才能正常設定無線網路
  • 在網路上亂找到的 ROM 檔案,擺入後卻無法被偵測或運行
    • 解法:還是裝一套 PC 版的來驗證吧 :P 有時真的是網路上的檔案格式問題,在 macOS 可以試試 OpenEMU 這套
  • 如何從 PC 傳 ROM 進入 Pi 3 + RetroPie
    • 解法:善用 RetroPie 的環境,可以把 SSH 打開,靠 SCP 或是透過 SAMBA 網路芳鄰進去也很方便
其他動作:
  • 在 https://retropie.org.uk/download/ 下載 Pi 3 作業系統
    • https://github.com/RetroPie/RetroPie-Setup/releases/download/4.6/retropie-buster-4.6-rpi2_rpi3.img.gz
  • 在 macOS command line 連續動作處理(此例 SD Card 位於 /dev/disk4,請不要隨意複製指令執行!)
    • % sudo diskutil unmountDisk /dev/disk4 % unzip retropie-buster-4.6-rpi2_rpi3.img.gz % sudo time dd bs=1m if=retropie-buster-4.6-rpi2_rpi3.img of=/dev/rdisk4 2729+0 records in 2729+0 records out 2861563904 bytes transferred in 506.080069 secs (5654370 bytes/sec) 506.10 real 0.01 user 2.08 sys % sudo diskutil unmountDisk /dev/disk4
  • 當 Pi 3 + RetroPie 啟動後,設定 Wi-fi Country 跟啟動 SSH
    • $ sudo raspi-config
      • Change User Password
      • Localisation Otions
        • Change WI-FI Country
      • Network Options
        • Wi-fi
      • Interfacing Options
        • SSH
      • Update
      • Finish
  • 更新系統以及 RetroPie 眾多資料(模擬器)
    • $ sudo apt update $ sudo apt upgrade $ sudo apt dist-upgrade $ sudo apt autoremove $ sudo apt install tmux vim

2020年5月4日 星期一

重溫超任「三國志3 中文版」

SENS 三國志3 中文版

記得第一次接觸是小學的時候,去幼稚園同學家的遊樂器材店,就這樣初次接觸三國志遊戲。下一次,則是 PC 版的三國志五了!

記得小時候搭配藍截者,有那種重返前一刻狀態的密技,就這樣用新增武將時,用耐心找到單一能力達 100 的員工 XD 此例是君主單純調配能力達到武力 100 ,其餘軍師則是花耐心找到智力 100。

就這樣,配一個君主跟三名武將,從許昌出發,而智力 100 的特色是做事不斷去煩軍師,只要軍師說 ok 就肯定 ok!透過偽書降低對方忠誠度,或是錄用對方都是軍師說好時,一定 100% 成功率的。沒想到這時把玩這款遊戲,一不小心就噴了 3 小時,更讓我想起工作上的瑣事

大概有三件事:

  • 大家特愛當中庸者,什麼都要摸一點,像是能力各個 85 甚至 95,都還不如單一項目專精 100 。單一能力達 100 時,才會進入另一個模式。
  • 單一武將兩個能力很好,不如兩個武將各一個能力好,在這種回合制上,就凸顯出兩個人的好用。例如一個人放偽書,另一個來錄用。因為有時對方身上兵權很重,第一次放偽書,可能下一回合兵權就被去除
  • 數字化,明明很普通的遊戲,卻還是被數字吸引著,養成一種無奈的耐心跟自律,規律地聽著洗腦的背景,時間就消逝了,而成就領地卻增加
這些是恰好跟工作有關,不要當英雄把責任跟任務攬在身上,一個人一天只有 24 小時!要多培養夥伴能力並珍惜單一能力技能很強的夥伴!最後,則是流量變現上持續數據化、遊戲化。