|
@@ -61,35 +61,26 @@ class InAppPurchaseView(View):
|
|
|
@return: response
|
|
|
"""
|
|
|
receipt = request_dict.get('receipt', None)
|
|
|
+ order_id = request_dict.get('orderId', None)
|
|
|
uid = request_dict.get('uid', None)
|
|
|
lang = request_dict.get('lang', 'en')
|
|
|
channel = request_dict.get('channel', None)
|
|
|
+
|
|
|
logger = logging.getLogger('apple_pay')
|
|
|
- logger.info(f"认证交易receipt:{receipt}")
|
|
|
+ logger.info(f"认证交易receipt:{receipt}, 订单orderId:{order_id}")
|
|
|
|
|
|
- if not all([receipt, uid, channel]):
|
|
|
+ if not all([receipt, uid, channel, order_id]):
|
|
|
return response.json(444)
|
|
|
|
|
|
# redis加锁,防止订单重复
|
|
|
redis_obj = RedisObject()
|
|
|
- redis_key = uid + 'in_app_purchase'
|
|
|
+ redis_key = order_id + 'in_app_purchase'
|
|
|
is_lock = redis_obj.CONN.setnx(redis_key, 1)
|
|
|
redis_obj.CONN.expire(redis_key, 60)
|
|
|
# if not is_lock:
|
|
|
# return response.json(5)
|
|
|
|
|
|
try:
|
|
|
- device_info_qs = Device_Info.objects.filter(userID_id=user_id, UID=uid, isShare=False, isExist=1).values(
|
|
|
- 'vodPrimaryUserID',
|
|
|
- 'vodPrimaryMaster')
|
|
|
- if not device_info_qs.exists():
|
|
|
- return response.json(12)
|
|
|
-
|
|
|
- device_info_qs = Device_Info.objects.filter(Q(UID=uid), ~Q(vodPrimaryUserID='')).values('vodPrimaryUserID')
|
|
|
- if device_info_qs.exists():
|
|
|
- if device_info_qs[0]['vodPrimaryUserID'] != user_id:
|
|
|
- return response.json(10033)
|
|
|
-
|
|
|
# 从交易信息中获取product_id
|
|
|
key_path = '{}/Ansjer/file/in_app_purchase/SubscriptionKey_N42WMFCV6A.p8'.format(BASE_DIR)
|
|
|
with open(key_path, 'rb') as file:
|
|
@@ -111,6 +102,9 @@ class InAppPurchaseView(View):
|
|
|
|
|
|
transaction_info = client.get_transaction_info(transaction_id)
|
|
|
signed_transaction_info = transaction_info.signedTransactionInfo
|
|
|
+ if Order_Model.objects.filter(payType=5, transaction_id=transaction_id).exists():
|
|
|
+ logger.info(f"该transaction_id已订阅过:{transaction_id}")
|
|
|
+ return response.json(10048)
|
|
|
|
|
|
root_certificates = []
|
|
|
for cert_name in [
|
|
@@ -130,49 +124,32 @@ class InAppPurchaseView(View):
|
|
|
payload = signed_data_verifier.verify_and_decode_signed_transaction(signed_transaction_info)
|
|
|
|
|
|
product_id = None
|
|
|
- originalTransaction_id = None
|
|
|
- agreement_id = ""
|
|
|
- if payload and payload.productId and payload.originalTransactionId:
|
|
|
+ original_transaction_id = ""
|
|
|
+
|
|
|
+ if payload and payload.productId:
|
|
|
product_id = payload.productId
|
|
|
- originalTransaction_id = payload.originalTransactionId
|
|
|
|
|
|
- if not product_id or not originalTransaction_id:
|
|
|
+ if not product_id:
|
|
|
pay_result_url = CommonService.get_payment_status_url(lang, 'fail')
|
|
|
return response.json(0, {'url': pay_result_url})
|
|
|
|
|
|
- # 之前订阅过任意套餐返回不可再次订阅
|
|
|
- if Store_Meal.objects.filter(product_id=product_id, cycle_config_id__isnull=False).exists():
|
|
|
- agreement_id = originalTransaction_id
|
|
|
+ if payload.rawType == "Auto-Renewable Subscription":
|
|
|
+ original_transaction_id = payload.originalTransactionId
|
|
|
|
|
|
- pay_type = PAY_TYPE_IN_APP_PURCHASE
|
|
|
now_time = int(time.time())
|
|
|
-
|
|
|
- store_qs = Store_Meal.objects.filter(
|
|
|
- product_id=product_id, lang__lang=lang, is_show=0). \
|
|
|
- values(
|
|
|
+ order_qs = Order_Model.objects.filter(orderID=order_id, UID=uid).values("rank_id")
|
|
|
+ if not order_qs.exists():
|
|
|
+ return response.json(173)
|
|
|
+ store_qs = Store_Meal.objects.filter(id=order_qs[0]['rank_id'], product_id=product_id).values(
|
|
|
'id', 'currency', 'price', 'lang__content', 'day', 'commodity_type', 'lang__title', 'expire',
|
|
|
'commodity_code', 'discount_price', 'bucket_id', 'bucket__mold', 'cycle_config_id', 'is_ai')
|
|
|
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']
|
|
|
- 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']
|
|
|
- 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
|
|
@@ -210,13 +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.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,
|
|
|
- agreement_id=agreement_id
|
|
|
- )
|
|
|
+ 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)
|
|
|
|
|
|
# 发送云存开通信息
|
|
|
date_time = time.strftime("%Y-%m-%d", time.localtime())
|
|
@@ -349,19 +322,24 @@ class InAppPurchaseView(View):
|
|
|
decoded_payload.data.signedTransactionInfo)
|
|
|
|
|
|
# originalTransactionId 原始购买的交易标识符
|
|
|
- originalTransaction_id = decoded_transaction_information.originalTransactionId
|
|
|
+ original_transaction_id = decoded_transaction_information.originalTransactionId
|
|
|
+ transaction_id = decoded_transaction_information.transactionId
|
|
|
|
|
|
- logger.info(f"App Store服务器通知originalTransactionId原始购买的交易标识符{originalTransaction_id}")
|
|
|
- if not originalTransaction_id:
|
|
|
+ logger.info(
|
|
|
+ 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(agreement_id=originalTransaction_id).order_by(
|
|
|
- 'addTime').first()
|
|
|
- channel = ord_order.channel
|
|
|
- uid = ord_order.uid
|
|
|
- pay_type = ord_order.payType
|
|
|
- user_id = ord_order.userID_id
|
|
|
+ ord_order = Order_Model.objects.filter(original_transaction_id=original_transaction_id).order_by(
|
|
|
+ '-addTime')
|
|
|
+ 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.rank). \
|
|
|
values(
|
|
@@ -441,7 +419,8 @@ class InAppPurchaseView(View):
|
|
|
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, agreement_id=originalTransaction_id
|
|
|
+ uid_bucket_id=uid_bucket_id, transaction_id=transaction_id,
|
|
|
+ original_transaction_id=original_transaction_id
|
|
|
)
|
|
|
|
|
|
# 发送云存开通信息
|
|
@@ -493,7 +472,6 @@ class InAppPurchaseView(View):
|
|
|
# PRODUCT_NOT_FOR_SALE,则表示订阅已过期,因为在订阅尝试续订时,产品已不可购买。
|
|
|
# 没有子类型的通知表示订阅因其他原因过期。
|
|
|
pass
|
|
|
-
|
|
|
else:
|
|
|
logger.info(f"App Store服务器通知decoded_payload.rawNotificationType 未处理")
|
|
|
return HttpResponse(status=500)
|