iT邦幫忙

2021 iThome 鐵人賽

DAY 1
0
自我挑戰組

後端工程師與圖的修練系列 第 1

蝦皮 Open Platform 與經典程式流程圖

不管是在哪開始學習寫程式,都一定會看到最經典的流程圖:

至今,流程圖的正確畫法也不是那麼容易被在乎,反正只要看起來能解讀成正確的意思就好; 但總的來說,以前的我只知道 if else 條件控制要用菱形,現在大概也只知道菱形的涵義。

既然這麼經典,那我就不多 Survey 這個流程圖的細節了,像這樣的標準流程圖應該可以參考 Wiki,我們直接來看看有趣的部份。

有一大陣子前,我去申請了 Shopee Open Platform 的 API 串接,那真的是個噩夢,蝦皮的文件 Definition 有些欄位告訴你是 float 或數值,但是在他沒有給定的時候,value 會直接送你一個 "" 空字串 (哈哈,想不到吧),然後程式就爆炸了 (抱怨結束);

詳情可以看看這個 Golang Open Platform API Wrapper 的描述:
https://github.com/teacat/shopeego

進入本題,蝦皮的文件 (V1, V2) 中特別註記了 API Call Flows 的流程,而且把它們畫成流程圖:

V1: https://open.shopee.com/documents?module=63&type=2&id=54&version=1
V2: https://open.shopee.com/documents?module=87&type=2&id=60&version=2

之所以 Shopee Open Platform 要把它們畫成 API,是因為開發者也必須知道店商流程是怎麼跑的,不能亂叫 API,作為範例,提供兩個重點的流程圖:

https://ithelp.ithome.com.tw/upload/images/20210911/20092753IMfrKMQnGT.png

這張圖告訴你,一個買家買完商品之後,一開始撈到的資料會是 UNPAID 狀態,如果他付完款 (含貨到付款,等一下之後),就會進入 READY_TO_SHIP 這個狀態,這個時候賣家後台應該就可以取得物流編號去超商寄件,只要被寄出之後,物流公司就會更新蝦皮狀態,狀態變成 SHIPPED

了解狀態流之後,接下來要看訂單要如何改變狀態,則需要參考第二個流程: Arrange Shipment & Get TrackingNo & Print AirwayBill

https://ithelp.ithome.com.tw/upload/images/20210911/200927535OS62g73kh.png

這上面大致上告訴你,如果你有一個很酷的應用程式,你可以用 get_shipment_list 或是 get_order_list 拿到訂單列表,然後你還需要 call 一個必要的 get_order_detail 這個函數,取得訂單詳細資料,也許是要呼叫這個,你才能拿到訂單是否需要拆開 (split_order) 這個資料欄位。

然後,不管怎樣你還需要呼叫 get_shipping_parameter 取得這個人的運送方式,於是,流程圖分支出現了 !!!,他居然寫 select one,意思是跟開發者說,請你選擇一個物流方式,這個應該不是叫你選一種,打天下,你可能會需要一些判斷,看資料有沒有某些參數,至少我在處理這個選擇時,程式是這麼寫的:


// 看看 NonIntegrated, Pickup, Dropoff 是不是空的,假設了蝦皮給資訊也是三責一給,不會超過 1 個。
if orderShipmentDetail.InfoNeeded.NonIntegrated != nil {
    nonIntegrated = &shopeego.InitRequestNonIntegrated{
        TrackingNo: "賣家自選物流 " + order.ID,
    }
}
if orderShipmentDetail.InfoNeeded.Pickup != nil {
    // TODO: 實作 Pickup (沒實作,因為在台灣沒有用到)
}
if orderShipmentDetail.InfoNeeded.Dropoff != nil {
    dropoff = &shopeego.InitRequestDropoff{
        SenderRealName: p.SenderRealName,
    }
}

此時,看看 API 文件說了什麼?

https://open.shopee.com/documents?module=95&type=1&id=553&version=2

從文件上看來,NonIntegrated 是自選物流,比方說 XX 物流XX 郵政,而且是賣家自己選的,不會有物流追蹤;

Pickup 很玄,大概是登門跟賣家取貨,至少之前在台灣我沒有遇過任何一個這樣的訂單,不過 2021 年 09 月蝦皮多了一個店到店的物流,也許跟這個有關;

DropOff 是目前處理過的大部分訂單都是給這個,這個才是最重要的,甚至裡面要放賣家寄件的名字,而且名稱不能亂填,否則退貨你賣家就無法領,通通拿去燒毀。

總之,他告訴你 Select one 意思就是請你選一個帶出直就好,不要三個 value 一起送,如果你這樣送:

{
    "order_sn": "F020D20S2F0DS20F",
    "non_integrated": { …略 },
    "pickup": { …略 },
    "dropoff": { …略 },
}

這將是一個 big no no。

https://ithelp.ithome.com.tw/upload/images/20210911/20092753LdJOa36xpj.png

請你送出一個就好:

{
    "order_sn": "DS5F4S4DF54DS", 
    "dropoff": { …略 },
}

https://ithelp.ithome.com.tw/upload/images/20210911/20092753D6bEtWk4xW.png

當你組合好必要的參數之後,就使用 logistics.ship_order 送出,此時你的訂單應該會進入產生物流的狀態,接著你就要不斷 update ,要用 update_shipping_order 去檢查這個訂單產生好了沒,因為有時候物流家的系統會自殺,全台物流大爆炸,賣家無法寄件,這時候你的系統就要等他。

總之如果他產生好了,對開發者來說還有兩個選擇可以進行 (self-design airway bill?) ,你要自己設計物流單嗎?

https://ithelp.ithome.com.tw/upload/images/20210911/20092753qP9GNeeiSl.png

要的話,只需要呼叫 get_shipping_document_info 自己產生條碼,如果不是,你可以按照 No 那排的流程依序呼叫,你就會拿到物流單的影像檔,像是全家是給你 Image,7-11 是丟給你網頁(現在應該是 pdf),萊爾富跟 OK 都是 pdf,對於 pdf 的處理要小心就是,如果你用太舊的 pdf engine 處理,你的字體會直接爆炸。

過來人建議: 以調動成本考量,蝦皮或超商一天到晚在那邊變動,自己產生條碼似乎是降低維護成本的方法。

對於流程圖的範例,可以看到蝦皮用了經典的 【檔案】 流程圖來描述更多訊息:

https://ithelp.ithome.com.tw/upload/images/20210911/20092753UJ8WTBfKqE.png

對於這個符號的使用情境,似乎會讓人有點好奇,為什麼不直接寫文字註解框起來就好,而是用檔案符號,所以啦,除了菱形是條件 (condition) 之外,其實你要怎麼畫,反正可以表達清楚就好。

額外補充

下面是一個初始化訂單的範例的程式碼 (框架基於 shopeego),不過這是 for V1 的 api。

// 初始化一個 Shopee 客戶端。client:=shopeego.NewClient(&shopeego.ClientOptions{
	Secret: "0c2c7b3bd597fcf49dc985df2e44",
})
// 取得指定商店的資料。shop, _:=client.GetShopInfo(&shopeego.GetShopInfoRequest{
	PartnerID: 1234567,
	ShopID:    1234567,
	Timestamp: int(time.Now().Unix()),
})

// v1 code 建立出貨單
_, err = client.Init(&shopeego.InitRequest{
        OrderSN:   orderID,
        PartnerID: p.PartnerID,
        ShopID:    p.ShopID,
        Timestamp: int(time.Now().Unix()),
        Dropoff:       dropoff,  // 如果沒有,這個應該要是 nil
        Pickup:        pickup,  // 如果沒有,這個應該要是 nil
        NonIntegrated: nonIntegrated, //如果沒有,這個應該要是 nil
    })

if err != nil {
        panic("gg")
    }

隨題附上可以繪製流程圖的工具參考: Visio、Visual Paradigm,也可以使用 Cacoo、Figma 或是用 HackMD 內建的 flowcharts 語法,用 code 來繪製流程圖,看起來就很潮。


下一篇
泳道圖
系列文
後端工程師與圖的修練31

尚未有邦友留言

立即登入留言