Closed akshetpandey closed 1 month ago
Sorry have been on a vacation, will get back to my PRs soon.
@akshetpandey Hello, can i use this PR on production?
@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...
@akshetpandey thank you!
@akshetpandey @omeraplak how are you using this in react native?
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
@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.
Yes that is what I am doing. You will need to be logged in to a valid app store account.
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)
}
}
})
})
}
@akshetpandey ok thanks will try something out!
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
).
Yes, calling refreshReceipt will give you those receipts back
Is there a reason this hasn't been merged?
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.
@akshetpandey does https://github.com/chirag04/react-native-in-app-utils/pull/140 contain the requested changes?
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