这三天为了接入支付宝支付功能,我把支付宝的网站支付开发文档看了好几遍,又百度了好多别人的资料,发现都没有我能直接拿来用的代码。而且支付宝官方文档的各种链接也是6的飞起....经常看着看着就迷路了...然后支付宝自己的python包,使用实例写的也是简单的飞起...看了下评论貌似较烂,而且网上确实找不到使用官方包部署的,我一个新手完全不好直接拿官方包,所以还是选了现在最成熟的python-alipay-sdk包
先安装这个包
pip install python-alipay-sdk
这个包的中文文档虽然也不全面,但是比官方的好多了已经!
这个链接是python-alipay-sdk包的链接
再放几个开发中用的到的支付宝官方文档
因为官方文档链接漫天飞...不太好一次找到所有需要的文档
沙箱使用文档
电脑支付文档
各种官方SDK包
在正式接入支付宝前,像我这样的新手还是要先走一个沙盒,顺顺代码的,我们一步一步来~
点开沙箱,查看APP_ID,配置秘钥和网关
打开你的沙箱,出行的APP_ID就是测试中要用的APP_ID
使用openssl或者淘宝提供的工具生成秘钥,将公钥上传到图中【RSA|查看应用公钥】,上传成功后,点击【查看支付宝公钥】
这里需要注意的是!你的网站中配置需要APPID/你的私钥/支付宝的公钥,这里是支付宝的公钥!不是你生成的公钥,地下另一个秘钥折磨了我好久....我一直没弄明白为啥有2秘钥,还一个RSA,一个RSA2。。。我现在也忘记这个秘钥是干啥的了,反正就是不用管它就可以了!
这里支付宝网关注意一下,和正式部署的区别是多了dev,在正式部署的时候记得更换下网关
好像还有哪里需要写这个授权回调地址
讲真...这个应用网关和授权回调地址也折磨了我一下...还有这个实例部分给的alipay的网址,整的我以为就是填这个网址
实际:不用管应用网关,授权回调地址是用户支付成功后,重定向的路由,我这里填了http://localhost:5000/callback/alipay
写付款API
使用包写付款,还是非常开心轻松哒!
首先我们新建一个Alipay对象,用于以后所有的支付接口调用
alipay = AliPay(
appid='你的APPID',
app_notify_url=None, # 默认回调url
sign_type="RSA2",
alipay_public_key_path=os.path.join(os.getcwd(),
'key', 'alipay_public_key'), #这里换成你的路径
app_private_key_path=os.path.join(os.getcwd(),
'key', 'app_secret_key'),#这里换成你的路径
debug=True
)
这里需要注意的是
两个Key参数还有对应的alipay_public_key_string
,字符串版本,但是不要用那个,我用了会报错,就老老实实用path
这里的debug决定了是沙箱支付宝网关还是正式网关
创建完alipay,我们写支付API
这个支付API就是网页中点击了支付按钮后转到的路由
# 这里的trade_id是我订单ID,用来取订单信息的,这里测试可以去掉不需要的
@pay.route('/start_pay/<int:trade_id>')
def start_alipay(trade_id):
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no="2018081104",# 这个No每次测试不能重复的
total_amount=0.01,
subject='测试支付',
return_url=url_for('.paid', _external=True)
#这个回调url要和第一步里面在支付宝配置的一致
)
alipay_url = current_app.config['ALIPAY_URL'] + "?" + order_string
return redirect(alipay_url)
这里先根据订单信息创建order_string
然后把这个查询字符串缀到支付宝网关URL上
最后跳转到这个URL,下面是我写到config的ALIPAY_URL
ALIPAY_URL = 'https://openapi.alipaydev.com/gateway.do'
最后一步!写回调路由,处理信息
支付成功后,用户会被调转到Return_url上,这里的GET请求查询字符串已经包含了所有订单信息,我的订单后面的GET格式如下:
http://localhost:5000/callback/alipay?charset=utf-8
&out_trade_no=20180811
&method=alipay.trade.page.pay.return
&total_amount=0.01
&sign=这里有很长的sign用于验签
&trade_no=2018081121001004730200696550
&auth_app_id=2016091800540443&version=1.0
&app_id=2016091800540443&sign_type=RSA2
&seller_id=2088102176193440
×tamp=2018-08-11+12%3A03%3A11)
这里虽然已经啥都有了,但是作为一个GET请求...还是不要依赖它确定用户是否支付成功了,但是这里我找不到应该咋验签,反正支付宝也说了不要依赖这玩意,
支付宝说用户支付成功后会通过3个渠道返回此次支付信息:
1.GET同步请求
2.POST异步请求,就是发form到你的notify_url,但是这里我测试了没有反应的....所以我没用这个方式
3.自己调用查询API:alipay.trade.query接口查询订单详情
因为官方也说了,可以跳过2,直接使用方法3验证,所以我在get请求中,没有用get到的querystring,而是发起了查询:
# 有一点注意,我在蓝图中定义了url_prefix=callbak,所以这里路由只写了alipay
@pay.route('/alipay')
def paid():
# 向alipay发起查询
result = alipay.api_alipay_trade_query(out_trade_no="2018081104")
#这里的out_trade_no可以用GET到的
if result.get("trade_status", "") == "TRADE_SUCCESS":
return result.get('trade_no') #这里使用支付宝返回的订单号来显示支付成功
return 'fail'
最后就是测试了,打开第二步中的路由,用沙箱提供的测试账号和密码登陆支付,就完成啦~ 接下来就按着业务需求重新整理下2个view啦~
以上
等我完成部署正式上线了再追加一份正式部署版