|
@@ -105,17 +105,29 @@ class InAppPurchaseView(View):
|
|
|
|
|
|
signed_transaction_info = transaction_info.signedTransactionInfo
|
|
|
|
|
|
- # 处理一台手机多账号登录订阅情况
|
|
|
if original_transaction_identifier != "":
|
|
|
device_apple_package_qs = DeviceApplePackage.objects.filter(
|
|
|
original_transaction_id=original_transaction_identifier)
|
|
|
if device_apple_package_qs.exists():
|
|
|
- if device_apple_package_qs[0].userID != user_id:
|
|
|
- pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
|
|
|
+ # 第一种情况: 套餐已过期再次订阅
|
|
|
+ if device_apple_package_qs[0].uid == uid and device_apple_package_qs[0].subscription_status == 2:
|
|
|
+ # 使用App Store服务器通知接口订阅
|
|
|
+ pay_result_url = CommonService.get_payment_status_url(lang, 'success')
|
|
|
return response.json(0, {'url': pay_result_url})
|
|
|
+
|
|
|
+ # 第二种情况: 套餐未过期已取消再次订阅
|
|
|
elif device_apple_package_qs[0].uid == uid and device_apple_package_qs[0].subscription_status == 3:
|
|
|
- device_apple_package_qs.update(subscription_status=1)
|
|
|
- pay_result_url = CommonService.get_payment_status_url(lang, 'success')
|
|
|
+ # 使用App Store服务器通知接口修改订阅状态
|
|
|
+ pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
|
|
|
+ return response.json(0, {'url': pay_result_url})
|
|
|
+
|
|
|
+ # 第三种情况: 首次订阅
|
|
|
+ elif device_apple_package_qs[0].uid == uid and device_apple_package_qs[0].subscription_status == 0:
|
|
|
+ logger.info(f"首次订阅直接充值,orderID:{order_id}")
|
|
|
+
|
|
|
+ else:
|
|
|
+ logger.info(f"错误调用此借口,orderID:{order_id}, uid:{uid}, 订阅状态:{device_apple_package_qs[0].subscription_status}")
|
|
|
+ pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
|
|
|
return response.json(0, {'url': pay_result_url})
|
|
|
|
|
|
# transaction_id相同的情况 ---- 本次订阅未过期,用户在苹果设置中将订阅重新打开时会传上次订阅相同的 transaction_id。
|
|
@@ -470,8 +482,128 @@ class InAppPurchaseView(View):
|
|
|
cls.do_vod_msg_notice(uid, user_id, lang, sys_msg_text_list)
|
|
|
|
|
|
elif str(decoded_payload.rawNotificationType) == "SUBSCRIBED":
|
|
|
- # 处理订阅 ---> 充值逻辑写在了认证交易
|
|
|
- pass
|
|
|
+ # 处理订阅 ---> 首次充值逻辑写在了认证交易
|
|
|
+ if decoded_payload.rawSubtype == "RESUBSCRIBE":
|
|
|
+ decoded_transaction_information = verifier.verify_and_decode_signed_transaction(
|
|
|
+ decoded_payload.data.signedTransactionInfo)
|
|
|
+ # originalTransactionId 原始购买的交易标识符
|
|
|
+ original_transaction_id = decoded_transaction_information.originalTransactionId
|
|
|
+ transaction_id = decoded_transaction_information.transactionId
|
|
|
+ logger.info(
|
|
|
+ f"App Store服务器通知originalTransactionId原始购买的交易标识符{original_transaction_id}")
|
|
|
+ if not original_transaction_id:
|
|
|
+ logger.info(f"App Store服务器通知originalTransactionId原始购买的交易标识符为空, 返回状态 400")
|
|
|
+ return HttpResponse(status=400)
|
|
|
+ else:
|
|
|
+ ord_order = Order_Model.objects.filter(
|
|
|
+ original_transaction_id=original_transaction_id).order_by('-addTime').values("channel",
|
|
|
+ "UID",
|
|
|
+ "payType",
|
|
|
+ "userID_id")
|
|
|
+ channel = ord_order[0]["channel"]
|
|
|
+ uid = ord_order[0]["UID"]
|
|
|
+ pay_type = ord_order[0]["payType"]
|
|
|
+ user_id = ord_order[0]["userID_id"]
|
|
|
+ # 用产品id找到使用的套餐
|
|
|
+ product_id = decoded_transaction_information.productId
|
|
|
+ rank_id = InAppPurchasePackage.objects.filter(product_id=product_id).values("rank")[0]["rank"]
|
|
|
+ store_qs = Store_Meal.objects.filter(id=rank_id). \
|
|
|
+ values(
|
|
|
+ 'id', 'currency', 'price', 'lang__content', 'day', 'commodity_type', 'lang__title',
|
|
|
+ 'expire', 'lang__lang',
|
|
|
+ 'commodity_code', 'discount_price', 'bucket_id', 'bucket__mold', 'cycle_config_id', 'is_ai')
|
|
|
+ if not store_qs.exists():
|
|
|
+ logger.info(f"App Store服务器通知云存套餐不存在, 返回状态 400")
|
|
|
+ return HttpResponse(status=400)
|
|
|
+
|
|
|
+ order_id = CommonService.createOrderID()
|
|
|
+ rank_id = store_qs[0]['id']
|
|
|
+ bucket_id = store_qs[0]['bucket_id']
|
|
|
+ currency = store_qs[0]['currency']
|
|
|
+ price = store_qs[0]['price']
|
|
|
+ is_ai = store_qs[0]['is_ai']
|
|
|
+ expire = store_qs[0]['expire']
|
|
|
+ end_time = CommonService.calcMonthLater(expire)
|
|
|
+ content = store_qs[0]['lang__content']
|
|
|
+ commodity_code = store_qs[0]['commodity_code']
|
|
|
+ commodity_type = store_qs[0]['commodity_type']
|
|
|
+ lang = store_qs[0]['lang__lang']
|
|
|
+ order_type = 1 if is_ai else 0
|
|
|
+
|
|
|
+ store_meal_qs = Store_Meal.objects.filter(id=rank_id, lang__lang='cn', is_show=0). \
|
|
|
+ values('lang__title', 'lang__content')
|
|
|
+ if store_meal_qs.exists():
|
|
|
+ store_meal_name = store_meal_qs[0]['lang__title'] + '-' + store_meal_qs[0]['lang__content']
|
|
|
+ else:
|
|
|
+ store_meal_name = '未知套餐'
|
|
|
+
|
|
|
+ # 查询设备是否已开过云存
|
|
|
+ use_flag = True
|
|
|
+ uid_bucket_qs = UID_Bucket.objects.filter(uid=uid). \
|
|
|
+ values('id', 'bucket_id', 'bucket__region', 'endTime', 'use_status')
|
|
|
+ now_time = int(time.time())
|
|
|
+ if uid_bucket_qs.exists():
|
|
|
+ uid_bucket = uid_bucket_qs.first()
|
|
|
+ uid_bucket_id = uid_bucket['id']
|
|
|
+ # 叠加相同套餐的过期时间
|
|
|
+ if uid_bucket['use_status'] == 1 and uid_bucket['endTime'] > now_time:
|
|
|
+ Unused_Uid_Meal.objects.create(
|
|
|
+ uid=uid, channel=channel, addTime=now_time, order_id=order_id, expire=expire,
|
|
|
+ is_ai=is_ai,
|
|
|
+ bucket_id=bucket_id)
|
|
|
+ UID_Bucket.objects.filter(id=uid_bucket_id).update(has_unused=1)
|
|
|
+ use_flag = False
|
|
|
+ # 更新套餐的过期时间
|
|
|
+ else:
|
|
|
+ UID_Bucket.objects.filter(id=uid_bucket_id).update(
|
|
|
+ channel=channel, bucket_id=bucket_id, endTime=end_time, updateTime=now_time,
|
|
|
+ use_status=1,
|
|
|
+ orderId=order_id)
|
|
|
+ else:
|
|
|
+ uid_bucket = UID_Bucket.objects.create(
|
|
|
+ uid=uid, channel=channel, bucket_id=bucket_id, endTime=end_time, use_status=1,
|
|
|
+ orderId=order_id,
|
|
|
+ addTime=now_time, updateTime=now_time)
|
|
|
+ uid_bucket_id = uid_bucket.id
|
|
|
+
|
|
|
+ # 开通AI服务
|
|
|
+ if is_ai and use_flag:
|
|
|
+ ai_service = AiService.objects.filter(uid=uid, channel=channel)
|
|
|
+ # 有正在使用的套餐,叠加套餐时间,否则创建
|
|
|
+ if ai_service.exists():
|
|
|
+ ai_service.update(updTime=now_time, use_status=1, orders_id=order_id,
|
|
|
+ endTime=end_time)
|
|
|
+ else:
|
|
|
+ AiService.objects.create(
|
|
|
+ uid=uid, channel=channel, detect_status=1, use_status=1, orders_id=order_id,
|
|
|
+ addTime=now_time, updTime=now_time, endTime=end_time)
|
|
|
+
|
|
|
+ Order_Model.objects.create(
|
|
|
+ orderID=order_id, UID=uid, channel=channel, userID_id=user_id, desc=content,
|
|
|
+ payType=pay_type,
|
|
|
+ payTime=now_time, price=price, currency=currency, addTime=now_time, updTime=now_time,
|
|
|
+ order_type=order_type, commodity_code=commodity_code, commodity_type=commodity_type,
|
|
|
+ rank_id=rank_id,
|
|
|
+ ai_rank_id=1, status=1, create_vod=1, store_meal_name=store_meal_name,
|
|
|
+ uid_bucket_id=uid_bucket_id, transaction_id=transaction_id,
|
|
|
+ original_transaction_id=original_transaction_id
|
|
|
+ )
|
|
|
+
|
|
|
+ # 发送云存开通信息
|
|
|
+ date_time = time.strftime("%Y-%m-%d", time.localtime())
|
|
|
+ # 如果存在序列号,消息提示用序列号
|
|
|
+ device_info_qs = Device_Info.objects.filter(UID=uid).values('serial_number', 'Type')
|
|
|
+ serial_number = device_info_qs[0]['serial_number']
|
|
|
+ device_type = device_info_qs[0]['Type']
|
|
|
+ if serial_number:
|
|
|
+ device_name = CommonService.get_full_serial_number(uid, serial_number, device_type)
|
|
|
+ else:
|
|
|
+ device_name = uid
|
|
|
+ sys_msg_text_list = [
|
|
|
+ '温馨提示:尊敬的客户,您的{}设备在{}已成功续订云存套餐'.format(device_name, date_time),
|
|
|
+ 'Dear customer,you already subscribed the cloud storage package successfully for device {} on '.
|
|
|
+ format(device_name, time.strftime('%b %dth,%Y', time.localtime()))]
|
|
|
+ cls.do_vod_msg_notice(uid, user_id, lang, sys_msg_text_list)
|
|
|
|
|
|
elif str(decoded_payload.rawNotificationType) == "EXPIRED":
|
|
|
# 一种通知类型,与其子类型一起表示订阅已过期。如果subtype为
|
|
@@ -503,6 +635,16 @@ class InAppPurchaseView(View):
|
|
|
DeviceApplePackage.objects.filter(original_transaction_id=original_transaction_id).update(
|
|
|
subscription_status=3)
|
|
|
|
|
|
+ elif decoded_payload.rawSubtype == "AUTO_RENEW_ENABLED":
|
|
|
+ # 自动续订被开启
|
|
|
+ decoded_transaction_information = verifier.verify_and_decode_signed_transaction(
|
|
|
+ decoded_payload.data.signedTransactionInfo)
|
|
|
+ original_transaction_id = decoded_transaction_information.originalTransactionId
|
|
|
+ if original_transaction_id:
|
|
|
+ DeviceApplePackage.objects.filter(original_transaction_id=original_transaction_id).update(
|
|
|
+ subscription_status=1)
|
|
|
+
|
|
|
+
|
|
|
elif str(decoded_payload.rawNotificationType) == "REFUND":
|
|
|
# 一种通知类型,表示 App Store 成功退还了消耗性应用内购买、非消耗性应用内购买、自动续订或不可续订的交易。
|
|
|
# revocationDate 包含退款交易的时间戳。originalTransactionId 和 productId 用于标识原始交易和产品。revocationReason 包含原因。
|