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. Unity 中调用Android的JAVA代码

    首先我们要创建一个android项目 因为项目需要使用Unity提供的接口,所以需要将接口classes.jar引入至当前工程但中.接口包的所在地,打开Finder->应用程序->Unit ...

  2. Linux/Mac中alias的使用

    最近在设置代理的时候,每次手写不方便,想起linux有个alias命令可以用,防止忘记,这边记录一下 一.alias 设置 1.设置别名 proxy # 1. # 设置别名前,使用 `type 自定义 ...

  3. POJ2449-A*算法-第k短路

    (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 题意:传送门  原题目描述在最下面.  给你一个有向图,求指定节点间的第k短路. 思路:  先反向跑出从终点开始的到每个节点的最短距离 ...

  4. ionic-CSS:ionic select

    ylbtech-ionic-CSS:ionic select 1.返回顶部 1. ionic select ionic select 的 select 相比原生的要更加美观些.但是弹出的可选选项样式是 ...

  5. (转)poi操作Excel, 各种具体操作和解释

    原文地址http://hi.baidu.com/j_changhong/item/981fa58d05fa755926ebd96b注原文是3.6 此文是3.9 java读取excel文件的顺序是: E ...

  6. kubeadm 安装k8s

    环境要求: 机器名 ip地址 cpu和内存要求 kubernetes-master 10.0.0.11 2c2g(关闭swap) kubernetes-node1 10.0.0.12 2c2g(关闭s ...

  7. uoj213 【UNR #1】争夺圣杯

    题目 设\(f_i\)表示所有长度为\(i\)的区间的最大值的和,求\(\bigoplus \sum_{i=1}^nf_i\) 不难发现随机数据非常好做 由于一个随机序列的前缀最大值期望只会变化\(\ ...

  8. 如何使用Hive集成Solr?

    (一)Hive+Solr简介 Hive作为Hadoop生态系统里面离线的数据仓库,可以非常方便的使用SQL的方式来离线分析海量的历史数据,并根据分析的结果,来干一些其他的事情,如报表统计查询等. So ...

  9. 字典配合split分裂填充

    Sub 配送日报()lastrow = Sheets("运营日报").Range("a1048576").End(xlUp).Rowarr = Sheets(& ...

  10. 查看ubuntu系统的版本信息

    显示如下 Linux version 4.10.0-28-generic (buildd@lgw01-12) linux内核版本号 gcc version 5.4.0 20160609 gcc编译器版 ...