[不做怎麼知道系列之Android開發者的30天後端養成故事 Day27] - 可以付錢給我了! #串接第三方金流 #綠界 #ShowMeTheMoney

哈囉,我們又見面了,前幾天我們把 Line 的 ChatBot 番外篇 完成了,今天我們來試著串接「第三方金流」的服務,在開始之前必須先釐清一件事:「第三方金流行動支付電子支付差在哪裡?」

第三方金流 vs. 行動支付 vs. 電子支付

詳細可以參考 行動支付?第三方支付?電子支付?別搞混了它們三個都不一樣!| 電獺少女,第三方金流主要功能就是,先向顧客代收交易金額,等交易完全成功,例如是顧客收到貨品確認沒問題,才撥款給電商平台,而第三方金流也不是免費的,錢經過了它的手,怎麼有不收過路費的道理呢 XD,所以就有 手續費 的存在拉,關於手續費和服務內容,也就是各家第三方金流所競爭的關鍵。

舉例來說

第三方金流就是你在電商網頁(博客來、蝦皮等等)上,進行結帳時會跳轉到一個要你輸入信用卡卡號的頁面,像下圖,要求你 填入卡號 或 選擇其他付款方式 的頁面,這就是第三方金流的服務。

那我們就來試試看第三方金流的服務

今天我們要來嘗試的第三方金流廠商是 **綠界**,可以說是台灣最早的第三方金流廠商,除了綠界還有其他廠商,不過各家廠商的糾葛,就像連續劇一樣的情節了,我也不是很瞭解它們的關係 XD

綠界-台灣最早的第三方金流

有提供 Python SDK,支援以下支付方式

  • 信用卡(一次付清、分期付款)
  • 網路ATM
  • ATM櫃員機
  • 超商代碼
  • 超商條碼
  • Google Pay

除了支援 All in One 金流之外,還有提供 物流整合服務,包含超商(全家、7-11、萊爾富)取貨付款,還有黑貓、宅配通,還有提供 電子發票的服務,算是相當完整,但手續費也不低 XD,文章下面有 2020 年 3 月的手續費表格截圖供參考。

先來註冊綠界

驗證完 → 填寫基本資料,到目前的步驟沒什麼問題,就是基本的註冊會員,下一步的收款設定比較麻煩

收款設定

這步驟需要決定,你是什麼商店、你賣哪些商品、提供身分或公司證明

因為我是個人戶,所以我放身分證正反面

到目前為止,已經可以接收非信用卡的收款了,如果要開通 接受信用卡收款 的功能、提領 的功能,需要另外由系統驗證證件,需要 2~3 個工作天的驗證流程,但實際上我提出之後在半小時左右就都驗證過了。

設定提領帳戶

申請完成後,長這樣

建立收款連結

如果只是簡單的需要收款,可以直接透過「建立收款連結」,就可以產生一組 網址QR code,像是 https://p.ecpay.com.tw/3E441 這樣的一串網址,而你只要把這組網址 或 QR code,轉貼到顧客看的到的地方(可能是你的文章或者是個人網頁等等),顧客就可以點進去網址,使用刷卡或超商付款等等的方式,透過各種方式給你錢 !

實際建立收款連結的過程

進到綠界的管理後台,點建立收款連結,然後填資料,建立一個固定金額的商品,如果有很多項商品,就需要建立多筆連結,如果你有串 金流 SDK 就不用手動新增了,可以透過後端程式邏輯,把你原本就有的訂單系統結合 SDK,新增 商品 與 收款連結 的對應關係。

因為各種付款方式有金額範圍限制,為了符合所有付款方式的最低限度,所以我才設 31 元這個奇怪的數字 XD

建立之後會得到一個連結、QR code,你只要把這串 網址 或 QR code 轉貼到 文章 或 私訊給你的顧客,他們就可以透過第三方金流來付款給你。

試著用「收款連結」來結帳看看

現在要模擬顧客刷卡的過程,自己結帳給自己 XD,點進去透過綠界產生的收款連結,就會跳轉到綠界的結帳頁面。

點下一步→ 填付款人的基本資料

填完基本資料後,選擇付款方式,因為這筆訂單是 31元,符合各類付款方式的範圍,就可以選各種付款方式。

填完信用卡資訊後,就近到熟悉的手機驗證頁面,可以看到特約商店是 GreenWorld 綠界,相當於是我的信用卡付款給 綠界,由 綠界 代管,等整筆訂單交易成功,綠界 再把訂單的 31 元扣除手續費,再放到 綠界帳戶,需要的時候再申請 提領,將放在 綠界帳戶 的錢,匯款到個人/公司銀行帳戶。

最後結帳成功

到綠界後台檢查訂單狀況

在綠界的後台可以查詢每一筆訂單,包括 消費者姓名手機email付款方式付款狀態等等,也可以決定是否 退款

被扣了 5 元,在國內使用 信用卡一次付清 的手續費是 2.75%,因為 31 元的 2.75% 低於最低手續費 5 元,所以就被收了 5 元,對於小額收款的電商平台來說,這是一個很大的抽成。

以我這一筆 31 元的訂單來講,就相當於是 16% 的手續費,非常高。

這張費率表是 2020-03-09 的截圖,不一定符合你現在觀看這篇文章時的手續費率。

在綠界後台也能處理取消訂單

因為是使用信用卡付款,還沒請款時,退款相對簡單,如果是已經請款了 或 客戶用的是別種結帳方式,那就要我們自己處理退款,也就是錢已經到綠界了,綠界是不會幫忙處理退款的,你需要用另外的帳戶來退款給顧客。

到這邊,已經瞭解綠界的操作流程了,再來就是後端Server 串接 第三方金流SDK 的部分。

Python 串接 綠界 All in One 金流 SDK

綠界提供 PHP、Java、Ruby、Node.js、C#(.Net) 和 Python,六種的程式語言的 SDK,而我們這篇使用的 Python 的 [All in One SDK](https://github.com/ECPay/ECPayAIO_PYTHON),在官方提供的 Github 上,除了有 SDK 之外,還有數個 sample codes,我們這邊參考的是 [sample_create_order_ALL.py](https://github.com/ECPay/ECPayAIO_Python/blob/master/sample/sample_create_order_ALL.py) 這個 sample code。

導入 SDK

首先需要先把 All in One SDK 放到 Django 專案底下

參考 sample code 來使用 SDK

原本 sample code 長這樣,落落長,而我們真的需要修改的地方,用註解的方法標註,真正的修改方法需要參考官方文件,我寫文章時所參考的文件版本是 5.1.47 (2020-02-10)

[sample_create_order_ALL.py](https://github.com/ECPay/ECPayAIO_Python/blob/master/sample/sample_create_order_ALL.py) 複製下來,並重新命名為 ecpay_testing.py,放在 shop/ 底下 (和 views.py 同層級),且把整個用一個叫做 main 的 function 包起來。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import importlib.util

# 第一個需要修改的,就是 SDK 路徑
spec = importlib.util.spec_from_file_location(
"ecpay_payment_sdk", # SDK檔名不用改
"/path/to/ecpay_payment_sdk.py" # 改成 django app name/sdk name,
# 以我把 SDK 放到 shop 為例,
# 我就是改成 "shop/ecpay_payment_sdk.py"
)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
from datetime import datetime

def main():
# 第二個需要修改的,商品資訊
order_params = {
'MerchantTradeNo': datetime.now().strftime("NO%Y%m%d%H%M%S"),
'StoreID': '',
'MerchantTradeDate': datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
'PaymentType': 'aio',
'TotalAmount': 2000, # 商品金額
'TradeDesc': '訂單測試', # 商品描述
'ItemName': '商品1#商品2', # 商品名稱,用井字號當分行
'ReturnURL': 'https://www.ecpay.com.tw/return_url.php', # 顧客填完付款資料後的跳轉頁面
'ChoosePayment': 'ALL', # 顧客的付費方式
'ClientBackURL': 'https://www.ecpay.com.tw/client_back_url.php', # 結帳後,先導到 OrderResultURL,
# 從綠界頁面跳回的頁面,如果沒有參數才會跳轉到 ClientBackURL
'ItemURL': 'https://www.ecpay.com.tw/item_url.php', # 商品資訊頁面
'Remark': '交易備註', # 備註文字
'ChooseSubPayment': '',
'OrderResultURL': 'https://www.ecpay.com.tw/order_result_url.php', # 結帳成功/失敗後的結果頁面,告知顧客本次的結帳結果
'NeedExtraPaidInfo': 'Y',
'DeviceSource': '',
'IgnorePayment': '',
'PlatformID': '',
'InvoiceMark': 'N',
'CustomField1': '',
'CustomField2': '',
'CustomField3': '',
'CustomField4': '',
'EncryptType': 1,
}

extend_params_1 = {
'ExpireDate': 7, # 商品上架期限
'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php', #付款資訊頁面
'ClientRedirectURL': '', # 看完付款資訊,要重導到哪裡
}

extend_params_2 = {
'StoreExpireDate': 15,
'Desc_1': '',
'Desc_2': '',
'Desc_3': '',
'Desc_4': '',
'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
'ClientRedirectURL': '',
}

extend_params_3 = {
'BindingCard': 0,
'MerchantMemberID': '',
}

extend_params_4 = {
'Redeem': 'N',
'UnionPay': 0,
}

# 發票資訊
inv_params = {
# 'RelateNumber': 'Tea0001', # 特店自訂編號
# 'CustomerID': 'TEA_0000001', # 客戶編號
# 'CustomerIdentifier': '53348111', # 統一編號
# 'CustomerName': '客戶名稱',
# 'CustomerAddr': '客戶地址',
# 'CustomerPhone': '0912345678', # 客戶手機號碼
# 'CustomerEmail': 'abc@ecpay.com.tw',
# 'ClearanceMark': '2', # 通關方式
# 'TaxType': '1', # 課稅類別
# 'CarruerType': '', # 載具類別
# 'CarruerNum': '', # 載具編號
# 'Donation': '1', # 捐贈註記
# 'LoveCode': '168001', # 捐贈碼
# 'Print': '1',
# 'InvoiceItemName': '測試商品1|測試商品2',
# 'InvoiceItemCount': '2|3',
# 'InvoiceItemWord': '個|包',
# 'InvoiceItemPrice': '35|10',
# 'InvoiceItemTaxType': '1|1',
# 'InvoiceRemark': '測試商品1的說明|測試商品2的說明',
# 'DelayDay': '0', # 延遲天數
# 'InvType': '07', # 字軌類別
}

# 建立實體
ecpay_payment_sdk = module.ECPayPaymentSdk(
MerchantID='2000132', # 參考綠界後台->系統開發管理->系統界接設定,開發時有測試用的 商店ID
HashKey='5294y06JbISpM5x9', # 參考綠界後台->系統開發管理->系統界接設定,開發時有測試用的 HashKey
HashIV='v77hoKGq4kWxNNIS' # 參考綠界後台->系統開發管理->系統界接設定,開發時有測試用的 HashIV
)

# 合併延伸參數
order_params.update(extend_params_1)
order_params.update(extend_params_2)
order_params.update(extend_params_3)
order_params.update(extend_params_4)

# 合併發票參數
order_params.update(inv_params)

try:
# 產生綠界訂單所需參數
final_order_params = ecpay_payment_sdk.create_order(order_params)

# 產生 html 的 form 格式
action_url = 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5' # 測試環境
# action_url = 'https://payment.ecpay.com.tw/Cashier/AioCheckOut/V5' # 正式環境
html = ecpay_payment_sdk.gen_html_post_form(action_url, final_order_params)

# 最後產出 html,回傳回去顯示此 html
return html
except Exception as error:
print('An exception happened: ' + str(error))

views.py

導入 ecpay_testing.pymain()

1
2
3
4
5
from .ecpay_testing import main

@csrf_exempt
def ecpay_view(request):
return HttpResponse(main())

urls.py

把這個測試頁面,綁在 ecpay/ 的網域底下,所以 urls.py 長這樣

1
2
3
4
5
urlpatterns = [
...
path('ecpay/', ecpay_view),
]

Djano 跑起來

$ python manage.py runserver

訪問 127.0.0.1:8000/ecpay/

進入到測試頁面

在結帳前,還會告知目前是測試環境

到目前為止,算是初次使用 綠界所提供的 All in One SDK,還沒有真正串接起來,因為中間還漏了 [CheckMacValue 的驗證流程](https://www.ecpay.com.tw/Content/files/ecpay_011.pdf),在文件的第 43 頁有解釋驗證流程該怎麼進行,但我暫時還沒有要完整的接起來,就不浪費時間在確認驗證流程了,可以參考【Flask 教學】Python 綠界金流 API 信用卡串接 | Max行銷誌,雖然我用了它的方法還是驗證失敗 QQ

單日心得總結

串接 SDK 最麻煩的就是 驗證,尤其還有 加解密編碼 的問題,非常麻煩,需要一步一步核對文件所描述的步驟,去確認每一步的輸出都是正確的,非常耗時間跟腦力,尤其是邊做的時候,邊腦中出現一句話「接起來是應該的,接不起來是你太弱」,就會覺得心累 XD

我就帶大家走到這步,後續驗證的苦差事就交給各位自己解決了,尤其是 程式語言作業系統預設編碼不一致,非常容易出錯,就算我今天做出來了,放到不同的作業系統說不定又不行,所以必須把 收到的資料 和 送出的資料 的編碼寫清楚,確保每次進來和出去的編碼符合文件需求。

這系列終於要結束了,很期待下一個系列的到來,又可以替自己刷新一套世界觀了~

我是 RS,這是我的 不做怎麼知道系列 文章,我們 明天見。


  • 喜歡我的文章嗎? 趕快來看看我都發了什麼文章吧:我的文章目錄
  • 歡迎閱讀我的上一篇: (番外篇-GAE)[不做怎麼知道系列之Android開發者的30天後端養成故事 Day26] - 來問問你認識的Youtuber的訂閱數吧~ #Django #GAE #LineChatBot
  • 歡迎閱讀我的下一篇: 待續
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2021-2022 Sam Ho
  • Visitors: | Views:

請我喝杯咖啡吧~

支付宝
微信