|
@@ -1,6 +1,6 @@
|
|
|
-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,Order_Model, Store_Meal, UID_Bucket, PromotionRuleModel,\
|
|
|
- Unused_Uid_Meal,Device_Info, CouponModel, Order_Model, PaypalWebHookEvent
|
|
|
+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, Order_Model, 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
|
|
@@ -21,12 +21,12 @@ import json
|
|
|
from paypalrestsdk import BillingPlan
|
|
|
|
|
|
|
|
|
-#周期扣款相关
|
|
|
+# 周期扣款相关
|
|
|
class Paypal:
|
|
|
- #检查是否有重复订阅
|
|
|
- def checkSubscriptions(userID,uid,rank):
|
|
|
- hasOrder = Order_Model.objects.filter(UID=uid,rank=rank)
|
|
|
- hasOrder = hasOrder.filter(~Q(agreement_id='')).values('agreement_id','orderID').order_by('-addTime')[0:1]
|
|
|
+ # 检查是否有重复订阅
|
|
|
+ def checkSubscriptions(userID, uid, rank):
|
|
|
+ hasOrder = Order_Model.objects.filter(UID=uid, rank=rank)
|
|
|
+ hasOrder = hasOrder.filter(~Q(agreement_id='')).values('agreement_id', 'orderID').order_by('-addTime')[0:1]
|
|
|
if not hasOrder.exists():
|
|
|
return True
|
|
|
paypalrestsdk.configure(PAYPAL_CRD)
|
|
@@ -35,7 +35,7 @@ class Paypal:
|
|
|
return False
|
|
|
return True
|
|
|
|
|
|
- def subscriptions(store_info,lang,orderID,price):
|
|
|
+ def subscriptions(store_info, lang, orderID, price):
|
|
|
logger = logging.getLogger('pay')
|
|
|
cycle_config = PayCycleConfigModel.objects.filter(id=store_info['cycle_config_id']).values()
|
|
|
if not cycle_config:
|
|
@@ -104,9 +104,9 @@ class Paypal:
|
|
|
start_date_timestamp = now_time + 86400 - 3600 # 下次扣款为明天,提前1个小时扣款
|
|
|
start_date_str = CommonService.timestamp_to_str(start_date_timestamp, "%Y-%m-%dT%H:%M:%SZ")
|
|
|
elif cycle_config[0]['frequency'] == "MONTH":
|
|
|
- start_date_timestamp = CommonService.calcMonthLater(1, now_time) - (5 * 86400) #下次扣款为下个月提前5天扣款
|
|
|
+ start_date_timestamp = CommonService.calcMonthLater(1, now_time) - (5 * 86400) # 下次扣款为下个月提前5天扣款
|
|
|
start_date_str = CommonService.timestamp_to_str(start_date_timestamp, "%Y-%m-%dT%H:%M:%SZ")
|
|
|
- #订阅
|
|
|
+ # 订阅
|
|
|
billingAgreement = {
|
|
|
"name": store_info['lang__content'],
|
|
|
"description": orderID,
|
|
@@ -129,6 +129,7 @@ class Paypal:
|
|
|
logger.info(billing_agreement.error)
|
|
|
return False
|
|
|
|
|
|
+
|
|
|
class PaypalCycleNotify(View):
|
|
|
def get(self, request, *args, **kwargs):
|
|
|
request.encoding = 'utf-8'
|
|
@@ -147,12 +148,13 @@ class PaypalCycleNotify(View):
|
|
|
elif operation == 'paypalCycleReturn': # paypal成功订阅回调
|
|
|
return self.do_paypal_cycle_return(request_dict, response)
|
|
|
elif operation == 'paypalCycleNotify': # paypal 周期付款回调
|
|
|
- return self.do_paypal_webhook_notify(request_dict,request, response)
|
|
|
- elif operation == 'subscriptionBreakNotify': # paypal 订阅相关回调
|
|
|
- return self.do_subscription_break_notify(request_dict,request, response)
|
|
|
+ return self.do_paypal_webhook_notify(request_dict, request, response)
|
|
|
+ elif operation == 'subscriptionBreakNotify': # paypal 订阅相关回调
|
|
|
+ return self.do_subscription_break_notify(request_dict, request, response)
|
|
|
+
|
|
|
def do_paypal_cycle_return(self, request_dict, response):
|
|
|
lang = request_dict.get('lang', 'en')
|
|
|
- token = request_dict.get('token',None)
|
|
|
+ token = request_dict.get('token', None)
|
|
|
|
|
|
logger = logging.getLogger('pay')
|
|
|
logger.info('--------进入paypay首次订阅付款回调--------')
|
|
@@ -169,12 +171,12 @@ class PaypalCycleNotify(View):
|
|
|
return HttpResponseRedirect(red_url)
|
|
|
|
|
|
orderID = billing_agreement_response.description
|
|
|
-
|
|
|
+ state = billing_agreement_response.state
|
|
|
+ nowTime = int(time.time())
|
|
|
+ promotion_rule_id = ''
|
|
|
logger.info('----订阅详情----')
|
|
|
logger.info(billing_agreement_response)
|
|
|
-
|
|
|
agreement_id = billing_agreement_response.id
|
|
|
- promotion_rule_id = ''
|
|
|
order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
|
|
|
order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
|
|
|
"userID__userID",
|
|
@@ -186,6 +188,15 @@ class PaypalCycleNotify(View):
|
|
|
red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
|
|
|
return HttpResponseRedirect(red_url)
|
|
|
UID = order_list[0]['UID']
|
|
|
+ if state != 'Active':
|
|
|
+ order_qs.update(status=2, promotion_rule_id=promotion_rule_id)
|
|
|
+ logger.info('----UID:{UID},用户名:{last_time} {first_time}首次订阅付款失败----'.format
|
|
|
+ (UID=UID,
|
|
|
+ last_time=billing_agreement_response.payer.payer_info.last_name,
|
|
|
+ first_time=billing_agreement_response.payer.payer_info.first_time,
|
|
|
+ ))
|
|
|
+ logger.info('billing_agreement_state')
|
|
|
+ logger.info(state)
|
|
|
try:
|
|
|
userid = order_list[0]['userID__userID']
|
|
|
username = order_list[0]['userID__username']
|
|
@@ -208,21 +219,20 @@ class PaypalCycleNotify(View):
|
|
|
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')
|
|
|
+ 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]
|
|
|
- if ubq['use_status'] == 1 and ubq['bucket_id'] == bucketId: #套餐使用中并且相同套餐叠加过期时间
|
|
|
+ if ubq['use_status'] == 1 and ubq['bucket_id'] == bucketId: # 套餐使用中并且相同套餐叠加过期时间
|
|
|
endTime = CommonService.calcMonthLater(expire, ubq['endTime'])
|
|
|
UID_Bucket.objects.filter(id=ubq['id']).update \
|
|
|
(uid=UID, channel=channel, bucket_id=bucketId,
|
|
|
endTime=endTime, updateTime=nowTime)
|
|
|
- else: #已过期或者不相同的套餐加入未使用的关联套餐表
|
|
|
+ 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():
|
|
@@ -230,15 +240,15 @@ class PaypalCycleNotify(View):
|
|
|
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)
|
|
|
+ Unused_Uid_Meal.objects.create(uid=UID, channel=channel, addTime=nowTime, num=nums,
|
|
|
+ expire=smqs[0]['expire'], bucket_id=bucketId)
|
|
|
UID_Bucket.objects.filter(id=ubq['id']).update(has_unused=1)
|
|
|
uid_bucket_id = ubq['id']
|
|
|
else:
|
|
|
endTime = CommonService.calcMonthLater(expire)
|
|
|
ub_cqs = UID_Bucket.objects.create \
|
|
|
(uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
|
|
|
- updateTime=nowTime,use_status=1)
|
|
|
+ updateTime=nowTime, use_status=1)
|
|
|
uid_bucket_id = ub_cqs.id
|
|
|
|
|
|
dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
|
|
@@ -262,14 +272,15 @@ class PaypalCycleNotify(View):
|
|
|
CouponModel.objects.filter(id=order_list[0]['coupon_id']).update(use_status=2)
|
|
|
|
|
|
order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id,
|
|
|
- promotion_rule_id=promotion_rule_id,agreement_id=agreement_id)
|
|
|
+ promotion_rule_id=promotion_rule_id, agreement_id=agreement_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())]
|
|
|
- CloudStorage.CloudStorageView().do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list, 'SMS_219738485')
|
|
|
+ CloudStorage.CloudStorageView().do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list,
|
|
|
+ 'SMS_219738485')
|
|
|
|
|
|
# return response.json(0)
|
|
|
red_url = "{SERVER_DOMAIN_SSL}web/paid2/success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
|
|
@@ -290,7 +301,6 @@ class PaypalCycleNotify(View):
|
|
|
red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
|
|
|
return HttpResponseRedirect(red_url)
|
|
|
|
|
|
-
|
|
|
def do_paypal_webhook_notify(self, request_dict, request, response):
|
|
|
logger = logging.getLogger('pay')
|
|
|
logger.info('--------进入周期扣款钩子--------')
|
|
@@ -363,7 +373,7 @@ class PaypalCycleNotify(View):
|
|
|
logger.info('----订阅详情----')
|
|
|
logger.info(billing_agreement)
|
|
|
logger.info('订阅续费订单完成周期数==0,结束')
|
|
|
- #更新order表,paypal的商家交易号
|
|
|
+ # 更新order表,paypal的商家交易号
|
|
|
Order_Model.objects.filter(orderID=billing_agreement.description).update(
|
|
|
updTime=int(time.time()),
|
|
|
trade_no=paypal_transaction_id
|
|
@@ -374,10 +384,11 @@ class PaypalCycleNotify(View):
|
|
|
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')
|
|
|
+ "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: #避免续费订单重复支付
|
|
|
+ if order_list[0]['addTime'] + 9200 > nowTime: # 避免续费订单重复支付
|
|
|
logger.info('----paypal重复异步回调----')
|
|
|
return HttpResponse('success')
|
|
|
|
|
@@ -452,12 +463,17 @@ class PaypalCycleNotify(View):
|
|
|
# UIDMainUser.objects.create(**uid_main_dict)
|
|
|
orderID = CommonService.createOrderID()
|
|
|
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='',
|
|
|
- coupon_id='',uid_bucket_id=uid_bucket_id,status=1,agreement_id=agreement_id,
|
|
|
- plan_id=order_list[0]['plan_id'], ai_rank_id=1, trade_no=paypal_transaction_id)
|
|
|
+ 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='',
|
|
|
+ coupon_id='', uid_bucket_id=uid_bucket_id, status=1,
|
|
|
+ agreement_id=agreement_id,
|
|
|
+ plan_id=order_list[0]['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())
|
|
@@ -470,11 +486,11 @@ class PaypalCycleNotify(View):
|
|
|
else:
|
|
|
lang = 'cn'
|
|
|
CloudStorage.CloudStorageView().do_vod_msg_Notice(UID, channel, userid, lang,
|
|
|
- sys_msg_text_list, 'SMS_219738485')
|
|
|
+ sys_msg_text_list, 'SMS_219738485')
|
|
|
logger.info('----周期扣款结果----')
|
|
|
logger.info('success')
|
|
|
|
|
|
- #更新agreement
|
|
|
+ # 更新agreement
|
|
|
billing_agreement_update_attributes = [
|
|
|
{
|
|
|
"op": "replace",
|
|
@@ -495,7 +511,6 @@ class PaypalCycleNotify(View):
|
|
|
logger.info(repr(e))
|
|
|
return HttpResponse('fail', status=500)
|
|
|
|
|
|
-
|
|
|
def do_subscription_break_notify(self, request_dict, request, response):
|
|
|
logger = logging.getLogger('pay')
|
|
|
logger.info('--------进入订阅失败,付款失败,暂停--------')
|
|
@@ -579,9 +594,7 @@ class PaypalCycleNotify(View):
|
|
|
logger.info(repr(e))
|
|
|
return HttpResponse('fail', status=500)
|
|
|
|
|
|
-
|
|
|
-
|
|
|
- def get_plan_desc(self,plan_id):
|
|
|
+ def get_plan_desc(self, plan_id):
|
|
|
paypalrestsdk.configure(PAYPAL_CRD)
|
|
|
billing_plan = paypalrestsdk.BillingPlan.find(plan_id)
|
|
|
print("Got Billing Plan Details for Billing Plan[%s]" % (billing_plan.id))
|
|
@@ -611,24 +624,26 @@ class payCycle(View):
|
|
|
if operation is None:
|
|
|
return response.json(444, 'error path')
|
|
|
elif operation == 'queryPayCycle': # paypal成功订阅回调
|
|
|
- return self.do_query_pay_cycle(request_dict,userID, response)
|
|
|
+ return self.do_query_pay_cycle(request_dict, userID, response)
|
|
|
elif operation == 'cancelPayCycle': # 取消自动续费
|
|
|
- return self.do_cancel_pay_cycle(request_dict,userID, response)
|
|
|
+ return self.do_cancel_pay_cycle(request_dict, userID, response)
|
|
|
+
|
|
|
def do_query_pay_cycle(self, request_dict, userID, response):
|
|
|
lang = request_dict.get('lang', 'en')
|
|
|
- uid = request_dict.get('uid',None)
|
|
|
- orderObject = Order_Model.objects.filter(userID=userID,status=1,rank__lang__lang=lang).annotate(rank__title=F('rank__lang__title'), rank__content=F('rank__lang__content'))
|
|
|
+ uid = request_dict.get('uid', None)
|
|
|
+ orderObject = Order_Model.objects.filter(userID=userID, status=1, rank__lang__lang=lang).annotate(
|
|
|
+ rank__title=F('rank__lang__title'), rank__content=F('rank__lang__content'))
|
|
|
if uid:
|
|
|
orderObject = orderObject.filter(UID=uid)
|
|
|
- orderObject = orderObject.filter(~Q(agreement_id = ''))
|
|
|
+ orderObject = orderObject.filter(~Q(agreement_id=''))
|
|
|
if not orderObject.exists():
|
|
|
- return response.json(0, {'data':[], 'count': 0})
|
|
|
+ return response.json(0, {'data': [], 'count': 0})
|
|
|
orderQuery = orderObject.values("orderID", "UID", "channel", "desc", "price", "currency",
|
|
|
- "addTime",
|
|
|
- "updTime", "paypal", "rank__day", "payType",
|
|
|
- "rank__price", "status",
|
|
|
- "rank__lang__content", "rank__lang__title", "rank__currency",
|
|
|
- "rank_id", "rank__expire","agreement_id").order_by('addTime')
|
|
|
+ "addTime",
|
|
|
+ "updTime", "paypal", "rank__day", "payType",
|
|
|
+ "rank__price", "status",
|
|
|
+ "rank__lang__content", "rank__lang__title", "rank__currency",
|
|
|
+ "rank_id", "rank__expire", "agreement_id").order_by('addTime')
|
|
|
new_data = []
|
|
|
values = []
|
|
|
for d in orderQuery:
|
|
@@ -641,7 +656,7 @@ class payCycle(View):
|
|
|
def do_cancel_pay_cycle(self, request_dict, userID, response):
|
|
|
orderID = request_dict.get('orderID', 'None')
|
|
|
orderObject = Order_Model.objects.filter(orderID=orderID)
|
|
|
- orderObject = orderObject.filter(~Q(agreement_id = '')).values("agreement_id")
|
|
|
+ orderObject = orderObject.filter(~Q(agreement_id='')).values("agreement_id")
|
|
|
if not orderObject.exists():
|
|
|
return response.json(800)
|
|
|
|
|
@@ -660,15 +675,3 @@ class payCycle(View):
|
|
|
return response.json(10052)
|
|
|
except Exception as e:
|
|
|
return response.json(10052)
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|