views.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. # coding=utf-8
  2. import json
  3. import xmltodict
  4. import traceback
  5. from django.db import transaction
  6. from django.http import HttpResponse
  7. from rest_framework.views import APIView
  8. from django.conf import settings
  9. from utils.wx.WXBizMsgCrypt import WXBizMsgCrypt
  10. from utils.exceptions import CustomError
  11. from utils.wechatpay import WechatPayNotify
  12. from utils import response_error, response_ok
  13. from apps.log.models import BizLog
  14. from apps.WechatTp.models import WechatTp
  15. from apps.WechatApplet.models import WechatApplet
  16. # from apps.WeChatResponse import WechatPayNotify
  17. class CallbackAuthorize(APIView):
  18. '''验证票据(component_verify_ticket)在第三方平台创建审核通过后,微信服务器会向其 ”授权事件接收URL”
  19. 每隔 10 分钟以 POST 的方式推送 component_verify_ticket 接收 POST 请求后,只需直接返回字符串 success。
  20. 为了加强安全性,postdata 中的 xml 将使用服务申请时的加解密 key 来进行加密'''
  21. def post(self, request):
  22. sMsgSignature = request.GET.get('msg_signature')
  23. sTimeStamp = request.GET.get('timestamp')
  24. sNonce = request.GET.get('nonce')
  25. sPostData = request.body.decode('utf-8')
  26. try:
  27. component = WechatTp.getDefault()
  28. if component:
  29. appid = component.getAppid()
  30. msg_crypt = WXBizMsgCrypt(component.getToken(), component.getEncodeKey(), appid)
  31. ret, decryp_xml = msg_crypt.DecryptMsg(sPostData, sMsgSignature, sTimeStamp, sNonce)
  32. data = json.loads(json.dumps(xmltodict.parse(decryp_xml)))['xml']
  33. if data['AppId'] == appid:
  34. if data['InfoType'] == 'component_verify_ticket':
  35. component.refreshVerifyTicket(data['ComponentVerifyTicket'])
  36. elif data['InfoType'] == 'unauthorized':
  37. authorizer_appid = data['AuthorizerAppid']
  38. authorizer = WechatApplet.getByAppidAndComponentAppid(authorizer_appid, appid)
  39. if authorizer:
  40. authorizer.revoke()
  41. except:
  42. pass
  43. return HttpResponse('success')
  44. class CallbackEvent(APIView):
  45. '''消息与事件接收'''
  46. def post(self, request, appid):
  47. appid = appid
  48. sMsgSignature = request.GET.get('msg_signature')
  49. sTimeStamp = request.GET.get('timestamp')
  50. sNonce = request.GET.get('nonce')
  51. sPostData = request.body.decode('utf-8')
  52. try:
  53. tp = WechatTp.getDefault()
  54. msg_crypt = WXBizMsgCrypt(tp.getToken(), tp.getEncodeKey(), tp.getAppid())
  55. ret, decryp_xml = msg_crypt.DecryptMsg(sPostData, sMsgSignature, sTimeStamp, sNonce)
  56. data = json.loads(json.dumps(xmltodict.parse(decryp_xml)))['xml']
  57. if data['MsgType'] == 'event':
  58. app = WechatApplet.getByAppid(appid)
  59. if data['Event'] == 'weapp_audit_success': # 代码审核通过
  60. app.weapp_audit_success()
  61. elif data['Event'] == 'weapp_audit_fail': # 代码审核不通过
  62. app.weapp_audit_fail(data['Reason'])
  63. elif data['Event'] == 'weapp_audit_delay': # 代码审核延后
  64. app.weapp_audit_delay(data['Reason'])
  65. except:
  66. pass
  67. return HttpResponse('success')
  68. class WechatNotifyView(APIView):
  69. def dispatch(self, request, *args, **kwargs):
  70. param = request.body
  71. appid = kwargs['appid']
  72. applet = WechatApplet.getByAppid(appid)
  73. # param = request.body.decode('utf-8')
  74. notify = WechatPayNotify(param, applet.agent_key)
  75. try:
  76. data = notify.handle()
  77. if not data:
  78. raise CustomError(u'错误的请求!')
  79. result_code = data['result_code']
  80. if result_code != 'SUCCESS':
  81. raise CustomError(u'错误的请求!')
  82. no = data['out_trade_no']
  83. amount = float(data['total_fee']) / 100.0
  84. with transaction.atomic():
  85. pay = Pay.getByNo(no)
  86. pay.paySuccess(amount)
  87. BizLog.objects.addnew(pay.user, BizLog.INSERT, u'微信支付成功,pay_no=%s' % no, param)
  88. except Exception as e:
  89. traceback.print_exc()
  90. return HttpResponse(WechatPayNotify.response_fail())
  91. return HttpResponse(WechatPayNotify.response_ok())