react-native-iap 15.5.0 → 15.5.2
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/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +19 -0
- package/ios/HybridRnIap.swift +16 -0
- package/lib/module/hooks/useIAP.js +6 -2
- package/lib/module/hooks/useIAP.js.map +1 -1
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.kepler.js.map +1 -1
- package/lib/module/kit-api.js +27 -0
- package/lib/module/kit-api.js.map +1 -1
- package/lib/module/types.js +7 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/vega-adapter.js +10 -6
- package/lib/module/vega-adapter.js.map +1 -1
- package/lib/typescript/src/hooks/useIAP.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.kepler.d.ts +1 -0
- package/lib/typescript/src/index.kepler.d.ts.map +1 -1
- package/lib/typescript/src/kit-api.d.ts +60 -0
- package/lib/typescript/src/kit-api.d.ts.map +1 -1
- package/lib/typescript/src/specs/RnIap.nitro.d.ts +28 -12
- package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +36 -1
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/vega-adapter.d.ts.map +1 -1
- package/nitrogen/generated/android/NitroIap+autolinking.cmake +1 -0
- package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +9 -0
- package/nitrogen/generated/android/c++/JIapkitClientPayloadFormat.hpp +61 -0
- package/nitrogen/generated/android/c++/JNitroIapkitProductClientPayload.hpp +71 -0
- package/nitrogen/generated/android/c++/JNitroVerifyPurchaseWithIapkitProps.hpp +7 -3
- package/nitrogen/generated/android/c++/JNitroVerifyPurchaseWithIapkitResult.hpp +20 -1
- package/nitrogen/generated/android/c++/JNitroVerifyPurchaseWithProviderResult.hpp +5 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_NitroIapkitProductClientPayload.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_NitroIapkitProductClientPayload.hpp +74 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_NitroVerifyPurchaseWithIapkitResult.hpp +8 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/IapkitClientPayloadFormat.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroIapkitProductClientPayload.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroVerifyPurchaseWithIapkitProps.kt +9 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroVerifyPurchaseWithIapkitResult.kt +14 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Variant_NullType_NitroIapkitProductClientPayload.kt +62 -0
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.hpp +50 -0
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +6 -0
- package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +6 -0
- package/nitrogen/generated/ios/swift/IapkitClientPayloadFormat.swift +44 -0
- package/nitrogen/generated/ios/swift/NitroIapkitProductClientPayload.swift +44 -0
- package/nitrogen/generated/ios/swift/NitroVerifyPurchaseWithIapkitProps.swift +38 -1
- package/nitrogen/generated/ios/swift/NitroVerifyPurchaseWithIapkitResult.swift +76 -2
- package/nitrogen/generated/ios/swift/Variant_NullType_NitroIapkitProductClientPayload.swift +30 -0
- package/nitrogen/generated/shared/c++/IapkitClientPayloadFormat.hpp +80 -0
- package/nitrogen/generated/shared/c++/NitroIapkitProductClientPayload.hpp +97 -0
- package/nitrogen/generated/shared/c++/NitroVerifyPurchaseWithIapkitProps.hpp +6 -2
- package/nitrogen/generated/shared/c++/NitroVerifyPurchaseWithIapkitResult.hpp +16 -1
- package/openiap-versions.json +3 -3
- package/package.json +5 -5
- package/src/hooks/useIAP.ts +6 -2
- package/src/index.kepler.ts +13 -0
- package/src/index.ts +13 -0
- package/src/kit-api.ts +107 -0
- package/src/specs/RnIap.nitro.ts +37 -12
- package/src/types.ts +38 -1
- package/src/vega-adapter.ts +14 -11
package/src/hooks/useIAP.ts
CHANGED
|
@@ -505,7 +505,9 @@ export function useIAP(options?: UseIapOptions): UseIap {
|
|
|
505
505
|
onlyIncludeActiveItemsIOS: options?.onlyIncludeActiveItemsIOS ?? true,
|
|
506
506
|
includeSuspendedAndroid: options?.includeSuspendedAndroid ?? false,
|
|
507
507
|
});
|
|
508
|
-
|
|
508
|
+
if (isMountedRef.current) {
|
|
509
|
+
setAvailablePurchases(result);
|
|
510
|
+
}
|
|
509
511
|
} catch (error) {
|
|
510
512
|
RnIapConsole.error('Error fetching available purchases:', error);
|
|
511
513
|
invokeOnError(error);
|
|
@@ -518,7 +520,9 @@ export function useIAP(options?: UseIapOptions): UseIap {
|
|
|
518
520
|
async (subscriptionIds?: string[]): Promise<ActiveSubscription[]> => {
|
|
519
521
|
try {
|
|
520
522
|
const result = await getActiveSubscriptions(subscriptionIds);
|
|
521
|
-
|
|
523
|
+
if (isMountedRef.current) {
|
|
524
|
+
setActiveSubscriptions(result);
|
|
525
|
+
}
|
|
522
526
|
return result;
|
|
523
527
|
} catch (error) {
|
|
524
528
|
RnIapConsole.error('Error getting active subscriptions:', error);
|
package/src/index.kepler.ts
CHANGED
|
@@ -32,6 +32,19 @@ export * from './vega';
|
|
|
32
32
|
export {useIAP, type UseIapOptions} from './hooks/useIAP';
|
|
33
33
|
export {connectWebhookStream, parseWebhookEventData} from './webhook-client';
|
|
34
34
|
export {kitApi, KitApiError} from './kit-api';
|
|
35
|
+
export type {
|
|
36
|
+
EntitlementsResponse,
|
|
37
|
+
KitApiOptions,
|
|
38
|
+
KitClientPayloadResponse,
|
|
39
|
+
KitProduct,
|
|
40
|
+
KitProductClientPayload,
|
|
41
|
+
KitProductOffer,
|
|
42
|
+
KitProductPlatform,
|
|
43
|
+
KitProductsOptions,
|
|
44
|
+
KitProductsResponse,
|
|
45
|
+
KitSubscription,
|
|
46
|
+
StatusResponse,
|
|
47
|
+
} from './kit-api';
|
|
35
48
|
|
|
36
49
|
export type ProductTypeInput = 'inapp' | 'in-app' | 'subs';
|
|
37
50
|
|
package/src/index.ts
CHANGED
|
@@ -165,6 +165,13 @@ export type {
|
|
|
165
165
|
export {kitApi, KitApiError} from './kit-api';
|
|
166
166
|
export type {
|
|
167
167
|
KitApiOptions,
|
|
168
|
+
KitClientPayloadResponse,
|
|
169
|
+
KitProduct,
|
|
170
|
+
KitProductClientPayload,
|
|
171
|
+
KitProductOffer,
|
|
172
|
+
KitProductPlatform,
|
|
173
|
+
KitProductsOptions,
|
|
174
|
+
KitProductsResponse,
|
|
168
175
|
KitSubscription,
|
|
169
176
|
EntitlementsResponse,
|
|
170
177
|
StatusResponse,
|
|
@@ -2337,7 +2344,13 @@ export const verifyPurchaseWithProvider: MutationField<
|
|
|
2337
2344
|
provider: result.provider,
|
|
2338
2345
|
iapkit: result.iapkit
|
|
2339
2346
|
? {
|
|
2347
|
+
...(result.iapkit.clientPayload == null
|
|
2348
|
+
? {}
|
|
2349
|
+
: {clientPayload: result.iapkit.clientPayload}),
|
|
2340
2350
|
isValid: result.iapkit.isValid,
|
|
2351
|
+
...(result.iapkit.productId == null
|
|
2352
|
+
? {}
|
|
2353
|
+
: {productId: result.iapkit.productId}),
|
|
2341
2354
|
state: result.iapkit.state,
|
|
2342
2355
|
store: result.iapkit.store,
|
|
2343
2356
|
}
|
package/src/kit-api.ts
CHANGED
|
@@ -40,6 +40,71 @@ export type StatusResponse = {
|
|
|
40
40
|
subscription: KitSubscription | null;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
+
export type KitProductPlatform = "IOS" | "Android";
|
|
44
|
+
|
|
45
|
+
export type KitProductClientPayload = {
|
|
46
|
+
format: "toml" | "json" | "text";
|
|
47
|
+
body: string;
|
|
48
|
+
version: number;
|
|
49
|
+
updatedAt: number;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type KitProductOffer = {
|
|
53
|
+
id: string;
|
|
54
|
+
kind:
|
|
55
|
+
| "FreeTrial"
|
|
56
|
+
| "IntroPayUpFront"
|
|
57
|
+
| "IntroPayAsYouGo"
|
|
58
|
+
| "PromotionalOffer"
|
|
59
|
+
| "BasePlan";
|
|
60
|
+
duration?: string;
|
|
61
|
+
numberOfPeriods?: number;
|
|
62
|
+
priceAmountMicros?: number;
|
|
63
|
+
currency?: string;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export type KitProduct = {
|
|
67
|
+
productId: string;
|
|
68
|
+
platform: KitProductPlatform;
|
|
69
|
+
type: "Subscription" | "NonConsumable" | "Consumable";
|
|
70
|
+
title: string;
|
|
71
|
+
description?: string;
|
|
72
|
+
priceAmountMicros?: number;
|
|
73
|
+
currency?: string;
|
|
74
|
+
state: "Draft" | "Ready" | "Active" | "Removed";
|
|
75
|
+
storeRef?: string;
|
|
76
|
+
subscriptionGroupId?: string;
|
|
77
|
+
subscriptionGroupName?: string;
|
|
78
|
+
billingPeriod?: "P1W" | "P1M" | "P2M" | "P3M" | "P6M" | "P1Y";
|
|
79
|
+
offers?: KitProductOffer[];
|
|
80
|
+
updatedAt: number;
|
|
81
|
+
clientPayload?: KitProductClientPayload;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export type KitProductsOptions = {
|
|
85
|
+
platform?: KitProductPlatform;
|
|
86
|
+
/** Include public client payload bodies in a bounded platform page. */
|
|
87
|
+
includeClientPayload?: boolean;
|
|
88
|
+
/** Page size for payload-inclusive reads (default 25, maximum 50).
|
|
89
|
+
* Ignored by the legacy non-payload catalog path. */
|
|
90
|
+
limit?: number;
|
|
91
|
+
/** Opaque cursor returned as `nextCursor` by the previous payload page.
|
|
92
|
+
* Ignored by the legacy non-payload catalog path. */
|
|
93
|
+
cursor?: string;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export type KitProductsResponse = {
|
|
97
|
+
products: KitProduct[];
|
|
98
|
+
/** Present on payload-inclusive catalog pages. */
|
|
99
|
+
hasMore?: boolean;
|
|
100
|
+
/** Present when a payload-inclusive catalog page has another page. */
|
|
101
|
+
nextCursor?: string;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export type KitClientPayloadResponse = {
|
|
105
|
+
clientPayload: KitProductClientPayload;
|
|
106
|
+
};
|
|
107
|
+
|
|
43
108
|
const DEFAULT_BASE_URL = "https://kit.openiap.dev";
|
|
44
109
|
|
|
45
110
|
// Merge caller-supplied headers with kit defaults (`accept`,
|
|
@@ -210,6 +275,48 @@ export function kitApi(options: KitApiOptions) {
|
|
|
210
275
|
`/v1/subscriptions/entitlements/${encodeURIComponent(options.apiKey)}?userId=${encodeURIComponent(userId)}`,
|
|
211
276
|
),
|
|
212
277
|
|
|
278
|
+
/** GET /v1/products — read the store-synced catalog. Client payloads
|
|
279
|
+
* are excluded unless explicitly requested because they may add up to
|
|
280
|
+
* 16 KiB per product. */
|
|
281
|
+
products: (productOptions: KitProductsOptions = {}) => {
|
|
282
|
+
if (
|
|
283
|
+
productOptions.includeClientPayload === true &&
|
|
284
|
+
!productOptions.platform
|
|
285
|
+
) {
|
|
286
|
+
throw new Error(
|
|
287
|
+
"kitApi.products requires platform when includeClientPayload is true",
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
const query = new URLSearchParams();
|
|
291
|
+
if (productOptions.platform) {
|
|
292
|
+
query.set("platform", productOptions.platform);
|
|
293
|
+
}
|
|
294
|
+
if (productOptions.includeClientPayload !== undefined) {
|
|
295
|
+
query.set(
|
|
296
|
+
"includeClientPayload",
|
|
297
|
+
String(productOptions.includeClientPayload),
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
if (productOptions.limit !== undefined) {
|
|
301
|
+
query.set("limit", String(productOptions.limit));
|
|
302
|
+
}
|
|
303
|
+
if (productOptions.cursor !== undefined) {
|
|
304
|
+
query.set("cursor", productOptions.cursor);
|
|
305
|
+
}
|
|
306
|
+
const encodedQuery = query.toString();
|
|
307
|
+
const suffix = encodedQuery ? `?${encodedQuery}` : "";
|
|
308
|
+
return call<KitProductsResponse>(
|
|
309
|
+
`/v1/products/${encodeURIComponent(options.apiKey)}${suffix}`,
|
|
310
|
+
);
|
|
311
|
+
},
|
|
312
|
+
|
|
313
|
+
/** GET one public client payload by its store-specific natural key.
|
|
314
|
+
* Payloads are app-facing data; never store secrets in them. */
|
|
315
|
+
clientPayload: (productId: string, platform: KitProductPlatform) =>
|
|
316
|
+
call<KitClientPayloadResponse>(
|
|
317
|
+
`/v1/products/${encodeURIComponent(options.apiKey)}/${encodeURIComponent(productId)}/client-payload?platform=${encodeURIComponent(platform)}`,
|
|
318
|
+
),
|
|
319
|
+
|
|
213
320
|
/** POST /v1/subscriptions/bind-user — call after a successful
|
|
214
321
|
* verifyReceipt so kit knows which userId owns the verified
|
|
215
322
|
* `purchaseToken`. Idempotent. */
|
package/src/specs/RnIap.nitro.ts
CHANGED
|
@@ -17,6 +17,13 @@ import type {HybridObject} from 'react-native-nitro-modules';
|
|
|
17
17
|
// ║ - Interface types from types.ts can be imported and used directly ║
|
|
18
18
|
// ║ - Union types with 2+ values can be imported from types.ts ║
|
|
19
19
|
// ║ - Single-value unions must be redefined locally with extra values ║
|
|
20
|
+
// ║ ║
|
|
21
|
+
// ║ 3. WRITE `null` FIRST IN NULLABLE UNIONS OF BOOLEANS AND ENUM ARRAYS ║
|
|
22
|
+
// ║ - Use `null | boolean`, not `boolean | null` (same for enum arrays) ║
|
|
23
|
+
// ║ - Since nitrogen 0.36 variant operands keep source order when their ║
|
|
24
|
+
// ║ "looseness" ties (boolean/enum-array tie with null), so null-last ║
|
|
25
|
+
// ║ would rename generated types (Variant_NullType_Bool → ║
|
|
26
|
+
// ║ Variant_Bool_NullType) and break hand-written Swift/Kotlin ║
|
|
20
27
|
// ╚══════════════════════════════════════════════════════════════════════════╝
|
|
21
28
|
|
|
22
29
|
// NOTE: This Nitro spec re-exports types from the generated schema (src/types.ts)
|
|
@@ -93,6 +100,8 @@ export type IapkitPurchaseState =
|
|
|
93
100
|
| 'unknown'
|
|
94
101
|
| 'inauthentic';
|
|
95
102
|
|
|
103
|
+
export type IapkitClientPayloadFormat = 'toml' | 'json' | 'text';
|
|
104
|
+
|
|
96
105
|
// Store identifier for purchase origin
|
|
97
106
|
// Defined locally for Nitro codegen (not in GQL schema)
|
|
98
107
|
export type IapStore = 'unknown' | 'apple' | 'google' | 'horizon' | 'amazon';
|
|
@@ -278,8 +287,8 @@ export interface NitroPurchaseRequest {
|
|
|
278
287
|
* iOS-specific options for getting available purchases
|
|
279
288
|
*/
|
|
280
289
|
export interface NitroAvailablePurchasesIosOptions extends PurchaseOptions {
|
|
281
|
-
alsoPublishToEventListener?:
|
|
282
|
-
onlyIncludeActiveItems?:
|
|
290
|
+
alsoPublishToEventListener?: null | boolean;
|
|
291
|
+
onlyIncludeActiveItems?: null | boolean;
|
|
283
292
|
}
|
|
284
293
|
|
|
285
294
|
type NitroAvailablePurchasesAndroidType = 'inapp' | 'subs';
|
|
@@ -292,7 +301,7 @@ export interface NitroAvailablePurchasesAndroidOptions {
|
|
|
292
301
|
* Users should be directed to the subscription center to resolve payment issues.
|
|
293
302
|
* Default: false (only active subscriptions are returned)
|
|
294
303
|
*/
|
|
295
|
-
includeSuspended?:
|
|
304
|
+
includeSuspended?: null | boolean;
|
|
296
305
|
}
|
|
297
306
|
|
|
298
307
|
export interface NitroAvailablePurchasesOptions {
|
|
@@ -358,7 +367,7 @@ export interface NitroBillingProgramInformationDialogParamsAndroid {
|
|
|
358
367
|
}
|
|
359
368
|
|
|
360
369
|
export interface NitroInAppMessageParamsAndroid {
|
|
361
|
-
categories?: InAppMessageCategoryAndroid[]
|
|
370
|
+
categories?: null | InAppMessageCategoryAndroid[];
|
|
362
371
|
}
|
|
363
372
|
|
|
364
373
|
// ╔══════════════════════════════════════════════════════════════════════════╗
|
|
@@ -450,7 +459,7 @@ export interface NitroVerifyPurchaseWithIapkitAmazonProps {
|
|
|
450
459
|
/** Amazon Appstore receipt id returned by PurchaseResponse.getReceipt().getReceiptId(). */
|
|
451
460
|
receiptId: string;
|
|
452
461
|
/** Use Amazon RVS Cloud Sandbox for App Tester receipts. */
|
|
453
|
-
sandbox?:
|
|
462
|
+
sandbox?: null | boolean;
|
|
454
463
|
/** Amazon Appstore user id returned by PurchaseResponse.getUserData().getUserId(). */
|
|
455
464
|
userId?: string | null;
|
|
456
465
|
}
|
|
@@ -466,6 +475,11 @@ export interface NitroVerifyPurchaseWithIapkitProps {
|
|
|
466
475
|
*/
|
|
467
476
|
baseUrl?: string | null;
|
|
468
477
|
google?: NitroVerifyPurchaseWithIapkitGoogleProps | null;
|
|
478
|
+
/**
|
|
479
|
+
* Available in OpenIAP Spec 2.4.0 / openiap-apple 2.4.1 / openiap-google 2.4.1.
|
|
480
|
+
* Include the product's public IAPKit client payload when available.
|
|
481
|
+
*/
|
|
482
|
+
includeClientPayload?: boolean | null;
|
|
469
483
|
}
|
|
470
484
|
|
|
471
485
|
export interface NitroVerifyPurchaseWithProviderProps {
|
|
@@ -474,11 +488,22 @@ export interface NitroVerifyPurchaseWithProviderProps {
|
|
|
474
488
|
}
|
|
475
489
|
|
|
476
490
|
export interface NitroVerifyPurchaseWithIapkitResult {
|
|
491
|
+
/** Available in OpenIAP Spec 2.4.0 / openiap-apple 2.4.1 / openiap-google 2.4.1. */
|
|
492
|
+
clientPayload?: NitroIapkitProductClientPayload | null;
|
|
477
493
|
isValid: boolean;
|
|
494
|
+
/** Available in OpenIAP Spec 2.4.0 / openiap-apple 2.4.1 / openiap-google 2.4.1. */
|
|
495
|
+
productId?: string | null;
|
|
478
496
|
state: IapkitPurchaseState;
|
|
479
497
|
store: IapStore;
|
|
480
498
|
}
|
|
481
499
|
|
|
500
|
+
export interface NitroIapkitProductClientPayload {
|
|
501
|
+
body: string;
|
|
502
|
+
format: IapkitClientPayloadFormat;
|
|
503
|
+
updatedAt: number;
|
|
504
|
+
version: number;
|
|
505
|
+
}
|
|
506
|
+
|
|
482
507
|
export interface NitroVerifyPurchaseWithProviderError {
|
|
483
508
|
code?: string | null;
|
|
484
509
|
message: string;
|
|
@@ -501,7 +526,7 @@ export interface NitroBillingProgramAvailabilityResultAndroid {
|
|
|
501
526
|
/** Whether the billing program is available for the user */
|
|
502
527
|
isAvailable: boolean;
|
|
503
528
|
/** Whether external-link payment is available for Billing Choice. */
|
|
504
|
-
isExternalLinkAvailable?:
|
|
529
|
+
isExternalLinkAvailable?: null | boolean;
|
|
505
530
|
}
|
|
506
531
|
|
|
507
532
|
/**
|
|
@@ -610,7 +635,7 @@ export interface NitroPurchase {
|
|
|
610
635
|
currencySymbolIOS?: string | null;
|
|
611
636
|
environmentIOS?: string | null;
|
|
612
637
|
expirationDateIOS?: number | null;
|
|
613
|
-
isUpgradedIOS?:
|
|
638
|
+
isUpgradedIOS?: null | boolean;
|
|
614
639
|
offerIOS?: string | null;
|
|
615
640
|
ownershipTypeIOS?: string | null;
|
|
616
641
|
reasonIOS?: string | null;
|
|
@@ -626,14 +651,14 @@ export interface NitroPurchase {
|
|
|
626
651
|
purchaseTokenAndroid?: string | null;
|
|
627
652
|
dataAndroid?: string | null;
|
|
628
653
|
signatureAndroid?: string | null;
|
|
629
|
-
autoRenewingAndroid?:
|
|
654
|
+
autoRenewingAndroid?: null | boolean;
|
|
630
655
|
purchaseStateAndroid?: number | null;
|
|
631
|
-
isAcknowledgedAndroid?:
|
|
656
|
+
isAcknowledgedAndroid?: null | boolean;
|
|
632
657
|
packageNameAndroid?: string | null;
|
|
633
658
|
obfuscatedAccountIdAndroid?: string | null;
|
|
634
659
|
obfuscatedProfileIdAndroid?: string | null;
|
|
635
660
|
developerPayloadAndroid?: string | null;
|
|
636
|
-
isSuspendedAndroid?:
|
|
661
|
+
isSuspendedAndroid?: null | boolean;
|
|
637
662
|
pendingPurchaseUpdateAndroid?: PendingPurchaseUpdateAndroid | null;
|
|
638
663
|
}
|
|
639
664
|
|
|
@@ -670,7 +695,7 @@ export interface NitroRenewalInfoIOS {
|
|
|
670
695
|
pendingUpgradeProductId?: string | null;
|
|
671
696
|
renewalDate?: number | null;
|
|
672
697
|
expirationReason?: string | null;
|
|
673
|
-
isInBillingRetry?:
|
|
698
|
+
isInBillingRetry?: null | boolean;
|
|
674
699
|
gracePeriodExpirationDate?: number | null;
|
|
675
700
|
priceIncreaseStatus?: string | null;
|
|
676
701
|
renewalBillingPlanType?: SubscriptionBillingPlanTypeIOS | null;
|
|
@@ -692,7 +717,7 @@ export interface NitroProduct {
|
|
|
692
717
|
platform: IapPlatform;
|
|
693
718
|
// iOS specific fields
|
|
694
719
|
typeIOS?: string | null;
|
|
695
|
-
isFamilyShareableIOS?:
|
|
720
|
+
isFamilyShareableIOS?: null | boolean;
|
|
696
721
|
jsonRepresentationIOS?: string | null;
|
|
697
722
|
pricingTermsIOS?: string | null;
|
|
698
723
|
subscriptionInfoIOS?: string | null;
|
package/src/types.ts
CHANGED
|
@@ -617,6 +617,20 @@ export type IapPlatform = 'ios' | 'android';
|
|
|
617
617
|
|
|
618
618
|
export type IapStore = 'unknown' | 'apple' | 'google' | 'horizon' | 'amazon';
|
|
619
619
|
|
|
620
|
+
/** Serialization format of a public IAPKit product client payload. */
|
|
621
|
+
export type IapkitClientPayloadFormat = 'toml' | 'json' | 'text';
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Public app-facing data attached to one store product in IAPKit.
|
|
625
|
+
* Never place credentials, signing keys, or server-authoritative rules here.
|
|
626
|
+
*/
|
|
627
|
+
export interface IapkitProductClientPayload {
|
|
628
|
+
body: string;
|
|
629
|
+
format: IapkitClientPayloadFormat;
|
|
630
|
+
updatedAt: number;
|
|
631
|
+
version: number;
|
|
632
|
+
}
|
|
633
|
+
|
|
620
634
|
/** Unified purchase states from IAPKit verification response. */
|
|
621
635
|
export type IapkitPurchaseState = 'entitled' | 'pending-acknowledgment' | 'pending' | 'canceled' | 'expired' | 'ready-to-consume' | 'consumed' | 'unknown' | 'inauthentic';
|
|
622
636
|
|
|
@@ -1987,11 +2001,34 @@ export interface RequestVerifyPurchaseWithIapkitProps {
|
|
|
1987
2001
|
baseUrl?: (string | null);
|
|
1988
2002
|
/** Google Play Store verification parameters. */
|
|
1989
2003
|
google?: (RequestVerifyPurchaseWithIapkitGoogleProps | null);
|
|
2004
|
+
/**
|
|
2005
|
+
* Available in OpenIAP Spec 2.4.0 / openiap-apple 2.4.1 / openiap-google 2.4.1.
|
|
2006
|
+
* Include the product's public IAPKit client payload in a valid Apple or
|
|
2007
|
+
* Google verification response. Defaults to false so existing response
|
|
2008
|
+
* shapes and bandwidth remain unchanged.
|
|
2009
|
+
*/
|
|
2010
|
+
includeClientPayload?: (boolean | null);
|
|
1990
2011
|
}
|
|
1991
2012
|
|
|
1992
2013
|
export interface RequestVerifyPurchaseWithIapkitResult {
|
|
1993
|
-
/**
|
|
2014
|
+
/**
|
|
2015
|
+
* Available in OpenIAP Spec 2.4.0 / openiap-apple 2.4.1 / openiap-google 2.4.1.
|
|
2016
|
+
* Public product payload when includeClientPayload was requested, the
|
|
2017
|
+
* Apple or Google receipt is valid, and a payload exists for that product.
|
|
2018
|
+
*/
|
|
2019
|
+
clientPayload?: (IapkitProductClientPayload | null);
|
|
2020
|
+
/**
|
|
2021
|
+
* True when the purchase is valid and actionable.
|
|
2022
|
+
* Only entitled, pending-acknowledgment, or ready-to-consume return true.
|
|
2023
|
+
* Callers must still match productId and use the platform plus app-owned product
|
|
2024
|
+
* type to choose the fulfillment path.
|
|
2025
|
+
*/
|
|
1994
2026
|
isValid: boolean;
|
|
2027
|
+
/**
|
|
2028
|
+
* Available in OpenIAP Spec 2.4.0 / openiap-apple 2.4.1 / openiap-google 2.4.1.
|
|
2029
|
+
* Store-verified product identifier when the provider returns one.
|
|
2030
|
+
*/
|
|
2031
|
+
productId?: (string | null);
|
|
1995
2032
|
/** The current state of the purchase. */
|
|
1996
2033
|
state: IapkitPurchaseState;
|
|
1997
2034
|
store: IapStore;
|
package/src/vega-adapter.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
NitroProduct,
|
|
5
5
|
NitroPurchase,
|
|
6
6
|
NitroPurchaseResult,
|
|
7
|
+
NitroVerifyPurchaseWithIapkitResult,
|
|
7
8
|
NitroVerifyPurchaseWithProviderProps,
|
|
8
9
|
NitroVerifyPurchaseWithProviderResult,
|
|
9
10
|
RnIap,
|
|
@@ -155,8 +156,7 @@ function isValidIpv4Address(address: string): boolean {
|
|
|
155
156
|
return (
|
|
156
157
|
octets.length === 4 &&
|
|
157
158
|
octets.every(
|
|
158
|
-
(octet) =>
|
|
159
|
-
/^(?:0|[1-9]\d{0,2})$/.test(octet) && Number(octet) <= 255,
|
|
159
|
+
(octet) => /^(?:0|[1-9]\d{0,2})$/.test(octet) && Number(octet) <= 255,
|
|
160
160
|
)
|
|
161
161
|
);
|
|
162
162
|
}
|
|
@@ -1236,10 +1236,7 @@ export function createVegaIapModule(service: VegaPurchasingService): RnIap {
|
|
|
1236
1236
|
function readIapkitResult(
|
|
1237
1237
|
json: Record<string, unknown>,
|
|
1238
1238
|
status: number,
|
|
1239
|
-
): {
|
|
1240
|
-
isValid: boolean;
|
|
1241
|
-
state: IapkitPurchaseState;
|
|
1242
|
-
} {
|
|
1239
|
+
): NitroVerifyPurchaseWithIapkitResult {
|
|
1243
1240
|
if (
|
|
1244
1241
|
typeof json.isValid !== 'boolean' ||
|
|
1245
1242
|
typeof json.state !== 'string' ||
|
|
@@ -1251,9 +1248,19 @@ export function createVegaIapModule(service: VegaPurchasingService): RnIap {
|
|
|
1251
1248
|
);
|
|
1252
1249
|
}
|
|
1253
1250
|
|
|
1251
|
+
const productId = json.productId;
|
|
1252
|
+
if (productId != null && typeof productId !== 'string') {
|
|
1253
|
+
throw createVegaError(
|
|
1254
|
+
ErrorCode.ReceiptFailed,
|
|
1255
|
+
`IAPKit returned malformed response (HTTP ${status}).`,
|
|
1256
|
+
);
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1254
1259
|
return {
|
|
1255
1260
|
isValid: json.isValid,
|
|
1261
|
+
...(productId == null ? {} : {productId}),
|
|
1256
1262
|
state: normalizeIapkitState(json.state),
|
|
1263
|
+
store: 'amazon',
|
|
1257
1264
|
};
|
|
1258
1265
|
}
|
|
1259
1266
|
|
|
@@ -1374,11 +1381,7 @@ export function createVegaIapModule(service: VegaPurchasingService): RnIap {
|
|
|
1374
1381
|
const result = readIapkitResult(json, response.status);
|
|
1375
1382
|
return {
|
|
1376
1383
|
provider: 'iapkit',
|
|
1377
|
-
iapkit:
|
|
1378
|
-
isValid: result.isValid,
|
|
1379
|
-
state: result.state,
|
|
1380
|
-
store: 'amazon',
|
|
1381
|
-
},
|
|
1384
|
+
iapkit: result,
|
|
1382
1385
|
};
|
|
1383
1386
|
};
|
|
1384
1387
|
|