PaymentCycle.py 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. import datetime as date_time
  2. import json
  3. import logging
  4. import threading
  5. import time
  6. import traceback
  7. import paypalrestsdk
  8. from django.db import transaction
  9. from django.db.models import Q, F
  10. from django.http import HttpResponseRedirect, HttpResponse
  11. from django.views.generic.base import View
  12. from AdminController.CloudServiceManage.AgentOrderController import AgentOrderView
  13. from Ansjer.config import PAYPAL_CRD, SERVER_DOMAIN_SSL, PAYPAL_WEB_HOOK_ID, CONFIG_INFO, \
  14. CONFIG_US, CONFIG_EUR
  15. from Controller import CloudStorage
  16. from Model.models import PayCycleConfigModel, Store_Meal, UID_Bucket, PromotionRuleModel, \
  17. Unused_Uid_Meal, Device_Info, CouponModel, Order_Model, PaypalWebHookEvent, CountryModel, AiService
  18. from Object.RedisObject import RedisObject
  19. from Object.ResponseObject import ResponseObject
  20. from Object.TokenObject import TokenObject
  21. from Service.CommonService import CommonService
  22. PAY_LOGGER = logging.getLogger('pay')
  23. # 周期扣款相关
  24. class Paypal:
  25. # 检查是否有重复订阅
  26. def checkSubscriptions(userID, uid, rank, app_type):
  27. hasOrder = Order_Model.objects.filter(UID=uid, app_type=app_type)
  28. hasOrder = hasOrder.filter(~Q(agreement_id='')).values('agreement_id', 'orderID').order_by('-addTime')[0:1]
  29. if not hasOrder.exists():
  30. return True
  31. if app_type == 1:
  32. paypalrestsdk.configure(PAYPAL_CRD['Zosi'])
  33. elif app_type == 2:
  34. paypalrestsdk.configure(PAYPAL_CRD['Vsees'])
  35. billing_agreement = paypalrestsdk.BillingAgreement.find(hasOrder[0]['agreement_id'])
  36. if billing_agreement.state == 'Active':
  37. return False
  38. return True
  39. def subscriptions(store_info, lang, orderID, price, app_type):
  40. logger = logging.getLogger('pay')
  41. cycle_config = PayCycleConfigModel.objects.filter(id=store_info['cycle_config_id']).values()
  42. if not cycle_config:
  43. logger.info('----创建订阅失败----')
  44. logger.info('订阅配置失败')
  45. return False
  46. cal_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  47. if lang != 'cn':
  48. cal_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  49. return_url = "{SERVER_DOMAIN_SSL}payCycle/paypalCycleReturn?lang={lang}&app_type={app_type}". \
  50. format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL, lang=lang, app_type=app_type)
  51. # call_sub_url = "http://binbin.uicp.vip/cloudstorage/dopaypalcallback?orderID={orderID}".format(
  52. # SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL, orderID=orderID)
  53. # exit(price)
  54. BillingPlan = {
  55. "description": orderID,
  56. "merchant_preferences": {
  57. "auto_bill_amount": "YES",
  58. "cancel_url": cal_url, # 取消协议url
  59. "initial_fail_amount_action": "CANCEL",
  60. "max_fail_attempts": "1", # 允许的最大失败付款尝试次数
  61. "return_url": return_url, # 客户批准协议的url
  62. # "notify_url": "http://www.notify.com", #通知客户协议已创建的 URL。只读并保留供将来使用。
  63. "setup_fee": {
  64. "currency": store_info['currency'],
  65. "value": price,
  66. }
  67. },
  68. "name": store_info['lang__content'],
  69. "payment_definitions": [
  70. {
  71. "amount": {
  72. "currency": store_info['currency'],
  73. "value": store_info['price']
  74. },
  75. # "charge_models": [
  76. # {
  77. # "amount": {
  78. # "currency": "USD",
  79. # "value": "20"
  80. # },
  81. # "type": "TAX" #税金
  82. # }
  83. # ],
  84. "cycles": cycle_config[0]['cycles'],
  85. "frequency": cycle_config[0]['frequency'],
  86. "frequency_interval": cycle_config[0]['frequencyInterval'],
  87. "name": store_info['lang__title'],
  88. "type": "REGULAR"
  89. },
  90. ],
  91. "type": "INFINITE",
  92. }
  93. if app_type == 1:
  94. paypalrestsdk.configure(PAYPAL_CRD['Zosi'])
  95. elif app_type == 2:
  96. paypalrestsdk.configure(PAYPAL_CRD['Vsees'])
  97. billing_plan = paypalrestsdk.BillingPlan(BillingPlan)
  98. if billing_plan.create():
  99. billing_plan.activate() # 激活
  100. plan_id = billing_plan.id
  101. else:
  102. logger.info('----创建计划失败----')
  103. logger.info(billing_plan.error)
  104. return False
  105. now_time = int(time.time())
  106. if cycle_config[0]['frequency'] == "DAY":
  107. start_date_timestamp = now_time + 86400 - 3600 # 下次扣款为明天,提前1个小时扣款
  108. start_date_str = CommonService.timestamp_to_str(start_date_timestamp, "%Y-%m-%dT%H:%M:%SZ")
  109. elif cycle_config[0]['frequency'] == "MONTH":
  110. start_date_timestamp = CommonService.calcMonthLater(1, now_time) - (5 * 86400) # 下次扣款为下个月提前5天扣款
  111. start_date_str = CommonService.timestamp_to_str(start_date_timestamp, "%Y-%m-%dT%H:%M:%SZ")
  112. # 订阅
  113. billingAgreement = {
  114. "name": store_info['lang__content'],
  115. "description": orderID,
  116. "start_date": start_date_str,
  117. "plan": {
  118. "id": plan_id
  119. },
  120. "payer": {
  121. "payment_method": "paypal"
  122. },
  123. }
  124. billing_agreement = paypalrestsdk.BillingAgreement(billingAgreement)
  125. # print(billing_agreement.create())
  126. if billing_agreement.create():
  127. for link in billing_agreement.links:
  128. if link.rel == "approval_url":
  129. return {"plan_id": plan_id, "url": link.href}
  130. else:
  131. logger.info('----创建订阅失败----')
  132. logger.info(billing_agreement.error)
  133. return False
  134. class PaypalCycleNotify(View):
  135. def get(self, request, *args, **kwargs):
  136. request.encoding = 'utf-8'
  137. operation = kwargs.get('operation')
  138. return self.validation(request.GET, request, operation)
  139. def post(self, request, *args, **kwargs):
  140. request.encoding = 'utf-8'
  141. operation = kwargs.get('operation')
  142. return self.validation(request.POST, request, operation)
  143. def validation(self, request_dict, request, operation):
  144. response = ResponseObject()
  145. if operation is None:
  146. return response.json(444, 'error path')
  147. elif operation == 'paypalCycleReturn': # paypal成功订阅回调
  148. return self.do_paypal_cycle_return(request_dict, response)
  149. elif operation == 'paypalCycleNotify': # paypal 周期付款回调
  150. return self.do_paypal_webhook_notify(request_dict, request, response)
  151. elif operation == 'subscriptionBreakNotify': # paypal 订阅相关回调
  152. return self.do_subscription_break_notify(request_dict, request, response)
  153. def create_vod(self, uid, expire, is_ai, now_time, channel, bucket_id, order_id, userid, username):
  154. ubqs = UID_Bucket.objects.filter(uid=uid).values("id", "endTime", "use_status")
  155. end_time = CommonService.calcMonthLater(expire)
  156. use_flag = True
  157. with transaction.atomic():
  158. if ubqs.exists():
  159. ubq = ubqs[0]
  160. uid_bucket_id = ubq['id']
  161. if ubq['use_status'] == 1 and ubq['endTime'] > now_time: # 套餐使用中并且未过期,加入未使用的关联套餐表
  162. Unused_Uid_Meal.objects.create(uid=uid, channel=channel, addTime=now_time, is_ai=is_ai,
  163. order_id=order_id, expire=expire, bucket_id=bucket_id)
  164. UID_Bucket.objects.filter(id=uid_bucket_id).update(has_unused=1)
  165. use_flag = False
  166. else: # 云存服务已过期则重新开通云存服务
  167. UID_Bucket.objects.filter(id=uid_bucket_id).update(uid=uid, channel=channel,
  168. bucket_id=bucket_id,
  169. endTime=end_time,
  170. updateTime=now_time,
  171. use_status=1,
  172. orderId=order_id)
  173. else:
  174. ub_cqs = UID_Bucket.objects.create \
  175. (uid=uid, channel=channel, bucket_id=bucket_id, endTime=end_time, addTime=now_time,
  176. updateTime=now_time, use_status=1, orderId=order_id)
  177. uid_bucket_id = ub_cqs.id
  178. dvq = Device_Info.objects.filter(UID=uid, vodPrimaryUserID='', vodPrimaryMaster='')
  179. if dvq.exists():
  180. dvq_set_update_dict = {
  181. 'vodPrimaryUserID': userid,
  182. 'vodPrimaryMaster': username
  183. }
  184. dvq.update(**dvq_set_update_dict)
  185. # 开通AI服务
  186. if is_ai and use_flag:
  187. ai_service = AiService.objects.filter(uid=uid, channel=channel)
  188. if ai_service.exists(): # 有正在使用的套餐,套餐结束时间保存为套餐有效期
  189. ai_service.update(updTime=now_time, use_status=1, orders_id=order_id, endTime=end_time)
  190. else:
  191. AiService.objects.create(uid=uid, channel=channel, detect_status=1, addTime=now_time,
  192. updTime=now_time, endTime=end_time, use_status=1, orders_id=order_id)
  193. return uid_bucket_id
  194. def do_paypal_cycle_return(self, request_dict, response):
  195. lang = request_dict.get('lang', 'en')
  196. token = request_dict.get('token', None)
  197. app_type = int(request_dict.get('app_type', 1))
  198. logger = logging.getLogger('pay')
  199. logger.info('--------进入paypay首次订阅付款回调--------')
  200. logger.info(request_dict)
  201. if app_type == 1:
  202. paypalrestsdk.configure(PAYPAL_CRD['Zosi'])
  203. elif app_type == 2:
  204. paypalrestsdk.configure(PAYPAL_CRD['Vsees'])
  205. billing_agreement = paypalrestsdk.BillingAgreement()
  206. billing_agreement_response = billing_agreement.execute(token)
  207. if billing_agreement_response.error:
  208. logger.info('----付款失败----')
  209. logger.info(billing_agreement_response.error)
  210. red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  211. if lang != 'cn':
  212. red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  213. return HttpResponseRedirect(red_url)
  214. orderID = billing_agreement_response.description
  215. state = billing_agreement_response.state
  216. nowTime = int(time.time())
  217. promotion_rule_id = ''
  218. logger.info('----订阅详情----')
  219. logger.info(billing_agreement_response)
  220. agreement_id = billing_agreement_response.id
  221. order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
  222. order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
  223. "userID__userID",
  224. "userID__username", 'coupon_id')
  225. if not orderID:
  226. logger.info('----订阅订单号失效----')
  227. red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  228. if lang != 'cn':
  229. red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  230. return HttpResponseRedirect(red_url)
  231. UID = order_list[0]['UID']
  232. if state != 'Active':
  233. order_qs.update(status=2, promotion_rule_id=promotion_rule_id)
  234. logger.info('----UID:{UID},用户名:{last_time} {first_time}首次订阅付款失败----'.format
  235. (UID=UID,
  236. last_time=billing_agreement_response.payer.payer_info.last_name,
  237. first_time=billing_agreement_response.payer.payer_info.first_time,
  238. ))
  239. logger.info('billing_agreement_state')
  240. logger.info(state)
  241. red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  242. if lang != 'cn':
  243. red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  244. return HttpResponseRedirect(red_url)
  245. try:
  246. userid = order_list[0]['userID__userID']
  247. username = order_list[0]['userID__username']
  248. channel = order_list[0]['channel']
  249. rank = order_list[0]['rank']
  250. smqs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire", "is_ai")
  251. bucketId = smqs[0]['bucket_id']
  252. if not smqs.exists():
  253. logger.info('----订阅套餐失效----')
  254. red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  255. if lang != 'cn':
  256. red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  257. return HttpResponseRedirect(red_url)
  258. # ##
  259. ubqs = UID_Bucket.objects.filter(uid=UID).values("id", "bucket_id", "bucket__storeDay", "bucket__region",
  260. "endTime", "use_status")
  261. expire = smqs[0]['expire']
  262. is_ai = smqs[0]['is_ai']
  263. if order_list[0]['isSelectDiscounts'] == 1:
  264. expire = smqs[0]['expire'] * 2
  265. # 是否有促销
  266. promotion = PromotionRuleModel.objects.filter(status=1, startTime__lte=nowTime,
  267. endTime__gte=nowTime).values('id', 'ruleConfig')
  268. if promotion.exists():
  269. promotion_rule_id = promotion[0]['id']
  270. expire = expire * 2
  271. endTime = CommonService.calcMonthLater(expire)
  272. use_flag = True
  273. with transaction.atomic():
  274. if ubqs.exists():
  275. ubq = ubqs[0]
  276. uid_bucket_id = ubq['id']
  277. if ubq['use_status'] == 1 and ubq['endTime'] > nowTime: # 套餐使用中并且未过期,加入未使用的关联套餐表
  278. Unused_Uid_Meal.objects.create(uid=UID, channel=channel, addTime=nowTime, is_ai=is_ai,
  279. order_id=orderID, expire=expire, bucket_id=bucketId)
  280. update_status = UID_Bucket.objects.filter(id=uid_bucket_id).update(has_unused=1)
  281. use_flag = False
  282. else: # 云存服务已过期则重新开通云存服务
  283. update_status = UID_Bucket.objects.filter(id=uid_bucket_id).update(uid=UID, channel=channel,
  284. bucket_id=bucketId,
  285. endTime=endTime,
  286. updateTime=nowTime,
  287. use_status=1,
  288. orderId=orderID)
  289. else:
  290. ub_cqs = UID_Bucket.objects.create \
  291. (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
  292. updateTime=nowTime, use_status=1, orderId=orderID)
  293. update_status = True
  294. uid_bucket_id = ub_cqs.id
  295. dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
  296. if dvq.exists():
  297. dvq_set_update_dict = {
  298. 'vodPrimaryUserID': userid,
  299. 'vodPrimaryMaster': username
  300. }
  301. dvq.update(**dvq_set_update_dict)
  302. # 开通AI服务
  303. if is_ai and use_flag:
  304. ai_service = AiService.objects.filter(uid=UID, channel=channel)
  305. if ai_service.exists(): # 有正在使用的套餐,套餐结束时间保存为套餐有效期
  306. ai_service.update(updTime=nowTime, use_status=1, orders_id=orderID, endTime=endTime)
  307. else:
  308. AiService.objects.create(uid=UID, channel=channel, detect_status=1, addTime=nowTime,
  309. updTime=nowTime, endTime=endTime, use_status=1, orders_id=orderID)
  310. # uid_main_exist = UIDMainUser.objects.filter(UID=UID)
  311. # if not uid_main_exist.exists():
  312. # uid_main_dict = {
  313. # 'UID': UID,
  314. # 'user_id': userid
  315. # }
  316. # UIDMainUser.objects.create(**uid_main_dict)
  317. # 核销coupon
  318. if order_list[0]['coupon_id']:
  319. CouponModel.objects.filter(id=order_list[0]['coupon_id']).update(use_status=2, update_time=nowTime)
  320. logger.info(
  321. 'uid:{},uid_bucket_id:{},update_status:{},order_id:{}'.format(UID, uid_bucket_id, update_status,
  322. orderID))
  323. order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id, create_vod=1, payTime=nowTime,
  324. promotion_rule_id=promotion_rule_id, agreement_id=agreement_id)
  325. # 如果存在序列号,消息提示用序列号
  326. device_name = CommonService.query_serial_with_uid(uid=UID)
  327. datetime = time.strftime("%Y-%m-%d", time.localtime())
  328. sys_msg_text_list = [
  329. '温馨提示:尊敬的客户,您的' + device_name + '设备在' + datetime + '已成功订阅云存套餐',
  330. 'Dear customer, you have now successfully subscribed to the cloud storage plan for device ' + device_name + ' on ' + time.strftime(
  331. "%b %dth,%Y", time.localtime())]
  332. CloudStorage.CloudStorageView().do_vod_msg_notice(UID, channel, userid, lang, sys_msg_text_list,
  333. 'SMS_219738485')
  334. # return response.json(0)
  335. red_url = "{SERVER_DOMAIN_SSL}web/paid2/success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  336. if lang != 'cn':
  337. red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  338. try:
  339. check_thread = threading.Thread(
  340. target=AgentOrderView.check_agent_service_package, args=(orderID, UID, rank)
  341. )
  342. check_thread.start()
  343. except Exception as e:
  344. logger.error('{}paypal自动续费异步检查代理订单失败:{}'.format(orderID, repr(e)))
  345. logger.info('{UID}成功开通paypal自动续费:----'.format(UID=UID))
  346. return HttpResponseRedirect(red_url)
  347. except Exception as e:
  348. print(repr(e))
  349. logger.info('do_paypal_cycle_return支付失败:----')
  350. logger.info('{UID}开通paypal自动续费失败'.format(UID=UID))
  351. logger.info("错误行数:{errLine}".format(errLine=e.__traceback__.tb_lineno))
  352. logger.info(repr(e))
  353. if order_qs:
  354. order_qs.update(status=10, promotion_rule_id=promotion_rule_id)
  355. red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  356. if lang != 'cn':
  357. red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  358. return HttpResponseRedirect(red_url)
  359. def do_paypal_webhook_notify(self, request_dict, request, response):
  360. PAY_LOGGER.info('--------进入周期扣款钩子--------')
  361. if not request.body:
  362. PAY_LOGGER.info('PayPal周期扣款失败---缺失请求体')
  363. return HttpResponse('fail', status=500)
  364. json_agreement_str = request.body.decode("utf-8")
  365. json_obj = json.loads(json_agreement_str)
  366. header = request.META
  367. paypal_body = json_obj.get('resource')
  368. PAY_LOGGER.info('----请求体数据:{}----'.format(json_agreement_str))
  369. PAY_LOGGER.info('----请求头数据:{}----'.format(header))
  370. try:
  371. transmission_id = header.get('HTTP_PAYPAL_TRANSMISSION_ID', None)
  372. transmission_time = header.get('HTTP_PAYPAL_TRANSMISSION_TIME', None)
  373. cert_url = header.get('HTTP_PAYPAL_CERT_URL', None)
  374. transmission_sig = header.get('HTTP_PAYPAL_TRANSMISSION_SIG', None)
  375. auth_algo = header.get('HTTP_PAYPAL_AUTH_ALGO', None)
  376. event_type = json_obj.get('event_type')
  377. summary = json_obj.get('summary')
  378. resource_type = json_obj.get('resource_type')
  379. agreement_id = paypal_body.get('billing_agreement_id')
  380. paypal_transaction_id = paypal_body.get('id')
  381. amount = paypal_body.get('amount')
  382. fee = paypal_body['transaction_fee']['value'] if 'transaction_fee' in paypal_body else 0
  383. PaypalWebHookEventInsert = {
  384. 'webhook_event_id': json_obj.get('id'),
  385. 'resource_type': json_obj.get('resource_type'),
  386. 'event_type': 1,
  387. 'summary': summary,
  388. 'trade_no': paypal_transaction_id,
  389. 'resource': json_agreement_str,
  390. 'created_time': int(time.time()),
  391. }
  392. if event_type != 'PAYMENT.SALE.COMPLETED':
  393. PAY_LOGGER.info('----event_type异常:{}----'.format(event_type))
  394. if resource_type == 'sale' and paypal_body.get('state') == 'completed':
  395. paypalrestsdk.configure(PAYPAL_CRD['Zosi'])
  396. response = paypalrestsdk.WebhookEvent.verify(
  397. transmission_id, transmission_time, PAYPAL_WEB_HOOK_ID['Zosi']['paypalCycleNotify'],
  398. json_agreement_str, cert_url, transmission_sig, auth_algo)
  399. app_type = 1
  400. if not response:
  401. paypalrestsdk.configure(PAYPAL_CRD['Vsees'])
  402. response = paypalrestsdk.WebhookEvent.verify(
  403. transmission_id, transmission_time, PAYPAL_WEB_HOOK_ID['Vsees']['paypalCycleNotify'],
  404. json_agreement_str, cert_url, transmission_sig, auth_algo)
  405. if not response:
  406. PAY_LOGGER.info('PayPal周期扣款失败---签名验证失败')
  407. return HttpResponse('Fail', status=500)
  408. app_type = 2
  409. else:
  410. PAY_LOGGER.info('PayPal周期扣款失败,付款状态有误,resource_type:{},state:{}----'.
  411. format(resource_type, paypal_body.get('state')))
  412. return HttpResponse('Fail', status=500)
  413. nowTime = int(time.time())
  414. if not agreement_id:
  415. # 记录钩子日志
  416. PaypalWebHookEvent.objects.create(**PaypalWebHookEventInsert)
  417. # 普通支付,更新paypal交易id
  418. paymentID = paypal_body.get('parent_payment')
  419. if paymentID and paypal_transaction_id:
  420. # 查询客户地区信息,地区跟服务器配置不匹配,返回500
  421. order_qs = Order_Model.objects.filter(paymentID=paymentID).values('UID', 'userID__region_country',
  422. 'create_vod', 'orderID',
  423. 'channel', 'rank__is_ai',
  424. 'rank__expire', 'rank_id',
  425. 'rank__bucket__id',
  426. 'isSelectDiscounts',
  427. 'userID__username',
  428. 'userID__userID', 'coupon_id')
  429. if not order_qs.exists():
  430. PAY_LOGGER.info('{}PayPal周期扣款失败---根据paymentID查询订单数据不存在'.format(paypal_transaction_id))
  431. return HttpResponse('Fail', status=500)
  432. # 判断用户地区是否跟服务器地区匹配
  433. uid = order_qs[0]['UID']
  434. country_id = order_qs[0]['userID__region_country']
  435. if not self.config_match_region(uid, country_id):
  436. return HttpResponse('Fail', status=500)
  437. # 检查是否云服务代理订单
  438. order_id = order_qs[0]['orderID']
  439. rank = order_qs[0]['rank_id']
  440. if order_qs[0]['create_vod']:
  441. order_qs.update(status=1, trade_no=paypal_transaction_id, updTime=nowTime, fee=fee)
  442. else:
  443. # 是否有促销
  444. expire = order_qs[0]['rank__expire']
  445. isSelectDiscounts = order_qs[0]['isSelectDiscounts']
  446. is_ai = order_qs[0]['rank__is_ai']
  447. channel = order_qs[0]['channel']
  448. bucketId = order_qs[0]['rank__bucket__id']
  449. userid = order_qs[0]['userID__userID']
  450. username = order_qs[0]['userID__username']
  451. coupon_id = order_qs[0]['coupon_id']
  452. promotion = PromotionRuleModel.objects.filter(status=1, startTime__lte=nowTime,
  453. endTime__gte=nowTime).values('id', 'ruleConfig')
  454. if promotion.exists():
  455. promotion_rule_id = promotion[0]['id']
  456. expire = expire * 2
  457. else:
  458. promotion_rule_id = ''
  459. if isSelectDiscounts:
  460. expire = expire * 2
  461. uid_bucket_id = self.create_vod(uid, expire, is_ai, nowTime, channel, bucketId, order_id,
  462. userid, username)
  463. order_qs.update(status=1, trade_no=paypal_transaction_id, updTime=nowTime,
  464. uid_bucket_id=uid_bucket_id, create_vod=1, fee=fee,
  465. promotion_rule_id=promotion_rule_id, agreement_id=agreement_id)
  466. # 核销coupon
  467. if coupon_id:
  468. CouponModel.objects.filter(id=coupon_id).update(use_status=2, update_time=nowTime)
  469. # PayPal支付成功后异步检查是否代理订单
  470. try:
  471. check_thread = threading.Thread(
  472. target=AgentOrderView.check_agent_service_package, args=(order_id, uid, rank)
  473. )
  474. check_thread.start()
  475. except Exception as e:
  476. PAY_LOGGER.error('PayPal周期扣款异步检查代理订单失败,order_id:{},e:{}'.format(order_id, repr(e)))
  477. PAY_LOGGER.info('PayPal周期扣款成功{}---更新交易id:{}'.format(order_id, paypal_transaction_id))
  478. return HttpResponse('success')
  479. else:
  480. PAY_LOGGER.info('PayPal周期扣款失败---paymentID:{}或paypal_transaction_id:{}为空'.
  481. format(paymentID, paypal_transaction_id))
  482. return HttpResponse('fail', status=500)
  483. billing_agreement = paypalrestsdk.BillingAgreement.find(agreement_id)
  484. PAY_LOGGER.info('billing_agreement:{}'.format(billing_agreement))
  485. # 记录钩子日志
  486. PaypalWebHookEventInsert['agreement_desc'] = repr(billing_agreement)
  487. PaypalWebHookEventInsert['agreement_id'] = agreement_id
  488. PaypalWebHookEventInsert['orderID'] = billing_agreement.description
  489. paypal_webhook_event_qs = PaypalWebHookEvent.objects.create(**PaypalWebHookEventInsert)
  490. # 查询订单数据
  491. order_id = billing_agreement.description
  492. order_qs = Order_Model.objects.filter(orderID=order_id).values('UID', 'channel', 'commodity_code', 'rank',
  493. 'isSelectDiscounts', 'plan_id', 'desc',
  494. 'payType', 'currency', 'addTime',
  495. 'commodity_type', 'updTime', 'order_type',
  496. 'userID__userID', 'uid_bucket_id',
  497. 'userID__username', 'userID__region_country',
  498. 'create_vod', 'coupon_id')
  499. if not order_qs.exists():
  500. PAY_LOGGER.info('PayPal周期扣款失败---根据order_id查询订单数据不存在,order_id:{},agreement_id:{}'.
  501. format(order_id, agreement_id))
  502. return HttpResponse('fail', status=500)
  503. # 限制同一订单号十分钟内重复处理请求
  504. redis_obj = RedisObject()
  505. lock_key = order_id + '_paypal_lock'
  506. lock = redis_obj.try_lock(lock_key, '1', 10, 60)
  507. if not lock:
  508. return HttpResponse('Fail', status=500)
  509. # 判断用户地区是否跟服务器地区匹配
  510. uid = order_qs[0]['UID']
  511. country_id = order_qs[0]['userID__region_country']
  512. if not self.config_match_region(uid, country_id):
  513. return HttpResponse('Fail', status=500)
  514. UID = order_qs[0]['UID']
  515. isSelectDiscounts = order_qs[0]['isSelectDiscounts']
  516. coupon_id = order_qs[0]['coupon_id']
  517. userid = order_qs[0]['userID__userID']
  518. username = order_qs[0]['userID__username']
  519. channel = order_qs[0]['channel']
  520. rank = order_qs[0]['rank']
  521. store_meal_qs = Store_Meal.objects.filter(id=rank).values("bucket_id", "expire", "is_ai")
  522. if not store_meal_qs.exists():
  523. PAY_LOGGER.info('{} PayPal周期扣款失败---套餐数据不存在'.format(UID))
  524. return HttpResponse('fail', status=500)
  525. expire = store_meal_qs[0]['expire']
  526. is_ai = store_meal_qs[0]['is_ai']
  527. bucketId = store_meal_qs[0]['bucket_id']
  528. # PayPal周期扣款首次扣款
  529. if billing_agreement.agreement_details.cycles_completed == '0':
  530. if order_qs[0]['create_vod']:
  531. order_qs.update(status=1, trade_no=paypal_transaction_id, updTime=nowTime, fee=fee)
  532. else:
  533. # 是否有促销
  534. promotion = PromotionRuleModel.objects.filter(status=1, startTime__lte=nowTime,
  535. endTime__gte=nowTime).values('id', 'ruleConfig')
  536. if promotion.exists():
  537. promotion_rule_id = promotion[0]['id']
  538. expire = expire * 2
  539. else:
  540. promotion_rule_id = ''
  541. if isSelectDiscounts:
  542. expire = expire * 2
  543. uid_bucket_id = self.create_vod(UID, expire, is_ai, nowTime, channel, bucketId, order_id,
  544. userid, username)
  545. order_qs.update(status=1, trade_no=paypal_transaction_id, updTime=nowTime,
  546. uid_bucket_id=uid_bucket_id, create_vod=1, fee=fee,
  547. promotion_rule_id=promotion_rule_id, agreement_id=agreement_id)
  548. # 核销coupon
  549. if coupon_id:
  550. CouponModel.objects.filter(id=coupon_id).update(use_status=2, update_time=nowTime)
  551. # PayPal首次扣款异步检查是否代理订单
  552. try:
  553. check_thread = threading.Thread(
  554. target=AgentOrderView.check_agent_service_package, args=(order_id, UID, rank)
  555. )
  556. check_thread.start()
  557. except Exception as e:
  558. PAY_LOGGER.error('{}PayPal周期扣款首次异步检查代理订单失败:{}'.format(order_id, repr(e)))
  559. PAY_LOGGER.info('{} PayPal周期扣款首次扣款成功'.format(UID))
  560. return HttpResponse('success')
  561. # 避免续费订单重复支付
  562. if order_qs[0]['addTime'] + 9200 > nowTime:
  563. PAY_LOGGER.info('{} PayPal周期扣款失败---续费订单已创建'.format(UID))
  564. return HttpResponse('success')
  565. repeat_order = Order_Model.objects.filter(trade_no=paypal_transaction_id, status=1)
  566. if repeat_order.exists():
  567. PAY_LOGGER.info('{} PayPal周期扣款失败---交易号已存在'.format(UID))
  568. return HttpResponse('success')
  569. desc = order_qs[0]['desc']
  570. pay_type = order_qs[0]['payType']
  571. commodity_code = order_qs[0]['commodity_code']
  572. commodity_type = order_qs[0]['commodity_type']
  573. plan_id = order_qs[0]['plan_id']
  574. order_type = order_qs[0]['order_type']
  575. endTime = CommonService.calcMonthLater(expire)
  576. use_flag = True
  577. orderID = CommonService.createOrderID()
  578. ubqs = UID_Bucket.objects.filter(uid=UID).values("id", "endTime", "use_status")
  579. with transaction.atomic():
  580. if ubqs.exists():
  581. ubq = ubqs[0]
  582. uid_bucket_id = ubq['id']
  583. if ubq['use_status'] == 1 and ubq['endTime'] > nowTime: # 套餐使用中并且未过期
  584. Unused_Uid_Meal.objects.create(uid=UID, channel=channel, addTime=nowTime, is_ai=is_ai,
  585. order_id=orderID, expire=expire, bucket_id=bucketId)
  586. update_status = UID_Bucket.objects.filter(id=ubq['id']).update(has_unused=1)
  587. use_flag = False
  588. else: # 已过期或者不相同的套餐加入未使用的关联套餐表
  589. update_status = UID_Bucket.objects.filter(id=uid_bucket_id).update(uid=UID, channel=channel,
  590. bucket_id=bucketId,
  591. endTime=endTime,
  592. updateTime=nowTime,
  593. use_status=1,
  594. orderId=orderID)
  595. else:
  596. ub_cqs = UID_Bucket.objects.create(uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime,
  597. addTime=nowTime, updateTime=nowTime, use_status=1,
  598. orderId=orderID)
  599. uid_bucket_id = ub_cqs.id
  600. update_status = True
  601. PAY_LOGGER.info(
  602. 'uid:{},uid_bucket_id:{},update_status:{},order_id:{}'.format(UID, uid_bucket_id, update_status,
  603. orderID))
  604. dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
  605. if dvq.exists():
  606. dvq_set_update_dict = {
  607. 'vodPrimaryUserID': userid,
  608. 'vodPrimaryMaster': username
  609. }
  610. dvq.update(**dvq_set_update_dict)
  611. store_meal_qs = Store_Meal.objects.filter(id=rank, lang__lang='cn', is_show=0).values('lang__title',
  612. 'lang__content')
  613. if store_meal_qs.exists():
  614. store_meal_name = store_meal_qs[0]['lang__title'] + '-' + store_meal_qs[0]['lang__content']
  615. else:
  616. store_meal_name = '未知套餐'
  617. Order_Model.objects.create(orderID=orderID, UID=UID, channel=channel, userID_id=userid,
  618. desc=desc, payType=pay_type, payTime=nowTime,
  619. price=amount.get('total'), app_type=app_type,
  620. currency=order_qs[0]['currency'], addTime=nowTime,
  621. updTime=nowTime, order_type=order_type,
  622. pay_url='', isSelectDiscounts=0, fee=fee,
  623. commodity_code=commodity_code, create_vod=1,
  624. commodity_type=commodity_type, rank_id=rank, paymentID='',
  625. coupon_id='', uid_bucket_id=uid_bucket_id, status=1,
  626. agreement_id=agreement_id, store_meal_name=store_meal_name,
  627. plan_id=plan_id, ai_rank_id=1, trade_no=paypal_transaction_id)
  628. # 开通AI服务
  629. if is_ai and use_flag:
  630. ai_service = AiService.objects.filter(uid=uid, channel=channel)
  631. if ai_service.exists(): # 有正在使用的套餐,套餐结束时间保存为套餐有效期
  632. ai_service.update(updTime=nowTime, use_status=1, orders_id=orderID, endTime=endTime)
  633. else:
  634. AiService.objects.create(uid=uid, channel=channel, detect_status=1, addTime=nowTime,
  635. updTime=nowTime, endTime=endTime, use_status=1, orders_id=orderID)
  636. # 如果存在序列号,消息提示用序列号
  637. device_name = CommonService.query_serial_with_uid(uid=UID)
  638. datetime = time.strftime("%Y-%m-%d", time.localtime())
  639. sys_msg_text_list = [
  640. '温馨提示:尊敬的客户,您的' + device_name + '设备在' + datetime + '已成功续订云存套餐',
  641. 'Dear customer,you already subscribed the cloud storage package successfully for device ' + device_name + ' on ' + time.strftime(
  642. "%b %dth,%Y", time.localtime())]
  643. if pay_type == 1:
  644. lang = 'en'
  645. else:
  646. lang = 'cn'
  647. CloudStorage.CloudStorageView().do_vod_msg_notice(UID, channel, userid, lang,
  648. sys_msg_text_list, 'SMS_219738485')
  649. # 更新agreement
  650. billing_agreement_update_attributes = [
  651. {
  652. "op": "replace",
  653. "path": "/",
  654. "value": {
  655. "description": orderID,
  656. }
  657. }
  658. ]
  659. update_status = billing_agreement.replace(billing_agreement_update_attributes)
  660. # 记录新订单号和更新状态
  661. PaypalWebHookEvent.objects.filter(id=paypal_webhook_event_qs.id).update(newOrderID=orderID,
  662. update_status=update_status)
  663. # PayPal检查是否云服务代理订单
  664. try:
  665. check_thread = threading.Thread(
  666. target=AgentOrderView.check_agent_service_package, args=(orderID, UID, rank)
  667. )
  668. check_thread.start()
  669. except Exception as e:
  670. PAY_LOGGER.error('{}PayPal周期扣款检查代理订单失败:{}'.format(order_id, repr(e)))
  671. PAY_LOGGER.info('{} PayPal周期扣款成功{}'.format(UID, orderID))
  672. return HttpResponse('success')
  673. except Exception as e:
  674. PAY_LOGGER.info('PayPal周期扣款异常: errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  675. return HttpResponse('fail', status=500)
  676. @staticmethod
  677. def config_match_region(uid, country_id):
  678. """
  679. 判断用户地区是否跟服务器地区匹配
  680. @param uid: uid
  681. @param country_id: 国家表id
  682. @return: bool
  683. """
  684. country_qs = CountryModel.objects.filter(id=country_id).values('region_id')
  685. # 不确定用户地区信息,默认美洲
  686. if not country_qs.exists():
  687. if CONFIG_INFO == CONFIG_EUR:
  688. PAY_LOGGER.info(
  689. 'PayPal周期扣款失败---不确定地区的用户请求欧洲服,uid:{},country_id:{}'.format(uid, country_id))
  690. return False
  691. else:
  692. return True
  693. region_id = country_qs[0]['region_id']
  694. PAY_LOGGER.info('uid{}的用户地区信息: country_id:{}, region_id:{}'.format(uid, country_id, region_id))
  695. if (CONFIG_INFO == CONFIG_US and region_id == 4) or (CONFIG_INFO == CONFIG_EUR and region_id != 4):
  696. PAY_LOGGER.info('PayPal周期扣款失败---服务器跟用户地区不匹配')
  697. return False
  698. return True
  699. def do_subscription_break_notify(self, request_dict, request, response):
  700. logger = logging.getLogger('pay')
  701. logger.info('--------进入订阅失败,付款失败,暂停--------')
  702. json_agreement_str = request.body.decode("utf-8")
  703. json_obj = json.loads(json_agreement_str)
  704. header = request.META
  705. paypal_body = json_obj.get('resource')
  706. logger.info('----主体信息----')
  707. logger.info(json_agreement_str)
  708. logger.info('----进入订阅失败头部信息----')
  709. logger.info(header)
  710. try:
  711. transmission_id = header.get('HTTP_PAYPAL_TRANSMISSION_ID', None)
  712. transmission_time = header.get('HTTP_PAYPAL_TRANSMISSION_TIME', None)
  713. cert_url = header.get('HTTP_PAYPAL_CERT_URL', None)
  714. transmission_sig = header.get('HTTP_PAYPAL_TRANSMISSION_SIG', None)
  715. auth_algo = header.get('HTTP_PAYPAL_AUTH_ALGO', None)
  716. event_type = json_obj.get('event_type')
  717. summary = json_obj.get('summary')
  718. resource_type = json_obj.get('resource_type')
  719. paypal_transaction_id = paypal_body.get('id')
  720. amount = paypal_body.get('amount')
  721. # self.get_plan_desc('P-4CG284532S612303METMEINY')
  722. paypalrestsdk.configure(PAYPAL_CRD['Zosi'])
  723. response = paypalrestsdk.WebhookEvent.verify(
  724. transmission_id, transmission_time, PAYPAL_WEB_HOOK_ID['Zosi']['subscriptionBreakNotify'],
  725. json_agreement_str, cert_url, transmission_sig, auth_algo)
  726. logger.info('----验证签名----')
  727. logger.info(response)
  728. if not response:
  729. paypalrestsdk.configure(PAYPAL_CRD['Vsees'])
  730. response = paypalrestsdk.WebhookEvent.verify(
  731. transmission_id, transmission_time, PAYPAL_WEB_HOOK_ID['Vsees']['subscriptionBreakNotify'],
  732. json_agreement_str, cert_url, transmission_sig, auth_algo)
  733. logger.info('----验证签名----')
  734. logger.info(response)
  735. if not response:
  736. return HttpResponse('Fail', status=500)
  737. event_type_code = 0
  738. billing_agreement_id = ''
  739. if event_type == 'PAYMENT.SALE.COMPLETED':
  740. event_type_code = 1
  741. billing_agreement_id = paypal_body.get('billing_agreement_id')
  742. elif event_type == 'PAYMENT.SALE.REVERSED':
  743. billing_agreement_id = paypal_body.get('billing_agreement_id')
  744. event_type_code = 2
  745. elif event_type == 'BILLING.SUBSCRIPTION.CANCELLED':
  746. billing_agreement_id = paypal_body.get('id')
  747. event_type_code = 3
  748. elif event_type == 'BILLING.SUBSCRIPTION.SUSPENDED':
  749. billing_agreement_id = paypal_body.get('id')
  750. event_type_code = 4
  751. elif event_type == 'BILLING.SUBSCRIPTION.PAYMENT.FAILED':
  752. billing_agreement_id = paypal_body.get('id')
  753. event_type_code = 5
  754. elif event_type == 'PAYMENT.SALE.REFUNDED':
  755. billing_agreement_id = paypal_body.get('billing_agreement_id')
  756. event_type_code = 6
  757. PaypalWebHookEventInsert = {
  758. 'webhook_event_id': json_obj.get('id'),
  759. 'resource_type': resource_type,
  760. 'event_type': event_type_code,
  761. 'summary': summary,
  762. 'trade_no': paypal_transaction_id,
  763. 'resource': json_agreement_str,
  764. 'created_time': int(time.time()),
  765. }
  766. if not billing_agreement_id:
  767. # 记录钩子日志
  768. PaypalWebHookEvent.objects.create(**PaypalWebHookEventInsert)
  769. return HttpResponse('success')
  770. billing_agreement = paypalrestsdk.BillingAgreement.find(billing_agreement_id)
  771. # 记录钩子日志
  772. PaypalWebHookEventInsert['agreement_desc'] = repr(billing_agreement)
  773. PaypalWebHookEventInsert['agreement_id'] = billing_agreement_id
  774. PaypalWebHookEventInsert['orderID'] = billing_agreement.description
  775. PaypalWebHookEvent.objects.create(**PaypalWebHookEventInsert)
  776. return HttpResponse('success')
  777. except Exception as e:
  778. print(e)
  779. logger.info('----进入订阅失败----')
  780. logger.info('do_paypal_webhook_notify支付失败:----')
  781. logger.info("错误行数:{errLine}".format(errLine=e.__traceback__.tb_lineno))
  782. logger.info(repr(e))
  783. return HttpResponse('fail', status=500)
  784. def get_plan_desc(self, plan_id):
  785. paypalrestsdk.configure(PAYPAL_CRD)
  786. billing_plan = paypalrestsdk.BillingPlan.find(plan_id)
  787. print("Got Billing Plan Details for Billing Plan[%s]" % (billing_plan.id))
  788. exit()
  789. class payCycle(View):
  790. def get(self, request, *args, **kwargs):
  791. request.encoding = 'utf-8'
  792. operation = kwargs.get('operation')
  793. return self.validation(request.GET, request, operation)
  794. def post(self, request, *args, **kwargs):
  795. request.encoding = 'utf-8'
  796. operation = kwargs.get('operation')
  797. return self.validation(request.POST, request, operation)
  798. def validation(self, request_dict, request, operation):
  799. response = ResponseObject()
  800. token = request_dict.get('token', None)
  801. # 设备主键uid
  802. tko = TokenObject(token)
  803. response.lang = tko.lang
  804. if tko.code != 0:
  805. return response.json(tko.code)
  806. userID = tko.userID
  807. if operation is None:
  808. return response.json(444, 'error path')
  809. elif operation == 'queryPayCycle': # paypal成功订阅回调
  810. return self.do_query_pay_cycle(request_dict, userID, response)
  811. elif operation == 'cancelPayCycle': # 取消自动续费
  812. return self.do_cancel_pay_cycle(request_dict, userID, response)
  813. def do_query_pay_cycle(self, request_dict, userID, response):
  814. lang = request_dict.get('lang', 'en')
  815. uid = request_dict.get('uid', None)
  816. orderObject = Order_Model.objects.filter(userID=userID, status=1, rank__lang__lang=lang).annotate(
  817. rank__title=F('rank__lang__title'), rank__content=F('rank__lang__content'))
  818. if uid:
  819. orderObject = orderObject.filter(UID=uid)
  820. orderObject = orderObject.filter(~Q(agreement_id=''))
  821. if not orderObject.exists():
  822. return response.json(0, {'data': [], 'count': 0})
  823. orderQuery = orderObject.values("orderID", "UID", "channel", "desc", "price", "currency",
  824. "addTime",
  825. "updTime", "paypal", "rank__day", "payType",
  826. "rank__price", "status",
  827. "rank__lang__content", "rank__lang__title", "rank__currency",
  828. "rank_id", "rank__expire", "agreement_id").order_by('addTime')
  829. new_data = []
  830. values = []
  831. for d in orderQuery:
  832. if d['agreement_id'] not in values:
  833. new_data.append(d)
  834. values.append(d['agreement_id'])
  835. count = len(new_data)
  836. return response.json(0, {'data': new_data, 'count': count})
  837. def do_cancel_pay_cycle(self, request_dict, userID, response):
  838. orderID = request_dict.get('orderID', 'None')
  839. orderObject = Order_Model.objects.filter(orderID=orderID)
  840. orderObject = orderObject.filter(~Q(agreement_id='')).values("agreement_id", "app_type")
  841. if not orderObject.exists():
  842. return response.json(800)
  843. app_type = orderObject[0]['app_type']
  844. if app_type == 1:
  845. paypalrestsdk.configure(PAYPAL_CRD['Zosi'])
  846. elif app_type == 2:
  847. paypalrestsdk.configure(PAYPAL_CRD['Vsees'])
  848. BILLING_AGREEMENT_ID = orderObject[0]['agreement_id']
  849. try:
  850. billing_agreement = paypalrestsdk.BillingAgreement.find(BILLING_AGREEMENT_ID)
  851. if billing_agreement.state != 'Active':
  852. Order_Model.objects.filter(agreement_id=BILLING_AGREEMENT_ID).update(agreement_id='')
  853. return response.json(0)
  854. cancel_note = {"note": "Canceling the agreement"}
  855. if billing_agreement.cancel(cancel_note):
  856. Order_Model.objects.filter(agreement_id=BILLING_AGREEMENT_ID).update(agreement_id='')
  857. return response.json(0)
  858. else:
  859. return response.json(10052)
  860. except Exception as e:
  861. return response.json(10052)