Selaa lähdekoodia

IAP苹果内购 --- 更改版本 + 证书文件

linhaohong 1 vuosi sitten
vanhempi
commit
19842c5794

BIN
Ansjer/file/in_app_purchase/AppleComputerRootCertificate.cer


BIN
Ansjer/file/in_app_purchase/AppleIncRootCertificate.cer


BIN
Ansjer/file/in_app_purchase/AppleRootCA-G2.cer


BIN
Ansjer/file/in_app_purchase/AppleRootCA-G3.cer


+ 6 - 0
Ansjer/file/in_app_purchase/SubscriptionKey_N42WMFCV6A.p8

@@ -0,0 +1,6 @@
+-----BEGIN PRIVATE KEY-----
+MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgK4ELia/I5IOMZ+ve
+RcPnCFaEIATOVxenaB+kiVk7pCqgCgYIKoZIzj0DAQehRANCAAT+BA31V9UzMjbF
+DCi3Suspp8jIkfKXkzaHSRv7AQsvvqdfXU5mlqJlaQ2c9seI4u4Rq1E2Ak1RdX8S
+3rd/4G+p
+-----END PRIVATE KEY-----

+ 60 - 7
Controller/InAppPurchaseController.py

@@ -4,10 +4,18 @@
 import logging
 import time
 
-import itunesiap
+from appstoreserverlibrary.api_client import AppStoreServerAPIClient, GetTransactionHistoryVersion
+from appstoreserverlibrary.models.Environment import Environment
+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 cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives.serialization import load_pem_private_key
+
 from django.db.models import Q
 from django.views import View
-from Ansjer.config import LOGGER, CONFIG_INFO, CONFIG_TEST, PAY_TYPE_IN_APP_PURCHASE
+from Ansjer.config import LOGGER, CONFIG_INFO, CONFIG_TEST, PAY_TYPE_IN_APP_PURCHASE, BASE_DIR
 from Controller.CheckUserData import DataValid
 from Model.models import Order_Model, Store_Meal, Device_Info, UID_Bucket, Unused_Uid_Meal, AiService, Device_User, \
     SysMsgModel
@@ -16,7 +24,7 @@ from Object.AliSmsObject import AliSmsObject
 from Object.RedisObject import RedisObject
 from Service.CommonService import CommonService
 
-ENV = itunesiap.env.sandbox if CONFIG_INFO == CONFIG_TEST else itunesiap.env.production
+ENV = Environment.SANDBOX if CONFIG_INFO == CONFIG_TEST else Environment.PRODUCTION
 
 
 class InAppPurchaseView(View):
@@ -77,10 +85,52 @@ class InAppPurchaseView(View):
                 if device_info_qs[0]['vodPrimaryUserID'] != user_id:
                     return response.json(10033)
 
-            order_id = CommonService.createOrderID()
-            verify_response = itunesiap.verify(receipt, env=ENV)
-            LOGGER.info('苹果内购收据认证响应:{}'.format(verify_response))
-            product_id = verify_response.receipt.in_app[0]['product_id']
+            # 从交易信息中获取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()
+
+            transaction_id = receipt_util.extract_transaction_id_from_app_receipt(receipt)
+            if transaction_id is None:
+                pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
+                return response.json(0, {'url': pay_result_url})
+
+            transaction_info = client.get_transaction_info(transaction_id)
+            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 = None     # 生产环境必需
+            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)
+
+            product_id = None
+            if payload and payload.productId:
+                product_id = payload.productId
+
+            if not product_id:
+                pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
+                return response.json(0, {'url': pay_result_url})
 
             pay_type = PAY_TYPE_IN_APP_PURCHASE
             now_time = int(time.time())
@@ -93,6 +143,7 @@ class InAppPurchaseView(View):
             if not store_qs.exists():
                 return response.json(173)
 
+            order_id = CommonService.createOrderID()
             rank_id = store_qs[0]['id']
             bucket_id = store_qs[0]['bucket_id']
             currency = store_qs[0]['currency']
@@ -174,6 +225,8 @@ class InAppPurchaseView(View):
             return response.json(0, {'url': pay_result_url})
         except Exception as e:
             redis_obj.del_data(redis_key)
+            LOGGER.info('苹果内购认证交易接口异常:{}'.
+                        format('error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))))
             pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
             return response.json(0, {'url': pay_result_url})