# coding=utf-8 import json import xmltodict from django.db import transaction from django.http import HttpResponse from rest_framework.views import APIView from utils.wx.WXBizMsgCrypt import WXBizMsgCrypt from utils.exceptions import CustomError from utils import response_ok, response_error from utils.wechatpay import WechatPayNotify from apps.log.models import BizLog from apps.WechatTp.models import WechatTp from apps.WechatApplet.models import WechatApplet from apps.tenant.models import Tenant from apps.tenant.biz import TenantBiz class CallbackAuthorize(APIView): '''验证票据(component_verify_ticket)在第三方平台创建审核通过后,微信服务器会向其 ”授权事件接收URL” 每隔 10 分钟以 POST 的方式推送 component_verify_ticket 接收 POST 请求后,只需直接返回字符串 success。 为了加强安全性,postdata 中的 xml 将使用服务申请时的加解密 key 来进行加密''' def post(self, request): sMsgSignature = request.GET.get('msg_signature') sTimeStamp = request.GET.get('timestamp') sNonce = request.GET.get('nonce') sPostData = request.body.decode('utf-8') try: component = WechatTp.getDefault() if component: appid = component.getAppid() msg_crypt = WXBizMsgCrypt(component.getToken(), component.getEncodeKey(), appid) ret, decryp_xml = msg_crypt.DecryptMsg(sPostData, sMsgSignature, sTimeStamp, sNonce) data = json.loads(json.dumps(xmltodict.parse(decryp_xml)))['xml'] if data['AppId'] == appid: if data['InfoType'] == 'component_verify_ticket': component.refreshVerifyTicket(data['ComponentVerifyTicket']) elif data['InfoType'] == 'unauthorized': authorizer_appid = data['AuthorizerAppid'] authorizer = WechatApplet.getByAppidAndComponentAppid(authorizer_appid, appid) if authorizer: authorizer.revoke() except: pass return HttpResponse('success') class RedirectAuthorize(APIView): '''小程序绑定授权回调''' def get(self, request, pk): try: with transaction.atomic(): tenant = Tenant.objects.select_for_update().filter(id=pk).first() app = TenantBiz.bindWechatApplet(tenant, request.GET.get('auth_code')) BizLog.objects.addnew(None, None, BizLog.INSERT, u'租户绑定小程序, id=%d' % app.id) except Exception as e: return response_error(str(e)) return response_ok() class CallbackEvent(APIView): '''消息与事件接收''' def post(self, request, appid): appid = appid sMsgSignature = request.GET.get('msg_signature') sTimeStamp = request.GET.get('timestamp') sNonce = request.GET.get('nonce') sPostData = request.body.decode('utf-8') try: tp = WechatTp.getDefault() msg_crypt = WXBizMsgCrypt(tp.getToken(), tp.getEncodeKey(), tp.getAppid()) ret, decryp_xml = msg_crypt.DecryptMsg(sPostData, sMsgSignature, sTimeStamp, sNonce) data = json.loads(json.dumps(xmltodict.parse(decryp_xml)))['xml'] if data['MsgType'] == 'event': app = WechatApplet.getByAppid(appid) if data['Event'] == 'weapp_audit_success': # 代码审核通过 app.weapp_audit_success() elif data['Event'] == 'weapp_audit_fail': # 代码审核不通过 app.weapp_audit_fail(data['Reason']) elif data['Event'] == 'weapp_audit_delay': # 代码审核延后 app.weapp_audit_delay(data['Reason']) except: pass return HttpResponse('success')