|
@@ -1,5 +1,5 @@
|
|
|
from Ansjer.config import PAYPAL_CRD,SERVER_DOMAIN,SERVER_DOMAIN_SSL
|
|
|
-from Model.models import PayCycleConfigModel,Order_Model, Store_Meal, UID_Bucket, PromotionRuleModel, Unused_Uid_Meal,Device_Info
|
|
|
+from Model.models import PayCycleConfigModel,Order_Model, Store_Meal, UID_Bucket, PromotionRuleModel, Unused_Uid_Meal,Device_Info, CouponModel
|
|
|
from Service.CommonService import CommonService
|
|
|
from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
|
|
|
import requests
|
|
@@ -125,6 +125,8 @@ class PaypalCycleNotify(View):
|
|
|
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 == 'test': # paypal 周期付款回调
|
|
|
+ return self.do_test(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)
|
|
@@ -153,7 +155,7 @@ class PaypalCycleNotify(View):
|
|
|
|
|
|
order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
|
|
|
"userID__userID",
|
|
|
- "userID__username")
|
|
|
+ "userID__username",'coupon_id')
|
|
|
userid = order_list[0]['userID__userID']
|
|
|
username = order_list[0]['userID__username']
|
|
|
UID = order_list[0]['UID']
|
|
@@ -225,6 +227,10 @@ class PaypalCycleNotify(View):
|
|
|
# }
|
|
|
# UIDMainUser.objects.create(**uid_main_dict)
|
|
|
|
|
|
+ # 核销coupon
|
|
|
+ if order_list[0]['coupon_id']:
|
|
|
+ CouponModel.objects.filter(id=order_list[0]['coupon_id']).update(use_status=1)
|
|
|
+
|
|
|
order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id,
|
|
|
promotion_rule_id=promotion_rule_id,agreement_id=agreement_id)
|
|
|
datetime = time.strftime("%Y-%m-%d", time.localtime())
|
|
@@ -267,12 +273,147 @@ class PaypalCycleNotify(View):
|
|
|
transmission_sig = header.get('paypal-transmission-sig',None)
|
|
|
auth_algo = header.get('paypal-auth-algo',None)
|
|
|
resource_type = json_obj.get('resource_type')
|
|
|
+
|
|
|
+ json_str = '{"id":"WH-22P96595RY482870W-2B701244WV459014K","event_version":"1.0","create_time":"2022-01-06T05:56:33.126Z","resource_type":"sale","event_type":"PAYMENT.SALE.COMPLETED","summary":"Payment completed for $ 0.02 USD","resource":{"billing_agreement_id":"I-CR65R6YXS3VA","amount":{"total":"0.02","currency":"USD","details":{"subtotal":"0.02"}},"payment_mode":"INSTANT_TRANSFER","update_time":"2022-01-06T05:56:18Z","create_time":"2022-01-06T05:56:18Z","protection_eligibility_type":"ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE","transaction_fee":{"currency":"USD","value":"0.02"},"protection_eligibility":"ELIGIBLE","links":[{"method":"GET","rel":"self","href":"https://api.sandbox.paypal.com/v1/payments/sale/2FE30648Y2273061H"},{"method":"POST","rel":"refund","href":"https://api.sandbox.paypal.com/v1/payments/sale/2FE30648Y2273061H/refund"}],"id":"2FE30648Y2273061H","state":"completed","invoice_number":""},"links":[{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-22P96595RY482870W-2B701244WV459014K","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-22P96595RY482870W-2B701244WV459014K/resend","rel":"resend","method":"POST"}]}'
|
|
|
+ header = "{'PATH_INFO': '/payCycle/paypalCycleNotify', 'wsgi.file_wrapper': <class 'gunicorn.http.wsgi.FileWrapper'>, 'CONTENT_LENGTH': '1226', 'wsgi.multiprocess': True, 'HTTP_PAYPAL_TRANSMISSION_TIME': '2022-01-06T05:56:36Z', 'wsgi.version': (1, 0), 'SERVER_NAME': '0.0.0.0', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.0', 'REMOTE_PORT': '42322', 'HTTP_HTTP_X_FORWARDED_FOR': '173.0.80.116', 'RAW_URI': '/payCycle/paypalCycleNotify', 'HTTP_X_REAL_IP': '173.0.80.116', 'HTTP_X_B3_SPANID': 'f37d2832010b10f2', 'REMOTE_ADDR': '127.0.0.1', 'wsgi.input': <gunicorn.http.body.Body object at 0x7ff31a5b92b0>, 'HTTP_PAYPAL_TRANSMISSION_SIG': 'JI+rFKqe9YqufExp/aJxkyRWG3II+4t6CSCWLHqNrjcd/FP729G0s8lFMPixnGpUemj4+WsJTbu29G4ZR3zxl+CwrlKhPQxe0fE0mUw+/AaBa6THpnoXEVwz9spI/kbH3dNmSXePfW0D5+HyVmWgkac23icxi4G92ZmmszPBzBdcNIc3BumXGSfJwX19cchta0VY7GnD5ePvW1FstPp9eC7NyhDH11xDpvM2qZZqhxH6hahIywVNA0gyNydkYbkbjnD+hGC+HrKKMx0Tpw8eGxUHReWJIEsiw7YCPLBwZIab5PV/+L4A/LscK/JicOeDealP+SKPJICZvinLHDzK0Q==', 'HTTP_PAYPAL_TRANSMISSION_ID': '688538e0-6eb5-11ec-a473-05e6d85b61e7', 'gunicorn.socket': <socket.socket fd=24, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8082), raddr=('127.0.0.1', 42322)>, 'HTTP_PAYPAL_AUTH_ALGO': 'SHA256withRSA', 'HTTP_PAYPAL_AUTH_VERSION': 'v2', 'wsgi.url_scheme': 'http', 'wsgi.errors': <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7ff31a5b9a58>, 'QUERY_STRING': '', 'wsgi.multithread': False, 'HTTP_CORRELATION_ID': 'b696eaa58ea49', 'HTTP_ACCEPT': '*/*', 'HTTP_USER_AGENT': 'PayPal/AUHD-214.0-56138150', 'CONTENT_TYPE': 'application/json', 'HTTP_PAYPAL_CERT_URL': 'https://api.sandbox.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a594-7a8abba8', 'HTTP_CONNECTION': 'close', 'SERVER_PORT': '8082', 'HTTP_HOST': 'test.zositechc.cn:443', 'HTTP_X_FORWARDED_FOR': '173.0.80.116', 'SERVER_SOFTWARE': 'gunicorn/19.7.1', 'wsgi.run_once': False, 'REQUEST_METHOD': 'POST'}"
|
|
|
+
|
|
|
if resource_type == 'plan':
|
|
|
paypalrestsdk.configure(PAYPAL_CRD)
|
|
|
response = paypalrestsdk.WebhookEvent.verify(
|
|
|
transmission_id, transmission_time, webhook_id, json_str, cert_url, transmission_sig, auth_algo)
|
|
|
|
|
|
- logger.info('response----------------')
|
|
|
- logger.info(response)
|
|
|
- return HttpResponse(json_obj.get('id'))
|
|
|
|
|
|
+
|
|
|
+ logger.info('response----------------')
|
|
|
+ logger.info(response)
|
|
|
+ return HttpResponse(json_obj.get('id'))
|
|
|
+
|
|
|
+
|
|
|
+ def do_test(self, request_dict, request, response):
|
|
|
+
|
|
|
+ json_str = '{"id":"WH-22P96595RY482870W-2B701244WV459014K","event_version":"1.0","create_time":"2022-01-06T05:56:33.126Z","resource_type":"sale","event_type":"PAYMENT.SALE.COMPLETED","summary":"Payment completed for $ 0.02 USD","resource":{"billing_agreement_id":"I-CR65R6YXS3VA","amount":{"total":"0.02","currency":"USD","details":{"subtotal":"0.02"}},"payment_mode":"INSTANT_TRANSFER","update_time":"2022-01-06T05:56:18Z","create_time":"2022-01-06T05:56:18Z","protection_eligibility_type":"ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE","transaction_fee":{"currency":"USD","value":"0.02"},"protection_eligibility":"ELIGIBLE","links":[{"method":"GET","rel":"self","href":"https://api.sandbox.paypal.com/v1/payments/sale/2FE30648Y2273061H"},{"method":"POST","rel":"refund","href":"https://api.sandbox.paypal.com/v1/payments/sale/2FE30648Y2273061H/refund"}],"id":"2FE30648Y2273061H","state":"completed","invoice_number":""},"links":[{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-22P96595RY482870W-2B701244WV459014K","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-22P96595RY482870W-2B701244WV459014K/resend","rel":"resend","method":"POST"}]}'
|
|
|
+ header = "{'PATH_INFO': '/payCycle/paypalCycleNotify', 'wsgi.file_wrapper': <class 'gunicorn.http.wsgi.FileWrapper'>, 'CONTENT_LENGTH': '1226', 'wsgi.multiprocess': True, 'HTTP_PAYPAL_TRANSMISSION_TIME': '2022-01-06T05:56:36Z', 'wsgi.version': (1, 0), 'SERVER_NAME': '0.0.0.0', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.0', 'REMOTE_PORT': '42322', 'HTTP_HTTP_X_FORWARDED_FOR': '173.0.80.116', 'RAW_URI': '/payCycle/paypalCycleNotify', 'HTTP_X_REAL_IP': '173.0.80.116', 'HTTP_X_B3_SPANID': 'f37d2832010b10f2', 'REMOTE_ADDR': '127.0.0.1', 'wsgi.input': <gunicorn.http.body.Body object at 0x7ff31a5b92b0>, 'HTTP_PAYPAL_TRANSMISSION_SIG': 'JI+rFKqe9YqufExp/aJxkyRWG3II+4t6CSCWLHqNrjcd/FP729G0s8lFMPixnGpUemj4+WsJTbu29G4ZR3zxl+CwrlKhPQxe0fE0mUw+/AaBa6THpnoXEVwz9spI/kbH3dNmSXePfW0D5+HyVmWgkac23icxi4G92ZmmszPBzBdcNIc3BumXGSfJwX19cchta0VY7GnD5ePvW1FstPp9eC7NyhDH11xDpvM2qZZqhxH6hahIywVNA0gyNydkYbkbjnD+hGC+HrKKMx0Tpw8eGxUHReWJIEsiw7YCPLBwZIab5PV/+L4A/LscK/JicOeDealP+SKPJICZvinLHDzK0Q==', 'HTTP_PAYPAL_TRANSMISSION_ID': '688538e0-6eb5-11ec-a473-05e6d85b61e7', 'gunicorn.socket': <socket.socket fd=24, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8082), raddr=('127.0.0.1', 42322)>, 'HTTP_PAYPAL_AUTH_ALGO': 'SHA256withRSA', 'HTTP_PAYPAL_AUTH_VERSION': 'v2', 'wsgi.url_scheme': 'http', 'wsgi.errors': <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7ff31a5b9a58>, 'QUERY_STRING': '', 'wsgi.multithread': False, 'HTTP_CORRELATION_ID': 'b696eaa58ea49', 'HTTP_ACCEPT': '*/*', 'HTTP_USER_AGENT': 'PayPal/AUHD-214.0-56138150', 'CONTENT_TYPE': 'application/json', 'HTTP_PAYPAL_CERT_URL': 'https://api.sandbox.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a594-7a8abba8', 'HTTP_CONNECTION': 'close', 'SERVER_PORT': '8082', 'HTTP_HOST': 'test.zositechc.cn:443', 'HTTP_X_FORWARDED_FOR': '173.0.80.116', 'SERVER_SOFTWARE': 'gunicorn/19.7.1', 'wsgi.run_once': False, 'REQUEST_METHOD': 'POST'}"
|
|
|
+
|
|
|
+ json_obj = json.loads(json_str)
|
|
|
+
|
|
|
+ # transmission_id = header.get('HTTP_PAYPAL_TRANSMISSION_ID',None)
|
|
|
+ # transmission_time = header.get('HTTP_PAYPAL_TRANSMISSION_TIME',None)
|
|
|
+ # webhook_id = '6TS30758D98835230'
|
|
|
+ # cert_url = header.get('HTTP_PAYPAL_CERT_URL',None)
|
|
|
+ # transmission_sig = header.get('HTTP_PAYPAL_TRANSMISSION_SIG',None)
|
|
|
+ # auth_algo = header.get('HTTP_PAYPAL_AUTH_ALGO',None)
|
|
|
+ # resource_type = json_obj.get('resource_type')
|
|
|
+
|
|
|
+ transmission_id = '688538e0-6eb5-11ec-a473-05e6d85b61e7'
|
|
|
+ transmission_time = '2022-01-06T05:56:36Z'
|
|
|
+ webhook_id = '6TS30758D98835230'
|
|
|
+ cert_url = 'https://api.sandbox.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a594-7a8abba8'
|
|
|
+ transmission_sig = 'JI+rFKqe9YqufExp/aJxkyRWG3II+4t6CSCWLHqNrjcd/FP729G0s8lFMPixnGpUemj4+WsJTbu29G4ZR3zxl+CwrlKhPQxe0fE0mUw+/AaBa6THpnoXEVwz9spI/kbH3dNmSXePfW0D5+HyVmWgkac23icxi4G92ZmmszPBzBdcNIc3BumXGSfJwX19cchta0VY7GnD5ePvW1FstPp9eC7NyhDH11xDpvM2qZZqhxH6hahIywVNA0gyNydkYbkbjnD+hGC+HrKKMx0Tpw8eGxUHReWJIEsiw7YCPLBwZIab5PV/+L4A/LscK/JicOeDealP+SKPJICZvinLHDzK0Q=='
|
|
|
+ auth_algo = 'SHA256withRSA'
|
|
|
+ resource_type = json_obj.get('resource_type')
|
|
|
+
|
|
|
+ if resource_type == 'sale':
|
|
|
+ paypalrestsdk.configure(PAYPAL_CRD)
|
|
|
+ response = paypalrestsdk.WebhookEvent.verify(
|
|
|
+ transmission_id, transmission_time, webhook_id, json_str, cert_url, transmission_sig, auth_algo)
|
|
|
+ if response:
|
|
|
+ try:
|
|
|
+ agreement_id = json_obj.get('resource')['billing_agreement_id']
|
|
|
+ order_qs = Order_Model.objects.filter(agreement_id=agreement_id, status=0)
|
|
|
+
|
|
|
+ if not order_qs:
|
|
|
+ return False
|
|
|
+ order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
|
|
|
+ "userID__userID",
|
|
|
+ "userID__username")
|
|
|
+ return HttpResponse(order_list)
|
|
|
+
|
|
|
+ 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():
|
|
|
+ print("not smqs")
|
|
|
+ red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
|
|
|
+ if lang != 'cn':
|
|
|
+ red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(
|
|
|
+ SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
|
|
|
+ return HttpResponseRedirect(red_url)
|
|
|
+ # ##
|
|
|
+ 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]
|
|
|
+ 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: # 已过期或者不相同的套餐加入未使用的关联套餐表
|
|
|
+ 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 = 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)
|
|
|
+ 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)
|
|
|
+ uid_bucket_id = ub_cqs.id
|
|
|
+
|
|
|
+ dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
|
|
|
+ if dvq.exists():
|
|
|
+ dvq_set_update_dict = {
|
|
|
+ 'vodPrimaryUserID': userid,
|
|
|
+ 'vodPrimaryMaster': username
|
|
|
+ }
|
|
|
+ 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)
|
|
|
+
|
|
|
+ order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id,
|
|
|
+ promotion_rule_id=promotion_rule_id, agreement_id=agreement_id)
|
|
|
+ datetime = time.strftime("%Y-%m-%d", time.localtime())
|
|
|
+ sys_msg_text_list = ['温馨提示:尊敬的客户,您的' + UID + '设备在' + datetime + '已成功订阅云存套餐',
|
|
|
+ 'Dear customer,you already subscribed the cloud storage package successfully for device ' + UID + ' on ' + time.strftime(
|
|
|
+ "%b %dth,%Y", time.localtime())]
|
|
|
+
|
|
|
+ CloudStorage.CloudStorageView.do_vod_msg_Notice(self, UID, channel, userid, lang,
|
|
|
+ sys_msg_text_list, 'SMS_219738485')
|
|
|
+ return True
|
|
|
+ except Exception as e:
|
|
|
+ print(repr(e))
|
|
|
+ if order_qs:
|
|
|
+ order_qs.update(status=10, promotion_rule_id=promotion_rule_id)
|
|
|
+ return False
|
|
|
+ return False
|