一.蚂蚁金服开发平台申请测试账号

  a. 登陆蚂蚁金服开放平台https://open.alipay.com/platform/manageHome.htm,在“开发中心”—“研发服务”下拉处选择沙箱作为测试环境。

  

  b. 填写相关信息,成功申请沙箱账号后进入沙箱环境页面

  

  c.下载沙箱钱包(目前仅支持安卓手机)

  

  d. 使用沙箱账号处的买家账号登陆下载好的沙箱钱包

  

二.制作公钥和密钥

  a.制作应用私钥和公钥

    在沙箱应用处点击查看应用公钥

    

    在显示的应用公钥处点击修改

    

     在点击查看密钥生成方法

    

    

    根据教程生成密钥和公钥

    

    

    得到一个RSA密钥文件夹,里面有两个文件

    

  b. 制作支付宝公钥

    将应用公钥复制上传,点击保存会自动生成支付宝公钥

    

      

    查看支付宝公钥

      

三.Django程序开发

  a.创建一个django项目

    

  b.配置支付宝公钥和应用私钥

    在私钥和公钥头围加上标记便于python识别

    

  c.代码编写

    首先安装依赖  pip3 install pycryptodome

    SDK官方加密代码,可以在github上找到

# _*_ 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.py

from django.contrib import admin
from django.urls import path
from api import views urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('result/', views.pay_result),
path('update_order/', views.update_order), ]

urls.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 utils.alipay import AliPay def aliPay():
obj = AliPay(
appid="", # 支付宝沙箱里面的APPID
app_notify_url="http://127.0.0.1:8800/update_order/", # 如果支付成功,支付宝会向这个地址发送POST请求(校验是否支付已经完成),此地址要能够在公网进行访问
return_url="http://127.0.0.1:8800/result/", # 如果支付成功,重定向回到你的网站的地址。
alipay_public_key_path="keys/alipay_public_2048.txt", # 支付宝公钥
app_private_key_path="keys/app_private_2048.txt", # 应用私钥
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('支付失败')

views.py

  d.进行测试

    启动项目,访问index页面,输入支付金额,点击支付

    

    使用下载的沙箱钱包扫描付款

    

 

   付款成功

  

  

  最后会重定向到return_url

    

注意:配置文件信息可以在setting中设置,要完成全部测试需要有一个公网IP和服务器,来测试支付宝向app_notify_url发送的POST请求

ALLOWED_HOSTS = ['*', ]
# 支付相关配置
APPID = "***6082500309412"
NOTIFY_URL = "http://127.0.0.1:8800/update_order/"
RETURN_URL = "http://127.0.0.1:8800/pay_result/"
PRI_KEY_PATH = "keys/app_private_2048.txt"
PUB_KEY_PATH = "keys/alipay_public_2048.txt"

  

  

  

  

Python支付宝在线支付API的更多相关文章

  1. 第四百零三节,python网站在线支付,支付宝接口集成与远程调试,

    第四百零三节,python网站在线支付,支付宝接口集成与远程调试, windows系统安装Python虚拟环境 首先保证你的系统已经安装好了Python 安装virtualenv C:\WINDOWS ...

  2. php支付宝在线支付接口开发教程【转】

    php支付宝在线支付接口开发教程 这篇文章主要为大家详细介绍了php支付宝在线支付接口开发教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下   1.什么是第三方支付 所谓第三方支付,就是一些和各 ...

  3. ASP.NET MVC Filters 4种默认过滤器的使用【附示例】 数据库常见死锁原因及处理 .NET源码中的链表 多线程下C#如何保证线程安全? .net实现支付宝在线支付 彻头彻尾理解单例模式与多线程 App.Config详解及读写操作 判断客户端是iOS还是Android,判断是不是在微信浏览器打开

    ASP.NET MVC Filters 4种默认过滤器的使用[附示例]   过滤器(Filters)的出现使得我们可以在ASP.NET MVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响 ...

  4. php实现支付宝在线支付和扫码支付demo

    ### php实现支付宝在线支付和扫码支付demo 背景:在做一个公众号时增加了h5端,需要接入支付,非微信环境,选择了支付宝,以下简单记录下实现过程,并做了简单的封装,拿来即可使用,注意:本项目只是 ...

  5. Python实现支付宝在线支付

    windows系统安装Python虚拟环境 首先保证你的系统已经安装好了Python 安装virtualenv C:\WINDOWS\system32>pip3 install virtuale ...

  6. .net实现支付宝在线支付

    流程参考<实物商品交易服务集成技术文档2.0.pdf>网关地址http://paytest.rupeng.cn/AliPay/PayGate.ashx 网关参数说明:partner:商户编 ...

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

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

  8. 微信小程序在线支付功能使用总结

    最近需要在微信小程序中用到在线支付功能,于是看了一下官方的文档,发现要在小程序里实现微信支付还是很方便的,如果你以前开发过服务号下的微信支付,那么你会发现其实小程序里的微信支付和服务号里的开发过程如出 ...

  9. 支付宝电脑支付沙箱配置(JAVA)

    支付宝电脑支付API地址:https://docs.open.alipay.com/270/105899/.支付宝提供了沙箱环境提供测试,具体配置步骤如下 1.先下载测试DEMO工程 下载地址:htt ...

随机推荐

  1. dubbo 序列化机制之 hessian2序列化实现原理分析

    对于远程通信,往往都会涉及到数据持久化传输问题.往大了说,就是,从A发出的信息,怎样能被B接收到相同信息内容!小点说就是,编码与解码问题! 而在dubbo或者说是java的远程通信中,编解码则往往伴随 ...

  2. 查看网卡及对应的IP、MAC

    #!/bin/bash# judge OS OS_release=`cat /etc/redhat-release | awk '{print $(NF-1)}'|cut -c 1`# To obta ...

  3. PHP——isset和empty

    前言 对于这两个PHP函数大家肯定都很熟悉,但是其二者的区别又有那些呢? 对比 isset  | 检测变量是否被设置过 1. 变量不存在,返回FALSE 2. 变量存在且其值为NULL,返回FALSE ...

  4. jquery删除内容是动态修改序号

    如图,点击删除图标的时候要删除当前的一条记录,同时界面上的序号要动态的排列好 以下是html结构: jquery实现思路: 首先,需要获取到当前要删除盒子的序号$indexCur,然后遍历父盒子,取出 ...

  5. .NET Core微服务之基于Steeltoe使用Zipkin实现分布式追踪

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 =>  Steeltoe目录快速导航: 1. 基于Steeltoe使用Spring Cloud Eureka 2. 基于Steelt ...

  6. 从零开始学习PYTHON3讲义(九)字典类型和插入排序

    <从零开始PYTHON3>第九讲 第六讲.上一讲我们都介绍了列表类型.列表类型是编程中最常用的一种类型,但也有挺明显的缺陷,比如: data = [5,22,34,12,87,67,3,4 ...

  7. 学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  8. sql的查询语句的总结

    一:基本的查询sql 1:基本常用查询 select * from student; --select select all sex from student; --all 查询所有 select d ...

  9. EF 外键不显示、如何让外键显示!增、删、改 操作时,外键不显示,只显示导航属性!

    一.问题描述:EF 外键不显示.如何让外键显示!增.删.改 操作时,外键不显示,只显示导航属性! EF 添加.增加.插入数据时,外键不显示! 二.解决方案:在根据数据库生成模型的时候,选中“在模型中” ...

  10. 自己实现的typeOf函数1

    自己实现的typeOf函数:返回传入参数的类型 主要用于解决,js自带的typeof返回结果不精确:Ext JS中typeOf对字符串对象.元素节点.文本节点.空白文本节点判断并不准确的问题 js代码 ...