diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index 3c938bd8c..8a2b6814d 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -812,10 +812,10 @@ describe('Public API (src/index.ts)', () => { .mockResolvedValueOnce([nitro('s1')]); const res = await IAP.getAvailablePurchases(); expect(mockIap.getAvailablePurchases).toHaveBeenNthCalledWith(1, { - android: {type: 'inapp'}, + android: {type: 'inapp', includeSuspended: false}, }); expect(mockIap.getAvailablePurchases).toHaveBeenNthCalledWith(2, { - android: {type: 'subs'}, + android: {type: 'subs', includeSuspended: false}, }); expect(res.map((p: any) => p.productId).sort()).toEqual(['p1', 's1']); }); diff --git a/src/hooks/useIAP.ts b/src/hooks/useIAP.ts index faff89651..f083da4fe 100644 --- a/src/hooks/useIAP.ts +++ b/src/hooks/useIAP.ts @@ -40,6 +40,7 @@ import type { VerifyPurchaseResult, VerifyPurchaseWithProviderProps, VerifyPurchaseWithProviderResult, + PurchaseOptions, } from '../types'; import type { ActiveSubscription, @@ -63,7 +64,7 @@ type UseIap = { promotedProductIOS?: Product; activeSubscriptions: ActiveSubscription[]; finishTransaction: (args: MutationFinishTransactionArgs) => Promise; - getAvailablePurchases: (skus?: string[]) => Promise; + getAvailablePurchases: (options?: PurchaseOptions) => Promise; fetchProducts: (params: { skus: string[]; type?: ProductQueryType | null; @@ -83,7 +84,7 @@ type UseIap = { verifyPurchaseWithProvider: ( options: VerifyPurchaseWithProviderProps, ) => Promise; - restorePurchases: () => Promise; + restorePurchases: (options?: PurchaseOptions) => Promise; getPromotedProductIOS: () => Promise; requestPurchaseOnPromotedProductIOS: () => Promise; getActiveSubscriptions: ( @@ -271,11 +272,13 @@ export function useIAP(options?: UseIapOptions): UseIap { ); const getAvailablePurchasesInternal = useCallback( - async (_skus?: string[]): Promise => { + async (options?: PurchaseOptions): Promise => { try { const result = await getAvailablePurchases({ - alsoPublishToEventListenerIOS: false, - onlyIncludeActiveItemsIOS: true, + alsoPublishToEventListenerIOS: + options?.alsoPublishToEventListenerIOS ?? false, + onlyIncludeActiveItemsIOS: options?.onlyIncludeActiveItemsIOS ?? true, + includeSuspendedAndroid: options?.includeSuspendedAndroid ?? false, }); setAvailablePurchases(result); } catch (error) { @@ -333,18 +336,21 @@ export function useIAP(options?: UseIapOptions): UseIap { [], ); - const restorePurchases = useCallback(async (): Promise => { - try { - if (Platform.OS === 'ios') { - await syncIOS(); - } + const restorePurchases = useCallback( + async (options?: PurchaseOptions): Promise => { + try { + if (Platform.OS === 'ios') { + await syncIOS(); + } - await getAvailablePurchasesInternal(); - } catch (error) { - RnIapConsole.warn('Failed to restore purchases:', error); - invokeOnError(error); - } - }, [getAvailablePurchasesInternal, invokeOnError]); + await getAvailablePurchasesInternal(options); + } catch (error) { + RnIapConsole.warn('Failed to restore purchases:', error); + invokeOnError(error); + } + }, + [getAvailablePurchasesInternal, invokeOnError], + ); const validateReceipt = useCallback( async (options: VerifyPurchaseProps): Promise => diff --git a/src/index.ts b/src/index.ts index 907412e5c..c65fac80e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -737,11 +737,14 @@ export const getAvailablePurchases: QueryField< return validPurchases.map(convertNitroPurchaseToPurchase); } else if (Platform.OS === 'android') { // For Android, we need to call twice for inapp and subs + const includeSuspended = Boolean( + options?.includeSuspendedAndroid ?? false, + ); const inappNitroPurchases = await IAP.instance.getAvailablePurchases({ - android: {type: 'inapp'}, + android: {type: 'inapp', includeSuspended}, }); const subsNitroPurchases = await IAP.instance.getAvailablePurchases({ - android: {type: 'subs'}, + android: {type: 'subs', includeSuspended}, }); // Validate and convert both sets of purchases