python3.7+flask+alipay 支付宝付款功能
文档参考github:https://github.com/fzlee/alipay/blob/master/docs/init.md
沙箱环境配置:https://opendocs.alipay.com/open/200/105311
1、进入沙箱环境进行配置,有对应的APPID和支付宝网关
2、然后设置RSA2密钥,可下载支付宝开放平台开发助手进行生成,可查看 文档 ,然后记录好密钥的存放位置
回调地址是在支付过程中,后台会默认去调用的接口,以此接口去确认支付是否成功。所以回调地址根据自己本地接口进行填写,可参考后续的完整代码;
线上真实配置也与沙箱类似,需要开通自己的支付宝账号为商家才能进行配置。
进入非沙箱环境 ,然后选择你所需要开发的应用,创建应用后填写所需的信息以及需要开通的功能,然后提交审核即可。
比如选择开发网页付款,创建后进入配置信息,而相应的服务会提醒需要商家账号才能开通使用。审核通过即可正常使用
本地代码配置文件及完整代码:
APP_PRIVATE_KEY_PATH:存放 app_private_key.txt 的文件路径
ALIPAY_PUBLIC_KEY_PATH:存放alipay_public_key.txt的文件路径
比如本地路径: d:/keys/app_private_key.txt
或 服务器路径: /mnt/keys/app_private_key.txt
项目中安装: pip install python-alipay-sdk
file_system.py 文件


1 # file_system.py
2 import os
3
4
5 env = "production"
6 # env = ""
7 if env == 'production':
8 APP_PRIVATE_KEY_PATH = '/mnt/alipay_keys/app_private_key.txt'
9 ALIPAY_PUBLIC_KEY_PATH = '/mnt/alipay_keys/alipay_public_key.txt'
10 else:
11 APP_PRIVATE_KEY_PATH = os.getcwd() + '/ipay/keys/app_private_key.txt'
12 ALIPAY_PUBLIC_KEY_PATH = os.getcwd() + '/ipay/keys/alipay_public_key.txt'
alipay_setting.py文件


1 # alipay_setting.py
2 from alipay import AliPay
3 from config import APP_PRIVATE_KEY_PATH, ALIPAY_PUBLIC_KEY_PATH
4
5
6 env == "production"
7 if env == "production":
8 # 支付宝应用APPID
9 APP_ID = '20210021******'
10 # 支付连接(支付宝网关)
11 PAY_URL = 'https://openapi.alipay.com/gateway.do?'
12 else:
13 # 沙箱
14 APP_ID = '2016102******'
15 PAY_URL = 'https://openapi.alipaydev.com/gateway.do?'
16
17 # 应用私钥文件路径
18 APP_PRIVATE_KEY = open(APP_PRIVATE_KEY_PATH).read()
19
20 # 支付宝公钥文件路径
21 ALIPAY_PUBLIC_KEY = open(ALIPAY_PUBLIC_KEY_PATH).read()
22 # 签名方式
23 SIGN_TYPE = 'RSA2'
24 # 是否是测试环境 - 是否是支付宝沙箱,默认为 False
25 DEBUG = False
26
27
28 def alipay_trade_page_pay(pay_id, paid_price, item_name, return_url, notify_url):
29 alipay = AliPay(
30 appid=APP_ID,
31 app_notify_url=notify_url,
32 app_private_key_string=APP_PRIVATE_KEY,
33 alipay_public_key_string=ALIPAY_PUBLIC_KEY,
34 sign_type=SIGN_TYPE,
35 debug=DEBUG
36 )
37
38 # 生成支付链接
39 order_string = alipay.api_alipay_trade_page_pay(
40 out_trade_no=pay_id,
41 total_amount=paid_price,
42 subject=item_name,
43 return_url=return_url, # 支付成功后同步回调的项目前台页面
44 notify_url=notify_url # 支付成功后异步回调的项目后台接口
45 )
46
47 # 支付链接 = 支付宝网关 + order_string
48 order_url = PAY_URL + order_string
49 return order_url
50
51
52 # 验证支付结果
53 def verify_payment_result(data, signature):
54 alipay = AliPay(
55 appid=APP_ID,
56 app_notify_url=None,
57 app_private_key_string=APP_PRIVATE_KEY,
58 alipay_public_key_string=ALIPAY_PUBLIC_KEY,
59 sign_type=SIGN_TYPE,
60 debug=DEBUG
61 )
62 success = alipay.verify(data, signature)
63 return success
数据库模版文件,主要清楚接口是如何去调用支付宝付款功能,以及会生成怎样的数据内容
resource:了解上面支付宝配置文件 alipay_setting.py 中的接口是如何被调用,这里是结合了数据库模版 AlipayModel 的代码
1 import json
2 from config import FILE_DOMAIN_PREFIX
3 from model import AlipayOrderModel, UserModel
4 from flask_cors import cross_origin
5 from flask_restful import Resource
6 from util import id_generator
7 from flask_jwt_extended import jwt_required, get_jwt_identity
8 from flask import request, jsonify
9 import time
10 from ipay.alipay_setting import alipay_trade_page_pay, verify_payment_result
11 from wrapper import universal_resource_wrapper, root_role_required
12 # 参考路径:https://github.com/fzlee/alipay
13
14
15 # 创建支付宝订单接口
16 class CreateAlipayOrder(Resource):
17 """
18 itemName,paidPrice,paymentMethod,itemDeadline,setMeal
19 """
20 @universal_resource_wrapper(required=['paymentMethod', 'itemName', 'paidPrice','itemDeadline', 'setMeal'])
21 @jwt_required
22 @cross_origin(allow_headers=['Content-Type'])
23 def post(self):
24 data = request.get_json()
25 uid = get_jwt_identity()
26 item_name = data['itemName']
27 paid_price = data['paidPrice']
28 payment_method = data['paymentMethod']
29 pay_id = id_generator(template='uuid')
30 notify_url = FILE_DOMAIN_PREFIX + '/api/check_payment_success'
31 return_url = FILE_DOMAIN_PREFIX + '/chooseProductking/cpkRenewalInstructions'
32 # 生成支付宝付款链接
33 order_url = alipay_trade_page_pay(pay_id=pay_id, paid_price=paid_price, item_name=item_name,
34 return_url=return_url, notify_url=notify_url)
35 # 保存到数据库中;
36 ao = AlipayOrderModel(
37 alipayId=pay_id, # 订单编号
38 itemName=item_name, # 项目名称
39 paymentMethod=payment_method,
40 paidPrice=paid_price, # 付费价格
41 paymentStatus=False,
42 paidAt=time.time(),
43 paymentUrl=order_url,
44 uid=uid,
45 setMeal=data['setMeal'],
46 itemDeadline=data['itemDeadline'] # 项目截止日期
47 )
48 ao.save()
49 resp = jsonify({
50 'msg': '成功创建订单数据,返回支付宝订单ID',
51 'status': True,
52 'alipayId': pay_id
53 })
54 return resp
55
56
57 class GetAlipayPaymentUrl(Resource):
58 """alipayId"""
59 @universal_resource_wrapper(required=['alipayId'])
60 @cross_origin(allow_headers=['Content-Type'])
61 def post(self):
62 """
63 alipayId
64 :return:
65 """
66 data = request.get_json()
67 url = AlipayOrderModel.get_payment_url(data['alipayId'])
68 resp = jsonify({
69 'msg': '获取支付宝付款链接',
70 'status': True,
71 'data': {
72 'url': url
73 }
74 })
75 return resp
76
77
78 # 验证是否支付成功,作为回调接口notify_url使用
79 class CheckPaymentSuccess(Resource):
80 @universal_resource_wrapper(required=[])
81 @cross_origin(allow_headers=['Content-Type'])
82 def post(self):
83 data = request.form.to_dict()
84 # sign must be poped out
85 signature = data.pop("sign")
86 print(json.dumps(data))
87 print(signature)
88 # verify
89 success = verify_payment_result(data, signature)
90 # 交易结果判断
91 if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
92 ao = AlipayOrderModel.find_by_alipay_id(data['out_trade_no'])
93 ao.paymentStatus = True
94 ao.save()
95 usr = UserModel.find_by_uid(ao.uid)
96 usr.update_expire_time(ao.setMeal, ao.itemDeadline)
97 print("trade succeed")
98 resp = jsonify({
99 'msg': '支付成功',
100 'status': True
101 })
102 else:
103 resp = jsonify({
104 'msg': '支付失败',
105 'status': False
106 })
107 return resp
108
109
110 class CheckPaymentStatus(Resource):
111 """
112 alipayId
113 """
114 @universal_resource_wrapper(required=['alipayId'])
115 @jwt_required
116 @cross_origin(allow_headers=['Content-Type'])
117 def post(self):
118 uid = get_jwt_identity()
119 data = request.get_json()
120 ao = AlipayOrderModel.get_payment_status(uid=uid, pay_id=data['alipayId'])
121 if ao is None:
122 resp = jsonify({
123 'msg': '支付失败,无法找到已付款订单',
124 'status': False
125 })
126 else:
127 resp = jsonify({
128 'msg': '支付成功',
129 'status': True,
130 'data': ao
131 })
132 return resp
133
134
135 class UpdatePaymentStatusForLocal(Resource):
136 """alipayId"""
137 @universal_resource_wrapper(required=['alipayId'])
138 @jwt_required
139 @root_role_required
140 @cross_origin(allow_headers=['Content-Type'])
141 def post(self):
142 data = request.get_json()
143 ao = AlipayOrderModel.find_by_alipay_id(data['alipayId'])
144 ao.paymentStatus = True
145 ao.save()
146 usr = UserModel.find_by_uid(ao.uid)
147 usr.update_expire_time(ao.setMeal, ao.itemDeadline)
148 print("trade succeed")
149 resp = jsonify({
150 'msg': '支付成功',
151 'status': True
152 })
153 return resp
model:根据自己的需求自定义的数据库模版,只为跟上面的接口代码结合使用而已。
1 from model import Collection
2 import custom_field as cf
3
4
5 MODIFIABLE = [
6 'paymentMethod',
7 'itemName',
8 'paidPrice',
9 'paymentStatus',
10 'paidAt',
11 'paymentUrl',
12 'uid',
13 'itemDeadline',
14 'setMeal'
15 ]
16 UNMODIFIABLE = []
17
18 ID_KEY = 'alipayId'
19 ID_KEY_TEMPLATE = 'uuid'
20
21
22 class AlipayOrderModel(Collection):
23 alipayId = cf.Uuid()
24 paymentMethod = cf.String(default='alipay')
25 itemName = cf.String()
26 paidPrice = cf.Float()
27 paymentStatus = cf.Bool()
28 paidAt = cf.Time(required=False)
29 paymentUrl = cf.String()
30 uid = cf.Uuid()
31 setMeal = cf.String(required='free', choices=['lowLevel', 'highLevel'])
32 itemDeadline = cf.String(required=False, choices=['oneMonth', 'halfYear', 'oneYear'])
33
34 meta = {"db_alias": "MAILDB", "collection": "alipay_order"}
35
36 @classmethod
37 def create_new(cls, data_, created_by):
38 return super()._create_new(data_, id_key=ID_KEY,
39 id_template=ID_KEY_TEMPLATE,
40 created_by=created_by,
41 strict_fields=MODIFIABLE + UNMODIFIABLE
42 )
43
44 def do_update(self, keys_values, update_by):
45 return super()._do_update(keys_values, update_by,
46 MODIFIABLE)
47
48 @classmethod
49 def find_by_alipay_id(cls, obj_id):
50 return cls._find_by({'alipayId': obj_id})
51
52 @classmethod
53 def get_payment_url(cls, pay_id):
54 obj = AlipayOrderModel._find_by(query={'alipayId': pay_id, 'paymentStatus': False})
55 return obj.paymentUrl
56
57 @classmethod
58 def get_payment_status(cls, uid, pay_id):
59 obj = AlipayOrderModel._find_by(query={'alipayId': pay_id, 'paymentStatus': True, 'uid': uid})
60 return obj
python3.7+flask+alipay 支付宝付款功能的更多相关文章
- 【转载】关于Alipay支付宝接口(Java版)
转载自:http://blog.163.com/lai_chao/blog/static/70340789201412724619514/ 1.alipay 双功能支付简介 2.alipay 提交支付 ...
- 关于Alipay支付宝接口(Java版)
支付宝开发文档:https://b.alipay.com/order/techService.htm 1.alipay 双功能支付简介 2.alipay 提交支付订单 3.alipay 整合双功能支付 ...
- 支付宝支付功能(使用支付宝sdk)
1.准备参数 新建一个公共参数配置类NewAlipayconfig (可将参数存放到config配置文件中读取) public class NewAlipayconfi ...
- SSM 实现支付宝支付功能(图文详解+完整代码)
阅读本文大概需要 4 分钟. 前言 本教程详细介绍了如何使用ssm框架实现支付宝支付功能.本文章分为两大部分,分别是「支付宝测试环境代码测试」和「将支付宝支付整合到ssm框架」,详细的代码和图文解释, ...
- laravel实现支付宝支付功能
起因 前段时间因为项目中需要实现支付宝手机网站支付功能,所以写下这篇文章以作记录,不足之处,欢迎指教. 后端框架:Laravel 5.5 业务功能 适用于商家在移动端网页应用中集成支付宝支付功能.商家 ...
- 支付宝内部功能调用APP的said说明
追加: 支付宝收款码 alipayqr://platformapi/startapp?saId=20000123 微信扫一扫 weixin://scanqrcode (跳转微信扫一扫) 支付宝扫一 ...
- iOS跳转支付宝付款码和扫一扫页面
iOS跳转支付宝付款码和扫一扫页面 // 是否支持支付宝 NSURL * myURL_APP_A = [NSURL URLWithString:@"alipay://"]; if ...
- django中使用事务以及接入支付宝支付功能
之前一直想记录一下在项目中使用到的事务以及支付宝支付功能,自己一直犯懒没有完,趁今天有点兴致,在这记录一下. 商城项目必备的就是支付订单的功能,所以就会涉及到订单的保存以及支付接口的引入.先来看看订单 ...
- Django 支付宝付款接口的使用
我们在开发的过程中经常会碰到调用微信或者支付宝接口进行付款,付款完成之后,如果用户绑定了我的账号,我只要有活动了,就要给这个关注我的用户推动消息,让用户知道,比如说,我们经常会关注一些公众号,然后这些 ...
随机推荐
- SpringCache(redis)
pom <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spr ...
- WPF LiveChart 图表详解
//参考网址:https://www.cnblogs.com/zh7791/p/12617961.html 本文主要介绍LiveChart.WPF 中的图表的使用方法 类: 数据绑定, 数据显示样式等 ...
- mysql基础操作(四):简单多表查询
-- 创建部门 (主表) create table dept( id int primary key auto_increment, name varchar(20) ); -- 创建员工 (副表) ...
- PHP小数点后保留位数并四舍五入
ceil() 函数向上舍入为最接近的整数,进一(k>0).ceil(0.60) --> 1ceil(0.40) --> 1ceil(5) --> 5ceil(5.1) --&g ...
- VMware ESXi 7.0 U2 SLIC & Unlocker Intel NUC 专用镜像 202109 更新
2021.08.31 更新:集成 "vmkusb-nic-fling" 和 "nvme-community",现在只有一个镜像. 2021.06.16 更新:集 ...
- spring整合jdbc方法一
用了一段时间的spring这,闲来没事做一下spring整合jdbc 目录文件 导入jar包 由于spring的jar包是在myeclipse中自动导入的有些暂时用不到的也没有处理. Emp类 pac ...
- samba网络共享
1.sanma简介 2. samba安装 #更新源 opkg update #搜索软件包,查看版本 opkg list | grep "samba" #根据查询的版本安装服务器和l ...
- Appium自动化(3) - adb无线连接手机的方法
如果你还想从头学起Appium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1693896.html 前言 除了USB方式连接Andro ...
- Mybatis-基本学习(下)
四,MAP的使用--超常用 思考:多表连接查询怎么做?---MAP的好处!---返回List
- 用Java写了一个程序,将一个Mysql库中的表,迁移到另外一个server上的Mysql库中
用Navicat做数据迁移,因为数据量比较大,迁移过过程中一个是进展不直观,另外就是cpu占用率高的时候,屏幕跟死机了一样点不动按钮,不好中断. 想了想,干脆自己写一个. 在网上找了一个sqllite ...