django支付宝支付集成
概要
本文是关于django集成支付宝【电脑网站支付】功能的过程记录。
功能逻辑主要分为两块:
- 用户下单跳转至支付宝支付界面
- 支付成功的回调验证
本文用到的alipay-sdk是基于阿里开发文档http接口请求规则的初步封装,也并非是本人原创。但真实上线门槛略高,需要企业营业执照,对个体程序员不是很友好,而且还要收取0.6%的手续费,不得不吐糟一下。
python 支付接口
# pip install pycryptodome
from datetime import datetime
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from base64 import b64encode, b64decode
from urllib.parse import quote_plus
from urllib.parse import urlparse, parse_qs
from urllib.request import urlopen
from base64 import decodebytes, encodebytes
import json
class AliPay(object):
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.import_key(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)
跳转支付界面
class OrderView(View):
def get(self,request,*args,**kwargs):
total_amount = request.GET.get('total_amount')
subject = request.GET.get('subject')
out_trade_no = request.GET.get('out_trade_no')
# 业务逻辑【保存订单】
# 跳转支付页面
alipay = AliPay(
appid="2016101100660254",
app_notify_url="http://127.0.0.1:8000/checkout/verify/",
app_private_key_path=private_key_path,
alipay_public_key_path=ali_pub_key_path, # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥
debug=True, # 默认False,
return_url="http://127.0.0.1:8000/checkout/verify/"
)
query_params = alipay.direct_pay(
subject=subject, # 商品简单描述
out_trade_no=out_trade_no, # 商户订单号
total_amount=total_amount, # 金额
)
pay_url = "https://openapi.alipaydev.com/gateway.do?{}".format(query_params)
return redirect(pay_url)
回调验证
class AlipayView(View):
def get(self, request):
"""
处理支付宝的return_url返回
:param request:
:return:
"""
processed_dict = {}
for key, value in request.GET.items():
processed_dict[key] = value
sign = processed_dict.pop("sign", None)
alipay = AliPay(
appid="2016101100660254",
app_notify_url="http://127.0.0.1:8000/checkout/verify/",
app_private_key_path=private_key_path,
alipay_public_key_path=ali_pub_key_path, # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
debug=True, # 默认False,
return_url="http://127.0.0.1:8000/checkout/verify/"
)
condition = alipay.verify(processed_dict, sign)
if condition:
# 更改订单状态
return HttpResponse('支付成功')
def post(self, request):
"""
处理支付宝的notify_url
:param request:
:return:
"""
processed_dict = {}
for key, value in request.POST.items():
processed_dict[key] = value
sign = processed_dict.pop("sign", None)
alipay = AliPay(
appid="",
app_notify_url="http://127.0.0.1:8000/checkout/verify/",
app_private_key_path=private_key_path,
alipay_public_key_path=ali_pub_key_path, # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
debug=True, # 默认False,
return_url="http://127.0.0.1:8000/checkout/verify/"
)
condition = alipay.verify(processed_dict, sign)
if condition:
# 更改订单状态
return HttpResponse("支付成功")
关于return_url 和notify_url

django支付宝支付集成的更多相关文章
- iOS支付宝支付集成
概述 iOS支付宝支付集成 详细 代码下载:http://www.demodashi.com/demo/10729.html 支付宝和微信都是业界的老大哥,相信大家都有所觉得文档.SDK都是各种坑吧( ...
- $Django 支付宝支付,微信服务号推送消息 (测试需要把应用程序部署到服务器上)
一 支付宝支付 大概 支付宝支付 正式环境:需要用营业执照去申请商户号,appid 测试环境:沙箱环境:https://openhome.alipay.com/platform/appDaily.ht ...
- Android最新版支付宝支付集成
上次集成支付宝支付已经很久了,今天写东西用到了支付宝支付,就大致写一下流程: 去蚂蚁金服下载最新版的Android&IOS端SDK 全部文档 -- 资源下载 -- App支付客户端 下载后解压 ...
- ios 支付宝支付集成
支付宝支付: 下载官方demo,把需要的framwork下载下来,在自己的工程中,新建文件夹,然后全部塞进去,到build phases中把需要的全部导入,其中xcode7以上需要多导入两个.a文件, ...
- iOS 支付宝支付集成获取私钥
http://doc.open.alipay.com/doc2/apiList?docType=4 登录到支付宝开放平台,下载相关支付宝支付的demo.解压出来有3个文件夹.(服务端demo,客户端 ...
- Django——支付宝支付功能
前期准备 首先我们需要获得支付宝提供的权限与接口,在蚂蚁开放平台进行相关申请:https://openhome.alipay.com/platform/appDaily.htm?tab=info 申请 ...
- 支付宝支付集成,上传RSA公钥一直显示格式错误
碰到同样的问题,支付宝的问题,已有解决方案:https://openhome.alipay.com/platform/keyManage.htm?keyType=partner
- 支付宝支付集成过程中如何生成商户订单号(out_trade_no)
out_trade_no是指商户网站唯一订单号,在商户端唯一,每个商户订单号会对应一个支付宝订单号 ,此订单号由珊瑚自己生成,商户订单号要求64个字符以内.可包含字母.数字.下划线:需保证在商户端不重 ...
- 支付宝支付集成中:refund_fastpay_by_platform_nopwd接口服务器通知验签不通过
在做p2p配资平台,也就是公司的项目,遇到了一个问题:refund_fastpay_by_platform_nopwd接口服务器通知验签不通过 下面是实录: 通知服务器的POST过来的数据: 1.si ...
随机推荐
- Elasticsearch 6.x版本全文检索学习之聚合分析入门
1.什么是聚合分析? 答:聚合分析,英文为Aggregation,是es除搜索功能外提供的针对es数据做统计分析的功能.特点如下所示: a.功能丰富,提供Bucket.Metric.Pipeline等 ...
- CSS学习笔记-背景属性
一.背景尺寸属性: 1.含义: 背景尺寸属性是CSS3中新增的一个属性,专门用于设置背景图片大小 2.格式: 1.1具体像素: backgro ...
- IDEA中GitLab的使用
首先安装git https://git-scm.com/downloads/ 下载对应的版本 下载好了,安装打开 Windows. 打开之后2步走,与git连接 首先选择仓库,进行git init本地 ...
- Python语法速查: 5. 运算符、math模块、表达式
返回目录 (1)一些较容易搞错的运算符 一般简单的如加减乘除之类的运算符就不写了,这里主要列些一些容易搞错或忘记的运算符.运算符不仅仅只有号,有一些英文单词如 in, and 之类,也是运算符,并不是 ...
- npm简单实用
npm包管理工具 npm可以理解为前端的maven,一个包的管理工具 1. 查看npm和node版本 node -v npm -v 2. 初始化项目 npm init 默认配置初始化项目 npm in ...
- 小程序-小菊花loading
界面----交互 wx.showLoading() 显示loading提示框.需主动调用wx.hideLoading()才能关闭提示框 参数: 属性 类型 默认值 必填 说明 title string ...
- RabbitMQ默认情况下不保证每次都把消息传递
有意思,RabbitMQ默认情况下是不保证每次都把消息传递的,很多情况下我们都是这样发送数据的, channel.BasicPublish(QUEUE_NAME, String.Empty, n ...
- 新终端必须source /etc/profile的解决办法,同时解决变色问题
Linux环境变量文件 /etc/profile:在登录时,操作系 统定制用户环境时使用的第一个文件 ,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. /etc /enviro ...
- Java并发编程:Java中的锁和线程同步机制
锁的基础知识 锁的类型 锁从宏观上分类,只分为两种:悲观锁与乐观锁. 乐观锁 乐观锁是一种乐观思想,即认为读多写少,遇到并发写的可能性低,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新 ...
- SQL查询--关于查询的练习题
下面的练习题出自LeetCode:https://leetcode-cn.com/problemset/database/,有兴趣的可以去上面刷刷题 练习题1:超过经理收入的员工 分析: 使用sql ...