背景
作者作爲個人開發者,想接入支付功能,所以瞭解了下目前支付相關的方案,發現大體有以下幾種(參見xpay):
- 支付寶和微信官方支付接口:基本都需要企業資格才能開通,最起碼也要是個體工商戶纔可以(有營業執照)。
- 第三方支付平臺:例如圖靈支付,xpay等,支持個人開發者,但是手續費太高。
- 野路子:網上有開源方案是監聽支付寶app收款通知,實現收款,例如PaysApi、綠點支付等,本質上依然是採用掛機監聽的策略,但針對的是移動端支付寶或微信的收款通知消息,成本高,配置麻煩,需24小時掛檯安卓手機,不免費
以上方案要麼沒有企業資質,要麼太麻煩,要麼太貴,幸好發現了支付寶當面付(支持個人開通,但是需要門店照片,這個百度就可以)。
營業執照是可選的,不上傳的話,限制單筆收款≤1000,單日收款≤5W,對於個人開發者足夠了。
支付寶當面付
接入流程
- 點擊在這裏進入,登陸支付寶賬戶選擇立即接入。
- 經營內容選擇百貨零售-超市-超市(非平臺類)
- 營業執照可不上傳
- 店鋪招牌 百度即可
- 提交申請後十多分鐘就可收到通過通知。
開發流程
成功接入以後,可以在螞蟻金服開放平臺網頁&移動應用中,看到我的應用列表中多了一個“應用2.0簽約******”的應用:
現在我們可以開發接入了,總體分爲以下幾個步驟(參考當面付文檔,當面付開發流程):
- 配置當面付公鑰私鑰
- 找到“應用2.0簽約******”的應用,點擊右側查看詳情
- 在應用信息中設置公鑰
支付寶官方提供了密鑰生成工具,很簡單,使用工具生成應用公鑰和私鑰,應用公鑰設置到支付寶,應用私鑰保存到本地,應用公鑰設置到支付寶後,支付寶會生成一個支付寶公鑰,保存到本地。具體參見這裏
- 找到“應用2.0簽約******”的應用,點擊右側查看詳情
- 開發:我是使用python作爲後端,使用這個開源庫,下面是簡單代碼示例:
from alipay import AliPay
import time
# 密鑰工具生成的私鑰,和支付寶公鑰(我保存在了文件中)
app_private_key_string = open("app_private_key.pem").read()
alipay_public_key_string = open("alipay_public_key.txt").read()
print(alipay_public_key_string)
'''
這裏打印應該是這種格式(如果支付寶密鑰生成工具生成的密鑰沒有頭尾要自己加上)
私鑰格式:
-----BEGIN RSA PRIVATE KEY-----
base64 encoded content
-----END RSA PRIVATE KEY-----
公鑰格式:
-----BEGIN PUBLIC KEY-----
base64 encoded content
-----END PUBLIC KEY-----
'''
alipay = AliPay(
appid="2019***********", # 應用列表中“應用2.0簽約******”的appid
app_notify_url=None, # 默認回調url
app_private_key_string=app_private_key_string, # 應用私鑰
alipay_public_key_string=alipay_public_key_string, # 支付寶公鑰
sign_type="RSA2", # RSA 或者 RSA2(具體要看你的密鑰是什麼類型)
debug=False # 默認False
)
out_trade_no = "out_trade_no_123"
# 創建訂單
result = alipay.api_alipay_trade_precreate(
subject="test subject", # 訂單標題
out_trade_no=out_trade_no, # 訂單號(不可重複)
total_amount=0.1 # 訂單金額,單位元
)
print(result)
# 這裏應該打印出{'code': '10000', 'msg': 'Success', 'out_trade_no': 'out_trade_no_123', 'qr_code': 'https://qr.alipay.com/bax05832mvaotxhcpjeh6074'}
# 其中用qr_code生成二維碼,支付寶掃描即可付款
# check order status
paid = False
for i in range(30):
# check every 3s, and 10 times in all
print("now sleep 3s")
time.sleep(3)
result = alipay.api_alipay_trade_query(out_trade_no=out_trade_no)
if result.get("trade_status", "") == "TRADE_SUCCESS":
paid = True
break
print("not paid...")
# order is not paid in 30s , cancel this order
if paid is False:
print("支付失敗,取消訂單")
alipay.api_alipay_trade_cancel(out_trade_no=out_trade_no)
else:
print("支付成功")