ソースを参照

苹果内购 - 封装代码

linhaohong 10 ヶ月 前
コミット
b51eea6d7d

+ 30 - 0
Ansjer/config.py

@@ -575,6 +575,36 @@ APP_MAPPING = {
 
 
 }
 }
 
 
+# 苹果内购配置
+IN_APP_CONFIG = {
+    # Zosi Smart 配置
+    'com.ansjer.zccloud': {
+        'key_id': 'N42WMFCV6A',
+        'issuer_id': '69a6de8c-789b-47e3-e053-5b8c7c11a4d1',
+        'cert_names': [
+            'AppleIncRootCertificate.cer',
+            'AppleComputerRootCertificate.cer',
+            'AppleRootCA-G2.cer',
+            'AppleRootCA-G3.cer'
+        ],
+        "key_filename": "SubscriptionKey_N42WMFCV6A.p8",
+        "app_apple_id": 1355964934
+    },
+    # Vsees 配置
+    'com.cloudlife.commissionf': {
+        'key_id': 'N42WMFCV6A',
+        'issuer_id': '69a6de8c-789b-47e3-e053-5b8c7c11a4d1',
+        'cert_names': [
+            'AppleIncRootCertificate.cer',
+            'AppleComputerRootCertificate.cer',
+            'AppleRootCA-G2.cer',
+            'AppleRootCA-G3.cer'
+        ],
+        "key_filename": "SubscriptionKey_N42WMFCV6A.p8",
+        "app_apple_id": 1355964934
+    },
+}
+
 SHOPIFY_CONFIG = {
 SHOPIFY_CONFIG = {
     "eu_token": "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",
     "eu_token": "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",
     "eu_multipass_secret": "f4863c9979d7ddd16e23817c0dfe7863"
     "eu_multipass_secret": "f4863c9979d7ddd16e23817c0dfe7863"

+ 134 - 97
Controller/InAppPurchaseController.py

@@ -23,9 +23,10 @@ from django.http import HttpResponse
 from Ansjer.config import LOGGER, CONFIG_INFO, CONFIG_TEST, PAY_TYPE_IN_APP_PURCHASE, BASE_DIR, CONFIG_US
 from Ansjer.config import LOGGER, CONFIG_INFO, CONFIG_TEST, PAY_TYPE_IN_APP_PURCHASE, BASE_DIR, CONFIG_US
 from Controller.CheckUserData import DataValid
 from Controller.CheckUserData import DataValid
 from Model.models import Order_Model, Store_Meal, Device_Info, UID_Bucket, Unused_Uid_Meal, AiService, Device_User, \
 from Model.models import Order_Model, Store_Meal, Device_Info, UID_Bucket, Unused_Uid_Meal, AiService, Device_User, \
-    SysMsgModel
+    SysMsgModel, InAppPurchasePackage
 from Object.AWS.S3Email import S3Email
 from Object.AWS.S3Email import S3Email
 from Object.AliSmsObject import AliSmsObject
 from Object.AliSmsObject import AliSmsObject
+from Object.AppleInAppPurchaseSubscriptionObject import InAppPurchase
 from Object.RedisObject import RedisObject
 from Object.RedisObject import RedisObject
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
 
 
@@ -67,6 +68,7 @@ class InAppPurchaseView(View):
         uid = request_dict.get('uid', None)
         uid = request_dict.get('uid', None)
         lang = request_dict.get('lang', 'en')
         lang = request_dict.get('lang', 'en')
         channel = request_dict.get('channel', None)
         channel = request_dict.get('channel', None)
+        app_type = request_dict.get('appType', 1)
         logger = logging.getLogger('apple_pay')
         logger = logging.getLogger('apple_pay')
         logger.info(f"receipt: {receipt}, 订单orderId: {order_id}, uid: {uid}")
         logger.info(f"receipt: {receipt}, 订单orderId: {order_id}, uid: {uid}")
 
 
@@ -82,128 +84,74 @@ class InAppPurchaseView(View):
             return response.json(5)
             return response.json(5)
 
 
         try:
         try:
-            # 从交易信息中获取product_id
-            key_path = '{}/Ansjer/file/in_app_purchase/SubscriptionKey_N42WMFCV6A.p8'.format(BASE_DIR)
-            with open(key_path, 'rb') as file:
-                # 读取文件内容
-                private_key = file.read()
-
-            key_id = 'N42WMFCV6A'
-            issuer_id = '69a6de8c-789b-47e3-e053-5b8c7c11a4d1'
-            bundle_id = 'com.ansjer.zccloud'
-            environment = ENV
-
-            client = AppStoreServerAPIClient(private_key, key_id, issuer_id, bundle_id, environment)
-            receipt_util = ReceiptUtility()
-
+            # 检查商品id是否正确
+            app_type = int(app_type)
+            if app_type == 1:
+                bundle_id = "com.ansjer.zccloud"
+            elif app_type == 2:
+                bundle_id = "com.cloudlife.commissionf"
+            else:
+                return response.json(444, "app_type不存在")
+            # 实例化订阅类
+            in_app_purchase = InAppPurchase(bundle_id=bundle_id)
+
+            # ReceiptUtility 用于解析收据为transaction_id
+            receipt_util = in_app_purchase.receipt_util
+            # AppStoreServerAPIClient 用于查询交易信息
+            client = in_app_purchase.client
+            # SignedDataVerifier 用于解析查询到的交易信息
+            signed_data_verifier = in_app_purchase.verifier
+
+            # 解析收据(循环扣款时不需要这一步, 直接获取transaction_id)
             transaction_id = receipt_util.extract_transaction_id_from_app_receipt(receipt)
             transaction_id = receipt_util.extract_transaction_id_from_app_receipt(receipt)
-            logger.info(f"订单orderId:{order_id}, transaction_id:{transaction_id}")
-
             if transaction_id is None:
             if transaction_id is None:
                 pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
                 pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
                 return response.json(0, {'url': pay_result_url})
                 return response.json(0, {'url': pay_result_url})
+            logger.info(f"订单orderId:{order_id}, transaction_id:{transaction_id}")
 
 
+            # 查询交易信息
             transaction_info = client.get_transaction_info(transaction_id)
             transaction_info = client.get_transaction_info(transaction_id)
-
             signed_transaction_info = transaction_info.signedTransactionInfo
             signed_transaction_info = transaction_info.signedTransactionInfo
-
-            root_certificates = []
-            for cert_name in [
-                'AppleIncRootCertificate.cer', 'AppleComputerRootCertificate.cer',
-                'AppleRootCA-G2.cer', 'AppleRootCA-G3.cer'
-            ]:
-                cert_path = '{}/Ansjer/file/in_app_purchase/{}'.format(BASE_DIR, cert_name)
-                with open(cert_path, 'rb') as file:
-                    # 读取文件内容
-                    root_certificates.append(file.read())
-
-            enable_online_checks = True
-            app_apple_id = 1355964934  # 生产环境必需
-            signed_data_verifier = SignedDataVerifier(
-                root_certificates, enable_online_checks, environment, bundle_id, app_apple_id)
-
+            # 解析交易信息
             payload = signed_data_verifier.verify_and_decode_signed_transaction(signed_transaction_info)
             payload = signed_data_verifier.verify_and_decode_signed_transaction(signed_transaction_info)
 
 
-            product_id = None
-
-            if payload and payload.productId:
-                product_id = payload.productId
-
+            # 获取交易的商品id
+            product_id = payload.productId if payload and payload.productId else None
             if not product_id:
             if not product_id:
                 pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
                 pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
                 return response.json(0, {'url': pay_result_url})
                 return response.json(0, {'url': pay_result_url})
 
 
-            now_time = int(time.time())
-            order_qs = Order_Model.objects.filter(orderID=order_id, UID=uid).values("rank_id")
+            in_app_purchase_package_qs = InAppPurchasePackage.objects.filter(product_id=product_id, app_type=app_type)
+            if not in_app_purchase_package_qs.exists():
+                return response.json(173, "内购商品id不存在")
+
+            # 验证订单是否存在
+            order_qs = Order_Model.objects.filter(orderID=order_id, UID=uid, app_type=app_type).values("rank_id")
             if not order_qs.exists():
             if not order_qs.exists():
                 return response.json(173, "订单不存在")
                 return response.json(173, "订单不存在")
+
+            # 验证套餐是否存在
             store_qs = Store_Meal.objects.filter(id=order_qs[0]['rank_id']).values(
             store_qs = Store_Meal.objects.filter(id=order_qs[0]['rank_id']).values(
                 'id', 'currency', 'price', 'lang__content', 'day', 'commodity_type', 'lang__title', 'expire',
                 'id', 'currency', 'price', 'lang__content', 'day', 'commodity_type', 'lang__title', 'expire',
                 'commodity_code', 'discount_price', 'bucket_id', 'bucket__mold', 'cycle_config_id', 'is_ai')
                 'commodity_code', 'discount_price', 'bucket_id', 'bucket__mold', 'cycle_config_id', 'is_ai')
             if not store_qs.exists():
             if not store_qs.exists():
-                return response.json(173, "套餐不存在")
-
-            bucket_id = store_qs[0]['bucket_id']
-            is_ai = store_qs[0]['is_ai']
-            expire = store_qs[0]['expire']
-            end_time = CommonService.calcMonthLater(expire)
-
-            # 查询设备是否已开过云存
-            use_flag = True
-            uid_bucket_qs = UID_Bucket.objects.filter(uid=uid). \
-                values('id', 'bucket_id', 'bucket__region', 'endTime', 'use_status')
-            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)
+                return response.json(173, "云存套餐不存在")
 
 
+            # 设备开通云存
+            now_time = int(time.time())
+            uid_bucket_id = cls.enable_cloud(channel, now_time, order_id, store_qs, uid)
+
+            # 修改订单信息
             order_qs.update(status=1, uid_bucket_id=uid_bucket_id, transaction_id=transaction_id, create_vod=1)
             order_qs.update(status=1, uid_bucket_id=uid_bucket_id, transaction_id=transaction_id, create_vod=1)
 
 
-            # 发送云存开通信息
-            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()))]
+            # 构建云存套餐消息
+            sys_msg_text_list = cls.cloud_storage_message(uid)
             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)
 
 
+            # 删除缓存
             redis_obj.del_data(redis_key)
             redis_obj.del_data(redis_key)
             pay_result_url = CommonService.get_payment_status_url(lang, 'success')
             pay_result_url = CommonService.get_payment_status_url(lang, 'success')
+
             return response.json(0, {'url': pay_result_url})
             return response.json(0, {'url': pay_result_url})
 
 
         except Exception as e:
         except Exception as e:
@@ -213,6 +161,66 @@ class InAppPurchaseView(View):
             pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
             pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
             return response.json(0, {'url': pay_result_url})
             return response.json(0, {'url': pay_result_url})
 
 
+    @classmethod
+    def cloud_storage_message(cls, uid):
+        # 发送云存开通信息
+        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()))]
+        return sys_msg_text_list
+
+    @classmethod
+    def enable_cloud(cls, channel, now_time, order_id, store_qs, uid):
+        bucket_id = store_qs[0]['bucket_id']
+        is_ai = store_qs[0]['is_ai']
+        expire = store_qs[0]['expire']
+        end_time = CommonService.calcMonthLater(expire)
+        # 查询设备是否已开过云存
+        use_flag = True
+        uid_bucket_qs = UID_Bucket.objects.filter(uid=uid). \
+            values('id', 'bucket_id', 'bucket__region', 'endTime', 'use_status')
+        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)
+        return uid_bucket_id
+
     @classmethod
     @classmethod
     def do_vod_msg_notice(cls, uid, user_id, lang, sys_msg_text_list):
     def do_vod_msg_notice(cls, uid, user_id, lang, sys_msg_text_list):
         """
         """
@@ -327,6 +335,35 @@ class InAppPurchaseView(View):
                 user_id = orders_qs[0].userID
                 user_id = orders_qs[0].userID
                 # 3. 未使用则删除未使用套餐表,已使用过则删除设备正在使用套餐,并关闭设备云存
                 # 3. 未使用则删除未使用套餐表,已使用过则删除设备正在使用套餐,并关闭设备云存
                 uid_bucket_qs = UID_Bucket.objects.filter(uid=uid, orderId=orderID, use_status=1, endTime__gt=int(time.time()))
                 uid_bucket_qs = UID_Bucket.objects.filter(uid=uid, orderId=orderID, use_status=1, endTime__gt=int(time.time()))
+                uid_bucket_qs = UID_Bucket.objects.filter(uid=uid, orderId=orderID, use_status=1,
+                                                          endTime__gt=int(time.time()))
+                unused_uid_meal_qs = Unused_Uid_Meal.objects.filter(order_id=orderID)
+                ai_service_qs = AiService.objects.filter(uid=uid, orderId=orderID, use_status=1,
+                                                         endTime__gt=int(time.time()))
+                if unused_uid_meal_qs.exists():
+                    unused_uid_meal_qs.delete()
+                if uid_bucket_qs.exists():
+                    uid_bucket_qs.update(status=0, use_status=2, endTime=int(time.time()), updateTime=int(time.time()))
+                if ai_service_qs.exists():
+                    ai_service_qs.update(detect_status=0, use_status=2, endTime=int(time.time()),
+                                         updTime=int(time.time()))
+                    # 关闭ai
+                    msg = {'commandType': 'AIDisable'}
+                    thing_name = CommonService.query_serial_with_uid(uid)  # 存在序列号则为使用序列号作为物品名
+                    topic_name = 'ansjer/generic/{}'.format(thing_name)
+                    req_success = CommonService.req_publish_mqtt_msg(thing_name, topic_name, msg)
+                    LOGGER.info(f'App Store服务器通知用户退款, 关闭AI:{req_success}')
+
+                # 4.发送邮件告知用户退款
+                email_content = f'{CONFIG_INFO}用户{user_id}, 订单:{orderID}, 设备{uid}退款'
+                S3Email().faEmail(email_content, 'servers@ansjer.com')
+            else:
+                if CONFIG_INFO == CONFIG_US:
+                    url = "https://api.zositeche.com/inAppPurchase/AppStoreServerNotifications"
+                    eur_response = requests.post(url=url, json=json.loads(request.body))
+                    status_code = eur_response.status_code
+
+        return HttpResponse(status=status_code)
                 unused_uid_meal_qs = Unused_Uid_Meal.objects.filter(order_id=orderID)
                 unused_uid_meal_qs = Unused_Uid_Meal.objects.filter(order_id=orderID)
                 ai_service_qs = AiService.objects.filter(uid=uid, orderId=orderID, use_status=1, endTime__gt=int(time.time()))
                 ai_service_qs = AiService.objects.filter(uid=uid, orderId=orderID, use_status=1, endTime__gt=int(time.time()))
                 if unused_uid_meal_qs.exists():
                 if unused_uid_meal_qs.exists():

+ 121 - 39
Object/AppleInAppPurchaseSubscriptionObject.py

@@ -1,11 +1,7 @@
-from django.db.models import Q
-
-from Ansjer.config import LOGGER, CONFIG_INFO, CONFIG_TEST, PAY_TYPE_IN_APP_PURCHASE, BASE_DIR
-from appstoreserverlibrary.api_client import AppStoreServerAPIClient, GetTransactionHistoryVersion
+from Ansjer.config import LOGGER, CONFIG_INFO, CONFIG_TEST, BASE_DIR, IN_APP_CONFIG
+from appstoreserverlibrary.api_client import AppStoreServerAPIClient
 from appstoreserverlibrary.models.Environment import Environment
 from appstoreserverlibrary.models.Environment import Environment
 from appstoreserverlibrary.receipt_utility import ReceiptUtility
 from appstoreserverlibrary.receipt_utility import ReceiptUtility
-from appstoreserverlibrary.models.HistoryResponse import HistoryResponse
-from appstoreserverlibrary.models.TransactionHistoryRequest import TransactionHistoryRequest, ProductType, Order
 from appstoreserverlibrary.signed_data_verifier import SignedDataVerifier
 from appstoreserverlibrary.signed_data_verifier import SignedDataVerifier
 
 
 from Model.models import Order_Model, DeviceApplePackage
 from Model.models import Order_Model, DeviceApplePackage
@@ -13,49 +9,135 @@ from Model.models import Order_Model, DeviceApplePackage
 ENV = Environment.SANDBOX if CONFIG_INFO == CONFIG_TEST else Environment.PRODUCTION
 ENV = Environment.SANDBOX if CONFIG_INFO == CONFIG_TEST else Environment.PRODUCTION
 
 
 
 
-class InAppSubscription:
-    def __init__(self):
-        key_id = 'N42WMFCV6A'
-        issuer_id = '69a6de8c-789b-47e3-e053-5b8c7c11a4d1'
-        bundle_id = 'com.ansjer.zccloud'
-        environment = ENV
-        key_path = '{}/Ansjer/file/in_app_purchase/SubscriptionKey_N42WMFCV6A.p8'.format(BASE_DIR)
-        with open(key_path, 'rb') as file:
-            # 读取文件内容
-            private_key = file.read()
-        self.client = AppStoreServerAPIClient(private_key, key_id, issuer_id, bundle_id, environment)
+class InAppConfig:
+    def __init__(self, bundle_id: str):
+        """
+       初始化 AppConfig,加载与指定 bundle_id 对应的配置。
+       :param bundle_id: 应用的 bundle ID,用于检索相关配置。
+       """
+        config = IN_APP_CONFIG.get(bundle_id)
+        if not config:
+            raise ValueError(f"没有找到与 bundle_id '{bundle_id}' 对应的配置")
+        self.key_id = config['key_id']
+        self.issuer_id = config['issuer_id']
+        self.key_filename = config['key_filename']
+        self.cert_names = config['cert_names']
+        self.app_apple_id = config.get("app_apple_id")
+        self.environment = ENV
+
 
 
-    def check_subscriptions(self, uid, subscription_group_id):
+class InAppPurchase:
+    def __init__(self, bundle_id):
         """
         """
-        检查用户是否订阅
-        :param uid:
-        :return: True/False True表示已订阅
+        初始化 InAppSubscription,加载私钥并初始化客户端和解码器。
+        :param app_config: 包含内购相关配置的 AppConfig 实例。
         """
         """
-        # 查询订单信息
-        has_order_qs = Order_Model.objects.filter(UID=uid, payType=5).exclude(original_transaction_id="")
-        if not has_order_qs.exists():
+        app_config = InAppConfig(bundle_id)
+        self.config = app_config
+        self.private_key = self._load_private_key(self.config.key_filename)
+        self.client = self._initialize_client()
+        self.verifier = self._initialize_verifier()
+        self.receipt_util = self._initialize_receipt_util()
+
+    def _load_private_key(self, key_filename: str) -> bytes:
+        """
+        加载私钥文件并返回其内容。
+        :param key_filename: 私钥文件的名称。
+        :return: 返回私钥文件的内容,类型为 bytes。
+        """
+
+        key_path = f'{BASE_DIR}/Ansjer/file/in_app_purchase/{key_filename}'
+        try:
+            with open(key_path, 'rb') as file:
+                return file.read()
+        except FileNotFoundError:
+            raise ValueError(f"Private key file not found: {key_path}")
+
+    def _initialize_client(self) -> AppStoreServerAPIClient:
+        """
+        初始化 AppStoreServerAPIClient 实例,用于与 App Store 进行通信。
+        :return: 返回初始化后的 AppStoreServerAPIClient 实例。
+        """
+        return AppStoreServerAPIClient(
+            self.private_key,
+            self.config.key_id,
+            self.config.issuer_id,
+            self.config.app_apple_id,
+            self.config.environment
+        )
+
+    def _initialize_verifier(self) -> SignedDataVerifier:
+        """
+       初始化 SignedDataVerifier 实例,用于内购验证签名数据。
+       :return: 返回初始化后的 SignedDataVerifier 实例。
+       """
+        root_certificates = [
+            self._load_certificate(cert_name)
+            for cert_name in self.config.cert_names
+        ]
+        enable_online_checks = True  # 根据需要设定在线检查是否启用
+        app_apple_id = None if CONFIG_INFO == CONFIG_TEST else self.config.app_apple_id
+
+        return SignedDataVerifier(
+            root_certificates,
+            enable_online_checks,
+            self.config.environment,
+            self.config.app_apple_id,
+            app_apple_id
+        )
+
+    def _load_certificate(self, cert_name: str) -> bytes:
+        """
+        加载指定的根证书文件并返回其内容。
+        :param cert_name: 根证书文件的名称。
+        :return: 返回根证书文件的内容,类型为 bytes。
+        """
+        cert_path = f'{BASE_DIR}/Ansjer/file/in_app_purchase/{cert_name}'
+        try:
+            with open(cert_path, 'rb') as file:
+                return file.read()
+        except FileNotFoundError:
+            raise ValueError(f"Certificate file not found: {cert_path}")
+
+    def _initialize_receipt_util(self):
+        receipt_util = ReceiptUtility()
+        return receipt_util
+
+    def check_subscriptions(self, uid: str, subscription_group_id: str) -> bool:
+        try:
+            has_order = self._get_last_order(uid)
+            if not has_order:
+                return False
+
+            subscription_status = self._get_subscription_status(has_order, subscription_group_id)
+            return subscription_status
+
+        except Exception as e:
+            LOGGER.error(f"Error checking subscriptions: {str(e)}")
             return False
             return False
-        has_order = has_order_qs.values('transaction_id', 'original_transaction_id', 'orderID', 'addTime').order_by(
-            '-addTime')
 
 
-        # 判断用户是否取消订阅
+    def _get_last_order(self, uid: str) -> dict:
+        return Order_Model.objects.filter(UID=uid, payType=5).exclude(
+            original_transaction_id=""
+        ).values(
+            'transaction_id', 'original_transaction_id', 'orderID', 'addTime'
+        ).order_by('-addTime').first()
+
+    def _get_subscription_status(self, order: dict, subscription_group_id: str) -> bool:
         device_apple_package = DeviceApplePackage.objects.filter(
         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:
+            original_transaction_id=order['original_transaction_id']
+        ).values("subscription_status").first()
+
+        if not device_apple_package or device_apple_package['subscription_status'] != 1:
             return False
             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(order['transaction_id'])
         if not subscription_statuses.data:
         if not subscription_statuses.data:
             return False
             return False
-        LOGGER.info("subscription_statuses:{}".format(subscription_statuses))
+
         for subscription_status in subscription_statuses.data:
         for subscription_status in subscription_statuses.data:
             if str(subscription_status.subscriptionGroupIdentifier) == subscription_group_id:
             if str(subscription_status.subscriptionGroupIdentifier) == subscription_group_id:
-                for subscription_status_item in subscription_status.lastTransactions:
-                    if str(subscription_status_item.status) == "Status.ACTIVE":
-                        return True
-        else:
-            return False
+                if any(str(item.status) == "Status.ACTIVE" for item in subscription_status.lastTransactions):
+                    return True
 
 
+        return False