chirag04 / react-native-in-app-utils

A react-native wrapper for handling in-app payments
MIT License
890 stars 185 forks source link

Support refreshing receipts #110

Closed akshetpandey closed 1 month ago

akshetpandey commented 7 years ago

Expose a method to refresh receipts. This is the recommended way by apple to restore purchases unless the purchases actually need the SKTransaction.

https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Restoring.html

akshetpandey commented 7 years ago

Sorry have been on a vacation, will get back to my PRs soon.

omeraplak commented 6 years ago

@akshetpandey Hello, can i use this PR on production?

akshetpandey commented 6 years ago

@omeraplak : We have been using this in production for a ~100k DAU app for about 6 months now so you should be safe to use it...

omeraplak commented 6 years ago

@akshetpandey thank you!

kyangy commented 6 years ago

@akshetpandey @omeraplak how are you using this in react native?

akshetpandey commented 6 years ago

On our pay gate we expose a "Restore Purchase/Subscription" button... on pressing that we call this method, then get the new receipts if there is any and use that to restore anything a user may have purchased

kyangy commented 6 years ago

@akshetpandey How are you calling it? I am calling it like this

InAppUtils.refreshReceipt((error, result) => {})

but it prompted me to sign in twice and then I get hit with an error.

akshetpandey commented 6 years ago

Yes that is what I am doing. You will need to be logged in to a valid app store account.

akshetpandey commented 6 years ago

Straight from the codebase...

  async restoreSubscription (onProgress, onSuccess, onError) {
    try {
      await this._refreshReceipt()
      const { subscriptionPurchaseReceipts } = await this._getValidReceipts()
      this._logTransactions(subscriptionPurchaseReceipts)
      const latestSubscriptionReceipt = this._findMostRecentReceipt(subscriptionPurchaseReceipts)
      this._updateSubscriptionStatus(latestSubscriptionReceipt)
      onSuccess(latestSubscriptionReceipt.product_id)
      } else {
        throw new Error('no_valid_receipts')
      }
    } catch (error) {
      onError(error)
    }
  }

  _refreshReceipt () {
    return new Promise((resolve, reject) => {
      debugLog('IAP', 'Refreshing receipt...')
      InAppUtils.refreshReceipt((error, response) => {
        if (error) {
          debugLog('IAP', 'Error refreshing receipt', error)
          reject(error)
        } else if (response) {
          debugLog('IAP', 'Refreshed receipt')
          resolve()
        }
      })
    })
  }

  _getValidReceipts () {
    return new Promise((resolve, reject) => {
      debugLog('IAP', 'Checking receipts...')
      InAppUtils.receiptData(async (error, receiptData) => {
        if (error) {
          if (error === 'not_available') {
            debugLog('IAP', 'No receipt on device, this is fine')
            resolve({subscriptionPurchaseReceipts: null, consumablePurchaseReceipts: null})
          } else {
            throw error
          }
          reject(error)
        } else {
          debugLog('IAP', `Validating receipt data...`)
          try {
            const validationResponse = await validateReceipt(receiptData)
            const receipts = {
              subscriptionPurchaseReceipts: _.get(validationResponse, ['latest_receipt_info'], null),
              consumablePurchaseReceipts: _.get(validationResponse, ['receipt', 'in_app'], null)
            }
            resolve(receipts)
          } catch (error) {
            debugLog('IAP', 'Error in validating Receipt', error)
            reject(error)
          }
        }
      })
    })
  }
kyangy commented 6 years ago

@akshetpandey ok thanks will try something out!

stefanwuest commented 6 years ago

Hi @akshetpandey! Will refreshReceipt enable me to give me receiptData after purchasing non-renewable subscriptions? At the moment I have the problem, that receiptData() returns not_available when I try to directly call it (not after purchaseProduct).

akshetpandey commented 6 years ago

Yes, calling refreshReceipt will give you those receipts back

djw27 commented 6 years ago

Is there a reason this hasn't been merged?

akshetpandey commented 6 years ago

The requested changed were never implemented. If you would like, you can create a new PR with the requested changes and I can close this one.

djw27 commented 6 years ago

@akshetpandey does https://github.com/chirag04/react-native-in-app-utils/pull/140 contain the requested changes?