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

  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. ubuntu-18.04 设置开机启动脚本-亲测有效

    ubuntu-18.04不能像ubuntu14一样通过编辑rc.local来设置开机启动脚本,通过下列简单设置后,可以使rc.local重新发挥作用. 2.将下列内容复制进rc-local.servi ...

  2. java常用API的总结(1)

    本篇是对于这一段时间以来接触到的常用api的一些总结,便于以后的查阅.... 一.正则表达式 对于正则表达式,我的感觉就是当我们在做某些题的时候正则表达式会省去我们很多的时间,并且正则表达式的使用格式 ...

  3. ASP.NET Core中使用GraphQL - 第二章 中间件

    前文:ASP.NET Core中使用GraphQL - 第一章 Hello World 中间件 如果你熟悉ASP.NET Core的中间件,你可能会注意到之前的博客中我们已经使用了一个中间件, app ...

  4. springcloud~Eureka实例搭建

    服务端 build.gradle配置 dependencies { compile('org.springframework.cloud:spring-cloud-starter-netflix-eu ...

  5. debian The type initializer for 'System.Drawing.KnownColors' threw an exception

     Change the "System.Drawing" reference of "CoreCompat.System.Drawing"if you thro ...

  6. Matlab图像处理常用基本函数

    之前用Matlab做图像处理工作时,用到什么函数就查什么函数,从没做过系统的总结,再做的时候又要去查,所以总结还是有必要的~ 为了方便,在此只列出函数名和基本用法,如不特别指出,不详细说明参数,辅助h ...

  7. 微信小程序开发03-这是一个组件

    编写组件 基本结构 接上文:微信小程序开发02-小程序基本介绍 我们今天先来实现这个弹出层: 之前这个组件是一个容器类组件,弹出层可设置载入的html结构,然后再设置各种事件即可,这种组件有一个特点: ...

  8. 浅谈基于Linux的Redis环境搭建

    本篇文章主要讲解基于Linux环境的Redis服务搭建,Redis服务配置.客户端访问和防火强配置等技术,适合具有一定Linux基础和Redis基础的读者阅读. 一  Redis服务搭建 1.在根路径 ...

  9. Centos7+nginx+keepalived集群及双主架构案例

    目录简介 一.简介 二.部署nginx+keepalived 集群 三.部署nginx+keepalived双主架构 四.高可用之调用辅助脚本进行资源监控,并根据监控的结果状态实现动态调整 一.简介 ...

  10. Revit通过API创建共享参数

    Revit共享参数是通过创建一个.txt类型的文件来保存相关信息,一旦与项目保存完毕之后,共享参数也就变成了项目参数(项目参数无法通过API创建),项目参数是保存在Revit项目里面的,所以此时这个. ...