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 支付宝付款接口的使用
我们在开发的过程中经常会碰到调用微信或者支付宝接口进行付款,付款完成之后,如果用户绑定了我的账号,我只要有活动了,就要给这个关注我的用户推动消息,让用户知道,比如说,我们经常会关注一些公众号,然后这些 ...
随机推荐
- beeline: 新版连接Hive server的工具
HiveServer2 支持一个新的命令行Shell,称为Beeline,它是基于SQLLine CLI的JDBC客户端.它是从 Hive 0.11版本引入的,是Hive新的命令行客户端工具.Hive ...
- springboot 2.0 整合 RestTemplate
首先导入springboot 的 web 包 <dependency> <groupId>org.springframework.boot</groupId> &l ...
- 新东方APP技术团队建设
作者:张建鑫, 曾任IBM高级软件架构师, 滴滴高级技术专家, 现任新东方集团高级技术总监 2019年注定是不平凡的一年,在俞敏洪老师对科技条线的密切关注下, 吴强老师亲自操盘了对产品技术条线的改革, ...
- Ubuntu 16.04 + Win10双系统 启动Ubuntu进入命令行 无界面
Ubuntu 16.04 + Win10双系统,启动Ubuntu时候报错,并入命令行(无界面). 原因:可能是双系统兼容性问题 解决办法: 重启系统,进入Win10 然后在Win10中重启电脑. 重启 ...
- 【HMS Core 6.0全球上线】Network Kit全链路网络加速技术,应用无惧网络拥塞
HMS Core 6.0已于7月15日全球上线,本次版本向广大开发者开放了众多全新能力与技术.其中HMS Core Network Kit开放了全链路网络加速技术,助力开发者为用户提供低时延的畅快网络 ...
- Appium自动化(8) - 可定位的控件属性
如果你还想从头学起Appium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1693896.html 前言 在前面几篇文章可以看到,一个 ...
- 《Go语言圣经》阅读笔记:第二章程序结构
第二章 程序结构 2.1 命名 在GO语言中,所有的变量名.函数.常量.类型.语句标号.包名都遵循一个原则: 名字必须以字母或者下划线开头,后面紧跟任意数量的字母数字下划线.区分大小写. 在GO语言中 ...
- PPP协议、PPPoE协议、L2TP协议的关系
1. 简述 首先对这3中协议做一个简单的描述: 协议 协议类型 描述 PPP 点对点链路层协议 应用最广泛的点对点协议,可应用在多种网络,改善了SLIP协议的不足 PPPoE 点对点链路层协议 对PP ...
- L2TP协议简介
传送门:L2TP代码实现 1. L2TP 概述 L2TP(Layer 2 Tunneling Protocol,二层隧道协议)是 VPDN(Virtual Private Dial-up Networ ...
- unity2021游戏引擎安装激活并汉化
今天重新搭建了下unity的开发环境,也踩了不少坑,还有就是看了一些unity3d的教程,越看越不可思议,unity居然能做这么多好玩的东西,像枪战类,模拟类,角色扮演,动作冒险都很震撼. 但是震撼归 ...