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 json class AliPay(object):
"""
支付宝支付接口(PC端支付接口)
""" def __init__(self, appid, app_notify_url, app_private_key_path,
alipay_public_key_path, return_url, debug=False):
self.appid = appid
self.app_notify_url = app_notify_url
self.app_private_key_path = app_private_key_path
self.app_private_key = None
self.return_url = return_url
with open(self.app_private_key_path) as fp:
self.app_private_key = RSA.importKey(fp.read())
self.alipay_public_key_path = alipay_public_key_path
with 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_url
data["return_url"] = self.return_url return data def 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_string def 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_key
signer = PKCS1_v1_5.new(key)
signature = signer.sign(SHA256.new(unsigned_string))
# base64 编码,转换为unicode表示并移除回车
sign = encodebytes(signature).decode("utf8").replace("\n", "")
return sign def _verify(self, raw_content, signature):
# 开始计算签名
key = self.alipay_public_key
signer = PKCS1_v1_5.new(key)
digest = SHA256.new()
digest.update(raw_content.encode("utf8"))
if signer.verify(digest, decodebytes(signature.encode("utf8"))):
return True
return False def 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 views urlpatterns = [
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 AliPay def 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里面的类AliPay
alipay = 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

支付宝接口流程:

python调用支付宝支付接口的更多相关文章

  1. python调用支付宝支付接口详细示例—附带Django demo代码

    项目演示: 一.输入金额 二.跳转到支付宝付款 三.支付成功 四.跳转回自己网站 在使用支付宝接口的前期准备: 1.支付宝公钥 2.应用公钥 3.应用私钥 4.APPID 5.Django 1.11. ...

  2. 调用支付宝第三方接口(沙箱环境) SpringMVC+Maven

    一.蚂蚁金服开放平台的操作 网址:https://open.alipay.com/platform/home.htm 支付宝扫码登陆

  3. 关于python调用zabbix api接口

    因公司业务需要,引进了自动化运维,所用到的监控平台为zbbix3.2,最近正在学习python,计划使用python调用zabbix api接口去做些事情,如生成报表,我想最基本的是要取得zabbix ...

  4. python调用C语言接口

    python调用C语言接口 注:本文所有示例介绍基于linux平台 在底层开发中,一般是使用C或者C++,但是有时候为了开发效率或者在写测试脚本的时候,会经常使用到python,所以这就涉及到一个问题 ...

  5. Python对接支付宝支付自实现

    Python对接支付宝支付自实现 # -*- coding: utf-8 -*- import base64 import json import urllib.parse from datetime ...

  6. web页面调用支付宝支付

    web页面调用支付宝支付 此文章是前端单独模拟完成支付,若在线上环境则需要后台配合产生签名等参数 在蚂蚁金服开放平台申请沙箱环境 将沙箱环境中的密钥.应用网关.回调地址补全,生成密钥的方法在此 配置好 ...

  7. 调用支付宝PHP接口API实现在线即时支付功能(UTF-8编码)

    这次在项目中要实现订单功能,所以要完成在线支付,在线支付一般有网银支付和第三方支付(支付宝.paypal等)这两种途径,未简单起见,先完成支付宝在线支付功能,由于项目基于Yii框架,且使用UTF-8编 ...

  8. 25-javaweb接入支付宝支付接口

    想熟悉支付宝接口支付,后面可能会用,不如在课设中试试手.好吧听说支付宝不微信支付要简单些,就拿支付宝的先练下手吧. 基本学习流程,百度一下,找篇博客看下. 推荐下面这个篇博客,讲的挺好的,复制过来. ...

  9. thinkphp3.2接入支付宝支付接口(PC端)

    下载支付宝接口包    点击这里        提取密码:aryp 整个接口核心类文件 alipay.config.php是相关参数的配置文件 alipayapi.php 是支付宝接口入口文件 not ...

随机推荐

  1. Jmeter实时监控+SpringBoot接口性能实战

    性能测试 Jmeter实时监控+SpringBoot接口性能实战 自动化 SpringBoot Java Jmeter实时监控+SpringBoot接口性能实战 一.实验目的及实验环境 1.1.实验目 ...

  2. dubbo webservice 区别

    DUBBO中可以设置采用webservice方式,进行数据交互. 随着交互系统的增多,这种方式对系统的侵入性越来越大,关系更为错综复杂,很容易出错. 较适用与外围系统通信,若是内部系统间则会出现以上较 ...

  3. [HNOI2012]矿场搭建 题解

    [HNOI2012]矿场搭建 时间限制: 1 Sec  内存限制: 128 MB 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出 ...

  4. 使用flink Table &Sql api来构建批量和流式应用(2)Table API概述

    从flink的官方文档,我们知道flink的编程模型分为四层,sql层是最高层的api,Table api是中间层,DataStream/DataSet Api 是核心,stateful Stream ...

  5. Linux关闭进程。

    一.shell命令根据端口后关闭指定进程. $(netstat -nlp | | awk '{print $7}' | awk -F"/" '{ print $1 }') nets ...

  6. GitHub使用整理——从开始到上传项目

    前期准备 首先是github官网: https://github.com/ 下载github工具: https://git-for-windows.github.io/ 进入github创建一个新的项 ...

  7. solidity智能合约中tx.origin的正确使用场景

    简介 tx.origin是Solidity的一个全局变量,它遍历整个调用栈并返回最初发送调用(或事务)的帐户的地址.在智能合约中使用此变量进行身份验证会使合约容易受到类似网络钓鱼的攻击. 但针对tx. ...

  8. 用MATLB仿真一个单闭环控制量,同时还存在两个开环控制变量的阶跃响应曲线。(自动控制方法是PID中的P控制。通过查表法直接给开环参数稳态最佳的大小)

    实际项目背景:甘肃省,航天510所的LIPS100电推力器.一共有三个控制变量,开环控制变量是:Ia(阳极电流).mmrf(阳极主流率) 这个阳极主流率是阀门变量,不能够突变,模拟用(大学一年级课,电 ...

  9. centos7 linux下增加swap虚拟内存分区大小

    此方法不限于centos,linux均适用 最近在服务器上部署了一个java项目,java进程经常性莫名被自动Kill,首先java程序是没有报错的,那么我想可能是内存不足的原因,因为4G内存的服务上 ...

  10. wordpress备份和还原和迁移

    备份用mysqldump -u root -p test person > backup.sql 还原用mysql -u root -p < ./backup.sql 数据库密码修改后怎么 ...