You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Apple原始API在Python服务端用收据获取订阅与购买信息?

基于旧VerifyReceipt端点处理自动续订订阅状态的Python实现

核心逻辑

虽然Apple的VerifyReceipt端点已标记为弃用,但目前仍可正常调用以解析收据中的订阅状态数据。无需升级到新API,只需重点解析响应返回的latest_receipt_info数组,即可获取自动续订订阅的续订/取消状态。

实现步骤

1. 构造验证请求

将客户端传来的Base64编码收据、你的App内购共享密钥作为参数,发送POST请求到对应环境的Apple验证服务器:

  • 沙箱环境:https://sandbox.itunes.apple.com/verifyReceipt
  • 生产环境:https://buy.itunes.apple.com/verifyReceipt

2. 解析订阅状态字段

从响应的latest_receipt_info中提取关键字段判断状态:

  • cancellation_date_ms:存在该字段则表示订阅已主动取消
  • expires_date_ms:订阅到期时间戳,与当前时间对比判断是否仍在有效期
  • auto_renew_status:0表示用户关闭自动续订,1表示开启
  • is_in_billing_retry_period:是否处于账单重试期(用户支付失败后,Apple会尝试自动扣费)

Python代码示例

import requests
import json
import time

def check_subscription_status(receipt_base64, shared_secret, use_sandbox=False):
    # 选择验证环境
    verify_url = "https://sandbox.itunes.apple.com/verifyReceipt" if use_sandbox else "https://buy.itunes.apple.com/verifyReceipt"
    
    # 构造请求体
    request_payload = {
        "receipt-data": receipt_base64,
        "password": shared_secret,
        "exclude-old-transactions": True  # 仅返回最新交易记录,减少数据量
    }
    
    # 发送请求
    response = requests.post(verify_url, data=json.dumps(request_payload), headers={"Content-Type": "application/json"})
    resp_data = response.json()
    
    # 验证失败处理
    if resp_data.get("status") != 0:
        return {"success": False, "error_code": resp_data["status"]}
    
    # 解析订阅状态
    subscription_list = []
    latest_receipts = resp_data.get("latest_receipt_info", [])
    
    for receipt in latest_receipts:
        # 判断订阅是否有效
        is_active = False
        if not receipt.get("cancellation_date_ms"):
            current_ts = int(round(time.time() * 1000))
            expires_ts = int(receipt["expires_date_ms"])
            is_active = expires_ts > current_ts
        
        subscription_list.append({
            "product_id": receipt["product_id"],
            "is_active": is_active,
            "expires_at": receipt["expires_date_ms"],
            "auto_renew_enabled": receipt.get("auto_renew_status") == "1",
            "in_retry_period": receipt.get("is_in_billing_retry_period") == "1",
            "cancelled_at": receipt.get("cancellation_date_ms")
        })
    
    # 返回结果,可存储latest_receipt用于后续查询
    return {
        "success": True,
        "subscriptions": subscription_list,
        "latest_receipt": resp_data.get("latest_receipt")
    }

关键注意事项

  • 优先存储返回的latest_receipt,后续查询时可直接使用该值,无需客户端重复上传原始收据
  • 务必严格区分沙箱和生产环境,避免跨环境验证导致的错误
  • 该端点虽仍可用,但Apple后续可能停止支持,记得按计划升级到App Store Server API
  • 处于账单重试期的订阅,即使已过到期时间,仍视为活跃状态,直到重试失败或用户更新支付方式

内容的提问来源于stack exchange,提问作者user984003

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 16:08:09