Django中对接第三方支付(支付宝)实现支付的流程
1. 业务逻辑
准备
1. 使用沙箱提供的商家环境
沙箱环境:是支付宝提供给开发者的模拟支付的环境
沙箱应用:https://docs.open.alipay.com/200/105311
沙箱账号:https://openhome.alipay.com/platform/appDaily.htm?tab=account
支付宝开发者文档:
文档主页:https://openhome.alipay.com/developmentDocument.htm
产品介绍:https://docs.open.alipay.com/270
快速接入:https://docs.open.alipay.com/270/105899/
SDK:https://docs.open.alipay.com/270/106291/
python对接支付宝SDK:https://github.com/fzlee/alipay/blob/master/README.zh-hans.m
API列表:https://docs.open.alipay.com/270/105900/
2.. 生成密钥对
3. 将公钥加到商品环境中
4. 将Alipay提供的公钥加入项目中
支付功能
5. 根据order_id查询订单对象
6. 创建alipay对象
7. 调用方法,生成url
8. 返回url
保存支付状态
9. 根据返回的url请求支付宝
10. 支付成功后返回商家回调页面--------->会传回很多Alipay传回来的参数,很多明文,防止别人攻击
11. 返回商家的同时请求后台服务器------>发送这些参数给后台
12. 接收参数并且验证,成功则创建订单支付对象返回订单号,否则提示支付失败
2.安装包
- pip install python-alipay-sdk --upgrade
3.新建一个payments的app应用
- python ../../manage.py startapp payments
4.定义一个模型类,继承自BaseModel(创建时间与修改时间)
- class Payment(BaseModel):
- """
- 支付信息
- """
- order = models.ForeignKey(
- OrderInfo, on_delete=models.CASCADE, verbose_name='订单')
- trade_id = models.CharField(
- max_length=100, verbose_name="支付流水号")
- class Meta:
- db_table = 'tb_payment'
- verbose_name = '支付信息'
- verbose_name_plural = verbose_name
5.配置密钥
5.1.登录沙箱
在payments应用中新建keys目录,用来保存秘钥文件。
将应用私钥文件app_private_key.pem复制到payment/keys目录下。
5.1.1生成应用的私钥和公钥
- openssl
- OpenSSL> genrsa -out app_private_key.pem 2048 # 私钥RSA2
- OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem # 导出公钥
- OpenSSL> exit
5.2 保存应用私钥文件
5.3 查看公钥
- cat app_publict_key.pem
# 将公钥内容复制给支付宝沙箱的<应用私钥>,得到支付宝的<支付宝公钥>
5.4 保存支付宝公钥
在payments/keys目录下新建alipay_public_key.pem文件,用于保存支付宝的公钥文件。
将支付宝的公钥内容复制到alipay_public_key.pem文件中
6.配置路由
- GET /orders/(?P<order_id>\d+)/payment/
7.在配置文件中配置ailipay的信息
- # 支付宝支付的配置
- ALIPAY_APPID = 'xxxxxxxxxxxxx'
- ALIPAY_PRIVATE_KEY_PATH = os.path.join(BASE_DIR, 'apps/payments/alipay/app_private_key.pem')
- ALIPAY_PUBLIC_KEY_PATH = os.path.join(BASE_DIR, 'apps/payments/alipay/alipay_public_key.pem')
- ALIPAY_DEBUG = True
- ALIPAY_SUBJECT = '智学客-订单支付'
- ALIPAY_RETURN_URL = 'http://www.xxx.com/pay_success.html'
- ALIPAY_GATE = 'https://openapi.alipaydev.com/gateway.do?'
8.定义视图
两个参数:
order_id: 订单编号
alipay_uel: 支付宝支付链接
代码如下:
- class AliPayURLView(APIView):
- def get(self, request, order_id):
- # 1.根据order_id查询订单对象
- try:
- order_obj = OrderInfo.objects.get(pk=order_id)
- except:
- raise Exception("订单号无效")
- # 2.创建alipay对象
- alipay = AliPay(
- appid=settings.ALIPAY_APPID,
- app_notify_url=None,
- app_private_key_path=settings.ALIPAY_PRIVATE_KEY_PATH,
- alipay_public_key_path=settings.ALIPAY_PUBLIC_KEY_PATH,
- debug=settings.ALIPAY_DEBUG
- )
- # 3.调用方法,生成url
- # 电脑网站支付,需要跳转到https://openapi.alipay.com/gateway.do? + order_string
- order_string = alipay.api_alipay_trade_page_pay(
- subject=settings.ALIPAY_SUBJECT,
- out_trade_no=order_id, # 订单编号
- total_amount=str(order_obj.total_amount), # 支付总金额,类型为Decimal(),不支持序列化,需要强转成str
- return_url=settings.ALIPAY_RETURN_URL # 支付成功后的回调地址
- )
- # 4.返回url
- return Response({"alipay_url": settings.ALIPAY_GATE + order_string})
8.1 在payments/urls.py中定义路由规则
- url('^orders/(?P<order_id>\d+)/payment/$',views.PaymentView.as_view()),
9.保存支付状态
请求方式:PUT /payment/status/?支付宝参数
参数:trade_id:支付宝流水账号
代码实现:
- class OrderStatusView(APIView):
- """验证用户是否登录成功"""
- def put(self, request):
- # 1.接收支付宝返回的数据
- data = request.query_params.dict()
- # 2.验证是否支付成功
- # 2.1删除签名,不参与验证
- signature = data.pop("sign")
- # 2.2 创建alipay对象
- alipay = AliPay(
- appid=settings.ALIPAY_APPID,
- app_notify_url=None,
- app_private_key_path=settings.ALIPAY_PRIVATE_KEY_PATH,
- alipay_public_key_path=settings.ALIPAY_PUBLIC_KEY_PATH,
- debug=settings.ALIPAY_DEBUG
- )
- # 2.3 调用verify(字典,签名)
- success = alipay.verify(data, signature)
- if success:
- # 支付成功
- '''
- {
- 'total_amount': '11388.00', 支付金额
- 'auth_app_id': '2016082100304973', 应用编号
- 'method': 'alipay.trade.page.pay.return',
- 'trade_no': '2018110722001420410500545016',流水号
- 'timestamp': '2018-11-07 16:59:20',时间
- 'app_id': '2016082100304973',应用编号
- 'out_trade_no': '20181107160224000000001',商城的订单编号
- 'charset': 'utf-8',编码
- 'seller_id': '2088102172415825',商家编号
- 'version': '1.0'版本
- }
- '''
- # 1 获取订单号
- order_id = data["out_trade_no"]
- # 2 修改订单状态
- try:
- order_obj = OrderInfo.objects.get(pk=order_id)
- except:
- raise Exception("订单号无效")
- order_obj.status = 2
- order_obj.save()
- # 3.创建订单支付对象
- trade_no = data.get('trade_no') # 获取流水号
- Payment.objects.create(
- order_id=order_id,
- trade_no=trade_no
- )
- # 4.响应
- return Response({"trade_id": trade_no})
- else:
- raise Exception("支付失败")
9.1 定义路由规则
- url('^payment/status/$',views.PaymentStatusView.as_view()),
Django中对接第三方支付(支付宝)实现支付的流程的更多相关文章
- Django day35 redis连接池,redis-list操作,django中使用redis,支付宝支付
一:redis连接池, 二:redis-list操作, 三:django中使用redis, 四:支付宝支付
- django中使用第三方包实现定时任务
# 转载请留言联系 在做主页静态化的时候,需要定时生成主页HTML,以保持数据的最新. 定时任务可以用第三方包django-crontab来实现. 附上官方文档:https://pypi.org/pr ...
- 微信、支付宝App支付-JPay0.0.2发布
JPay 对微信App支付.支付宝App支付的二次封装,对外提供一个相对简单的接口以及支付结果的回调 GitHub:https://github.com/Javen205/JPay OsChina:h ...
- uni-app开发经验分享十八:对接第三方h5
1.uni-app中对接第三方为了防止跳出app使用了webview <template> <view> <web-view :src="url" @ ...
- php支付走过的坑(微信篇 包含h5支付和app支付 注册 秘钥 环境等等配置)
支付这东西,说容易也容易,说难也难 代码这玩意还比较好说 但是 如果没有demo 直接去看官方文档 十有八九一脸懵逼 今天就整理一下 支付这块走过的坑 涉及 微信h5支付 支付宝h5支付 (api文档 ...
- django中的静态文件
静态文件 1.什么是静态文件 在django中静态文件是指那些图片.css样式.js样式.视频.音频等静态资源. 2.为什么要配置静态文件 这些静态文件往往不需要频繁的进行变动,如果我们将这些静态文件 ...
- django中使用事务以及接入支付宝支付功能
之前一直想记录一下在项目中使用到的事务以及支付宝支付功能,自己一直犯懒没有完,趁今天有点兴致,在这记录一下. 商城项目必备的就是支付订单的功能,所以就会涉及到订单的保存以及支付接口的引入.先来看看订单 ...
- Django对接支付宝Alipay支付接口
最新博客更新见我的个人主页: https://xzajyjs.cn 我们在使用Django构建网站时常需要对接第三方支付平台的支付接口,这里就以支付宝为例(其他平台大同小异),使用支付宝开放平台的沙箱 ...
- 对接第三方支付接口-获取http中的返回参数
这几天对接第三方支付接口,在回调通知里获取返回参数,有一家返回的json格式,请求参数可以从标准输入流中获取. //1.解析参数 , 读取请求内容 BufferedReader br; String ...
随机推荐
- 11.6NOIP模拟赛
[数据规模和限制] 对于全部测试数据,满足 N,M,K≤,W≤ 各个测试点的数据规模及特殊性质如下表. 测试点 N M K ≤ ≤ ≤ ≤ ≤ ≤ ≤ ≤ ≤ ≤ 师 更多咨询:北京信息学窦老师 QQ ...
- VMware安装Centos 7,网络连接问题以及解决方案
转自: https://www.cnblogs.com/owaowa/p/6123902.html 在这里表示万分感谢 在使用CentOS虚拟机后,出现了无法上网的情况,使用主机ping虚机地址可以p ...
- Java 反射机制详解(下)
续:Java 反射机制详解(上) 三.怎么使用反射 想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过字节码文件对象,就能够通过该类中的方法获取到我们想要的所有信息(方法,属 ...
- 递归(Recursion)
递归是一种非常常用的算法,分为“递”和“归”两个步骤.满足递归算法有三个条件:1.一个问题,可以分解为子问题:2.该问题,与分解后的子问题,解决思路一致:3.存在终止条件.案例演示:假设有n个台阶,每 ...
- iOS UITableView ExpandableHeader(可形变的Header)
最常见的header就是在tableView下拉时header里的图片会放大的那种, 最近研究了一下,自己实现了这种header. 1.设置TableView的contentInset(为header ...
- Planning CodeForces - 854C
Planning CodeForces - 854C 题意:有n架航班,第i架原先的时候是在第i分钟起飞的.现在前k分钟无法有飞机起飞,因此需要调整安排表,延后飞机起飞.仍然要求每一分钟只有一架飞机起 ...
- Sublime Text 3列编辑
Sublime Text 3 的列编辑方式如下 1.使用鼠标 (Ubuntu 14.04验证通过) 不同的平台要使用不同的鼠标按钮: 1.1 OS X 鼠标左键 + Option 或: 鼠标中键 添加 ...
- D. Black Hills golden jewels 二分答案 + 二分判定
http://codeforces.com/gym/101064/problem/D 题目是给定一个数组,如果两两组合,有C(n, 2)种结果,(找出第一个大于等于第k大的结果) 思路, 二分答案va ...
- python函数基础(3)
第1章 编码补充 1.1 字符编码对照表 1.2 编码特性 1.4 encode/decode第2章 集合 2.1 特点 2.2 [重点]作用:去重 2.3 常用操作 2.3.1 删除 2.3.2 交 ...
- BigDecimal取余运算
取余运算在编程中运用非常广泛,对于BigDecimal对象取余运算可以通过divideAndRemainder方法实现. public BigDecimal[] divideAndRemainder( ...