【问题标题】:Expo in app purchases for React Native — how to tell if subscription is current / active?为 React Native 购买应用程序中的 Expo — 如何判断订阅是否是当前/活动的?
【发布时间】:2023-03-09 20:06:01
【问题描述】:

当前的应用程序是 React Native 的 Expo,它被弹出到裸工作流中。 使用 expo-in-app-purchases 进行 IAP。

如何判断订阅是否有效?

当我通过以下方式获取购买历史记录时:

const { results } = InAppPurchases.connectAsync();

如果查看结果,结果会返回以下字段:

  • 购买时间
  • 交易收据
  • 订单编号
  • 产品标识
  • 已确认
  • 原始购买时间
  • 原始订单编号
  • 购买状态

现在 purchaseState 始终是一个整数。我主要看到3(我想我曾经看过1...)不确定这是否真的告诉我任何有价值的东西,因为它们都是3s

没有手动进行最近一次购买并添加 30 天(这是每月订阅)然后查看此日期是否过去,我不确定如何查找当前用户是否有有效订阅。救命!

提前致谢!

【问题讨论】:

  • 您找到解决方案了吗?我有同样的问题。您似乎可以解密收据并阅读其内容?
  • @chairsandtable 你如何实现“expo-in-app-purchases”?当我安装并尝试构建解决方案时,它会自行构建失败。如 SKErrorPaymentCancelled 等任何解决方案?

标签: react-native in-app-purchase expo in-app-subscription


【解决方案1】:

Apple 将收据作为签名和 base64 编码的字符串提供给您。为了查看收据的内容(包括“过期”日期),您需要将此收据连同您的应用专用密码一起发送到 Apple 的收据验证端点。

更多信息在这里:https://developer.apple.com/documentation/storekit/in-app_purchase/validating_receipts_with_the_app_store

类似的功能对我有用。这会将收据信息作为 JSON 对象检索,其中有 expires_at_ms,可以将其与今天的日期进行比较,以查看订阅是否已过期。

async validateAppleReceipt(receipt) {
  const prodURL = 'https://buy.itunes.apple.com/verifyReceipt'
  const stagingURL = 'https://sandbox.itunes.apple.com/verifyReceipt'
  const appSecret = '1234...'

  const payload = {
    "receipt-data": receipt,
    "password": appSecret,
    "exclude-old-transactions": true,
  }

  // First, try to validate against production
  const prodRes = await axios.post(prodURL, payload)

  // If status is 21007, fall back to sandbox
  if (prodRes.data && prodRes.data.status === 21007) {
    const sandboxRes = await axios.post(stagingURL, payload)
    return sandboxRes.data.latest_receipt_info[0]
  }

  // Otherwise, return the prod data!
  return prodRes.data.latest_receipt_info[0]
}

【讨论】:

    【解决方案2】:

    或者,您可以使用第三方 SDK 来处理应用内订阅并获取服务器端收据验证。这里检查当前订阅状态的代码看起来像Qonversion.io SDK。披露 - 我是 Qonversion.io 的联合创始人

    const permissions: Map<string, Permission> = await Qonversion.checkPermissions();
        
    const premiumPermission = permissions.get('premium');
    if (mainPermission != null) {
      switch (premiumPermission.renewState) {
        case RenewState.NON_RENEWABLE:
          // NON_RENEWABLE is the state of consumable/non-consumable IAPs that could unlock lifetime access
          break;
        case RenewState.WILL_RENEW:
          // WILL_RENEW is the state of an auto-renewable subscription 
          break;
        case RenewState.CANCELED:
          // The user has turned off auto-renewal for the subscription, but the subscription has not expired yet.
          // Prompt the user to resubscribe with a special offer.
          break;
        case RenewState.BILLING_ISSUE:
          // Grace period: permission is active, but there was some billing issue.
          // Prompt the user to update the payment method.
          break;
      }
    }
    

    【讨论】:

      【解决方案3】:

      你试过用吗

      const { responseCode, results } = await getPurchaseHistoryAsync(true);
      

      【讨论】:

      • 这会检索购买列表,但不清楚如何识别自动续订订阅购买是否仍然有效。
      • 我发现您需要一个后端并连接到播放商店服务(在 android 中),您可以使用 firebase 云功能简单地做到这一点
      猜你喜欢
      • 1970-01-01
      • 2021-02-13
      • 2016-04-29
      • 2010-10-05
      • 2011-07-04
      • 2013-02-22
      • 2011-09-13
      • 1970-01-01
      • 2019-02-27
      相关资源
      最近更新 更多