Эх сурвалжийг харах

优化PayPal周期扣款接口

locky 2 жил өмнө
parent
commit
df02b1ac63
1 өөрчлөгдсөн 82 нэмэгдсэн , 113 устгасан
  1. 82 113
      Controller/PaymentCycle.py

+ 82 - 113
Controller/PaymentCycle.py

@@ -1,27 +1,22 @@
+import datetime as date_time
+import json
+import logging
+import time
 import traceback
 
-from Ansjer.config import PAYPAL_CRD, SERVER_DOMAIN, SERVER_DOMAIN_SSL, PAYPAL_WEB_HOOK_ID, PAYPAL_WEB_HOOK_ID_TWO
-from Model.models import PayCycleConfigModel, Store_Meal, UID_Bucket, PromotionRuleModel, \
-    Unused_Uid_Meal, Device_Info, CouponModel, Order_Model, PaypalWebHookEvent
-from Service.CommonService import CommonService
-from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
-import requests
-import time
-import sys
-from Object.TokenObject import TokenObject
-from Object.UidTokenObject import UidTokenObject
-from Object.ResponseObject import ResponseObject
 import paypalrestsdk
-from paypalrestsdk import BillingAgreement
-from django.views.generic.base import View
 from django.db import transaction
+from django.db.models import Q, F
+from django.http import HttpResponseRedirect, HttpResponse
+from django.views.generic.base import View
+
+from Ansjer.config import PAYPAL_CRD, SERVER_DOMAIN_SSL, PAYPAL_WEB_HOOK_ID, PAYPAL_WEB_HOOK_ID_TWO
 from Controller import CloudStorage
-from django.db.models import Q, F, Count
-from paypalrestsdk.notifications import WebhookEvent
-import logging
-import json
-from paypalrestsdk import BillingPlan
-import datetime as date_time
+from Model.models import PayCycleConfigModel, Store_Meal, UID_Bucket, PromotionRuleModel, \
+    Unused_Uid_Meal, Device_Info, CouponModel, Order_Model, PaypalWebHookEvent
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
 
 
 # 周期扣款相关
@@ -283,9 +278,10 @@ class PaypalCycleNotify(View):
                 # 如果存在序列号,消息提示用序列号
                 device_name = CommonService.query_serial_with_uid(uid=UID)
                 datetime = time.strftime("%Y-%m-%d", time.localtime())
-                sys_msg_text_list = ['温馨提示:尊敬的客户,您的' + device_name + '设备在' + datetime + '已成功订阅云存套餐',
-                                     'Dear customer,you already subscribed the cloud storage package successfully for device ' + device_name + ' on ' + time.strftime(
-                                         "%b %dth,%Y", time.localtime())]
+                sys_msg_text_list = [
+                    '温馨提示:尊敬的客户,您的' + device_name + '设备在' + datetime + '已成功订阅云存套餐',
+                    'Dear customer,you already subscribed the cloud storage package successfully for device ' + device_name + ' on ' + time.strftime(
+                        "%b %dth,%Y", time.localtime())]
                 CloudStorage.CloudStorageView().do_vod_msg_notice(UID, channel, userid, lang, sys_msg_text_list,
                                                                   'SMS_219738485')
 
@@ -331,15 +327,14 @@ class PaypalCycleNotify(View):
         logger = logging.getLogger('pay')
         logger.info('--------进入周期扣款钩子--------')
         if not request.body:
+            logger.info('PayPal周期扣款失败---缺失请求体')
             return HttpResponse('fail', status=500)
         json_agreement_str = request.body.decode("utf-8")
         json_obj = json.loads(json_agreement_str)
         header = request.META
         paypal_body = json_obj.get('resource')
-        logger.info('----主体信息----')
-        logger.info(json_agreement_str)
-        logger.info('----周期扣款头部信息----')
-        logger.info(header)
+        logger.info('----请求体数据:{}----'.format(json_agreement_str))
+        logger.info('----请求头数据:{}----'.format(header))
         try:
             transmission_id = header.get('HTTP_PAYPAL_TRANSMISSION_ID', None)
             transmission_time = header.get('HTTP_PAYPAL_TRANSMISSION_TIME', None)
@@ -363,22 +358,20 @@ class PaypalCycleNotify(View):
             }
             self.paypal_webhook_log(**PaypalWebHookEventInsert)
             if event_type != 'PAYMENT.SALE.COMPLETED':
-                logger.info('----钩子异常----')
+                logger.info('----event_type异常:{}----'.format(event_type))
             self.find_subscription_transactions(billing_agreement_id)
+
             if resource_type == 'sale' and paypal_body.get('state') == 'completed':
                 paypalrestsdk.configure(PAYPAL_CRD)
                 response = paypalrestsdk.WebhookEvent.verify(
                     transmission_id, transmission_time, PAYPAL_WEB_HOOK_ID, json_agreement_str, cert_url,
                     transmission_sig, auth_algo)
-                logger.info('----验证签名----')
-                logger.info(response)
                 if not response:
+                    logger.info('PayPal周期扣款失败---签名验证失败')
                     return HttpResponse('Fail', status=500)
-
             else:
-                logger.info('----付款状态有误----')
-                logger.info(resource_type)
-                logger.info(paypal_body.get('state'))
+                logger.info('PayPal周期扣款失败,付款状态有误,resource_type:{},state:{}----'.
+                            format(resource_type, paypal_body.get('state')))
                 return HttpResponse('Fail', status=500)
 
             if not billing_agreement_id:
@@ -391,76 +384,70 @@ class PaypalCycleNotify(View):
                         updTime=int(time.time()),
                         trade_no=paypal_transaction_id
                     )
-                    logger.info('----paypal_transaction_id----更新成功')
-                    logger.info('----paypal_transaction_id----:')
-                    logger.info(paypal_transaction_id)
+                    logger.info('PayPal周期扣款成功---更新交易id:{}'.format(paypal_transaction_id))
                     return HttpResponse('success')
                 else:
-                    logger.info('----paymentID and transactions_id某个为空')
-                    logger.info(paymentID)
-                    logger.info(paypal_transaction_id)
+                    logger.info('PayPal周期扣款失败---paymentID:{}或paypal_transaction_id:{}为空'.
+                                format(paymentID, paypal_transaction_id))
                     return HttpResponse('fail', status=500)
 
             agreement_id = paypal_body.get('billing_agreement_id')
             billing_agreement = paypalrestsdk.BillingAgreement.find(agreement_id)
-            logger.info(type(billing_agreement))
+            logger.info('billing_agreement:{}'.format(billing_agreement))
+
             # 记录钩子日志
             PaypalWebHookEventInsert['agreement_desc'] = repr(billing_agreement)
             PaypalWebHookEventInsert['agreement_id'] = agreement_id
             PaypalWebHookEventInsert['orderID'] = billing_agreement.description
             PaypalWebHookEvent.objects.create(**PaypalWebHookEventInsert)
 
-            # 订阅续费订单(如果完成周期数`==0,则是自动续费第一次扣款。否则说明是续费订单)
+            # 查询订单数据
+            order_id = billing_agreement.description
+            order_qs = Order_Model.objects.filter(orderID=order_id).values('UID', 'channel', 'commodity_code', 'rank',
+                                                                           'isSelectDiscounts', 'plan_id', 'desc',
+                                                                           'payType', 'currency', 'addTime',
+                                                                           'commodity_type', 'updTime',
+                                                                           'userID__userID', 'uid_bucket_id',
+                                                                           'userID__username'
+                                                                           )
+            if not order_qs.exists():
+                logger.info('PayPal周期扣款失败---订单数据不存在')
+                return HttpResponse('fail', status=500)
+
+            UID = order_qs[0]['UID']
+            # PayPal周期扣款首次扣款
             if billing_agreement.agreement_details.cycles_completed == '0':
-                logger.info('----订阅详情----')
-                logger.info(billing_agreement)
-                logger.info('订阅续费订单完成周期数==0,结束')
                 # 更新order表,paypal的商家交易号
-                Order_Model.objects.filter(orderID=billing_agreement.description).update(
-                    updTime=int(time.time()),
-                    trade_no=paypal_transaction_id
-                )
+                order_qs.update(updTime=int(time.time()), trade_no=paypal_transaction_id)
+                logger.info('{} PayPal周期扣款首次扣款成功'.format(UID))
                 return HttpResponse('success')
-            oldOrderID = billing_agreement.description
-            order_qs = Order_Model.objects.filter(orderID=oldOrderID, status=1)
-            if not order_qs:
-                return HttpResponse('fail', status=500)
-            order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
-                                         "userID__userID", "uid_bucket_id",
-                                         "userID__username", 'plan_id', 'addTime', 'desc', 'payType', 'currency',
-                                         'commodity_type', 'updTime')
+
             nowTime = int(time.time())
-            if order_list[0]['addTime'] + 9200 > nowTime:  # 避免续费订单重复支付
-                logger.info('----paypal重复异步回调----')
+            if order_qs[0]['addTime'] + 9200 > nowTime:  # 避免续费订单重复支付
+                logger.info('{} PayPal周期扣款失败---续费订单已创建'.format(UID))
                 return HttpResponse('success')
 
-            logger.info('----走入订阅过程----')
-
-            userid = order_list[0]['userID__userID']
-            username = order_list[0]['userID__username']
-            UID = order_list[0]['UID']
-            channel = order_list[0]['channel']
-            rank = order_list[0]['rank']
-            smqs = Store_Meal.objects.filter(id=rank). \
-                values("day", "bucket_id", "bucket__storeDay", "expire")
-            bucketId = smqs[0]['bucket_id']
-            if not smqs.exists():
+            desc = order_qs[0]['desc']
+            pay_type = order_qs[0]['payType']
+            currency = order_qs[0]['currency']
+            commodity_code = order_qs[0]['commodity_code']
+            commodity_type = order_qs[0]['commodity_type']
+            plan_id = order_qs[0]['plan_id']
+            userid = order_qs[0]['userID__userID']
+            username = order_qs[0]['userID__username']
+            channel = order_qs[0]['channel']
+            rank = order_qs[0]['rank']
+            store_meal_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire")
+            if not store_meal_qs.exists():
+                logger.info('{} PayPal周期扣款失败---套餐数据不存在'.format(UID))
                 return HttpResponse('fail', status=500)
-            # ##
-            ubqs = UID_Bucket.objects.filter(uid=UID).values("id", "bucket_id", "bucket__storeDay",
-                                                             "bucket__region",
+
+            bucketId = store_meal_qs[0]['bucket_id']
+            expire = store_meal_qs[0]['expire']
+
+            ubqs = UID_Bucket.objects.filter(uid=UID).values("id", "bucket_id", "bucket__storeDay", "bucket__region",
                                                              "endTime", "use_status")
-            expire = smqs[0]['expire']
 
-            # if order_list[0]['isSelectDiscounts'] == 1:
-            #     expire = smqs[0]['expire'] * 2
-            # 是否有促销
-            # nowTime = int(time.time())
-            # promotion = PromotionRuleModel.objects.filter(status=1, startTime__lte=nowTime,
-            #                                               endTime__gte=nowTime).values('id', 'ruleConfig')
-            # if promotion.exists():
-            #     promotion_rule_id = promotion[0]['id']
-            #     expire = expire * 2
             with transaction.atomic():
                 if ubqs.exists():
                     ubq = ubqs[0]
@@ -471,14 +458,12 @@ class PaypalCycleNotify(View):
                              endTime=endTime, updateTime=nowTime)
                     else:  # 已过期或者不相同的套餐加入未使用的关联套餐表
                         has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
-                        # nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
-                        # if promotion.exists():
                         nums = 1
                         if has_unused.exists():
                             Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
                         else:
                             Unused_Uid_Meal.objects.create(uid=UID, channel=channel, addTime=nowTime, num=nums,
-                                                           expire=smqs[0]['expire'], bucket_id=bucketId)
+                                                           expire=expire, bucket_id=bucketId)
                         UID_Bucket.objects.filter(id=ubq['id']).update(has_unused=1)
                     uid_bucket_id = ubq['id']
                 else:
@@ -496,13 +481,6 @@ class PaypalCycleNotify(View):
                     }
                     dvq.update(**dvq_set_update_dict)
 
-                # uid_main_exist = UIDMainUser.objects.filter(UID=UID)
-                # if not uid_main_exist.exists():
-                #     uid_main_dict = {
-                #         'UID': UID,
-                #         'user_id': userid
-                #     }
-                #     UIDMainUser.objects.create(**uid_main_dict)
                 orderID = CommonService.createOrderID()
                 store_meal_qs = Store_Meal.objects.filter(id=rank, lang__lang='cn', is_show=0).values('lang__title',
                                                                                                       'lang__content')
@@ -511,32 +489,27 @@ class PaypalCycleNotify(View):
                 else:
                     store_meal_name = '未知套餐'
                 Order_Model.objects.create(orderID=orderID, UID=UID, channel=channel, userID_id=userid,
-                                           desc=order_list[0]['desc'], payType=order_list[0]['payType'],
-                                           payTime=nowTime,
-                                           price=amount.get('total'), currency=order_list[0]['currency'],
-                                           addTime=nowTime, updTime=nowTime,
-                                           pay_url='', isSelectDiscounts=0,
-                                           commodity_code=order_list[0]['commodity_code'],
-                                           commodity_type=order_list[0]['commodity_type'], rank_id=rank, paymentID='',
+                                           desc=desc, payType=pay_type, payTime=nowTime, price=amount.get('total'),
+                                           currency=order_qs[0]['currency'], addTime=nowTime, updTime=nowTime,
+                                           pay_url='', isSelectDiscounts=0, commodity_code=commodity_code,
+                                           commodity_type=commodity_type, rank_id=rank, paymentID='',
                                            coupon_id='', uid_bucket_id=uid_bucket_id, status=1,
                                            agreement_id=agreement_id, store_meal_name=store_meal_name,
-                                           plan_id=order_list[0]['plan_id'], ai_rank_id=1,
-                                           trade_no=paypal_transaction_id)
+                                           plan_id=plan_id, ai_rank_id=1, trade_no=paypal_transaction_id)
                 # 如果存在序列号,消息提示用序列号
                 device_name = CommonService.query_serial_with_uid(uid=UID)
                 datetime = time.strftime("%Y-%m-%d", time.localtime())
-                sys_msg_text_list = ['温馨提示:尊敬的客户,您的' + device_name + '设备在' + datetime + '已成功续订云存套餐',
-                                     'Dear customer,you already subscribed the cloud storage package successfully for device ' + device_name + ' on ' + time.strftime(
-                                         "%b %dth,%Y", time.localtime())]
+                sys_msg_text_list = [
+                    '温馨提示:尊敬的客户,您的' + device_name + '设备在' + datetime + '已成功续订云存套餐',
+                    'Dear customer,you already subscribed the cloud storage package successfully for device ' + device_name + ' on ' + time.strftime(
+                        "%b %dth,%Y", time.localtime())]
 
-                if order_list[0]['payType'] == 1:
+                if pay_type == 1:
                     lang = 'en'
                 else:
                     lang = 'cn'
                 CloudStorage.CloudStorageView().do_vod_msg_notice(UID, channel, userid, lang,
                                                                   sys_msg_text_list, 'SMS_219738485')
-                logger.info('----周期扣款结果----')
-                logger.info('success')
 
                 # 更新agreement
                 billing_agreement_update_attributes = [
@@ -549,14 +522,10 @@ class PaypalCycleNotify(View):
                     }
                 ]
                 billing_agreement.replace(billing_agreement_update_attributes)
-                logger.info('{UID}成功续费paypal:----'.format(UID=UID))
+                logger.info('{} PayPal周期扣款成功'.format(UID))
                 return HttpResponse('success')
         except Exception as e:
-            print(e)
-            logger.info('----周期扣款钩子失败----')
-            logger.info('do_paypal_webhook_notify支付失败:----')
-            logger.info("错误行数:{errLine}".format(errLine=e.__traceback__.tb_lineno))
-            logger.info(repr(e))
+            logger.info('PayPal周期扣款异常: errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
             return HttpResponse('fail', status=500)
 
     @staticmethod