我们再web开发中,经常会遇到接入QQ登录,微信登录,支付宝支付,微信登录等等需求,以下针对python接入支付宝的流程进行总结。
github上有大神写出了python对接支付宝的教程,大家可以参考https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
# 安装python-alipay-sdk
pip install python-alipay-sdk --upgrade
# 对于python2, 请安装2.0以下版本: pip install python-alipay-sdk==1.1
这里面有两对密钥对
生成密钥的两种方式
openssl # openssl 是Linux自带的 在终端即可执行
OpenSSL> genrsa -out app_private_key.pem 2048 # 私钥
OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem # 导出公钥
OpenSSL> exit # 注意这个生成的密钥会在当前路径下
支付宝的私钥支付宝自己保存了,我们需要将我们的公钥交给我们的沙箱
支付宝公钥我们复制,保存起来,因为等一下参数要用到。
因为我们在沙箱环境中已经设置了应用公钥,所以这里没有必要将应用公钥放进来
注意,还需要在公钥文件中补充开始与结束标志
-----BEGIN PUBLIC KEY-----
此处是公钥内容
-----END PUBLIC KEY-----
这一步做完了之后配置就完成啦,当我们创建完订单选择支付宝付款后,我们后端就需要请求支付宝,支付宝接收我的订单拼接url用户尽心登录,输入密码,确认支付
app_private_key_str = open(r'/home/python/Desktop/2020jxsz_teach/student_items/selfblog/SelfBlog/order/keys/app_private_key.pem').read()
alipay_public_key_str = open(r'/home/python/Desktop/2020jxsz_teach/student_items/selfblog/SelfBlog/order/keys/alipay_public_key.pem').read()
class AliPayView(APIView):
def get(self, request, order_id):
# 向支付宝发起请求,获取支付链接参数
print("订单号为:", order_id)
alipay_client = AliPay(
appid=settings.ALIPAY_APPID,
app_notify_url=None, # 默认回调url
app_private_key_string = app_private_key_str,
alipay_public_key_string=alipay_public_key_str,
sign_type="RSA2", # RSA 或者 RSA2
debug=settings.ALIPAY_DEBUG # 默认False 是否是沙箱环境 True 代表沙箱
)
try:
order = OrderInfo.objects.get(order_id=order_id)
except OrderInfo.DoesNotExist:
return Response({"msg":"非法请求,不存在此订单"}, status= status.HTTP_400_BAD_REQUEST)
# 电脑网站支付,需要跳转到https://openapi.alipay.com/gateway.do? + order_string
order_string = alipay_client.api_alipay_trade_page_pay(
out_trade_no=order_id, # 订单编号
total_amount=str(order.total_amount), # 总金额
subject='昆仑的数据展示:%s' % order_id,
return_url="http://127.0.0.1:8000/order/success/",
notify_url=None # 可选, 不填则使用默认notify url
)
# 拼接支付链接网址
alipay_url = settings.ALIPAY_URL + '?' + order_string
return Response({"alipay_url":alipay_url, "msg":"SUCCESS"}, status = 200)
完成支付后,支付宝会返回回调url,回调url由我们调用支付宝接口时传递的return_url参数指定,支付宝返回给我们的签名,支付宝付款流水等信息拼接在该url后面
我们在支付完成后也需要完成后端逻辑,比如既然完成了支付,我们的商品状态就应该由为支付改为已支付,销量+1等,但记住,在执行这些逻辑之前必须得先用应用公钥进行验签,不然可能会被人冒用支付宝而篡改我们订单。
class OrderSuccessView(APIView):
def get(self, request):
# 接收参数
# 校验
alipay_req_data = request.query_params # QueryDict
if not alipay_req_data:
return Response({'message': "缺少参数"}, status=status.HTTP_400_BAD_REQUEST)
alipay_req_dict = alipay_req_data.dict()
sign = alipay_req_dict.pop('sign')
alipay_client = AliPay(
appid=settings.ALIPAY_APPID,
app_notify_url=None, # 默认回调url
app_private_key_string=app_private_key_str,
alipay_public_key_string=alipay_public_key_str,
sign_type="RSA2", # RSA 或者 RSA2
debug=settings.ALIPAY_DEBUG # 默认False 是否是沙箱环境
)
# 返回验证结果,True False
result = alipay_client.verify(alipay_req_dict, sign) # 验签
print(alipay_req_dict)
print(result,"result")
if result:
order_id = alipay_req_dict.get('out_trade_no')
trade_id = alipay_req_dict.get('trade_no')
# 保存数据
# 保存支付结果数据Payment
Payment.objects.create(
order_id=order_id,
trade_id=trade_id
)
# 修改订单状态
OrderInfo.objects.filter(order_id=order_id).update(status=5)
return Response({'trade_id': trade_id})
else:
return Response({'message': '参数有误'}, status=status.HTTP_400_BAD_REQUEST)
alipay_client.verify(alipay_req_dict, sign)
进行验签,结果为True代表验证通过。那么就表示时支付宝发送过来的请求。
下面贴出我的一些执行流程,界面比较丑,见谅。
首页,想做个博客,还没成功,后续会慢慢更新。
提交订单
订单支付页面
进行支付,不过这里的账号不是你真正的支付宝的账号,而是要你支付宝沙箱环境里面拿
点这里: https://openhome.alipay.com/platform/appDaily.htm?tab=account
以上是我的测试数据。
以上,希望大家一同交流
项目git地址:https://gitee.com/hanzhou521/selfblog.git