|
@@ -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
|