|
@@ -0,0 +1,217 @@
|
|
|
+# coding=utf-8
|
|
|
+
|
|
|
+import json
|
|
|
+import xmltodict
|
|
|
+
|
|
|
+from django.db import transaction
|
|
|
+from django.http import HttpResponse
|
|
|
+from apps.customer import customer_log
|
|
|
+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.pay.models import Pay
|
|
|
+from apps.tenant.biz import TenantBiz
|
|
|
+from utils.xgj.xgj import XGJ
|
|
|
+from utils.permission import IsCustomerUser
|
|
|
+
|
|
|
+
|
|
|
+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')
|
|
|
+
|
|
|
+class WechatNotifyView(APIView):
|
|
|
+
|
|
|
+ def dispatch(self, request, *args, **kwargs):
|
|
|
+ appid = kwargs['appid']
|
|
|
+ applet = WechatApplet.getByAppid(appid)
|
|
|
+ param = request.body.decode('utf-8')
|
|
|
+ notify = WechatPayNotify(param, applet.tenant_key)
|
|
|
+
|
|
|
+ try:
|
|
|
+ data = notify.handle()
|
|
|
+ if not data:
|
|
|
+ raise CustomError(u'错误的请求!')
|
|
|
+
|
|
|
+ result_code = data['result_code']
|
|
|
+ if result_code != 'SUCCESS':
|
|
|
+ raise CustomError(u'错误的请求!')
|
|
|
+
|
|
|
+ no = data['out_trade_no']
|
|
|
+ amount = int(data['total_fee']) * 100
|
|
|
+
|
|
|
+ with transaction.atomic():
|
|
|
+ pay = Pay.getByNo(no)
|
|
|
+ pay.payConfirm(amount)
|
|
|
+ customer_log(pay.customer, BizLog.INSERT, u'支付成功,no=%s' % no, param)
|
|
|
+ except:
|
|
|
+ return HttpResponse(WechatPayNotify.response_fail())
|
|
|
+ return HttpResponse(WechatPayNotify.response_ok())
|
|
|
+
|
|
|
+
|
|
|
+class GetCompany(APIView):
|
|
|
+ permission_classes = [IsCustomerUser, ]
|
|
|
+
|
|
|
+ def get(self, request):
|
|
|
+ appid = request.GET.get('appid')
|
|
|
+ try:
|
|
|
+ res = XGJ.get_company(appid)
|
|
|
+ except Exception as e:
|
|
|
+ return response_error(str(e))
|
|
|
+ return response_ok(res)
|
|
|
+
|
|
|
+
|
|
|
+class GetMemberCard(APIView):
|
|
|
+ permission_classes = [IsCustomerUser, ]
|
|
|
+
|
|
|
+ def post(self, request):
|
|
|
+ appid = request.POST.get('appid')
|
|
|
+ company_id = request.POST.get('company_id')
|
|
|
+ tel = request.POST.get('tel')
|
|
|
+ number = request.POST.get('number')
|
|
|
+ try:
|
|
|
+ res = XGJ.get_member_card(appid, company_id, tel, number)
|
|
|
+ except Exception as e:
|
|
|
+ return response_error(str(e))
|
|
|
+ return response_ok(res)
|
|
|
+
|
|
|
+
|
|
|
+class GetMemberInfo(APIView):
|
|
|
+ permission_classes = [IsCustomerUser, ]
|
|
|
+
|
|
|
+ def get(self, request):
|
|
|
+ appid = request.GET.get('appid')
|
|
|
+ customer = request.customer
|
|
|
+ if not customer.member_id:
|
|
|
+ raise CustomError(u'请先绑定会员卡')
|
|
|
+ try:
|
|
|
+ res = XGJ.get_member_info(appid, str(customer.member_id))
|
|
|
+ except Exception as e:
|
|
|
+ return response_error(str(e))
|
|
|
+ return response_ok(res)
|
|
|
+
|
|
|
+
|
|
|
+class GetMemberPoints(APIView):
|
|
|
+ permission_classes = [IsCustomerUser, ]
|
|
|
+
|
|
|
+ def get(self, request):
|
|
|
+ appid = request.GET.get('appid')
|
|
|
+ page = request.GET.get('page')
|
|
|
+ pageSize = request.GET.get('pageSize')
|
|
|
+ customer = request.customer
|
|
|
+ if not customer.member_id:
|
|
|
+ raise CustomError(u'请先绑定会员卡')
|
|
|
+ try:
|
|
|
+ res = XGJ.get_member_points(appid, str(customer.member_id), page, pageSize)
|
|
|
+ except Exception as e:
|
|
|
+ return response_error(str(e))
|
|
|
+ return response_ok(res)
|
|
|
+
|
|
|
+
|
|
|
+class GetMemberRecord(APIView):
|
|
|
+ permission_classes = [IsCustomerUser, ]
|
|
|
+
|
|
|
+ def get(self, request):
|
|
|
+ appid = request.GET.get('appid')
|
|
|
+ page = request.GET.get('page')
|
|
|
+ pageSize = request.GET.get('pageSize')
|
|
|
+ customer = request.customer
|
|
|
+ if not customer.member_id:
|
|
|
+ raise CustomError(u'请先绑定会员卡')
|
|
|
+ try:
|
|
|
+ res = XGJ.get_member_record(appid, str(customer.member_id), page, pageSize)
|
|
|
+ except Exception as e:
|
|
|
+ return response_error(str(e))
|
|
|
+ return response_ok(res)
|
|
|
+
|
|
|
+
|
|
|
+class GetMemberBalance(APIView):
|
|
|
+ permission_classes = [IsCustomerUser, ]
|
|
|
+
|
|
|
+ def get(self, request):
|
|
|
+ appid = request.GET.get('appid')
|
|
|
+ customer = request.customer
|
|
|
+ if not customer.member_id:
|
|
|
+ raise CustomError(u'未绑定会员卡')
|
|
|
+ try:
|
|
|
+ res = XGJ.get_member_balance(appid, str(customer.member_id))
|
|
|
+ except Exception as e:
|
|
|
+ return response_error(str(e))
|
|
|
+ return response_ok(res)
|
|
|
+
|