python调用支付宝支付接口详细示例—附带Django demo代码
项目演示:
一、输入金额
二、跳转到支付宝付款
三、支付成功
四、跳转回自己网站
在使用支付宝接口的前期准备:
1、支付宝公钥
2、应用公钥
3、应用私钥
4、APPID
5、Django 1.11.11 环境
1234均由阿里开放平台生成
如果你不是商户或者你只是想测试,阿里提供了沙箱环境供测试
沙箱环境下的商户账号和用户账号、支付宝app都是沙箱版的,不能用实际账号
这时候我们需要去阿里开放平台去生成一些1234参数
注册网址:https://openhome.alipay.com/platform/appDaily.htm?tab=info
点击设置应用公钥
下载签名生成工具,解压后找到 RSA签名验签工具.bat 文件打开
这个工具会自动保存应用公钥和应用私钥到 RSA密钥 文件夹
将应用公钥拷贝到网站窗口,点保存,在原应用公钥按钮旁就会自动生成支付宝公钥
我们需要将网站窗口生成的支付宝公钥也新建一个txt文件放到这里面
继续操作
修改三个txt文件的名字为英文,如:app_public.txt \ app_private.txt \ alipay_public.txt
修改三个txt文件内容为固定格式:
-----BEGIN PUBLIC KEY----- # 加上这行密钥部分 -----END PUBLIC KEY----- # 同上
将三个文件copy到django项目下新建文件夹中,如:
你也可以放在app下面,都可以,随你自己,但你可以先按我的一模一样配置将项目先跑通。
建议新建alipay的文件夹,配置及相关py文件可以全部放到这里面来
接下来在settings配置文件中配置这三个txt文件的路径
我的配置:
ALIPAY_PUBLIC = os.path.join(BASE_DIR,'alipay_use','alipay','alipay_keys','alipay_public.txt') APP_PUBLIC = os.path.join(BASE_DIR,'alipay_use','alipay','alipay_keys','app_public.txt') APP_PRIVATE = os.path.join(BASE_DIR,'alipay_use','alipay','alipay_keys','app_private.txt')
alipay文件夹下新建alipay.py文件
alipay.py 代码如下:
# _*_ coding=utf-8 _*_ from datetime import datetime from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import SHA256 from urllib.parse import quote_plus from base64 import decodebytes, encodebytes import jsonclass AliPay(object):"""支付宝支付接口(PC端支付接口)"""def __init__(self, appid, app_notify_url, app_private_key_path,alipay_public_key_path, return_url, debug=False):self.appid = appidself.app_notify_url = app_notify_urlself.app_private_key_path = app_private_key_pathself.app_private_key = Noneself.return_url = return_urlwith open(self.app_private_key_path) as fp:self.app_private_key = RSA.importKey(fp.read())self.alipay_public_key_path = alipay_public_key_pathwith open(self.alipay_public_key_path) as fp:self.alipay_public_key = RSA.importKey(fp.read())if debug is True:self.__gateway = "https://openapi.alipaydev.com/gateway.do"else:self.__gateway = "https://openapi.alipay.com/gateway.do"def direct_pay(self, subject, out_trade_no, total_amount, return_url=None, **kwargs):biz_content = {"subject": subject,"out_trade_no": out_trade_no,"total_amount": total_amount,"product_code": "FAST_INSTANT_TRADE_PAY",# "qr_pay_mode":4 }biz_content.update(kwargs)data = self.build_body("alipay.trade.page.pay", biz_content, self.return_url)return self.sign_data(data)def build_body(self, method, biz_content, return_url=None):data = {"app_id": self.appid,"method": method,"charset": "utf-8","sign_type": "RSA2","timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),"version": "1.0","biz_content": biz_content}if return_url is not None:data["notify_url"] = self.app_notify_urldata["return_url"] = self.return_urlreturn datadef sign_data(self, data):data.pop("sign", None)# 排序后的字符串unsigned_items = self.ordered_data(data)unsigned_string = "&".join("{0}={1}".format(k, v) for k, v in unsigned_items)sign = self.sign(unsigned_string.encode("utf-8"))# ordered_items = self.ordered_data(data)quoted_string = "&".join("{0}={1}".format(k, quote_plus(v)) for k, v in unsigned_items)# 获得最终的订单信息字符串signed_string = quoted_string + "&sign=" + quote_plus(sign)return signed_stringdef ordered_data(self, data):complex_keys = []for key, value in data.items():if isinstance(value, dict):complex_keys.append(key)# 将字典类型的数据dump出来for key in complex_keys:data[key] = json.dumps(data[key], separators=(',', ':'))return sorted([(k, v) for k, v in data.items()])def sign(self, unsigned_string):# 开始计算签名key = self.app_private_keysigner = PKCS1_v1_5.new(key)signature = signer.sign(SHA256.new(unsigned_string))# base64 编码,转换为unicode表示并移除回车sign = encodebytes(signature).decode("utf8").replace("\n", "")return signdef _verify(self, raw_content, signature):# 开始计算签名key = self.alipay_public_keysigner = PKCS1_v1_5.new(key)digest = SHA256.new()digest.update(raw_content.encode("utf8"))if signer.verify(digest, decodebytes(signature.encode("utf8"))):return Truereturn Falsedef verify(self, data, signature):if "sign_type" in data:sign_type = data.pop("sign_type")# 排序后的字符串unsigned_items = self.ordered_data(data)message = "&".join(u"{}={}".format(k, v) for k, v in unsigned_items)return self._verify(message, signature)
这个Alipay类主要是用来生成一个包含订单详情、签名的大字典,然后把这个大字典加密成字符串拼接到支付宝付款网关接口路径后面
视图中重定向到该地址,支付宝处理完成后向我们的路由发get请求携带详细信息和签名,使用这个类的一个方法来校验签名即可
路由层(项目中)
urls.py
from django.contrib import admin from django.conf.urls import url from app01 import viewsurlpatterns = [url('admin/', admin.site.urls),url('index/', views.index),url('result/', views.pay_result), # 支付宝处理完成后回调的get请求路由url('update_order/', views.update_order), # 支付宝处理完成后回调的post请求路由 ]
视图层(app中)
views.py
import time from urllib.parse import parse_qs from django.conf import settings from django.shortcuts import render, redirect, HttpResponse from django.views.decorators.csrf import csrf_exempt from alipay_use.alipay.alipay import AliPaydef aliPay():obj = AliPay(appid="2016100100642208", # 支付宝沙箱里面的APPID,需要改成你自己的app_notify_url="http://129.211.29.98/update_order/", # 如果支付成功,支付宝会向这个地址发送POST请求(校验是否支付已经完成),此地址要能够在公网进行访问,需要改成你自己的服务器地址return_url="http://129.211.29.98/result/", # 如果支付成功,重定向回到你的网站的地址。需要你自己改,这里是我的服务器地址alipay_public_key_path=settings.ALIPAY_PUBLIC, # 支付宝公钥app_private_key_path=settings.APP_PRIVATE, # 应用私钥debug=True, # 默认False,True表示使用沙箱环境测试 )# 优化:在settings里面的设置后使用# obj = AliPay(# appid=settings.APPID,# app_notify_url=settings.NOTIFY_URL,# return_url=settings.RETURN_URL,# alipay_public_key_path=settings.PUB_KEY_PATH,# app_private_key_path=settings.PRI_KEY_PATH,# debug=True,# )return obj@csrf_exempt def index(request):if request.method == "GET":return render(request, 'index.html')# 实例化SDK里面的类AliPayalipay = aliPay()# 对购买的数据进行加密money = float(request.POST.get('price')) # 保留俩位小数 前端传回的数据out_trade_no = "x2" + str(time.time()) # 商户订单号 # 订单号可以有多中生成方式,可以百度一下# 1. 在数据库创建一条数据:状态(待支付) query_params = alipay.direct_pay(subject="充气式Saber", # 商品简单描述 这里一般是从前端传过来的数据out_trade_no=out_trade_no, # 商户订单号 这里一般是从前端传过来的数据total_amount=money, # 交易金额(单位: 元 保留俩位小数) 这里一般是从前端传过来的数据 )# 拼接url,转到支付宝支付页面pay_url = "https://openapi.alipaydev.com/gateway.do?{}".format(query_params)return redirect(pay_url)@csrf_exempt def update_order(request):"""支付成功后,支付宝向该地址发送的POST请求(用于修改订单状态):param request::return:"""if request.method == 'POST':body_str = request.body.decode('utf-8')post_data = parse_qs(body_str)post_dict = {}for k, v in post_data.items():post_dict[k] = v[0]alipay = aliPay()sign = post_dict.pop('sign', None)status = alipay.verify(post_dict, sign)if status:# 1.修改订单状态out_trade_no = post_dict.get('out_trade_no')print(out_trade_no)# 2. 根据订单号将数据库中的数据进行更新return HttpResponse('支付成功')else:return HttpResponse('支付失败')return HttpResponse('')@csrf_exempt def pay_result(request):"""支付完成后,跳转回的地址:param request::return:"""params = request.GET.dict()sign = params.pop('sign', None)alipay = aliPay()status = alipay.verify(params, sign)if status:return HttpResponse('支付成功')return HttpResponse('支付失败')
index.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><form action="" method="post"><input type="text" name="price"><input type="submit"> </form></body> </html>
需要装的模块:
--pycryptodome --urllib --base64
支付宝接口流程:
转载于:https://www.cnblogs.com/gwklan/p/11173523.html
python调用支付宝支付接口详细示例—附带Django demo代码相关推荐
- python 支付宝接口_python调用支付宝支付接口流程
项目演示: 一.输入金额 二.跳转到支付宝付款 三.支付成功 四.跳转回自己网站 在使用支付宝接口的前期准备: 1.支付宝公钥 2.应用公钥 3.应用私钥 4.APPID 5.Django 1.11. ...
- php编程之如何调用支付宝支付接口的实现
对于任何一款软件来说,支付功能都是核心的,那么目前的主流支付接口主要是支付宝.微信和银联卡,而大多数开发技术人员对于如何调用支付宝的支付接口还存在很大的困扰,今天就来跟大家分享一下如何正确调用支付宝支 ...
- php开发支付宝支付密码忘记了怎么办_php编程之如何调用支付宝支付接口的实现...
对于任何一款软件来说,支付功能都是核心的,那么目前的主流支付接口主要是支付宝.微信和银联卡,而大多数开发技术人员对于如何调用支付宝的支付接口还存在很大的困扰,今天就来跟大家分享一下如何正确调用支付宝支 ...
- java 调用支付宝支付接口
最近公司在做支付模块,在接入过程中遇到了很多坑,费了不少事,现在分享一下接入方法,也记录一下,以后可能还用的到.用的是支付宝的即时到帐支付功能和微信的扫码支付功能,相比起来,个人感觉支付宝的文档和接入 ...
- Python 调用支付宝沙箱接口 实现 扫码支付
思路剖析 支付宝开放平台 登录 登陆之后 点击这个 研发服务 然后下载 一个 支付宝沙箱的 移动端 点击左侧的沙箱账号,就可以知道 登录沙箱的 账号和 密码了,也可以 往死充钱.他是可以扫 沙箱收款的 ...
- python 调用支付宝微信接口_前端在h5页面调起微信支付接口和支付宝接口(日常笔记)...
微信支付 微信文档中的例子如下. function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "ap ...
- java 支付宝h5网页支付接口,移动端h5网页调用支付宝支付接口
领导第一次让我做h5支付宝支付的时候,去了支付宝开放平台,一顿上上下下左左右右,看完了长呼一口气.这个支付好像没我啥事儿啊!小伙伴儿们自行查看:https://opendocs.alipay.com/ ...
- 移动端h5网页调用支付宝支付接口
来源 | https://www.dsiab.com/post/4181 领导第一次让我做h5支付宝支付的时候,去了支付宝开放平台,一顿上上下下左左右右,看完了长呼一口气. 这个支付好像没我啥事儿啊! ...
- Java调用支付宝支付接口
一.场景:公司需要在网站上进行支付宝支付. 二.API:使用支付宝开放平台的支付能力-即时到账接口.支付宝开放平台链接 三.分析: 1.支付宝的文档比较容易看,主要是有相应的DEMO,我这里看的DEM ...
最新文章
- 独家 | 如何跳出编程这个坑
- 证明黎曼猜想的5页论文已发布!最简洁的解读在这里
- 正则判断 手机邮箱的正确格式
- 转换环境与执行环境、宿主环境与独立环境、宿主实现与独立实现
- 混合云应用双活容灾实践
- Socket重叠IO
- 错误请联系管理员文件 index.php,帝国CMS订单、反馈信息、投稿与留言发邮件通知管理员的方法...
- Qt工作笔记-对QObject::connect函数进一步认识(重载)
- Linux基础之while语句
- matlab2c使用c++实现matlab函数系列教程-reshape函数
- python中深浅复制的问题
- GNN + Zero-shot
- NanoPi M1 Plus:Allwinner H3 搭建编译环境、编译主线Uboot、编译主线Linux Kernel 4.14、加Matrix2‘8屏、加Qt
- 计算机控制液位控制系统,计算机控制系统的液位流量串级控制系统设计
- 计算机专业师范类分析,师范生应具备的信息技术能力分析
- 从深圳流水线女工到美国谷歌程序员-一位女孩的奋斗史诗
- python基础入门(变量)
- YS_20190822_图像_Matlab_04
- 找规律填数字(c++基础)
- RPG Maker的引擎分析(一)
热门文章
- Spring+SpringMVC+MyBatis深入学习及搭建(二)——MyBatis原始Dao开发和mapper代理开发
- RunJs使用评测(IE9)
- oracle 11g的em界面按钮乱码的解决办法
- Android中文API (60) —— DatePicker.OnDateChangedListener
- WPF触屏Touch事件在嵌套控件中的响应问题
- 视力检查-2019年2月2日
- psql: FATAL: role “appleyuchi” does not exist与修改默认密码
- 获取png格式的MNIST数据集
- 李航-HMM-直接计算法
- Ubuntu下面Master PDF Editor背景颜色设置