Python对接支付宝支付自实现

# -*- coding: utf-8 -*-

import base64
import json
import urllib.parse
from datetime import datetime import requests
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding class AliPayException(Exception):
def __init__(self, data):
super(AliPayException, self).__init__()
self.data = data def __str__(self):
return "alipay - {}".format(self.data) def __unicode__(self):
return u"alipay - {}".format(self.data) class AliPayVerifyException(AliPayException):
def __init__(self, msg, data):
super(AliPayVerifyException, self).__init__('alipay verify except - {}:{}'.format(msg, data)) class AliPay:
def __init__(self, **kwargs):
"""
:param kwargs:
url: 请求地址
notify_url: 支付宝服务器主动通知商户服务器里指定的页面http/https路径
app_id: 支付宝分配给开发者的应用ID
sign_type: 商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2
app_private_key: 签名私钥
"""
self._app_id = kwargs['app_id']
self._seller_id = kwargs['seller_id']
self._gateway_url = kwargs['gateway_url']
self._notify_url = kwargs.get('notify_url')
self._sign_type = kwargs.get('sign_type', 'RSA2')
if self._sign_type not in ('RSA', 'RSA2'):
raise Exception('alipay sign_type must `RSA` or `RSA2`')
self._charset = 'utf-8'
self._format = 'json' with open(kwargs['app_private_key']) as f:
self._app_private_key = serialization.load_pem_private_key(
f.read().encode('utf8'),
None,
default_backend()
)
with open(kwargs['public_key']) as f:
self._public_key = serialization.load_pem_public_key(
f.read().encode('utf8'),
default_backend()
) @property
def app_id(self):
return self._app_id @property
def seller_id(self):
return self._seller_id def app_private_sign(self, data):
if self._sign_type == 'RSA':
signature = self._app_private_key.sign(
data.encode('utf8'),
padding.PKCS1v15(),
hashes.SHA1())
else:
signature = self._app_private_key.sign(
data.encode('utf8'),
padding.PKCS1v15(),
hashes.SHA256())
return base64.b64encode(signature).decode('utf8') def sync_verify(self, method, raw_data):
"""
同步验签
:return:
"""
method = method.replace('.', '_') + '_response'
raw_data = raw_data.decode('utf8')
sign_index = raw_data.rfind('sign')
signature = base64.b64decode(raw_data[sign_index + 7: -2])
method_data = raw_data[raw_data.find(method) + len(method) + 2: sign_index - 2]
self._public_key.verify(
signature,
method_data.encode('utf8'),
padding.PKCS1v15(),
hashes.SHA256()) def async_verify(self, data):
"""
异步验签
:return:
"""
sign_data = {}
for k, v in data.items():
if k in ('sign', 'sign_type'):
continue
sign_data[k] = v self._public_key.verify(
base64.b64decode(data['sign']),
'&'.join(['{}={}'.format(item) for item in self.sort_data(sign_data)]).encode('utf8'),
padding.PKCS1v15(),
hashes.SHA256()) @staticmethod
def sort_data(data):
return [(k, data[k]) for k in sorted(data.keys())] def params(self, method, biz_content):
data = {
'app_id': self._app_id,
'method': method,
'format': self._format,
'charset': self._charset,
'sign_type': self._sign_type,
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), # yyyy-MM-dd HH:mm:ss
'version': '1.0',
'biz_content': json.dumps(biz_content, separators=(',', ':'))
}
if self._notify_url:
data['notify_url'] = self._notify_url sign = self.app_private_sign('&'.join(['{}={}'.format(item) for item in self.sort_data(data)])) p = '&'.join(['{}={}'.format(item[0], urllib.parse.quote(item[1])) for item in self.sort_data(data)])
p += '&{}={}}'.format('sign', urllib.parse.quote(sign)) return p def command(self, method, biz_content):
params = self.params(method, biz_content) response = requests.get('%s?%s' % (self._gateway_url, params))
response_raw_data = response.content
response_data = response.json()
alipay_response_data = response_data[method.replace('.', '_') + '_response']
if alipay_response_data.get('code', '10000') != '10000':
raise AliPayException(alipay_response_data)
self.sync_verify(method, response_raw_data)
return alipay_response_data if __name__ == '__main__':
alipay = AliPay(**{
'app_id': '...',
'seller_id': '...',
'gateway_url': 'https://openapi.alipaydev.com/gateway.do',
'notify_url': '...',
'app_private_key': 'path to private_key.pem',
'public_key': 'path to public_key.pem'
})
biz_content = {
'out_trade_no': "111",
'total_amount': 0.01,
'subject': "test",
}
alipay.command('alipay.trade.precreate', biz_content)

Python对接支付宝支付自实现的更多相关文章

  1. python调用支付宝支付接口

    python调用支付宝支付接口详细示例—附带Django demo代码   项目演示: 一.输入金额 二.跳转到支付宝付款 三.支付成功 四.跳转回自己网站 在使用支付宝接口的前期准备: 1.支付宝公 ...

  2. Django 对接 支付宝支付, 回调

    平台 点击这里进入 蚂蚁金服开放平台 沙箱 点击这里进入 沙箱环境 初始界面 设置公钥 下载创建秘钥工具 1.  进入文档中心 这里 2. 选中 电脑网站支付 3. 进入后选中 API 列表 中的 统 ...

  3. tp5对接支付宝支付简单集成

    对于每个刚开始工作的新手来说,无论支付宝支付还是微信支付都是跑不掉的一个小门槛. 在加上本人比较技术比较渣(比较懒导致的),不太喜欢引用那么大的SDK,于是就简单集成了一下支付宝的支付. 但也只是只有 ...

  4. python调用支付宝支付接口详细示例—附带Django demo代码

    项目演示: 一.输入金额 二.跳转到支付宝付款 三.支付成功 四.跳转回自己网站 在使用支付宝接口的前期准备: 1.支付宝公钥 2.应用公钥 3.应用私钥 4.APPID 5.Django 1.11. ...

  5. springboot项目对接支付宝支付

    支付宝对接文档 一.准备工作 1. 首先要到 蚂蚁金服开发者中心 https://openhome.alipay.com/platform/home.htm 注册商家账户,并认证. 2.下载java版 ...

  6. python - 对接微信支付(PC)和 注意点

    注:本文仅提供 pc 端微信扫码支付(模式一)的示例代码. 关于对接过程中遇到的问题总结在本文最下方. 参考: 官方文档,    https://blog.csdn.net/lm_is_dc/arti ...

  7. Thinkcmf对接支付宝支付和获取用户信息

    一.         登录支付宝开放平台 平台地址:https://open.alipay.com/ 二.         创建应用并申请上线 登录后,[进入我的开放平台],依次点击[开发者中心]-& ...

  8. Django中对接第三方支付(支付宝)实现支付的流程

    1. 业务逻辑准备 1. 使用沙箱提供的商家环境 沙箱环境:是支付宝提供给开发者的模拟支付的环境 沙箱应用:https://docs.open.alipay.com/200/105311 沙箱账号:h ...

  9. django中使用事务以及接入支付宝支付功能

    之前一直想记录一下在项目中使用到的事务以及支付宝支付功能,自己一直犯懒没有完,趁今天有点兴致,在这记录一下. 商城项目必备的就是支付订单的功能,所以就会涉及到订单的保存以及支付接口的引入.先来看看订单 ...

随机推荐

  1. Android中的Parcel机制(上)

    一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化--,其作用是能将数据对象存入字节流当中,在需要时重新生成对象.主要应用是利用外部存储设备保存对象状态, ...

  2. linux中hadoop组件启动日志存放问题

    如果是nohup xxxx &的话会在当前目录下生成一个nohup文件存放当前出现所有的日志,&表示后台启动: 当然你也可以将日志存放在>/dev/null表示当前日志存放的位置 ...

  3. CF696B Puzzles(期望dp)

    传送门 解题思路 比较有意思的一道题.首先假如这个点\(x\)只有\(1\)个儿子\(u\),那么显然可得\(dp[u]=dp[x]+1\).继续如果多加一个儿子\(p\),那么\(p\)在\(u\) ...

  4. NX二次开发-UFUN计时函数UF_end_timer

    1 NX9+VS2012 2 3 #include <uf.h> 4 #include <uf_modl.h> 5 6 7 UF_initialize(); 8 9 //计时开 ...

  5. Linux命令(2):cat

    cat命令是一个文本连接和查看的命令,用于文件的输出显示. 三大功能 一次显示整个文件. $ cat filename 从键盘创建一个文件.只能创建新文件,不能编辑已有文件. $ cat > f ...

  6. Openstack Paste.ini 文件详解

    目录 目录 pasteini 配置文件详解 composite pipeline filter app DEFAULT server Request 被 pasteini 处理的流程 如何加载 pas ...

  7. 2、http请求与http响应

    我们在接口测试过程中,可能会用http协议,webservice协议,当然用的较多的还是http协议,webservice协议在此不做过多介绍,我们先了解一下http协议,然后重点介绍http请求与响 ...

  8. java 8 lambda函数

    1 为什么要引进lambda函数 可以简化编码,将事情更多的交给编译器,让编译器帮我们推断我们写的代码的完整形式. 2 lambda函数的语法 2.1 -> (arg1, arg2) -> ...

  9. n-map安装实操

    强烈建议大家从官网下载nmap,而不是其他的第三方.官网地址:https://nmap.org/download.html 打开是这样的,感觉有点阴森森的色调.BTW,谁能逃得过真香定律呢. wind ...

  10. JAVA利用JXL导出 EXCEL (在原有的excel模板上把数据导到excel上)

    添加依赖 <dependency> <groupId>net.sourceforge.jexcelapi</groupId> <artifactId>j ...