Bläddra i källkod

创建支付订单 -修改创建状态
认证交易 - 优化代码

linhaohong 1 år sedan
förälder
incheckning
7cdf807723
2 ändrade filer med 190 tillägg och 191 borttagningar
  1. 1 2
      Controller/CloudStorage.py
  2. 189 189
      Controller/InAppPurchaseController.py

+ 1 - 2
Controller/CloudStorage.py

@@ -1683,8 +1683,7 @@ class CloudStorageView(View):
                 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,
                 isSelectDiscounts=is_select_discount, order_type=order_type, commodity_code=commodity_code,
-                commodity_type=commodity_type, rank_id=rank, ai_rank_id=1, status=1, create_vod=1,
-                store_meal_name=store_meal_name)
+                commodity_type=commodity_type, rank_id=rank, ai_rank_id=1, store_meal_name=store_meal_name)
             return JsonResponse(status=200,
                                 data={'result_code': 0, 'reason': 'success', 'result': {"orderID": order_id},
                                       'error_code': 0})

+ 189 - 189
Controller/InAppPurchaseController.py

@@ -187,9 +187,9 @@ class InAppPurchaseView(View):
                         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.filter(orderID=order_id).update(status=1, uid_bucket_id=uid_bucket_id,
-                                                                transaction_id=transaction_id,
-                                                                original_transaction_id=original_transaction_id)
+            order_qs.update(status=1, uid_bucket_id=uid_bucket_id,
+                            transaction_id=transaction_id, create_vod=1,
+                            original_transaction_id=original_transaction_id)
 
             # 发送云存开通信息
             date_time = time.strftime("%Y-%m-%d", time.localtime())
@@ -286,199 +286,199 @@ class InAppPurchaseView(View):
             logger.info('App Store服务器通知请求类型:{}'.format(request.method))
             logger.info('App Store服务器通知参数:{}'.format(request.POST))
             logger.info('App Store服务器通知请求body:{}'.format(request.body))
-            if request.method == 'POST':
-                payload = json.loads(request.body.decode('utf-8'))
-                logger.info('App Store服务器通知payload:{}'.format(payload))
-                # 获取 signedPayload
-                signed_payload = payload.get('signedPayload')
-                if not signed_payload:
-                    return HttpResponse(status=400)
+            if request.method != 'POST':
+                logger.info(f'App Store服务器通知不是post请求, 参数{request_dict}')
+                return HttpResponse(status=400)
+
+            payload = json.loads(request.body.decode('utf-8'))
+            logger.info('App Store服务器通知payload:{}'.format(payload))
+            # 获取 signedPayload
+            signed_payload = payload.get('signedPayload')
+            if not signed_payload:
+                return HttpResponse(status=400)
+
+            bundle_id = 'com.ansjer.zccloud'
+            environment = ENV
+            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 = None  # 生产环境必需
+
+            # 验证签名并解码 payload
+            verifier = SignedDataVerifier(
+                root_certificates, enable_online_checks, environment, bundle_id, app_apple_id)
+            decoded_payload = verifier.verify_and_decode_notification(signed_payload)
+
+            logger.info(f"App Store服务器通知解码后decoded_payload:{decoded_payload}")
+            logger.info(
+                f"App Store服务器通知decoded_payload.rawNotificationType{str(decoded_payload.rawNotificationType)}")
+            if str(decoded_payload.rawNotificationType) == "DID_RENEW":
+                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
 
-                bundle_id = 'com.ansjer.zccloud'
-                environment = ENV
-                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 = None  # 生产环境必需
-
-                # 验证签名并解码 payload
-                verifier = SignedDataVerifier(
-                    root_certificates, enable_online_checks, environment, bundle_id, app_apple_id)
-                decoded_payload = verifier.verify_and_decode_notification(signed_payload)
-
-                logger.info(f"App Store服务器通知解码后decoded_payload:{decoded_payload}")
                 logger.info(
-                    f"App Store服务器通知decoded_payload.rawNotificationType{str(decoded_payload.rawNotificationType)}")
-                if str(decoded_payload.rawNotificationType) == "DID_RENEW":
-                    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")
+                    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", "rank_id")
+                    if not ord_order.exists():
+                        logger.info(f"App Store服务器通知未查询到旧订单信息, 返回状态 400")
+                        return HttpResponse(status=400)
+                    channel = ord_order[0]["channel"]
+                    uid = ord_order[0]["UID"]
+                    pay_type = ord_order[0]["payType"]
+                    user_id = ord_order[0]["userID_id"]
+
+                    store_qs = Store_Meal.objects.filter(id=ord_order[0]["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)
-                    else:
-                        ord_order = Order_Model.objects.filter(original_transaction_id=original_transaction_id).order_by(
-                            '-addTime').values("channel", "UID", "payType", "userID_id", "rank_id")
-                        if not ord_order.exists():
-                            logger.info(f"App Store服务器通知未查询到旧订单信息, 返回状态 400")
-                            return HttpResponse(status=400)
-                        channel = ord_order[0]["channel"]
-                        uid = ord_order[0]["UID"]
-                        pay_type = ord_order[0]["payType"]
-                        user_id = ord_order[0]["userID_id"]
-
-                        store_qs = Store_Meal.objects.filter(id=ord_order[0]["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)
+                    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 = 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)
+                            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:
-                            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) == "SUBSCRIBED":
-                    # 处理订阅
-                    # 一种通知类型,与其子类型一起表示客户订阅了自动续订的套餐。如果子类型为
-                    # INITIAL_BUY(首次购买),则表示用户首次购买或通过家庭共享访问该订阅。如果子类型为
-                    decoded_transaction_information = verifier.verify_and_decode_signed_transaction(
-                        decoded_payload.data.signedTransactionInfo)
-
-                    # 之前订阅过不可重复订阅
-                    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()
-
-                    client = AppStoreServerAPIClient(private_key, key_id, issuer_id, bundle_id, environment)
-                    transaction_id = decoded_transaction_information.transactionId
-                    transaction_subscription = client.get_all_subscription_statuses(transaction_id)
-                    if transaction_subscription.data:
-                        for subscription in transaction_subscription.data[0].lastTransactions:
-                            if str(subscription.status) == "Status.ACTIVE":
-                                return HttpResponse(status=400)
-
-                elif str(decoded_payload.rawNotificationType) == "EXPIRED":
-                    # 一种通知类型,与其子类型一起表示订阅已过期。如果subtype为
-                    # VOLUNTARY(自愿),则表示订阅在用户禁用订阅续订后过期。如果subtype是
-                    # BILLING_RETRY(计费重试),则表示订阅过期,因为计费重试期结束时没有成功的计费交易。如果subtype为
-                    # PRICE_INCREASE,则表示订阅已过期,因为客户不同意需要客户同意的价格上涨。如果subtype为
-                    # PRODUCT_NOT_FOR_SALE,则表示订阅已过期,因为在订阅尝试续订时,产品已不可购买。
-                    # 没有子类型的通知表示订阅因其他原因过期。
-                    pass
-                else:
-                    logger.info(f"App Store服务器通知decoded_payload.rawNotificationType 未处理")
-                    return HttpResponse(status=500)
-                return HttpResponse(status=200)
+                            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) == "SUBSCRIBED":
+                # 处理订阅
+                # 一种通知类型,与其子类型一起表示客户订阅了自动续订的套餐。如果子类型为
+                # INITIAL_BUY(首次购买),则表示用户首次购买或通过家庭共享访问该订阅。如果子类型为
+                decoded_transaction_information = verifier.verify_and_decode_signed_transaction(
+                    decoded_payload.data.signedTransactionInfo)
+
+                # 之前订阅过不可重复订阅
+                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()
+
+                client = AppStoreServerAPIClient(private_key, key_id, issuer_id, bundle_id, environment)
+                transaction_id = decoded_transaction_information.transactionId
+                transaction_subscription = client.get_all_subscription_statuses(transaction_id)
+                if transaction_subscription.data:
+                    for subscription in transaction_subscription.data[0].lastTransactions:
+                        if str(subscription.status) == "Status.ACTIVE":
+                            return HttpResponse(status=400)
+
+            elif str(decoded_payload.rawNotificationType) == "EXPIRED":
+                # 一种通知类型,与其子类型一起表示订阅已过期。如果subtype为
+                # VOLUNTARY(自愿),则表示订阅在用户禁用订阅续订后过期。如果subtype是
+                # BILLING_RETRY(计费重试),则表示订阅过期,因为计费重试期结束时没有成功的计费交易。如果subtype为
+                # PRICE_INCREASE,则表示订阅已过期,因为客户不同意需要客户同意的价格上涨。如果subtype为
+                # PRODUCT_NOT_FOR_SALE,则表示订阅已过期,因为在订阅尝试续订时,产品已不可购买。
+                # 没有子类型的通知表示订阅因其他原因过期。
+                pass
             else:
-                logger.info(f'App Store服务器通知不是post请求, 参数{request_dict}')
-                return HttpResponse(status=400)
+                logger.info(f"App Store服务器通知decoded_payload.rawNotificationType 未处理")
+                return HttpResponse(status=500)
+            return HttpResponse(status=200)
         except Exception as e:
             logger.info('App Store服务器通知异常:{}'.
                         format('error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))))