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

  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. 跟我一起学opencv 第三课之图像在opencv中的表示-Mat对象

    1.下面第一章图是一位美女图像,和其他数据一样图像在计算机中也是以二进制存储,下面第二张图 2.在摄像头眼里一幅图像就是一个矩阵或者说是二维数组,数组元素是像素值 3.opencv中以Mat对象表示图 ...

  2. select 如何在选中后获取选中的时是什么元素 ,(原生js)

    在日常开发中,我们经常遇到选择框的业务处理:如何去获取我们所选中的数据呢? 很多小伙伴还不是很熟悉! <!DOCTYPE html> <html lang="en" ...

  3. “挑三拣四”地学一学Java I/O

    古人云:“读书破万卷,下笔如有神”.也就是说,只有大量的阅读,写作的时候才能风生水起——写作意味着输出(我的知识传播给他人),而读书意味着输入(从他人的知识中汲取营养). 对于Java I/O来说,I ...

  4. MySQL系列--3.数据类型和连接查询

    1.存储引擎 数据创建,查询,更新和删除操作都是通过数据引擎来进行的.不同的存储引擎存储限制不同,支持不同的索引机制等. 查询数据库支持的存储引擎 MySQL 5.7.2支持的存储引擎有:InnoDB ...

  5. SQL优化 MySQL版 - 多表优化及细节详讲

    多表优化及细节详讲 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 注:本文章需要MySQL数据库优化基础或观看前几篇文章,传送门: B树索引详讲(初识SQL优化,认识索引):htt ...

  6. Tensorflow之基于LSTM神经网络写唐诗

    最近看了不少关于写诗的博客,在前人的基础上做了一些小的改动,因比较喜欢一次输入很长的开头句,所以让机器人输出压缩为一个开头字生成两个诗句,写五言和七言诗,当然如果你想写更长的诗句是可以继续改动的. 在 ...

  7. XSS 绕过技术

    XSS Cross-Site Scripting(XSS)是一类出现在 web 应用程序上的安全弱点,攻击者可以通过 XSS 插入一 些代码,使得访问页面的其他用户都可以看到,XSS 通常是可以被看作 ...

  8. asp.netcore 深入了解配置文件加载过程

    前言     配置文件中程序运行中,担当着不可或缺的角色:通常情况下,使用 visual studio 进行创建项目过程中,项目配置文件会自动生成在项目根目录下,如 appsettings.json, ...

  9. 图像检索(2):均值聚类-构建BoF

    在图像检索时,通常首先提取图像的局部特征,这些局部特征通常有很高的维度(例如,sift是128维),有很多的冗余信息,直接利用局部特征进行检索,效率和准确度上都不是很好.这就需要重新对提取到的局部特征 ...

  10. dubbo-源码分析Consumer

    counsumer使用服务的时候会在xml中配置<dubbo:reference> dubbo在spring.handles里的NamespaceHandle又有如下配置: registe ...