Эх сурвалжийг харах

苹果内购退款临时处理

linhaohong 9 сар өмнө
parent
commit
ea3a37a1e2

+ 74 - 7
Controller/InAppPurchaseController.py

@@ -7,7 +7,17 @@ import json
 
 import requests
 from appstoreserverlibrary.api_client import AppStoreServerAPIClient, GetTransactionHistoryVersion
+from appstoreserverlibrary.models.AccountTenure import AccountTenure
+from appstoreserverlibrary.models.ConsumptionRequest import ConsumptionRequest
+from appstoreserverlibrary.models.ConsumptionStatus import ConsumptionStatus
+from appstoreserverlibrary.models.DeliveryStatus import DeliveryStatus
 from appstoreserverlibrary.models.Environment import Environment
+from appstoreserverlibrary.models.LifetimeDollarsPurchased import LifetimeDollarsPurchased
+from appstoreserverlibrary.models.LifetimeDollarsRefunded import LifetimeDollarsRefunded
+from appstoreserverlibrary.models.Platform import Platform
+from appstoreserverlibrary.models.PlayTime import PlayTime
+from appstoreserverlibrary.models.RefundPreference import RefundPreference
+from appstoreserverlibrary.models.UserStatus import UserStatus
 from appstoreserverlibrary.receipt_utility import ReceiptUtility
 from appstoreserverlibrary.models.HistoryResponse import HistoryResponse
 from appstoreserverlibrary.models.TransactionHistoryRequest import TransactionHistoryRequest, ProductType, Order
@@ -23,7 +33,7 @@ from django.http import HttpResponse
 from Ansjer.config import LOGGER, CONFIG_INFO, CONFIG_TEST, PAY_TYPE_IN_APP_PURCHASE, BASE_DIR, CONFIG_US
 from Controller.CheckUserData import DataValid
 from Model.models import Order_Model, Store_Meal, Device_Info, UID_Bucket, Unused_Uid_Meal, AiService, Device_User, \
-    SysMsgModel
+    SysMsgModel, OrderPayLog, InAppRefund
 from Object.AWS.S3Email import S3Email
 from Object.AliSmsObject import AliSmsObject
 from Object.RedisObject import RedisObject
@@ -321,7 +331,7 @@ class InAppPurchaseView(View):
             orders_qs = Order_Model.objects.filter(transaction_id=transaction_id)
             # 2. 查找云存套餐使用表 和 云存套餐
             if orders_qs.exists():
-                orders_qs.update(status=11)
+                orders_qs.update(status=5, updTime=int(time.time()))
                 orderID = orders_qs[0].orderID
                 uid = orders_qs[0].UID
                 user_id = orders_qs[0].userID
@@ -341,12 +351,69 @@ class InAppPurchaseView(View):
                     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}')
+                OrderPayLog.objects.create(order_id=orderID, order_no=transaction_id,
+                                           business_name=f'{user_id}App Store退款, 设备uid: {uid}',
+                                           sender="InAppPurchase", request_content=signed_payload,
+                                           created_time=int(time.time()), updated_time=int(time.time()))
 
-                # 4.发送邮件告知用户退款
-                email_content = f'{CONFIG_INFO}用户{user_id}, 订单:{orderID}, 设备{uid}退款'
-                S3Email().faEmail(email_content, 'servers@ansjer.com')
-            else:
-                if CONFIG_INFO == CONFIG_US:
+            elif 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
+
+        elif str(decoded_payload.rawNotificationType) == "CONSUMPTION_REQUEST":
+            # 从交易信息中获取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)
+            decoded_transaction_information = verifier.verify_and_decode_signed_transaction(
+                decoded_payload.data.signedTransactionInfo)
+            transaction_id = decoded_transaction_information.transactionId
+            orders_qs = Order_Model.objects.filter(transaction_id=transaction_id)
+            if orders_qs.exists():
+                orderID = orders_qs[0].orderID
+                unused_uid_meal_qs = Unused_Uid_Meal.objects.filter(order_id=orderID)
+                uid_bucket_qs = UID_Bucket.objects.filter(orderId=orderID, endTime__gt=int(time.time()))
+                if unused_uid_meal_qs.exists():
+                    consumptionStatus = ConsumptionStatus.NOT_CONSUMED
+                    deliveryStatus = DeliveryStatus.DELIVERED_AND_WORKING_PROPERLY
+                elif uid_bucket_qs.exists():
+                    consumptionStatus = ConsumptionStatus.PARTIALLY_CONSUMED
+                    deliveryStatus = DeliveryStatus.DELIVERED_AND_WORKING_PROPERLY
+                elif UID_Bucket.objects.filter(orderId=orderID, endTime__lt=int(time.time())):
+                    consumptionStatus = ConsumptionStatus.FULLY_CONSUMED
+                    deliveryStatus = DeliveryStatus.DELIVERED_AND_WORKING_PROPERLY
+                else:
+                    consumptionStatus = ConsumptionStatus.UNDECLARED
+                    deliveryStatus = DeliveryStatus.DID_NOT_DELIVER_FOR_OTHER_REASON
+                in_app_refund_qs = InAppRefund.objects.filter(transaction_id=transaction_id).exists()
+                refundPreference = RefundPreference.PREFER_DECLINE
+                if in_app_refund_qs.exists():
+                    if in_app_refund_qs[0].refund_preference == 1:
+                        refundPreference = RefundPreference.PREFER_GRANT
+                consumption_request = ConsumptionRequest(
+                    customerConsented=True,
+                    consumptionStatus=consumptionStatus,
+                    platform=Platform.UNDECLARED,
+                    sampleContentProvided=True,
+                    deliveryStatus=deliveryStatus,
+                    appAccountToken="",
+                    accountTenure=AccountTenure.UNDECLARED,
+                    playTime=PlayTime.UNDECLARED,
+                    lifetimeDollarsRefunded=LifetimeDollarsRefunded.UNDECLARED,
+                    lifetimeDollarsPurchased=LifetimeDollarsPurchased.UNDECLARED,
+                    userStatus=UserStatus.ACTIVE,
+                    refundPreference=refundPreference,
+                )
+                client.send_consumption_data(transaction_id, consumption_request)
+            elif 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

+ 15 - 1
Model/models.py

@@ -1858,7 +1858,7 @@ class Order_Model(models.Model):
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
     isSelectDiscounts = models.SmallIntegerField(default=0, verbose_name=u'用户是否选择了第二年优惠 [0=否,1是]')
-    # 0: 待支付, 1:支付成功, 2: 取消支付, 4: 退款失败, 5: 全额退款, 6: 部分退款, 7: PayPal已退款, 9:处理中, 10:支付失败 11:苹果通知退款
+    # 0: 待支付, 1:支付成功, 2: 取消支付, 4: 退款失败, 5: 全额退款, 6: 部分退款, 7: PayPal已退款, 9:处理中, 10:支付失败 11:客户申请退款
     status = models.SmallIntegerField(default=0, verbose_name='付款状态')
     # 1: PayPal, 2: 支付宝, 3: 微信, 5: 苹果内购, 10: 免费体验, 11: 激活码
     payType = models.SmallIntegerField(default=0, verbose_name='支付方式')
@@ -5141,3 +5141,17 @@ class UserSetStatus(models.Model):
     class Meta:
         db_table = 'user_set_status'
         verbose_name = '用户设置状态'
+
+
+class InAppRefund(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增标记ID')
+    transaction_id = models.CharField(default='', max_length=32, verbose_name='苹果事务id')
+    orderID = models.CharField(blank=True, max_length=20, verbose_name=u'订单id')
+    # 0不同意 1同意
+    refund_preference = models.IntegerField(default=0, verbose_name='是否同意退款')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+    updated_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'in_app_refund'
+        verbose_name = '退款状态'