فهرست منبع

周期付款 - 修复订阅过期后订阅充值失败的问题

linhaohong 1 سال پیش
والد
کامیت
68b5f227b4
3فایلهای تغییر یافته به همراه37 افزوده شده و 6 حذف شده
  1. 23 4
      Controller/InAppPurchaseController.py
  2. 1 1
      Model/models.py
  3. 13 1
      Object/AppleInAppPurchaseSubscriptionObject.py

+ 23 - 4
Controller/InAppPurchaseController.py

@@ -116,9 +116,9 @@ class InAppPurchaseView(View):
                     pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
                     pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
                     if device_apple_package_qs[0].userID != user_id:
                     if device_apple_package_qs[0].userID != user_id:
                         return response.json(0, {'url': pay_result_url})
                         return response.json(0, {'url': pay_result_url})
-                    elif device_apple_package_qs[0].uid == uid:
+                    elif device_apple_package_qs[0].uid == uid and device_apple_package_qs[0].subscription_status == 0:
                         device_apple_package_qs.update(subscription_status=1)
                         device_apple_package_qs.update(subscription_status=1)
-                        return response.json(0)
+                        return response.json(0, {'url': pay_result_url})
                     else:
                     else:
                         return response.json(0, {'url': pay_result_url})
                         return response.json(0, {'url': pay_result_url})
 
 
@@ -463,7 +463,7 @@ class InAppPurchaseView(View):
                     cls.do_vod_msg_notice(uid, user_id, lang, sys_msg_text_list)
                     cls.do_vod_msg_notice(uid, user_id, lang, sys_msg_text_list)
 
 
             elif str(decoded_payload.rawNotificationType) == "SUBSCRIBED":
             elif str(decoded_payload.rawNotificationType) == "SUBSCRIBED":
-                # 处理订阅
+                # 处理订阅 ---> 充值逻辑写在了认证交易
                 pass
                 pass
 
 
             elif str(decoded_payload.rawNotificationType) == "EXPIRED":
             elif str(decoded_payload.rawNotificationType) == "EXPIRED":
@@ -473,7 +473,14 @@ class InAppPurchaseView(View):
                 # PRICE_INCREASE,则表示订阅已过期,因为客户不同意需要客户同意的价格上涨。如果subtype为
                 # PRICE_INCREASE,则表示订阅已过期,因为客户不同意需要客户同意的价格上涨。如果subtype为
                 # PRODUCT_NOT_FOR_SALE,则表示订阅已过期,因为在订阅尝试续订时,产品已不可购买。
                 # PRODUCT_NOT_FOR_SALE,则表示订阅已过期,因为在订阅尝试续订时,产品已不可购买。
                 # 没有子类型的通知表示订阅因其他原因过期。
                 # 没有子类型的通知表示订阅因其他原因过期。
-                pass
+                decoded_transaction_information = verifier.verify_and_decode_signed_transaction(
+                    decoded_payload.data.signedTransactionInfo)
+
+                # originalTransactionId 原始购买的交易标识符
+                original_transaction_id = decoded_transaction_information.originalTransactionId
+                if original_transaction_id:
+                    DeviceApplePackage.objects.filter(original_transaction_id=original_transaction_id).update(
+                        subscription_status=2)
 
 
             elif str(decoded_payload.rawNotificationType) == "CONSUMPTION_REQUEST":
             elif str(decoded_payload.rawNotificationType) == "CONSUMPTION_REQUEST":
                 # 一种通知类型,指示客户发起了消费型 App 内购买项目或自动续期订阅的退款请求,并且 App Store 要求您提供消费数据。有关详细信息,请参阅发送消耗信息。
                 # 一种通知类型,指示客户发起了消费型 App 内购买项目或自动续期订阅的退款请求,并且 App Store 要求您提供消费数据。有关详细信息,请参阅发送消耗信息。
@@ -488,6 +495,18 @@ class InAppPurchaseView(View):
                     if original_transaction_id:
                     if original_transaction_id:
                         DeviceApplePackage.objects.filter(original_transaction_id=original_transaction_id).update(
                         DeviceApplePackage.objects.filter(original_transaction_id=original_transaction_id).update(
                             subscription_status=0)
                             subscription_status=0)
+
+            elif str(decoded_payload.rawNotificationType) == "REFUND":
+                # 一种通知类型,表示 App Store 成功退还了消耗性应用内购买、非消耗性应用内购买、自动续订或不可续订的交易。
+                # revocationDate 包含退款交易的时间戳。originalTransactionId 和 productId 用于标识原始交易和产品。revocationReason 包含原因。
+                # 要请求客户所有退款交易的列表,请参阅 App Store 服务器 API 中的获取退款历史记录。
+                pass
+
+            elif str(decoded_payload.rawNotificationType) == "REFUND_DECLINED":
+                # 一种通知类型,表示 App Store 由于客户提出的争议而撤销了先前批准的退款。如果您的应用程序因相关退款而撤销了内容或服务,则需要恢复这些内容或服务。
+                # 此通知类型可适用于任何应用程序内购买类型:消耗品、非消耗品、不可续订订阅和自动续订订阅。对于自动续订,当 App Store 撤销退款时,续订日期保持不变。
+                pass
+
             else:
             else:
                 logger.info(f"App Store服务器通知decoded_payload.rawNotificationType 未处理")
                 logger.info(f"App Store服务器通知decoded_payload.rawNotificationType 未处理")
                 return HttpResponse(status=500)
                 return HttpResponse(status=500)

+ 1 - 1
Model/models.py

@@ -5137,7 +5137,7 @@ class DeviceApplePackage(models.Model):
     uid = models.CharField(max_length=20, verbose_name='设备UID', db_index=True)
     uid = models.CharField(max_length=20, verbose_name='设备UID', db_index=True)
     package_id = models.ForeignKey(InAppPurchasePackage, blank=True, to_field='id', null=True,
     package_id = models.ForeignKey(InAppPurchasePackage, blank=True, to_field='id', null=True,
                                    on_delete=models.SET_NULL, verbose_name='关联苹果内购订阅套餐表')
                                    on_delete=models.SET_NULL, verbose_name='关联苹果内购订阅套餐表')
-    subscription_status = models.SmallIntegerField(default=0, verbose_name='订阅状态') # 0:取消订阅, 1:订阅
+    subscription_status = models.SmallIntegerField(default=0, verbose_name='订阅状态') # 0:取消订阅, 1:订阅 2: 订阅已过期
     original_transaction_id = models.CharField(default='', blank=True, max_length=64, verbose_name=u'苹果内购originalTransactionId')
     original_transaction_id = models.CharField(default='', blank=True, max_length=64, verbose_name=u'苹果内购originalTransactionId')
     created_time = models.IntegerField(verbose_name='创建时间', default=0)
     created_time = models.IntegerField(verbose_name='创建时间', default=0)
     update_time = models.IntegerField(verbose_name='更新时间', default=0)
     update_time = models.IntegerField(verbose_name='更新时间', default=0)

+ 13 - 1
Object/AppleInAppPurchaseSubscriptionObject.py

@@ -31,10 +31,22 @@ class InAppSubscription:
         :param uid:
         :param uid:
         :return: True/False True表示已订阅
         :return: True/False True表示已订阅
         """
         """
+        # 查询订单信息
         has_order_qs = Order_Model.objects.filter(UID=uid, payType=5).exclude(original_transaction_id="")
         has_order_qs = Order_Model.objects.filter(UID=uid, payType=5).exclude(original_transaction_id="")
         if not has_order_qs.exists():
         if not has_order_qs.exists():
             return False
             return False
-        has_order = has_order_qs.values('transaction_id', 'orderID', 'addTime').order_by('-addTime')
+        has_order = has_order_qs.values('transaction_id', 'original_transaction_id', 'orderID', 'addTime').order_by(
+            '-addTime')
+
+        # 判断用户是否取消订阅
+        device_apple_package = DeviceApplePackage.objects.filter(
+            original_transaction_id=has_order[0]['original_transaction_id']).values("subscription_status")
+        if not device_apple_package.exists():
+            return False
+        elif device_apple_package[0]['subscription_status'] != 1:
+            return False
+
+        # 通过 transaction_id 获取订阅状态
         subscription_statuses = self.client.get_all_subscription_statuses(has_order[0]['transaction_id'])
         subscription_statuses = self.client.get_all_subscription_statuses(has_order[0]['transaction_id'])
         if not subscription_statuses.data:
         if not subscription_statuses.data:
             return False
             return False