python调用支付宝支付接口流程


Posted in Python onAugust 15, 2019

项目演示:

一、输入金额

python调用支付宝支付接口流程

二、跳转到支付宝付款

python调用支付宝支付接口流程

三、支付成功

python调用支付宝支付接口流程

四、跳转回自己网站

python调用支付宝支付接口流程

在使用支付宝接口的前期准备:

1、支付宝公钥

2、应用公钥

3、应用私钥

4、APPID

5、Django 1.11.11 环境

1234均由阿里开放平台生成

如果你不是商户或者你只是想测试,阿里提供了沙箱环境供测试

沙箱环境下的商户账号和用户账号、支付宝app都是沙箱版的,不能用实际账号

这时候我们需要去阿里开放平台去生成一些1234参数

注册网址: https://openhome.alipay.com/platform/appDaily.htm?tab=info

python调用支付宝支付接口流程

点击设置应用公钥

python调用支付宝支付接口流程

下载签名生成工具,解压后找到 RSA签名验签工具.bat 文件打开

python调用支付宝支付接口流程

这个工具会自动保存应用公钥和应用私钥到 RSA密钥 文件夹

将应用公钥拷贝到网站窗口,点保存,在原应用公钥按钮旁就会自动生成支付宝公钥

我们需要将网站窗口生成的支付宝公钥也新建一个txt文件放到这里面

继续操作

修改三个txt文件的名字为英文,如:app_public.txt \  app_private.txt  \ alipay_public.txt

修改三个txt文件内容为固定格式:

-----BEGIN PUBLIC KEY-----  # 加上这行
        密钥部分
-----END PUBLIC KEY-----   # 同上

将三个文件copy到django项目下新建文件夹中,如:

python调用支付宝支付接口流程

你也可以放在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调用支付宝支付接口流程

总结

以上所述是小编给大家介绍的python调用支付宝支付接口流程,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
Python实现遍历数据库并获取key的值
May 17 Python
Python网络爬虫出现乱码问题的解决方法
Jan 05 Python
Python基于Matplotlib库简单绘制折线图的方法示例
Aug 14 Python
Python统计单词出现的次数
Apr 04 Python
python实现简易内存监控
Jun 21 Python
python检测文件夹变化,并拷贝有更新的文件到对应目录的方法
Oct 17 Python
Python从数据库读取大量数据批量写入文件的方法
Dec 10 Python
PythonWeb项目Django部署在Ubuntu18.04腾讯云主机上
Apr 01 Python
使用python模拟命令行终端的示例
Aug 13 Python
python 实现矩阵按对角线打印
Nov 29 Python
python 如何调用 dubbo 接口
Sep 24 Python
Python Matplotlib绘制条形图的全过程
Oct 24 Python
Python使用字典实现的简单记事本功能示例
Aug 15 #Python
Flask框架学习笔记之模板操作实例详解
Aug 15 #Python
Flask框架学习笔记之消息提示与异常处理操作详解
Aug 15 #Python
python打造爬虫代理池过程解析
Aug 15 #Python
使用selenium和pyquery爬取京东商品列表过程解析
Aug 15 #Python
如何爬取通过ajax加载数据的网站
Aug 15 #Python
Python K最近邻从原理到实现的方法
Aug 15 #Python
You might like
四月新番又没了,《Re:从零开始的异世界生活》第二季延期至7月播出
2020/05/06 日漫
关于url地址传参数时字符串有回车造成页面脚本赋值失败的解决方法
2013/06/28 PHP
PHP调试及性能分析工具Xdebug详解
2017/02/09 PHP
使用PHPStorm+XDebug搭建单步调试环境
2017/11/19 PHP
PHP 多任务秒级定时器的实现方法
2018/05/13 PHP
教你如何解密js/vbs/vbscript加密的编码异处理小结
2008/06/25 Javascript
jquery $.each 和for怎么跳出循环终止本次循环
2013/09/27 Javascript
js实现幻灯片播放图片示例代码
2013/11/07 Javascript
js 操作select与option(示例讲解)
2013/12/20 Javascript
Jquery插件easyUi表单验证提交(示例代码)
2013/12/30 Javascript
jQuery实现鼠标滑过点击事件音效试听
2015/08/31 Javascript
实例解析jQuery插件EasyUI最常用的表单验证规则
2015/11/29 Javascript
ionic js 复选框 与普通的 HTML 复选框到底有没区别
2016/06/06 Javascript
Angularjs之filter过滤器(推荐)
2016/11/27 Javascript
easyui-edatagrid.js实现回车键结束编辑功能的实例
2017/04/12 Javascript
详解element-ui表格中勾选checkbox,高亮当前行
2019/09/02 Javascript
vue路由守卫,限制前端页面访问权限的例子
2019/11/11 Javascript
vue实例的选项总结
2020/06/09 Javascript
node.js基础知识汇总
2020/08/25 Javascript
[06:35]2014DOTA2国际邀请赛 老男孩梦圆西雅图中国军团世界最强
2014/07/22 DOTA
浅谈Python基础之I/O模型
2017/05/11 Python
python读取word文档,插入mysql数据库的示例代码
2018/11/07 Python
python如何调用字典的key
2020/05/25 Python
Python中zip函数如何使用
2020/06/04 Python
基于python调用jenkins-cli实现快速发布
2020/08/14 Python
酒店管理毕业生自荐信
2014/05/25 职场文书
物业品质提升方案
2014/06/08 职场文书
学校联谊协议书
2014/09/16 职场文书
法定代表人授权委托书范本
2014/10/07 职场文书
学习保证书
2015/01/17 职场文书
二手车转让协议书
2015/01/29 职场文书
委托函范文
2015/01/29 职场文书
事业单位聘任报告
2015/03/02 职场文书
2019年度政务公开考核工作总结模板
2019/11/11 职场文书
html form表单基础入门案例讲解
2021/07/15 HTML / CSS
spring cloud 配置中心native配置方式
2021/09/25 Java/Android