react-native-iap 15.2.3 → 15.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -51
- package/android/build.gradle +92 -22
- package/android/gradle.properties +5 -1
- package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +24 -8
- package/android/src/main/java/com/margelo/nitro/iap/RnIapLog.kt +3 -1
- package/ios/HybridRnIap.swift +172 -73
- package/lib/module/hooks/useIAP.js +1 -1
- package/lib/module/hooks/useIAP.js.map +1 -1
- package/lib/module/index.js +138 -165
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/src/hooks/useIAP.d.ts +22 -16
- package/lib/typescript/src/hooks/useIAP.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +61 -90
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/RnIap.nitro.d.ts +5 -16
- package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +63 -49
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/nitro.json +0 -1
- package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +11 -6
- package/nitrogen/generated/android/c++/JHybridRnIapSpec.hpp +2 -2
- package/nitrogen/generated/android/c++/JPurchaseUpdatedListenerOptions.hpp +61 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/HybridRnIapSpec.kt +4 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/PurchaseUpdatedListenerOptions.kt +38 -0
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.hpp +27 -0
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +9 -4
- package/nitrogen/generated/ios/swift/HybridRnIapSpec.swift +2 -2
- package/nitrogen/generated/ios/swift/HybridRnIapSpec_cxx.swift +8 -12
- package/nitrogen/generated/ios/swift/PurchaseUpdatedListenerOptions.swift +61 -0
- package/nitrogen/generated/shared/c++/HybridRnIapSpec.hpp +5 -2
- package/nitrogen/generated/shared/c++/PurchaseUpdatedListenerOptions.hpp +85 -0
- package/openiap-versions.json +3 -3
- package/package.json +4 -6
- package/src/hooks/useIAP.ts +23 -15
- package/src/index.ts +198 -215
- package/src/specs/RnIap.nitro.ts +10 -18
- package/src/types.ts +66 -49
package/lib/module/index.js
CHANGED
|
@@ -28,13 +28,14 @@ import { parseAppTransactionPayload } from "./utils.js";
|
|
|
28
28
|
|
|
29
29
|
export * from "./types.js";
|
|
30
30
|
export * from "./utils/error.js";
|
|
31
|
-
const LEGACY_INAPP_WARNING = "[react-native-iap] `type: 'inapp'` is deprecated and will be removed in
|
|
31
|
+
const LEGACY_INAPP_WARNING = "[react-native-iap] `type: 'inapp'` is deprecated and will be removed in a future major version. Use 'in-app' instead.";
|
|
32
32
|
const toErrorMessage = error => {
|
|
33
33
|
if (typeof error === 'object' && error !== null && 'message' in error && error.message != null) {
|
|
34
34
|
return String(error.message);
|
|
35
35
|
}
|
|
36
36
|
return String(error ?? '');
|
|
37
37
|
};
|
|
38
|
+
const unsupportedPlatformError = () => new Error(`Unsupported platform: ${Platform.OS}`);
|
|
38
39
|
// ActiveSubscription and PurchaseError types are already exported via 'export * from ./types'
|
|
39
40
|
|
|
40
41
|
// Export hooks
|
|
@@ -114,11 +115,15 @@ const IAP = {
|
|
|
114
115
|
// ============================================================================
|
|
115
116
|
|
|
116
117
|
const purchaseUpdateJsListeners = new Set();
|
|
118
|
+
const purchaseUpdateDuplicateJsListeners = new Set();
|
|
117
119
|
let purchaseUpdateNativeAttached = false;
|
|
118
|
-
|
|
120
|
+
let purchaseUpdateDuplicateNativeAttached = false;
|
|
121
|
+
let purchaseUpdateNativeToken = null;
|
|
122
|
+
let purchaseUpdateDuplicateNativeToken = null;
|
|
123
|
+
const emitPurchaseUpdateToListeners = (nitroPurchase, listeners) => {
|
|
119
124
|
if (validateNitroPurchase(nitroPurchase)) {
|
|
120
125
|
const convertedPurchase = convertNitroPurchaseToPurchase(nitroPurchase);
|
|
121
|
-
for (const listener of
|
|
126
|
+
for (const listener of listeners) {
|
|
122
127
|
try {
|
|
123
128
|
listener(convertedPurchase);
|
|
124
129
|
} catch (e) {
|
|
@@ -129,6 +134,12 @@ const purchaseUpdateNativeHandler = nitroPurchase => {
|
|
|
129
134
|
RnIapConsole.error('Invalid purchase data received from native — productId:', nitroPurchase?.productId ?? 'unknown');
|
|
130
135
|
}
|
|
131
136
|
};
|
|
137
|
+
const purchaseUpdateNativeHandler = nitroPurchase => {
|
|
138
|
+
emitPurchaseUpdateToListeners(nitroPurchase, purchaseUpdateJsListeners);
|
|
139
|
+
};
|
|
140
|
+
const purchaseUpdateDuplicateNativeHandler = nitroPurchase => {
|
|
141
|
+
emitPurchaseUpdateToListeners(nitroPurchase, purchaseUpdateDuplicateJsListeners);
|
|
142
|
+
};
|
|
132
143
|
const purchaseErrorJsListeners = new Set();
|
|
133
144
|
let purchaseErrorNativeAttached = false;
|
|
134
145
|
const purchaseErrorNativeHandler = error => {
|
|
@@ -168,6 +179,9 @@ const promotedProductNativeHandler = nitroProduct => {
|
|
|
168
179
|
*/
|
|
169
180
|
export const resetListenerState = () => {
|
|
170
181
|
purchaseUpdateNativeAttached = false;
|
|
182
|
+
purchaseUpdateDuplicateNativeAttached = false;
|
|
183
|
+
purchaseUpdateNativeToken = null;
|
|
184
|
+
purchaseUpdateDuplicateNativeToken = null;
|
|
171
185
|
purchaseErrorNativeAttached = false;
|
|
172
186
|
promotedProductNativeAttached = false;
|
|
173
187
|
userChoiceBillingNativeAttached = false;
|
|
@@ -175,17 +189,21 @@ export const resetListenerState = () => {
|
|
|
175
189
|
subscriptionBillingIssueNativeAttached = false;
|
|
176
190
|
// Clear all JS listeners since native side clears them in endConnection
|
|
177
191
|
purchaseUpdateJsListeners.clear();
|
|
192
|
+
purchaseUpdateDuplicateJsListeners.clear();
|
|
178
193
|
purchaseErrorJsListeners.clear();
|
|
179
194
|
promotedProductJsListeners.clear();
|
|
180
195
|
userChoiceBillingJsListeners.clear();
|
|
181
196
|
developerProvidedBillingJsListeners.clear();
|
|
182
197
|
subscriptionBillingIssueJsListeners.clear();
|
|
183
198
|
};
|
|
184
|
-
export const purchaseUpdatedListener = listener => {
|
|
185
|
-
|
|
186
|
-
|
|
199
|
+
export const purchaseUpdatedListener = (listener, options) => {
|
|
200
|
+
const receiveDuplicateTransactionUpdatesIOS = Platform.OS === 'ios' && options?.dedupeTransactionIOS === false;
|
|
201
|
+
const listeners = receiveDuplicateTransactionUpdatesIOS ? purchaseUpdateDuplicateJsListeners : purchaseUpdateJsListeners;
|
|
202
|
+
listeners.add(listener);
|
|
203
|
+
if (!purchaseUpdateNativeAttached && !receiveDuplicateTransactionUpdatesIOS) {
|
|
187
204
|
try {
|
|
188
|
-
IAP.instance.addPurchaseUpdatedListener(purchaseUpdateNativeHandler);
|
|
205
|
+
const token = IAP.instance.addPurchaseUpdatedListener(purchaseUpdateNativeHandler);
|
|
206
|
+
purchaseUpdateNativeToken = typeof token === 'number' ? token : null;
|
|
189
207
|
purchaseUpdateNativeAttached = true;
|
|
190
208
|
} catch (e) {
|
|
191
209
|
const msg = toErrorMessage(e);
|
|
@@ -196,9 +214,50 @@ export const purchaseUpdatedListener = listener => {
|
|
|
196
214
|
}
|
|
197
215
|
}
|
|
198
216
|
}
|
|
217
|
+
if (!purchaseUpdateDuplicateNativeAttached && receiveDuplicateTransactionUpdatesIOS) {
|
|
218
|
+
try {
|
|
219
|
+
const nativeOptions = {
|
|
220
|
+
dedupeTransactionIOS: false
|
|
221
|
+
};
|
|
222
|
+
const token = IAP.instance.addPurchaseUpdatedListener(purchaseUpdateDuplicateNativeHandler, nativeOptions);
|
|
223
|
+
purchaseUpdateDuplicateNativeToken = typeof token === 'number' ? token : null;
|
|
224
|
+
purchaseUpdateDuplicateNativeAttached = true;
|
|
225
|
+
} catch (e) {
|
|
226
|
+
const msg = toErrorMessage(e);
|
|
227
|
+
if (msg.includes('Nitro runtime not installed')) {
|
|
228
|
+
RnIapConsole.warn('[purchaseUpdatedListener] Nitro not ready yet; listener inert until initConnection()');
|
|
229
|
+
} else {
|
|
230
|
+
throw e;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
let removed = false;
|
|
199
235
|
return {
|
|
200
236
|
remove: () => {
|
|
201
|
-
|
|
237
|
+
if (removed) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
removed = true;
|
|
241
|
+
listeners.delete(listener);
|
|
242
|
+
if (listeners.size > 0) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const token = receiveDuplicateTransactionUpdatesIOS ? purchaseUpdateDuplicateNativeToken : purchaseUpdateNativeToken;
|
|
246
|
+
if (token == null) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
IAP.instance.removePurchaseUpdatedListener(token);
|
|
251
|
+
if (receiveDuplicateTransactionUpdatesIOS) {
|
|
252
|
+
purchaseUpdateDuplicateNativeToken = null;
|
|
253
|
+
purchaseUpdateDuplicateNativeAttached = false;
|
|
254
|
+
} else {
|
|
255
|
+
purchaseUpdateNativeToken = null;
|
|
256
|
+
purchaseUpdateNativeAttached = false;
|
|
257
|
+
}
|
|
258
|
+
} catch (e) {
|
|
259
|
+
RnIapConsole.warn('[purchaseUpdatedListener] native remove failed:', e);
|
|
260
|
+
}
|
|
202
261
|
}
|
|
203
262
|
};
|
|
204
263
|
};
|
|
@@ -272,7 +331,7 @@ export const promotedProductListenerIOS = listener => {
|
|
|
272
331
|
* const subscription = userChoiceBillingListenerAndroid((details) => {
|
|
273
332
|
* console.log('User chose alternative billing');
|
|
274
333
|
* console.log('Products:', details.products);
|
|
275
|
-
* console.log('
|
|
334
|
+
* console.log('External transaction token received; send it to your backend without logging it.');
|
|
276
335
|
*
|
|
277
336
|
* // Send token to backend for Google Play reporting
|
|
278
337
|
* await reportToGooglePlay(details.externalTransactionToken);
|
|
@@ -339,7 +398,7 @@ export const userChoiceBillingListenerAndroid = listener => {
|
|
|
339
398
|
* ```typescript
|
|
340
399
|
* const subscription = developerProvidedBillingListenerAndroid((details) => {
|
|
341
400
|
* console.log('User chose developer billing');
|
|
342
|
-
* console.log('
|
|
401
|
+
* console.log('External transaction token received; send it to your backend without logging it.');
|
|
343
402
|
*
|
|
344
403
|
* // Process payment through your external payment system
|
|
345
404
|
* await processExternalPayment();
|
|
@@ -490,7 +549,7 @@ export const subscriptionBillingIssueListener = listener => {
|
|
|
490
549
|
* @remarks This is a regular promise-based call. Don't confuse with `request*` APIs
|
|
491
550
|
* (`requestPurchase`), which are event-based.
|
|
492
551
|
*
|
|
493
|
-
* @see {@link https://
|
|
552
|
+
* @see {@link https://openiap.dev/docs/apis/fetch-products}
|
|
494
553
|
*/
|
|
495
554
|
export const fetchProducts = async request => {
|
|
496
555
|
const {
|
|
@@ -597,7 +656,7 @@ export const fetchProducts = async request => {
|
|
|
597
656
|
* }
|
|
598
657
|
* ```
|
|
599
658
|
*
|
|
600
|
-
* @see {@link https://
|
|
659
|
+
* @see {@link https://openiap.dev/docs/apis/get-available-purchases}
|
|
601
660
|
*/
|
|
602
661
|
export const getAvailablePurchases = async options => {
|
|
603
662
|
const alsoPublishToEventListenerIOS = Boolean(options?.alsoPublishToEventListenerIOS ?? false);
|
|
@@ -642,7 +701,7 @@ export const getAvailablePurchases = async options => {
|
|
|
642
701
|
}
|
|
643
702
|
return validPurchases.map(convertNitroPurchaseToPurchase);
|
|
644
703
|
} else {
|
|
645
|
-
throw
|
|
704
|
+
throw unsupportedPlatformError();
|
|
646
705
|
}
|
|
647
706
|
} catch (error) {
|
|
648
707
|
RnIapConsole.error('Failed to get available purchases:', error);
|
|
@@ -655,7 +714,7 @@ export const getAvailablePurchases = async options => {
|
|
|
655
714
|
* @returns Promise<Product | null> - The promoted product or null if none available
|
|
656
715
|
* @platform iOS
|
|
657
716
|
*
|
|
658
|
-
* @see {@link https://
|
|
717
|
+
* @see {@link https://openiap.dev/docs/apis/ios/get-promoted-product-ios}
|
|
659
718
|
*/
|
|
660
719
|
export const getPromotedProductIOS = async () => {
|
|
661
720
|
if (Platform.OS !== 'ios') {
|
|
@@ -692,7 +751,7 @@ export const requestPromotedProductIOS = getPromotedProductIOS;
|
|
|
692
751
|
* console.log('User storefront:', storefront); // e.g., 'USA', 'GBR', 'KOR'
|
|
693
752
|
* ```
|
|
694
753
|
*
|
|
695
|
-
* @see {@link https://
|
|
754
|
+
* @see {@link https://openiap.dev/docs/apis/ios/get-storefront-ios}
|
|
696
755
|
*/
|
|
697
756
|
export const getStorefrontIOS = async () => {
|
|
698
757
|
if (Platform.OS !== 'ios') {
|
|
@@ -710,7 +769,7 @@ export const getStorefrontIOS = async () => {
|
|
|
710
769
|
/**
|
|
711
770
|
* Return the user's storefront country code.
|
|
712
771
|
*
|
|
713
|
-
* @see {@link https://
|
|
772
|
+
* @see {@link https://openiap.dev/docs/apis/get-storefront}
|
|
714
773
|
*/
|
|
715
774
|
export const getStorefront = async () => {
|
|
716
775
|
if (Platform.OS !== 'ios' && Platform.OS !== 'android') {
|
|
@@ -753,7 +812,7 @@ export const getStorefront = async () => {
|
|
|
753
812
|
* }
|
|
754
813
|
* ```
|
|
755
814
|
*
|
|
756
|
-
* @see {@link https://
|
|
815
|
+
* @see {@link https://openiap.dev/docs/apis/ios/get-app-transaction-ios}
|
|
757
816
|
*/
|
|
758
817
|
export const getAppTransactionIOS = async () => {
|
|
759
818
|
if (Platform.OS !== 'ios') {
|
|
@@ -788,7 +847,7 @@ export const getAppTransactionIOS = async () => {
|
|
|
788
847
|
* @throws Error when called on non-iOS platforms or when IAP is not initialized
|
|
789
848
|
* @platform iOS
|
|
790
849
|
*
|
|
791
|
-
* @see {@link https://
|
|
850
|
+
* @see {@link https://openiap.dev/docs/apis/ios/subscription-status-ios}
|
|
792
851
|
*/
|
|
793
852
|
export const subscriptionStatusIOS = async sku => {
|
|
794
853
|
if (Platform.OS !== 'ios') {
|
|
@@ -816,7 +875,7 @@ export const subscriptionStatusIOS = async sku => {
|
|
|
816
875
|
* @returns Promise<Purchase | null> - Current entitlement or null
|
|
817
876
|
* @platform iOS
|
|
818
877
|
*
|
|
819
|
-
* @see {@link https://
|
|
878
|
+
* @see {@link https://openiap.dev/docs/apis/ios/current-entitlement-ios}
|
|
820
879
|
*/
|
|
821
880
|
export const currentEntitlementIOS = async sku => {
|
|
822
881
|
if (Platform.OS !== 'ios') {
|
|
@@ -847,7 +906,7 @@ export const currentEntitlementIOS = async sku => {
|
|
|
847
906
|
* @returns Promise<Purchase | null> - Latest transaction or null
|
|
848
907
|
* @platform iOS
|
|
849
908
|
*
|
|
850
|
-
* @see {@link https://
|
|
909
|
+
* @see {@link https://openiap.dev/docs/apis/ios/latest-transaction-ios}
|
|
851
910
|
*/
|
|
852
911
|
export const latestTransactionIOS = async sku => {
|
|
853
912
|
if (Platform.OS !== 'ios') {
|
|
@@ -877,7 +936,7 @@ export const latestTransactionIOS = async sku => {
|
|
|
877
936
|
* @returns Promise<Purchase[]> - Array of pending transactions
|
|
878
937
|
* @platform iOS
|
|
879
938
|
*
|
|
880
|
-
* @see {@link https://
|
|
939
|
+
* @see {@link https://openiap.dev/docs/apis/ios/get-pending-transactions-ios}
|
|
881
940
|
*/
|
|
882
941
|
export const getPendingTransactionsIOS = async () => {
|
|
883
942
|
if (Platform.OS !== 'ios') {
|
|
@@ -901,7 +960,7 @@ export const getPendingTransactionsIOS = async () => {
|
|
|
901
960
|
/**
|
|
902
961
|
* List every StoreKit transaction (finished + unfinished) for the current user.
|
|
903
962
|
*
|
|
904
|
-
* @see {@link https://
|
|
963
|
+
* @see {@link https://openiap.dev/docs/apis/ios/get-all-transactions-ios}
|
|
905
964
|
*/
|
|
906
965
|
export const getAllTransactionsIOS = async () => {
|
|
907
966
|
if (Platform.OS !== 'ios') {
|
|
@@ -927,7 +986,7 @@ export const getAllTransactionsIOS = async () => {
|
|
|
927
986
|
* @returns Promise<Purchase[]> - Subscriptions where auto-renewal status changed
|
|
928
987
|
* @platform iOS
|
|
929
988
|
*
|
|
930
|
-
* @see {@link https://
|
|
989
|
+
* @see {@link https://openiap.dev/docs/apis/ios/show-manage-subscriptions-ios}
|
|
931
990
|
*/
|
|
932
991
|
export const showManageSubscriptionsIOS = async () => {
|
|
933
992
|
if (Platform.OS !== 'ios') {
|
|
@@ -954,7 +1013,7 @@ export const showManageSubscriptionsIOS = async () => {
|
|
|
954
1013
|
* @returns Promise<boolean> - Eligibility status
|
|
955
1014
|
* @platform iOS
|
|
956
1015
|
*
|
|
957
|
-
* @see {@link https://
|
|
1016
|
+
* @see {@link https://openiap.dev/docs/apis/ios/is-eligible-for-intro-offer-ios}
|
|
958
1017
|
*/
|
|
959
1018
|
export const isEligibleForIntroOfferIOS = async groupID => {
|
|
960
1019
|
if (Platform.OS !== 'ios') {
|
|
@@ -979,7 +1038,7 @@ export const isEligibleForIntroOfferIOS = async groupID => {
|
|
|
979
1038
|
* @returns Promise<string> - Base64 encoded receipt data
|
|
980
1039
|
* @platform iOS
|
|
981
1040
|
*
|
|
982
|
-
* @see {@link https://
|
|
1041
|
+
* @see {@link https://openiap.dev/docs/apis/ios/get-receipt-data-ios}
|
|
983
1042
|
*/
|
|
984
1043
|
export const getReceiptDataIOS = async () => {
|
|
985
1044
|
if (Platform.OS !== 'ios') {
|
|
@@ -1048,7 +1107,7 @@ export const requestReceiptRefreshIOS = async () => {
|
|
|
1048
1107
|
* @returns Promise<boolean> - Verification status
|
|
1049
1108
|
* @platform iOS
|
|
1050
1109
|
*
|
|
1051
|
-
* @see {@link https://
|
|
1110
|
+
* @see {@link https://openiap.dev/docs/apis/ios/is-transaction-verified-ios}
|
|
1052
1111
|
*/
|
|
1053
1112
|
export const isTransactionVerifiedIOS = async sku => {
|
|
1054
1113
|
if (Platform.OS !== 'ios') {
|
|
@@ -1074,7 +1133,7 @@ export const isTransactionVerifiedIOS = async sku => {
|
|
|
1074
1133
|
* @returns Promise<string | null> - JWS representation or null
|
|
1075
1134
|
* @platform iOS
|
|
1076
1135
|
*
|
|
1077
|
-
* @see {@link https://
|
|
1136
|
+
* @see {@link https://openiap.dev/docs/apis/ios/get-transaction-jws-ios}
|
|
1078
1137
|
*/
|
|
1079
1138
|
export const getTransactionJwsIOS = async sku => {
|
|
1080
1139
|
if (Platform.OS !== 'ios') {
|
|
@@ -1115,7 +1174,7 @@ export const getTransactionJwsIOS = async sku => {
|
|
|
1115
1174
|
* @remarks When using `useIAP()`, connection is auto-managed on mount/unmount —
|
|
1116
1175
|
* pass options to the hook instead of calling this directly.
|
|
1117
1176
|
*
|
|
1118
|
-
* @see {@link https://
|
|
1177
|
+
* @see {@link https://openiap.dev/docs/apis/init-connection}
|
|
1119
1178
|
*/
|
|
1120
1179
|
export const initConnection = async config => {
|
|
1121
1180
|
try {
|
|
@@ -1135,7 +1194,7 @@ export const initConnection = async config => {
|
|
|
1135
1194
|
/**
|
|
1136
1195
|
* Close the store connection and release resources.
|
|
1137
1196
|
*
|
|
1138
|
-
* @see {@link https://
|
|
1197
|
+
* @see {@link https://openiap.dev/docs/apis/end-connection}
|
|
1139
1198
|
*/
|
|
1140
1199
|
export const endConnection = async () => {
|
|
1141
1200
|
try {
|
|
@@ -1158,7 +1217,7 @@ export const endConnection = async () => {
|
|
|
1158
1217
|
/**
|
|
1159
1218
|
* Restore non-consumable and active subscription purchases.
|
|
1160
1219
|
*
|
|
1161
|
-
* @see {@link https://
|
|
1220
|
+
* @see {@link https://openiap.dev/docs/apis/restore-purchases}
|
|
1162
1221
|
*/
|
|
1163
1222
|
export const restorePurchases = async () => {
|
|
1164
1223
|
try {
|
|
@@ -1205,7 +1264,7 @@ export const restorePurchases = async () => {
|
|
|
1205
1264
|
* @remarks Event-based. Listen for the result via {@link purchaseUpdatedListener} /
|
|
1206
1265
|
* {@link purchaseErrorListener}, or use `useIAP({ onPurchaseSuccess, onPurchaseError })`.
|
|
1207
1266
|
*
|
|
1208
|
-
* @see {@link https://
|
|
1267
|
+
* @see {@link https://openiap.dev/docs/apis/request-purchase}
|
|
1209
1268
|
*/
|
|
1210
1269
|
export const requestPurchase = async request => {
|
|
1211
1270
|
try {
|
|
@@ -1232,7 +1291,7 @@ export const requestPurchase = async request => {
|
|
|
1232
1291
|
throw new Error('Invalid request for Android. The `skus` property is required and must be a non-empty array.');
|
|
1233
1292
|
}
|
|
1234
1293
|
} else {
|
|
1235
|
-
throw
|
|
1294
|
+
throw unsupportedPlatformError();
|
|
1236
1295
|
}
|
|
1237
1296
|
const unifiedRequest = {};
|
|
1238
1297
|
|
|
@@ -1259,6 +1318,18 @@ export const requestPurchase = async request => {
|
|
|
1259
1318
|
if (iosRequest.advancedCommerceData) {
|
|
1260
1319
|
iosPayload.advancedCommerceData = iosRequest.advancedCommerceData;
|
|
1261
1320
|
}
|
|
1321
|
+
if (isSubs) {
|
|
1322
|
+
const subscriptionRequest = iosRequest;
|
|
1323
|
+
if (subscriptionRequest.introductoryOfferEligibility !== undefined) {
|
|
1324
|
+
iosPayload.introductoryOfferEligibility = subscriptionRequest.introductoryOfferEligibility;
|
|
1325
|
+
}
|
|
1326
|
+
if (subscriptionRequest.promotionalOfferJWS) {
|
|
1327
|
+
iosPayload.promotionalOfferJWS = subscriptionRequest.promotionalOfferJWS;
|
|
1328
|
+
}
|
|
1329
|
+
if (subscriptionRequest.winBackOffer) {
|
|
1330
|
+
iosPayload.winBackOffer = subscriptionRequest.winBackOffer;
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1262
1333
|
unifiedRequest.ios = iosPayload;
|
|
1263
1334
|
}
|
|
1264
1335
|
|
|
@@ -1340,7 +1411,7 @@ export const requestPurchase = async request => {
|
|
|
1340
1411
|
* @remarks **Critical:** Android purchases must be finalized within 3 days or Google
|
|
1341
1412
|
* auto-refunds. iOS unfinished transactions replay on every app launch.
|
|
1342
1413
|
*
|
|
1343
|
-
* @see {@link https://
|
|
1414
|
+
* @see {@link https://openiap.dev/docs/apis/finish-transaction}
|
|
1344
1415
|
*/
|
|
1345
1416
|
export const finishTransaction = async args => {
|
|
1346
1417
|
const {
|
|
@@ -1370,7 +1441,7 @@ export const finishTransaction = async args => {
|
|
|
1370
1441
|
}
|
|
1371
1442
|
};
|
|
1372
1443
|
} else {
|
|
1373
|
-
throw
|
|
1444
|
+
throw unsupportedPlatformError();
|
|
1374
1445
|
}
|
|
1375
1446
|
const result = await IAP.instance.finishTransaction(params);
|
|
1376
1447
|
const success = getSuccessFromPurchaseVariant(result, 'finishTransaction');
|
|
@@ -1404,7 +1475,7 @@ export const finishTransaction = async args => {
|
|
|
1404
1475
|
* await acknowledgePurchaseAndroid('purchase_token_here');
|
|
1405
1476
|
* ```
|
|
1406
1477
|
*
|
|
1407
|
-
* @see {@link https://
|
|
1478
|
+
* @see {@link https://openiap.dev/docs/apis/android/acknowledge-purchase-android}
|
|
1408
1479
|
*/
|
|
1409
1480
|
export const acknowledgePurchaseAndroid = async purchaseToken => {
|
|
1410
1481
|
try {
|
|
@@ -1440,7 +1511,7 @@ export const acknowledgePurchaseAndroid = async purchaseToken => {
|
|
|
1440
1511
|
* await consumePurchaseAndroid('purchase_token_here');
|
|
1441
1512
|
* ```
|
|
1442
1513
|
*
|
|
1443
|
-
* @see {@link https://
|
|
1514
|
+
* @see {@link https://openiap.dev/docs/apis/android/consume-purchase-android}
|
|
1444
1515
|
*/
|
|
1445
1516
|
export const consumePurchaseAndroid = async purchaseToken => {
|
|
1446
1517
|
try {
|
|
@@ -1494,7 +1565,7 @@ export const consumePurchaseAndroid = async purchaseToken => {
|
|
|
1494
1565
|
* });
|
|
1495
1566
|
* ```
|
|
1496
1567
|
*
|
|
1497
|
-
* @see {@link https://
|
|
1568
|
+
* @see {@link https://openiap.dev/docs/apis/validate-receipt}
|
|
1498
1569
|
*/
|
|
1499
1570
|
export const validateReceipt = async options => {
|
|
1500
1571
|
const {
|
|
@@ -1603,7 +1674,7 @@ export const validateReceipt = async options => {
|
|
|
1603
1674
|
* @param options - Receipt validation options containing the SKU
|
|
1604
1675
|
* @returns Promise resolving to receipt validation result
|
|
1605
1676
|
*
|
|
1606
|
-
* @see {@link https://
|
|
1677
|
+
* @see {@link https://openiap.dev/docs/features/validation#verify-purchase}
|
|
1607
1678
|
*/
|
|
1608
1679
|
export const verifyPurchase = validateReceipt;
|
|
1609
1680
|
|
|
@@ -1614,7 +1685,7 @@ export const verifyPurchase = validateReceipt;
|
|
|
1614
1685
|
* consumers who imported `validateReceiptIOS` — which is still declared on the
|
|
1615
1686
|
* OpenIAP Query interface — keep working. Throws on non-iOS platforms.
|
|
1616
1687
|
*
|
|
1617
|
-
* @see {@link https://
|
|
1688
|
+
* @see {@link https://openiap.dev/docs/apis/ios/validate-receipt-ios}
|
|
1618
1689
|
*/
|
|
1619
1690
|
export const validateReceiptIOS = async options => {
|
|
1620
1691
|
if (Platform.OS !== 'ios') {
|
|
@@ -1645,7 +1716,7 @@ export const validateReceiptIOS = async options => {
|
|
|
1645
1716
|
* });
|
|
1646
1717
|
* ```
|
|
1647
1718
|
*
|
|
1648
|
-
* @see {@link https://
|
|
1719
|
+
* @see {@link https://openiap.dev/docs/features/validation#verify-purchase-with-provider}
|
|
1649
1720
|
*/
|
|
1650
1721
|
export const verifyPurchaseWithProvider = async options => {
|
|
1651
1722
|
try {
|
|
@@ -1686,7 +1757,7 @@ export const verifyPurchaseWithProvider = async options => {
|
|
|
1686
1757
|
* @returns Promise<boolean>
|
|
1687
1758
|
* @platform iOS
|
|
1688
1759
|
*
|
|
1689
|
-
* @see {@link https://
|
|
1760
|
+
* @see {@link https://openiap.dev/docs/apis/ios/sync-ios}
|
|
1690
1761
|
*/
|
|
1691
1762
|
export const syncIOS = async () => {
|
|
1692
1763
|
if (Platform.OS !== 'ios') {
|
|
@@ -1712,7 +1783,7 @@ export const syncIOS = async () => {
|
|
|
1712
1783
|
* @returns Promise<boolean> - Indicates whether the redemption sheet was presented
|
|
1713
1784
|
* @platform iOS
|
|
1714
1785
|
*
|
|
1715
|
-
* @see {@link https://
|
|
1786
|
+
* @see {@link https://openiap.dev/docs/apis/ios/present-code-redemption-sheet-ios}
|
|
1716
1787
|
*/
|
|
1717
1788
|
export const presentCodeRedemptionSheetIOS = async () => {
|
|
1718
1789
|
if (Platform.OS !== 'ios') {
|
|
@@ -1753,7 +1824,7 @@ export const presentCodeRedemptionSheetIOS = async () => {
|
|
|
1753
1824
|
* @returns Promise<boolean> - true when the request triggers successfully
|
|
1754
1825
|
* @platform iOS
|
|
1755
1826
|
*
|
|
1756
|
-
* @see {@link https://
|
|
1827
|
+
* @see {@link https://openiap.dev/docs/apis/ios/request-purchase-on-promoted-product-ios}
|
|
1757
1828
|
*/
|
|
1758
1829
|
export const requestPurchaseOnPromotedProductIOS = async () => {
|
|
1759
1830
|
if (Platform.OS !== 'ios') {
|
|
@@ -1788,7 +1859,7 @@ export const requestPurchaseOnPromotedProductIOS = async () => {
|
|
|
1788
1859
|
* @returns Promise<boolean>
|
|
1789
1860
|
* @platform iOS
|
|
1790
1861
|
*
|
|
1791
|
-
* @see {@link https://
|
|
1862
|
+
* @see {@link https://openiap.dev/docs/apis/ios/clear-transaction-ios}
|
|
1792
1863
|
*/
|
|
1793
1864
|
export const clearTransactionIOS = async () => {
|
|
1794
1865
|
if (Platform.OS !== 'ios') {
|
|
@@ -1815,7 +1886,7 @@ export const clearTransactionIOS = async () => {
|
|
|
1815
1886
|
* @returns Promise<string | null> - The refund status or null if not available
|
|
1816
1887
|
* @platform iOS
|
|
1817
1888
|
*
|
|
1818
|
-
* @see {@link https://
|
|
1889
|
+
* @see {@link https://openiap.dev/docs/apis/ios/begin-refund-request-ios}
|
|
1819
1890
|
*/
|
|
1820
1891
|
export const beginRefundRequestIOS = async sku => {
|
|
1821
1892
|
if (Platform.OS !== 'ios') {
|
|
@@ -1840,7 +1911,7 @@ export const beginRefundRequestIOS = async sku => {
|
|
|
1840
1911
|
* Deeplinks to native interface that allows users to manage their subscriptions
|
|
1841
1912
|
* Cross-platform alias aligning with expo-iap
|
|
1842
1913
|
*
|
|
1843
|
-
* @see {@link https://
|
|
1914
|
+
* @see {@link https://openiap.dev/docs/apis/deep-link-to-subscriptions}
|
|
1844
1915
|
*/
|
|
1845
1916
|
export const deepLinkToSubscriptions = async options => {
|
|
1846
1917
|
const resolvedOptions = options ?? undefined;
|
|
@@ -1852,16 +1923,14 @@ export const deepLinkToSubscriptions = async options => {
|
|
|
1852
1923
|
return;
|
|
1853
1924
|
}
|
|
1854
1925
|
if (Platform.OS === 'ios') {
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
await IAP.instance.showManageSubscriptionsIOS();
|
|
1860
|
-
}
|
|
1861
|
-
} catch (error) {
|
|
1862
|
-
RnIapConsole.warn('[deepLinkToSubscriptions] Failed on iOS:', error);
|
|
1926
|
+
if (typeof IAP.instance.deepLinkToSubscriptionsIOS === 'function') {
|
|
1927
|
+
await IAP.instance.deepLinkToSubscriptionsIOS();
|
|
1928
|
+
} else {
|
|
1929
|
+
await IAP.instance.showManageSubscriptionsIOS();
|
|
1863
1930
|
}
|
|
1931
|
+
return;
|
|
1864
1932
|
}
|
|
1933
|
+
throw unsupportedPlatformError();
|
|
1865
1934
|
};
|
|
1866
1935
|
export const deepLinkToSubscriptionsIOS = async () => {
|
|
1867
1936
|
if (Platform.OS !== 'ios') {
|
|
@@ -1898,7 +1967,7 @@ export const deepLinkToSubscriptionsIOS = async () => {
|
|
|
1898
1967
|
* @param subscriptionIds - Optional array of subscription IDs to filter by
|
|
1899
1968
|
* @returns Promise<ActiveSubscription[]> - Array of active subscriptions
|
|
1900
1969
|
*
|
|
1901
|
-
* @see {@link https://
|
|
1970
|
+
* @see {@link https://openiap.dev/docs/apis/get-active-subscriptions}
|
|
1902
1971
|
*/
|
|
1903
1972
|
export const getActiveSubscriptions = async subscriptionIds => {
|
|
1904
1973
|
try {
|
|
@@ -1919,7 +1988,7 @@ export const getActiveSubscriptions = async subscriptionIds => {
|
|
|
1919
1988
|
environmentIOS: sub.environmentIOS ?? null,
|
|
1920
1989
|
willExpireSoon: sub.willExpireSoon ?? null,
|
|
1921
1990
|
daysUntilExpirationIOS: sub.daysUntilExpirationIOS ?? null,
|
|
1922
|
-
//
|
|
1991
|
+
// renewalInfoIOS contains subscription lifecycle information on iOS.
|
|
1923
1992
|
renewalInfoIOS: sub.renewalInfoIOS ? {
|
|
1924
1993
|
willAutoRenew: sub.renewalInfoIOS.willAutoRenew ?? false,
|
|
1925
1994
|
autoRenewPreference: sub.renewalInfoIOS.autoRenewPreference ?? null,
|
|
@@ -1954,90 +2023,6 @@ export const getActiveSubscriptions = async subscriptionIds => {
|
|
|
1954
2023
|
}
|
|
1955
2024
|
};
|
|
1956
2025
|
|
|
1957
|
-
// OLD IMPLEMENTATION - REPLACED WITH NATIVE CALL
|
|
1958
|
-
/*
|
|
1959
|
-
export const getActiveSubscriptions_OLD: QueryField<
|
|
1960
|
-
'getActiveSubscriptions'
|
|
1961
|
-
> = async (subscriptionIds) => {
|
|
1962
|
-
try {
|
|
1963
|
-
// Get all available purchases first
|
|
1964
|
-
const allPurchases = await getAvailablePurchases();
|
|
1965
|
-
|
|
1966
|
-
// For the critical bug fix: this function was previously returning ALL purchases
|
|
1967
|
-
// Now we properly filter for subscriptions only
|
|
1968
|
-
|
|
1969
|
-
// In production with real data, Android subscription filtering is done via platform-specific calls
|
|
1970
|
-
// But for backward compatibility and test support, we also check platform-specific fields
|
|
1971
|
-
|
|
1972
|
-
// Since expirationDateIOS and subscriptionGroupIdIOS are not available in NitroPurchase,
|
|
1973
|
-
// we need to rely on other indicators or assume all purchases are subscriptions
|
|
1974
|
-
// when called from getActiveSubscriptions
|
|
1975
|
-
const purchases = allPurchases;
|
|
1976
|
-
|
|
1977
|
-
// Filter for subscriptions and map to ActiveSubscription format
|
|
1978
|
-
const subscriptions = purchases
|
|
1979
|
-
.filter((purchase) => {
|
|
1980
|
-
// Filter by subscription IDs if provided
|
|
1981
|
-
if (subscriptionIds && subscriptionIds.length > 0) {
|
|
1982
|
-
return subscriptionIds.includes(purchase.productId);
|
|
1983
|
-
}
|
|
1984
|
-
return true;
|
|
1985
|
-
})
|
|
1986
|
-
.map((purchase): ActiveSubscription => {
|
|
1987
|
-
// Safe access to platform-specific fields with type guards
|
|
1988
|
-
const expirationDateIOS =
|
|
1989
|
-
'expirationDateIOS' in purchase
|
|
1990
|
-
? ((purchase as PurchaseIOS).expirationDateIOS ?? null)
|
|
1991
|
-
: null;
|
|
1992
|
-
|
|
1993
|
-
const environmentIOS =
|
|
1994
|
-
'environmentIOS' in purchase
|
|
1995
|
-
? ((purchase as PurchaseIOS).environmentIOS ?? null)
|
|
1996
|
-
: null;
|
|
1997
|
-
|
|
1998
|
-
const autoRenewingAndroid =
|
|
1999
|
-
'autoRenewingAndroid' in purchase || 'isAutoRenewing' in purchase
|
|
2000
|
-
? ((purchase as PurchaseAndroid).autoRenewingAndroid ??
|
|
2001
|
-
(purchase as PurchaseAndroid).isAutoRenewing) // deprecated - use isAutoRenewing instead
|
|
2002
|
-
: null;
|
|
2003
|
-
|
|
2004
|
-
// 🆕 Extract renewalInfoIOS if available
|
|
2005
|
-
const renewalInfoIOS =
|
|
2006
|
-
'renewalInfoIOS' in purchase
|
|
2007
|
-
? ((purchase as PurchaseIOS).renewalInfoIOS ?? null)
|
|
2008
|
-
: null;
|
|
2009
|
-
|
|
2010
|
-
return {
|
|
2011
|
-
productId: purchase.productId,
|
|
2012
|
-
isActive: true, // If it's in availablePurchases, it's active
|
|
2013
|
-
// Backend validation fields - use transactionId ?? id for proper field mapping
|
|
2014
|
-
transactionId: purchase.transactionId ?? purchase.id,
|
|
2015
|
-
purchaseToken: purchase.purchaseToken,
|
|
2016
|
-
transactionDate: purchase.transactionDate,
|
|
2017
|
-
// Platform-specific fields
|
|
2018
|
-
expirationDateIOS,
|
|
2019
|
-
autoRenewingAndroid,
|
|
2020
|
-
environmentIOS,
|
|
2021
|
-
renewalInfoIOS,
|
|
2022
|
-
// Convenience fields
|
|
2023
|
-
willExpireSoon: false, // Would need to calculate based on expiration date
|
|
2024
|
-
daysUntilExpirationIOS:
|
|
2025
|
-
expirationDateIOS != null
|
|
2026
|
-
? Math.ceil(
|
|
2027
|
-
(expirationDateIOS - Date.now()) / (1000 * 60 * 60 * 24),
|
|
2028
|
-
)
|
|
2029
|
-
: null,
|
|
2030
|
-
};
|
|
2031
|
-
});
|
|
2032
|
-
|
|
2033
|
-
return subscriptions;
|
|
2034
|
-
} catch (error) {
|
|
2035
|
-
RnIapConsole.error('Failed to get active subscriptions:', error);
|
|
2036
|
-
const errorJson = parseErrorStringToJsonObj(error);
|
|
2037
|
-
throw new Error(errorJson.message);
|
|
2038
|
-
}
|
|
2039
|
-
};
|
|
2040
|
-
|
|
2041
2026
|
/**
|
|
2042
2027
|
* Check if the user has any active subscriptions (OpenIAP compliant)
|
|
2043
2028
|
* Returns true if the user has at least one active subscription, false otherwise.
|
|
@@ -2046,7 +2031,7 @@ export const getActiveSubscriptions_OLD: QueryField<
|
|
|
2046
2031
|
* @param subscriptionIds - Optional array of subscription IDs to check
|
|
2047
2032
|
* @returns Promise<boolean> - True if there are active subscriptions
|
|
2048
2033
|
*
|
|
2049
|
-
* @see {@link https://
|
|
2034
|
+
* @see {@link https://openiap.dev/docs/apis/has-active-subscriptions}
|
|
2050
2035
|
*/
|
|
2051
2036
|
export const hasActiveSubscriptions = async subscriptionIds => {
|
|
2052
2037
|
try {
|
|
@@ -2150,7 +2135,7 @@ const normalizeProductQueryType = type => {
|
|
|
2150
2135
|
* }
|
|
2151
2136
|
* ```
|
|
2152
2137
|
*
|
|
2153
|
-
* @see {@link https://
|
|
2138
|
+
* @see {@link https://openiap.dev/docs/apis/android/check-alternative-billing-availability-android}
|
|
2154
2139
|
*/
|
|
2155
2140
|
export const checkAlternativeBillingAvailabilityAndroid = async () => {
|
|
2156
2141
|
if (Platform.OS !== 'android') {
|
|
@@ -2187,7 +2172,7 @@ export const checkAlternativeBillingAvailabilityAndroid = async () => {
|
|
|
2187
2172
|
* }
|
|
2188
2173
|
* ```
|
|
2189
2174
|
*
|
|
2190
|
-
* @see {@link https://
|
|
2175
|
+
* @see {@link https://openiap.dev/docs/apis/android/show-alternative-billing-dialog-android}
|
|
2191
2176
|
*/
|
|
2192
2177
|
export const showAlternativeBillingDialogAndroid = async () => {
|
|
2193
2178
|
if (Platform.OS !== 'android') {
|
|
@@ -2224,7 +2209,7 @@ export const showAlternativeBillingDialogAndroid = async () => {
|
|
|
2224
2209
|
* }
|
|
2225
2210
|
* ```
|
|
2226
2211
|
*
|
|
2227
|
-
* @see {@link https://
|
|
2212
|
+
* @see {@link https://openiap.dev/docs/apis/android/create-alternative-billing-token-android}
|
|
2228
2213
|
*/
|
|
2229
2214
|
export const createAlternativeBillingTokenAndroid = async sku => {
|
|
2230
2215
|
if (Platform.OS !== 'android') {
|
|
@@ -2238,18 +2223,6 @@ export const createAlternativeBillingTokenAndroid = async sku => {
|
|
|
2238
2223
|
}
|
|
2239
2224
|
};
|
|
2240
2225
|
|
|
2241
|
-
/**
|
|
2242
|
-
* Parameters for launching an external link (Android 8.2.0+).
|
|
2243
|
-
*/
|
|
2244
|
-
|
|
2245
|
-
/**
|
|
2246
|
-
* Result of checking billing program availability (Android 8.2.0+).
|
|
2247
|
-
*/
|
|
2248
|
-
|
|
2249
|
-
/**
|
|
2250
|
-
* Reporting details for external transactions (Android 8.2.0+).
|
|
2251
|
-
*/
|
|
2252
|
-
|
|
2253
2226
|
/**
|
|
2254
2227
|
* Enable a billing program before initConnection (Android only).
|
|
2255
2228
|
* Must be called BEFORE initConnection() to configure the BillingClient.
|
|
@@ -2293,7 +2266,7 @@ export const enableBillingProgramAndroid = program => {
|
|
|
2293
2266
|
* }
|
|
2294
2267
|
* ```
|
|
2295
2268
|
*
|
|
2296
|
-
* @see {@link https://
|
|
2269
|
+
* @see {@link https://openiap.dev/docs/apis/android/is-billing-program-available-android}
|
|
2297
2270
|
*/
|
|
2298
2271
|
export const isBillingProgramAvailableAndroid = async program => {
|
|
2299
2272
|
if (Platform.OS !== 'android') {
|
|
@@ -2330,7 +2303,7 @@ export const isBillingProgramAvailableAndroid = async program => {
|
|
|
2330
2303
|
* });
|
|
2331
2304
|
* ```
|
|
2332
2305
|
*
|
|
2333
|
-
* @see {@link https://
|
|
2306
|
+
* @see {@link https://openiap.dev/docs/apis/android/create-billing-program-reporting-details-android}
|
|
2334
2307
|
*/
|
|
2335
2308
|
export const createBillingProgramReportingDetailsAndroid = async program => {
|
|
2336
2309
|
if (Platform.OS !== 'android') {
|
|
@@ -2369,7 +2342,7 @@ export const createBillingProgramReportingDetailsAndroid = async program => {
|
|
|
2369
2342
|
* }
|
|
2370
2343
|
* ```
|
|
2371
2344
|
*
|
|
2372
|
-
* @see {@link https://
|
|
2345
|
+
* @see {@link https://openiap.dev/docs/apis/android/launch-external-link-android}
|
|
2373
2346
|
*/
|
|
2374
2347
|
export const launchExternalLinkAndroid = async params => {
|
|
2375
2348
|
if (Platform.OS !== 'android') {
|
|
@@ -2411,7 +2384,7 @@ export const launchExternalLinkAndroid = async params => {
|
|
|
2411
2384
|
* }
|
|
2412
2385
|
* ```
|
|
2413
2386
|
*
|
|
2414
|
-
* @see {@link https://
|
|
2387
|
+
* @see {@link https://openiap.dev/docs/apis/ios/can-present-external-purchase-notice-ios}
|
|
2415
2388
|
*/
|
|
2416
2389
|
export const canPresentExternalPurchaseNoticeIOS = async () => {
|
|
2417
2390
|
if (Platform.OS !== 'ios') {
|
|
@@ -2441,7 +2414,7 @@ export const canPresentExternalPurchaseNoticeIOS = async () => {
|
|
|
2441
2414
|
* }
|
|
2442
2415
|
* ```
|
|
2443
2416
|
*
|
|
2444
|
-
* @see {@link https://
|
|
2417
|
+
* @see {@link https://openiap.dev/docs/apis/ios/present-external-purchase-notice-sheet-ios}
|
|
2445
2418
|
*/
|
|
2446
2419
|
export const presentExternalPurchaseNoticeSheetIOS = async () => {
|
|
2447
2420
|
if (Platform.OS !== 'ios') {
|
|
@@ -2470,7 +2443,7 @@ export const presentExternalPurchaseNoticeSheetIOS = async () => {
|
|
|
2470
2443
|
* }
|
|
2471
2444
|
* ```
|
|
2472
2445
|
*
|
|
2473
|
-
* @see {@link https://
|
|
2446
|
+
* @see {@link https://openiap.dev/docs/apis/ios/present-external-purchase-link-ios}
|
|
2474
2447
|
*/
|
|
2475
2448
|
export const presentExternalPurchaseLinkIOS = async url => {
|
|
2476
2449
|
if (Platform.OS !== 'ios') {
|
|
@@ -2504,7 +2477,7 @@ export const presentExternalPurchaseLinkIOS = async url => {
|
|
|
2504
2477
|
* }
|
|
2505
2478
|
* ```
|
|
2506
2479
|
*
|
|
2507
|
-
* @see {@link https://
|
|
2480
|
+
* @see {@link https://openiap.dev/docs/apis/ios/is-eligible-for-external-purchase-custom-link-ios}
|
|
2508
2481
|
*/
|
|
2509
2482
|
export const isEligibleForExternalPurchaseCustomLinkIOS = async () => {
|
|
2510
2483
|
if (Platform.OS !== 'ios') {
|
|
@@ -2537,7 +2510,7 @@ export const isEligibleForExternalPurchaseCustomLinkIOS = async () => {
|
|
|
2537
2510
|
* }
|
|
2538
2511
|
* ```
|
|
2539
2512
|
*
|
|
2540
|
-
* @see {@link https://
|
|
2513
|
+
* @see {@link https://openiap.dev/docs/apis/ios/get-external-purchase-custom-link-token-ios}
|
|
2541
2514
|
*/
|
|
2542
2515
|
export const getExternalPurchaseCustomLinkTokenIOS = async tokenType => {
|
|
2543
2516
|
if (Platform.OS !== 'ios') {
|
|
@@ -2570,7 +2543,7 @@ export const getExternalPurchaseCustomLinkTokenIOS = async tokenType => {
|
|
|
2570
2543
|
* }
|
|
2571
2544
|
* ```
|
|
2572
2545
|
*
|
|
2573
|
-
* @see {@link https://
|
|
2546
|
+
* @see {@link https://openiap.dev/docs/apis/ios/show-external-purchase-custom-link-notice-ios}
|
|
2574
2547
|
*/
|
|
2575
2548
|
export const showExternalPurchaseCustomLinkNoticeIOS = async noticeType => {
|
|
2576
2549
|
if (Platform.OS !== 'ios') {
|