1,环境
ubuntu16.04,python3.6, alipay-sdk-python(3.20)
2,安装包
alipay提供了python包,封装了很多api调用、签名验证等功能,直接
pip install alipay-sdk-python
因为该包依赖其他几个包,在安装pycrypto包时在我这环境下报错‘fatal error: Python.h: No such file or directory’
解决方法:apt-get install python3.6-dev, 如果python版本不是3.6 改成对应的就可以了
3,准备
注册支付宝开发账户,并申请相应的功能等工作
注意:开发者代码中用到的密钥有两个,一个公钥一个私钥。但是千万注意他们不是一对,
公钥ALIPAY_PUBLIC_KEY是支付宝公钥,由支付宝提供,用来验证支付宝发过来的消息验证用的;
私钥APP_PRIVATE_KEY是自己生成的,对应的公钥填到支付宝那边的,用来给向支付宝发送消息签名用的,支付宝用你提供的公钥对你发送的消息进行验证
3,后端代码实现
a, 实现生成二维码收款逻辑,返回的response_url直接打开就会访问alipay生成对应的二维收钱码(当然也可以不选二维码)
from alipay.aop.api.AlipayClientConfig import AlipayClientConfig
from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClient
from alipay.aop.api.domain.AlipayTradePagePayModel import AlipayTradePagePayModel
from alipay.aop.api.request.AlipayTradePagePayRequest import AlipayTradePagePayRequest
from alipay.aop.api.util.SignatureUtils import verify_with_rsa
config = AlipayClientConfig()
config.server_url =
config.app_id =
config.app_private_key=
config.alipay_public_key=
model = AlipayTradePagePayModel()
model.out_trade_no=
model.total_amount=
model.subject=
model.body=
model.product_code=
ali_request = AlipayTradePagePayRequest(biz_model=model)
ali_request.notify_url =
ali_request.return_url =
client = DefaultAlipayClient(alipay_client_config=config)
response_url = client.page_execute(ali_request, http_method='GET')
model.subject设置的内容会显示在支付页面,可以写产品名,或跟用户相关的显示。如下图所示(圈红线位置)
b, 支付成功跳转(前面设置的return_url)
这是个GET请求,编写没有难度,但是不可靠(容易被伪造)
c, 支付结果异步通知
支付结果可以通过接口主动向阿里云查询获得,也可以接受alipay发送的结果,此处采用接受alipay发送的异步通知结果。
def webhook_alipay():
data = request.form.to_dict()
#sign, sign_type 都要从数据中取出,否则签名通不过
sign, sign_type = data.pop('sign'), data.pop('sign_type')
params = sorted(data.items(), key=lambda e: e[0], reverse=False)
message = "&".join(u"{}={}".format(k, v) for k, v in params).encode()
alipay_public_key = os.environ.get('ALI_ALIPAY_PUBLIC_KEY')
try:
if verify_with_rsa(alipay_public_key.encode('utf-8').decode('utf-8'), message, sign):
...
#一定是success这个单词,其他的alipay不认
return Response('success')
else:
...
except:
...
注意坑:alipay发送的post请求header是application/x-www-form-urlencoded;text/html;charset=utf-8 ,因此在flask中通过request.get_json(),不仅取不到数据,而且会自动返回none,导致后面逻辑都不会运行,不知道的以为没收到有通知。建议用request.form
4,沙箱测试设置
https://docs.open.alipay.com/200/105311
沙箱测试和正式的类似但是要重新申请,然后另设密钥对。
另外沙箱钱包目前只有Android版的,所以要完整测试备一台Android手机吧。。。
5,关于密钥
alipay-sdj-python在调用函数签名或验证时, 会自动判断是否有‘-----BEGIN RSA PRIVATE KEY-----’然后填补, 因此可有可无。