准备工作:

1.银联技术开放平台注册:https://open.unionpay.com/tjweb/acproduct/list?apiservId=448
2.点击网关支付 --> 我要测试 (按照提示下载密钥)
3.安装需要的模块 pip install pyOpenSSL

代码实现:

目录结构

pay.py 文件
import xxx  # 自行导入class UnionPay:"""银联支付接口(PC端)"""def __init__(self,version,mer_id,front_url,back_url,backend_url,cert_path,debug=False):self.version = versionself.mer_id = mer_idself.front_url = front_urlself.back_url = back_urlself.backend_url = backend_urlself.cert = {}self.cert_id = self.__get_cert_id(cert_path)if debug is True:# 支付网关self.gateway = "https://gateway.test.95516.com/gateway/api/frontTransReq.do"# 查询网关self.query_gateway = "https://gateway.test.95516.com/gateway/api/queryTrans.do"else:self.gateway = "https://gateway.95516.com/gateway/api/frontTransReq.do"self.query_gateway = "https://gateway.95516.com/gateway/api/queryTrans.do"def build_request_data(self, order_id, txn_amt, **kwargs):"""构建请求数据:param order_id: 商户订单号:param txn_amt: 交易金额(单位: 分):return:"""request_data = {"version": self.version,  # 版本"encoding": "utf-8",  # 编码"txnType": "01",  # 交易类型  01:消费"txnSubType": "01",  # 交易子类  01:自助消费"bizType": "000201",  # 产品类型  000201:B2C网关支付"frontUrl": self.front_url,  # 前台通知地址"backUrl": self.back_url,  # 后台通知地址 需外网"signMethod": "01",  # 签名方法  01:RSA签名"channelType": "07",  # 渠道类型  07:互联网"accessType": "0",  # 接入类型  0:普通商户直连接入"currencyCode": "156",  # 交易币种  156:人民币"merId": self.mer_id,  # 商户代码"txnAmt": txn_amt,  # 订单金额(单位: 分)"txnTime": datetime.now().strftime("%Y%m%d%H%M%S"),  # 订单发送时间"certId": self.cert_id,"orderId": order_id,"signature": ""}request_data.update(**kwargs)self.get_sign(request_data)return request_datadef pay_url(self, request_data):payment_url = "{}?{}".format(self.backend_url, parse.urlencode(request_data))return payment_urldef pay_html(self, request_data):result = """<html><head><meta http-equiv="Content-Type" content="text/html"charset="utf-8"/></head><body onload="pay_form.submit();"><form id="pay_form" name="pay_form" action="{}" method="post">""".format(self.gateway)for key, value in request_data.items():result += """<input type="hidden" name="{0}" id="{0}" value="{1}"/>""".format(key, value)result = result + """<!-- <input type="submit" type="hidden">--></form></body></html>"""return resultdef get_sign(self, data):"""获取签名:param data::return:"""sha256 = hashlib.sha256(self.build_sign_str(data).encode("utf-8")).hexdigest()private = OpenSSL.crypto.sign(self.cert["pkey"], sha256, "sha256")data["signature"] = str(base64.b64encode(private), encoding="utf-8")def verify_sign(self, data):"""银联回调签名校验"""signature = data.pop('signature')  # 获取签名link_string = self.build_sign_str(data)digest = hashlib.sha256(bytes(link_string, encoding="utf-8")).hexdigest()signature = base64.b64decode(signature)sign_pubkey_cert = data.get("signPubKeyCert", None)try:x509_ert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, sign_pubkey_cert)OpenSSL.crypto.verify(x509_ert, signature, digest, 'sha256')return Trueexcept Exception as exc:return Falsedef verify_query(self, order_num, txn_time):'''验证查询的交易状态:param order_num: 订单号:param txn_time: 交易时间:return: True or False'''request_data = {"version": self.version,"encoding": "utf-8","txnType": "00",  # 00:查询"txnSubType": "00","bizType": "000201","signMethod": "01",  # 签名方法  01:RSA签名"accessType": "0","merId": self.mer_id,"txnTime": txn_time,"orderId": order_num,"certId": self.cert_id,}self.get_sign(request_data)request_data['signature'] = parse.urlencode({'signature': request_data['signature']})[10:]req_string = self.build_sign_str(request_data)res = requests.post(url=self.query_gateway,data=req_string,headers={'content-type': 'application/x-www-form-urlencoded'})if res.status_code != requests.codes.ok:query_status = Falseelse:content = self.parse_arguments(res.content.decode('utf-8'))if content.get('origRespCode', '') == '00':query_status = Trueelse:query_status = Falsereturn query_statusdef __get_cert_id(self, cert_path):"""获取证书ID(签名KEY):param cert_path::return:"""with open(cert_path, "rb") as f:certs = OpenSSL.crypto.load_pkcs12(f.read(), UnionPayConfig.cert_password)x509data = certs.get_certificate()self.cert["certid"] = x509data.get_serial_number()self.cert["pkey"] = certs.get_privatekey()return self.cert["certid"]@staticmethoddef build_sign_str(data):"""排序:param data::return:"""req = []for key in sorted(data.keys()):if data[key] != '':req.append("%s=%s" % (key, data[key]))return '&'.join(req)@staticmethoddef parse_arguments(raw):""":param raw: raw data to parse argument:return:"""data = {}qs_params = parse.parse_qs(str(raw))for name in qs_params.keys():data[name] = qs_params.get(name)[-1]return data
views.py 文件
import xxx  # 自行导入# 充值页面
def pay_page(request):return render(request, 'user/pay_page.html')# 获取一个UnionPay对象
def get_uni_object(uid):uni_pay = UnionPay(version=UnionPayConfig.version,mer_id=UnionPayConfig.mer_id,front_url=UnionPayConfig.front_url + uid + "/",back_url=UnionPayConfig.back_url + uid + "/",backend_url=UnionPayConfig.back_url,cert_path=UnionPayConfig.cert_path,debug=UnionPayConfig.debug,)return uni_pay# 生成订单号(自定义)
def order_num(package_num,uid):'''商品代码后两位+下单时间后十二位+用户id后四位+随机数四位:param package_num: 商品代码:return: 唯一的订单号'''local_time = time.strftime('%Y%m%d%H%M%S',time.localtime(time.time()))[2:]result = str(package_num)[-2:] + local_time +uid[-4:]+str(random.randint(1000,9999))return result# 账户充值(银联)  # uid参数可不传入,此处用于生成订单号
def unipay(request,uid):money = float(request.POST.get('money'))unipay = get_uni_object(uid)query_params = unipay.build_request_data(order_id=order_num('xx',uid),  # 用户购买订单(每次不一样)txn_amt=int(float(money)*100)  # 交易金额 单位分)pay_html = unipay.pay_html(query_params)rsp = HttpResponse()rsp.content = pay_htmlreturn rsp# 充值成功后前台回调(银联)
def uni_back(request,uid):if request.method == "POST":params = request.POST.dict()unipay = get_uni_object(uid)res = unipay.verify_sign(params)if res:if unipay.verify_query(params['orderId'], params['txnTime']):  # 再次查询状态return HttpResponse('充值成功')else:return HttpResponse('充值失败')# 充值成功后后台回调(银联)
def uni_notify(request,uid):if request.method == "POST":params = request.POST.dict()unipay = get_uni_object(uid)res = unipay.verify_sign(params)if res:status = unipay.verify_query(params['orderId'], params['txnTime'])  # 再次查询状态if status:try:updata_data(uid,float(int(params['txnAmt']) / 100))return HttpResponse('ok')except User.DoesNotExist as e:raise eelse:return HttpResponse('')else:params = request.GET.dict()for k,v in params.items():print(k,v,'\n')return HttpResponse('failed')
urls.py 文件
from django.urls import path
from . import viewsapp_name = 'pay'urlpatterns = [path('pay_page/',views.pay_page,name='pay_page'),path('unipay/<str:uid>/',views.unipay,name='unipay'),path('uni_notify/<str:uid>/',views.uni_notify,name='uni_notify'),path('uni_back/<str:uid>/',views.uni_back,name='uni_back'),
]
sittings.py 文件
# 银联支付参数配置
class UnionPayConfig(object):# 银联版本号(固定)version = "5.1.0"# 商户ID(配置项)mer_id = "xxxxxxxxxxx"  # 你的商户id  (正式生产环境需修改)# 前台回调地址(支付成功回调成功)(配置项)(正式生产环境需修改)front_url = "http://127.0.0.1:8000/pay/uni_back/"  # http://公网IP/back/ # 后台回调地址(配置项)(正式生产环境需修改)back_url = "http://127.0.0.1:8000/pay/uni_notify/"  # http://公网IP/notify/ # 证书地址(配置项)(正式生产环境需修改)cert_path = "keys/acp_test_sign.p12" # 证书解密密码(根据实际去调配)(配置项) (正式生产环境需修改)cert_password = "000000"# 是否开启测试模式(默认False)(配置项)(正式生产环境为False)debug = True
效果图


代码参考:
1.https://blog.csdn.net/cnweike/article/details/52669089
2.https://blog.csdn.net/yulei_qq/article/details/49025045
3.https://github.com/jie/unionpay
以上代码仅供参考,如直接用于商用出现任何问题概不负责。

django2.0调用银联支付接口实现银联支付相关推荐

  1. java upopsdk如何使用_UpopSDK 中国银联在线接口,包括支付 查询 。适合电子商务系统 Jsp/Servlet 238万源代码下载- www.pudn.com...

    文件名称: UpopSDK下载 收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 241 KB 上传时间: 2013-08-14 下载次数: 24 提 供 者: dany ...

  2. 如何申请游戏支付接口(三方支付)

    如何申请游戏支付接口(三方支付) 随着科技的发展,各类游戏产品层出不穷,而游戏都离不开充值,充值就需要有相应的游戏支付接口,那么我们如何申请游戏支付接口呢? 一.如何申请游戏支付接口 1.第三方支付接 ...

  3. PrestaShop支付接口-网银在线支付,在线支付收款,外贸收款

    2019独角兽企业重金招聘Python工程师标准>>> 国内第一家支持prestashop中文支付接口网银在线-chinapay 需要请联系QQ:1285872439 PrestaS ...

  4. 第三方支付接口 个人第三方支付接口 第三方支付接口费率

    第三方支付接口 个人第三方支付接口 第三方支付接口费率 支付扫码是现在很多人日常都会有的一个行为,不管是去超市.饭店还是其他地方消费的话都会打开微信扫描商家提供的收款码.不过有很多商家和消费者就发现微 ...

  5. 银联在线php支付接口,ecshop银联在线支付接口插件(官方版)

    分享一个银联在线支付(UPOP)ecshop支付接口的插件,亲自用过.你只需放到ec对应的目录,然后进到后台"支付方式"页面安装就能调用了.希望能对你有用!! 此插件在ecshop ...

  6. 西米支付:如何申请游戏支付接口(三方支付)

    随着科技的发展,各类游戏产品层出不穷,而游戏都离不开充值,充值就需要有相应的游戏支付接口,那么我们如何申请游戏支付接口呢? 一.如何申请游戏支付接口 1.第三方支付接口有哪些? 目前中国国内的第三方支 ...

  7. 怎么对接个人收款支付接口(扫码支付)

    实现个人收款是一件很麻烦的事,可以通过 paybob 注册个人收款接口,帮助签约个人支付宝,微信支付接口(不需要营业执照),几分钟就可以开通,申请开通后,获取商户号和通信密钥,然后开始对接,本章主要说 ...

  8. 电商平台接入第三方支付接口之微信支付接入订单系统

    边做边更新------ 先接入微信接口: 支付方式:用户扫描二维码支付 接口类型:扫码支付之模式二 先copy一份模式二的业务流程时序图 业务流程说明: (1)商户后台系统根据用户选购的商品生成订单. ...

  9. 支付宝企业账户支付接口申请-移动支付

    支付宝支付接口申请入口 https://b.alipay.com/login.htm 如果没有企业账户,点击下图所示的"注册"按钮进行注册,注册步骤很简单,我这里就不介绍了. 有企 ...

最新文章

  1. ffmpeg命令 音频文件格式转换
  2. error: xxxx.o: Relocations in generic ELF (EM: 3)解决办法
  3. tomcat linux dump,Linux下Tomcat常用命令与配置
  4. 【NLP】四万字全面详解 | 深度学习中的注意力机制(三)
  5. 解决vmware报错:Mac OS X is not supported with binary translation.
  6. sqldeveloper不能启动,显示Unable to create an instance of the Java Virtual Machine...的解决办法...
  7. Flutter 入门安装——C#程序喵的Flutter之旅
  8. 初级计算机处理员试题及答案,计算机软考信息技术处理员模拟试题及答案(1)[5]...
  9. 微型计算机咋样插网卡,PCI网卡怎么装及插在哪 PCI网卡安装使用图文教程
  10. 华为2020校招-数字化IT应用工程师-凉经
  11. recovery mode
  12. SQL server中提示对象名无效
  13. 三极管发射极负反馈电阻的原理是什么?为什么就能起到负反馈作用呢
  14. 再一次获取你的WIFI密码(fluxion附视频)
  15. spring_定时任务时间设置详解
  16. 稠密集和疏朗集_康托集为啥不是疏朗集?
  17. 物联网之STM32开发四(中断系统)
  18. React native 照片压缩上传
  19. Python3的基本数据类型
  20. Cesium-1.72学习(中国国界线)

热门文章

  1. python 圆形检测_基于opencv-python的圆形检测
  2. floor puzzles
  3. 用RVIZ2显示毫米波雷达点云
  4. 人力资源案例:薪酬与绩效考核体系建设
  5. sql语句分析是否走索引_SQL Server 索引使用分析(2)- 改善SQL语句,防止索引失效...
  6. 为dev c++配置图形开发环境easyx之mingw32
  7. java和javac版本不一致(三种解决方法)
  8. CYJian的水题大赛[第二弹] U34202 JerryC Loves Driving
  9. RANSAC算法及其代码解析
  10. 高校一键健康打卡及其检测系统