# -*- coding: utf-8 -*-
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import pymysql
import json
import xmltodict
from hashlib import md5
from tornado.options import define, options
####################微信支付异步回调消息########################
WEIXIN_KEY = '8mdRLb1yeesYssfasdfsadfassdaV'
def generate_sign(params):
"""
生成md5签名的参数
"""
if 'sign' in params:
params.pop('sign')
src = '&'.join(['%s=%s' % (k, v) for k, v in sorted(params.items())]) + '&key=%s' % WEIXIN_KEY
return md5(src.encode('utf-8')).hexdigest().upper()
def validate_sign(resp_dict):
"""
验证微信返回的签名
"""
if 'sign' not in resp_dict:
return False
wx_sign = resp_dict['sign']
sign = generate_sign(resp_dict)
if sign == wx_sign:
return True
return False
def handle_wx_response_xml(params):
"""
处理微信支付返回的xml格式数据
"""
try:
resp_dict = xmltodict.parse(params)['xml']
if not resp_dict or len(resp_dict) < 1:
print('resp_dict is zero+++++++++')
return None
return_code = resp_dict.get('return_code')
if return_code == 'SUCCESS': # 仅仅判断通信标识成功,非交易标识成功,交易需判断result_code
if validate_sign(resp_dict):
print('验证成功!!!')
return resp_dict
except Exception as e:
print(e)
return None
return None
def weixinpay_call_back(request):
"""
微信支付回调
:param request: 回调参数
:return:
"""
args = str(request.body,'utf-8')
if args is None:
return None
print(args)
# 验证平台签名
resp_dict = handle_wx_response_xml(args)
if resp_dict is None:
print('签名验证失败!!!')
return None
return resp_dict
def weixinpay_response_xml(params):
"""
生成交易成功返回信息
"""
def generate_response_data(resp_dict):
"""
字典转xml
"""
return xmltodict.unparse({'xml': resp_dict}, pretty=True, full_document=False).encode('utf-8')
return_info = {
'return_code': params,
'return_msg': 'OK'
}
return generate_response_data(return_info)
def weixinpay_sucess_db(dicts):
"""微信支付成功后数据库日志操作"""
if isinstance(dicts,dict):
trade_status = dicts['result_code'] # 业务结果 SUCCESS/FAIL
trade_no = dicts['out_trade_no'] # 商户订单号
if trade_status == "SUCCESS":
appid = dicts['appid'] # 应用ID
bank_type = dicts['bank_type'] # 付款银行
cash_fee = dicts['cash_fee'] # 现金支付金额(分)
device_info = dicts['device_info'] # 微信支付分配的终端设备号
fee_type = dicts['fee_type'] # 货币种类
gmt_create = dicts['time_end'] # 支付完成时间
total_amount = int(dicts['total_fee']) / 100 # 总金额(单位由分转元)
trade_type = dicts['trade_type'] # 交易类型
out_trade_no = dicts['transaction_id'] # 微信支付订单号
seller_id = dicts['mch_id'] # 商户号
openid = dicts['openid'] # 用户标识
update_sql = ''' update weixin_trade set trade_status='{trade_status}', appid='{appid}', ''' + \
'''seller_id='{seller_id}', openid='{openid}', total_amount='{total_amount}',''' + \
'''out_trade_no='{out_trade_no}', gmt_create='{gmt_create}', '''+ \
'''device_info='{device_info}', trade_type='{trade_type}', bank_type='{bank_type}', ''' + \
'''fee_type='{fee_type}', cash_fee='{cash_fee}' where trade_no='{trade_no}' '''
update_sql = update_sql.format(
trade_status=trade_status,
appid=appid,
seller_id=seller_id,
openid=openid,
total_amount=total_amount,
out_trade_no=out_trade_no,
gmt_create=gmt_create,
device_info=device_info,
trade_type=trade_type,
bank_type=bank_type,
fee_type=fee_type,
cash_fee=cash_fee,
trade_no=trade_no)
print(update_sql)
#写数据库
def weixin_rollback(request):
"""
【API】: 微信宝支付结果回调接口,供微信服务端调用
"""
try:
# 支付异步回调验证
data = weixinpay_call_back(request)
if data:
print('微信支付返回====={0}'.format(data))
res = "success"
trade_status = data['result_code'] # 业务结果 SUCCESS/FAIL
out_trade_no = data['out_trade_no'] # 商户订单号
if trade_status == "SUCCESS":
weixinpay_sucess_db(data)
device_info = data['device_info'] # 微信支付分配的终端设备号
# 如果状态是支付成功则发放物品
hall = KBEngine.globalData["Halls"]
if hall:
player_data = hall.GetPlayerByDbId(int(device_info))
if player_data:
player = player_data.entityCall
if player:
print('微信发放奖品到客户端,订单号======%s' % out_trade_no)
player.GmBkCmd({'cmd':'PayReward','Order_id':out_trade_no})
else:
print('找不到玩家++++++++')
else:
res = "error: pay failed! "
status = 0
err_code = data['err_code'] # 错误代码
err_code_des = data['err_code_des'] # 错误代码描述
else:
res = "error: verify failed! "
except Exception as e:
print(e)
res='err:exception==='
finally:
return weixinpay_response_xml(res)
class WeChatPayNotify(tornado.web.RequestHandler):
"""微信支付回调"""
def post(self):
"""
【API】: 微信宝支付结果回调接口,供微信服务端调用
"""
self.write(weixin_rollback(self.request))
class WeChatPay(tornado.web.RequestHandler):
def post(self):
to_client={}
for k,v in self.request.arguments.items():
to_client[k] = str(v[0],encoding='utf-8')
pid = to_client.pop('pid')
if isinstance(pid,str):
pid = int(pid)
self.write('')