expo-iap 3.1.38 → 3.2.1

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.
Files changed (43) hide show
  1. package/.prettierignore +1 -0
  2. package/README.md +1 -22
  3. package/android/src/main/java/expo/modules/iap/ExpoIapModule.kt +141 -13
  4. package/build/index.d.ts +15 -6
  5. package/build/index.d.ts.map +1 -1
  6. package/build/index.js +46 -29
  7. package/build/index.js.map +1 -1
  8. package/build/modules/android.d.ts +53 -1
  9. package/build/modules/android.d.ts.map +1 -1
  10. package/build/modules/android.js +61 -0
  11. package/build/modules/android.js.map +1 -1
  12. package/build/modules/ios.d.ts.map +1 -1
  13. package/build/modules/ios.js +4 -2
  14. package/build/modules/ios.js.map +1 -1
  15. package/build/types.d.ts +349 -20
  16. package/build/types.d.ts.map +1 -1
  17. package/build/types.js.map +1 -1
  18. package/build/useIAP.d.ts.map +1 -1
  19. package/build/useIAP.js +2 -0
  20. package/build/useIAP.js.map +1 -1
  21. package/coverage/clover.xml +176 -166
  22. package/coverage/coverage-final.json +3 -3
  23. package/coverage/lcov-report/index.html +23 -23
  24. package/coverage/lcov-report/src/index.html +14 -14
  25. package/coverage/lcov-report/src/index.ts.html +90 -39
  26. package/coverage/lcov-report/src/modules/android.ts.html +233 -8
  27. package/coverage/lcov-report/src/modules/index.html +15 -15
  28. package/coverage/lcov-report/src/modules/ios.ts.html +13 -7
  29. package/coverage/lcov-report/src/utils/debug.ts.html +1 -1
  30. package/coverage/lcov-report/src/utils/errorMapping.ts.html +1 -1
  31. package/coverage/lcov-report/src/utils/index.html +1 -1
  32. package/coverage/lcov.info +305 -284
  33. package/ios/ExpoIapModule.swift +1 -1
  34. package/openiap-versions.json +3 -3
  35. package/package.json +1 -1
  36. package/plugin/build/withIAP.d.ts +8 -5
  37. package/plugin/build/withIAP.js +12 -3
  38. package/plugin/src/withIAP.ts +18 -9
  39. package/src/index.ts +46 -29
  40. package/src/modules/android.ts +75 -0
  41. package/src/modules/ios.ts +4 -2
  42. package/src/types.ts +370 -21
  43. package/src/useIAP.ts +2 -0
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">94.11% </span>
26
+ <span class="strong">94.26% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>464/493</span>
28
+ <span class='fraction'>477/506</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">86.77% </span>
33
+ <span class="strong">87.02% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>223/257</span>
35
+ <span class='fraction'>228/262</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">79.38% </span>
40
+ <span class="strong">80% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>77/97</span>
42
+ <span class='fraction'>80/100</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">93.99% </span>
47
+ <span class="strong">94.11% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>438/466</span>
49
+ <span class='fraction'>448/476</span>
50
50
  </div>
51
51
 
52
52
 
@@ -80,32 +80,32 @@
80
80
  </thead>
81
81
  <tbody><tr>
82
82
  <td class="file high" data-value="src"><a href="src/index.html">src</a></td>
83
- <td data-value="96.83" class="pic high">
83
+ <td data-value="96.88" class="pic high">
84
84
  <div class="chart"><div class="cover-fill" style="width: 96%"></div><div class="cover-empty" style="width: 4%"></div></div>
85
85
  </td>
86
- <td data-value="96.83" class="pct high">96.83%</td>
87
- <td data-value="221" class="abs high">214/221</td>
88
- <td data-value="90.47" class="pct high">90.47%</td>
89
- <td data-value="105" class="abs high">95/105</td>
86
+ <td data-value="96.88" class="pct high">96.88%</td>
87
+ <td data-value="225" class="abs high">218/225</td>
88
+ <td data-value="90.9" class="pct high">90.9%</td>
89
+ <td data-value="110" class="abs high">100/110</td>
90
90
  <td data-value="79.06" class="pct medium">79.06%</td>
91
91
  <td data-value="43" class="abs medium">34/43</td>
92
- <td data-value="97.07" class="pct high">97.07%</td>
93
- <td data-value="205" class="abs high">199/205</td>
92
+ <td data-value="97.12" class="pct high">97.12%</td>
93
+ <td data-value="209" class="abs high">203/209</td>
94
94
  </tr>
95
95
 
96
96
  <tr>
97
97
  <td class="file high" data-value="src/modules"><a href="src/modules/index.html">src/modules</a></td>
98
- <td data-value="94.44" class="pic high">
98
+ <td data-value="94.77" class="pic high">
99
99
  <div class="chart"><div class="cover-fill" style="width: 94%"></div><div class="cover-empty" style="width: 6%"></div></div>
100
100
  </td>
101
- <td data-value="94.44" class="pct high">94.44%</td>
102
- <td data-value="144" class="abs high">136/144</td>
101
+ <td data-value="94.77" class="pct high">94.77%</td>
102
+ <td data-value="153" class="abs high">145/153</td>
103
103
  <td data-value="98.18" class="pct high">98.18%</td>
104
104
  <td data-value="55" class="abs high">54/55</td>
105
- <td data-value="80" class="pct high">80%</td>
106
- <td data-value="30" class="abs high">24/30</td>
107
- <td data-value="94.11" class="pct high">94.11%</td>
108
- <td data-value="136" class="abs high">128/136</td>
105
+ <td data-value="81.81" class="pct high">81.81%</td>
106
+ <td data-value="33" class="abs high">27/33</td>
107
+ <td data-value="94.36" class="pct high">94.36%</td>
108
+ <td data-value="142" class="abs high">134/142</td>
109
109
  </tr>
110
110
 
111
111
  <tr>
@@ -131,7 +131,7 @@
131
131
  <div class='footer quiet pad2 space-top1 center small'>
132
132
  Code coverage generated by
133
133
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
134
- at 2025-12-07T08:40:10.740Z
134
+ at 2025-12-13T16:00:09.743Z
135
135
  </div>
136
136
  <script src="prettify.js"></script>
137
137
  <script>
@@ -23,16 +23,16 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">96.83% </span>
26
+ <span class="strong">96.88% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>214/221</span>
28
+ <span class='fraction'>218/225</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">90.47% </span>
33
+ <span class="strong">90.9% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>95/105</span>
35
+ <span class='fraction'>100/110</span>
36
36
  </div>
37
37
 
38
38
 
@@ -44,9 +44,9 @@
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">97.07% </span>
47
+ <span class="strong">97.12% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>199/205</span>
49
+ <span class='fraction'>203/209</span>
50
50
  </div>
51
51
 
52
52
 
@@ -80,17 +80,17 @@
80
80
  </thead>
81
81
  <tbody><tr>
82
82
  <td class="file high" data-value="index.ts"><a href="index.ts.html">index.ts</a></td>
83
- <td data-value="96.83" class="pic high">
83
+ <td data-value="96.88" class="pic high">
84
84
  <div class="chart"><div class="cover-fill" style="width: 96%"></div><div class="cover-empty" style="width: 4%"></div></div>
85
85
  </td>
86
- <td data-value="96.83" class="pct high">96.83%</td>
87
- <td data-value="221" class="abs high">214/221</td>
88
- <td data-value="90.47" class="pct high">90.47%</td>
89
- <td data-value="105" class="abs high">95/105</td>
86
+ <td data-value="96.88" class="pct high">96.88%</td>
87
+ <td data-value="225" class="abs high">218/225</td>
88
+ <td data-value="90.9" class="pct high">90.9%</td>
89
+ <td data-value="110" class="abs high">100/110</td>
90
90
  <td data-value="79.06" class="pct medium">79.06%</td>
91
91
  <td data-value="43" class="abs medium">34/43</td>
92
- <td data-value="97.07" class="pct high">97.07%</td>
93
- <td data-value="205" class="abs high">199/205</td>
92
+ <td data-value="97.12" class="pct high">97.12%</td>
93
+ <td data-value="209" class="abs high">203/209</td>
94
94
  </tr>
95
95
 
96
96
  </tbody>
@@ -101,7 +101,7 @@
101
101
  <div class='footer quiet pad2 space-top1 center small'>
102
102
  Code coverage generated by
103
103
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
104
- at 2025-12-07T08:40:10.740Z
104
+ at 2025-12-13T16:00:09.743Z
105
105
  </div>
106
106
  <script src="../prettify.js"></script>
107
107
  <script>
@@ -23,16 +23,16 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">96.83% </span>
26
+ <span class="strong">96.88% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>214/221</span>
28
+ <span class='fraction'>218/225</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">90.47% </span>
33
+ <span class="strong">90.9% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>95/105</span>
35
+ <span class='fraction'>100/110</span>
36
36
  </div>
37
37
 
38
38
 
@@ -44,9 +44,9 @@
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">97.07% </span>
47
+ <span class="strong">97.12% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>199/205</span>
49
+ <span class='fraction'>203/209</span>
50
50
  </div>
51
51
 
52
52
 
@@ -874,7 +874,24 @@
874
874
  <a name='L809'></a><a href='#L809'>809</a>
875
875
  <a name='L810'></a><a href='#L810'>810</a>
876
876
  <a name='L811'></a><a href='#L811'>811</a>
877
- <a name='L812'></a><a href='#L812'>812</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
877
+ <a name='L812'></a><a href='#L812'>812</a>
878
+ <a name='L813'></a><a href='#L813'>813</a>
879
+ <a name='L814'></a><a href='#L814'>814</a>
880
+ <a name='L815'></a><a href='#L815'>815</a>
881
+ <a name='L816'></a><a href='#L816'>816</a>
882
+ <a name='L817'></a><a href='#L817'>817</a>
883
+ <a name='L818'></a><a href='#L818'>818</a>
884
+ <a name='L819'></a><a href='#L819'>819</a>
885
+ <a name='L820'></a><a href='#L820'>820</a>
886
+ <a name='L821'></a><a href='#L821'>821</a>
887
+ <a name='L822'></a><a href='#L822'>822</a>
888
+ <a name='L823'></a><a href='#L823'>823</a>
889
+ <a name='L824'></a><a href='#L824'>824</a>
890
+ <a name='L825'></a><a href='#L825'>825</a>
891
+ <a name='L826'></a><a href='#L826'>826</a>
892
+ <a name='L827'></a><a href='#L827'>827</a>
893
+ <a name='L828'></a><a href='#L828'>828</a>
894
+ <a name='L829'></a><a href='#L829'>829</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
878
895
  <span class="cline-any cline-yes">2x</span>
879
896
  <span class="cline-any cline-yes">2x</span>
880
897
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1301,7 +1318,20 @@
1301
1318
  <span class="cline-any cline-neutral">&nbsp;</span>
1302
1319
  <span class="cline-any cline-neutral">&nbsp;</span>
1303
1320
  <span class="cline-any cline-neutral">&nbsp;</span>
1321
+ <span class="cline-any cline-neutral">&nbsp;</span>
1304
1322
  <span class="cline-any cline-yes">10x</span>
1323
+ <span class="cline-any cline-yes">6x</span>
1324
+ <span class="cline-any cline-neutral">&nbsp;</span>
1325
+ <span class="cline-any cline-yes">4x</span>
1326
+ <span class="cline-any cline-neutral">&nbsp;</span>
1327
+ <span class="cline-any cline-neutral">&nbsp;</span>
1328
+ <span class="cline-any cline-neutral">&nbsp;</span>
1329
+ <span class="cline-any cline-neutral">&nbsp;</span>
1330
+ <span class="cline-any cline-neutral">&nbsp;</span>
1331
+ <span class="cline-any cline-neutral">&nbsp;</span>
1332
+ <span class="cline-any cline-neutral">&nbsp;</span>
1333
+ <span class="cline-any cline-neutral">&nbsp;</span>
1334
+ <span class="cline-any cline-neutral">&nbsp;</span>
1305
1335
  <span class="cline-any cline-neutral">&nbsp;</span>
1306
1336
  <span class="cline-any cline-neutral">&nbsp;</span>
1307
1337
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1590,9 +1620,12 @@
1590
1620
  <span class="cline-any cline-yes">2x</span>
1591
1621
  <span class="cline-any cline-neutral">&nbsp;</span>
1592
1622
  <span class="cline-any cline-neutral">&nbsp;</span>
1593
- <span class="cline-any cline-yes">4x</span>
1623
+ <span class="cline-any cline-yes">5x</span>
1624
+ <span class="cline-any cline-neutral">&nbsp;</span>
1625
+ <span class="cline-any cline-yes">5x</span>
1626
+ <span class="cline-any cline-yes">2x</span>
1627
+ <span class="cline-any cline-yes">1x</span>
1594
1628
  <span class="cline-any cline-neutral">&nbsp;</span>
1595
- <span class="cline-any cline-yes">4x</span>
1596
1629
  <span class="cline-any cline-yes">1x</span>
1597
1630
  <span class="cline-any cline-neutral">&nbsp;</span>
1598
1631
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1603,6 +1636,7 @@
1603
1636
  <span class="cline-any cline-neutral">&nbsp;</span>
1604
1637
  <span class="cline-any cline-neutral">&nbsp;</span>
1605
1638
  <span class="cline-any cline-neutral">&nbsp;</span>
1639
+ <span class="cline-any cline-neutral">&nbsp;</span>
1606
1640
  <span class="cline-any cline-yes">1x</span>
1607
1641
  <span class="cline-any cline-neutral">&nbsp;</span>
1608
1642
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -2111,24 +2145,28 @@ function normalizeRequestProps(
2111
2145
  | RequestSubscriptionPropsByPlatforms,
2112
2146
  platform: 'ios' | 'android',
2113
2147
  ) {
2114
- // Platform-specific format - directly return the appropriate platform data
2115
- return platform === 'ios' ? request.ios : request.android;
2148
+ // Support both new (apple/google) and legacy (ios/android) field names
2149
+ // New fields take precedence over deprecated ones
2150
+ if (platform === 'ios') {
2151
+ return request.apple ?? request.ios;
2152
+ }
2153
+ return request.google ?? request.android;
2116
2154
  }
2117
2155
  &nbsp;
2118
2156
  /**
2119
2157
  * Request a purchase for products or subscriptions.
2120
2158
  *
2121
2159
  * @param requestObj - Purchase request configuration
2122
- * @param requestObj.request - Platform-specific purchase parameters
2160
+ * @param requestObj.request - Store-specific purchase parameters
2123
2161
  * @param requestObj.type - Type of purchase: 'in-app' for products (default) or 'subs' for subscriptions
2124
2162
  *
2125
2163
  * @example
2126
2164
  * ```typescript
2127
- * // Product purchase
2165
+ * // Product purchase (recommended: use apple/google)
2128
2166
  * await requestPurchase({
2129
2167
  * request: {
2130
- * ios: { sku: productId },
2131
- * android: { skus: [productId] }
2168
+ * apple: { sku: productId },
2169
+ * google: { skus: [productId] }
2132
2170
  * },
2133
2171
  * type: 'in-app'
2134
2172
  * });
@@ -2136,14 +2174,23 @@ function normalizeRequestProps(
2136
2174
  * // Subscription purchase
2137
2175
  * await requestPurchase({
2138
2176
  * request: {
2139
- * ios: { sku: subscriptionId },
2140
- * android: {
2177
+ * apple: { sku: subscriptionId },
2178
+ * google: {
2141
2179
  * skus: [subscriptionId],
2142
2180
  * subscriptionOffers: [{ sku: subscriptionId, offerToken: 'token' }]
2143
2181
  * }
2144
2182
  * },
2145
2183
  * type: 'subs'
2146
2184
  * });
2185
+ *
2186
+ * // Legacy format (deprecated, but still supported)
2187
+ * await requestPurchase({
2188
+ * request: {
2189
+ * ios: { sku: productId },
2190
+ * android: { skus: [productId] }
2191
+ * },
2192
+ * type: 'in-app'
2193
+ * });
2147
2194
  * ```
2148
2195
  */
2149
2196
  export const requestPurchase: MutationField&lt;'requestPurchase'&gt; = async (
@@ -2158,12 +2205,12 @@ export const requestPurchase: MutationField&lt;'requestPurchase'&gt; = async (
2158
2205
  &nbsp;
2159
2206
  if (!normalizedRequest?.sku) {
2160
2207
  throw new Error(
2161
- 'Invalid request for iOS. The `sku` property is required and must be a string.\n\n' +
2208
+ 'Invalid request for Apple. The `sku` property is required and must be a string.\n\n' +
2162
2209
  'Expected format:\n' +
2163
2210
  ' requestPurchase({\n' +
2164
2211
  ' request: {\n' +
2165
- ' android: { skus: ["product_id"] },\n' +
2166
- ' ios: { sku: "product_id" }\n' +
2212
+ ' apple: { sku: "product_id" },\n' +
2213
+ ' google: { skus: ["product_id"] }\n' +
2167
2214
  ' },\n' +
2168
2215
  ' type: "in-app"\n' +
2169
2216
  ' })\n\n' +
@@ -2206,12 +2253,12 @@ export const requestPurchase: MutationField&lt;'requestPurchase'&gt; = async (
2206
2253
  &nbsp;
2207
2254
  if (!normalizedRequest?.skus?.length) {
2208
2255
  throw new Error(
2209
- 'Invalid request for Android. The `skus` property is required and must be a non-empty array.\n\n' +
2256
+ 'Invalid request for Google. The `skus` property is required and must be a non-empty array.\n\n' +
2210
2257
  'Expected format:\n' +
2211
2258
  ' requestPurchase({\n' +
2212
2259
  ' request: {\n' +
2213
- ' android: { skus: ["product_id"] },\n' +
2214
- ' ios: { sku: "product_id" }\n' +
2260
+ ' apple: { sku: "product_id" },\n' +
2261
+ ' google: { skus: ["product_id"] }\n' +
2215
2262
  ' },\n' +
2216
2263
  ' type: "in-app"\n' +
2217
2264
  ' })\n\n' +
@@ -2248,12 +2295,12 @@ export const requestPurchase: MutationField&lt;'requestPurchase'&gt; = async (
2248
2295
  &nbsp;
2249
2296
  if (!normalizedRequest?.skus?.length) {
2250
2297
  throw new Error(
2251
- 'Invalid request for Android. The `skus` property is required and must be a non-empty array.\n\n' +
2298
+ 'Invalid request for Google. The `skus` property is required and must be a non-empty array.\n\n' +
2252
2299
  'Expected format:\n' +
2253
2300
  ' requestPurchase({\n' +
2254
2301
  ' request: {\n' +
2255
- ' android: { skus: ["subscription_id"] },\n' +
2256
- ' ios: { sku: "subscription_id" }\n' +
2302
+ ' apple: { sku: "subscription_id" },\n' +
2303
+ ' google: { skus: ["subscription_id"] }\n' +
2257
2304
  ' },\n' +
2258
2305
  ' type: "subs"\n' +
2259
2306
  ' })\n\n' +
@@ -2401,29 +2448,33 @@ export const deepLinkToSubscriptions: MutationField&lt;
2401
2448
  export const validateReceipt: MutationField&lt;'validateReceipt'&gt; = async (
2402
2449
  options,
2403
2450
  ) =&gt; {
2404
- const {sku, androidOptions} = options as MutationValidateReceiptArgs;
2451
+ const {apple, google} = options as MutationValidateReceiptArgs;
2405
2452
  &nbsp;
2406
2453
  if (Platform.OS === 'ios') {
2407
- return validateReceiptIOS({sku});
2454
+ if (!apple?.sku) {
2455
+ throw new Error('iOS validation requires apple.sku');
2456
+ }
2457
+ return validateReceiptIOS({apple: {sku: apple.sku}});
2408
2458
  }
2409
2459
  &nbsp;
2410
2460
  if (Platform.OS === 'android') {
2411
2461
  if (
2412
- !androidOptions ||
2413
- !androidOptions.packageName ||
2414
- !androidOptions.productToken ||
2415
- !androidOptions.accessToken
2462
+ !google ||
2463
+ !google.sku ||
2464
+ !google.packageName ||
2465
+ !google.purchaseToken ||
2466
+ !google.accessToken
2416
2467
  ) {
2417
2468
  throw new Error(
2418
- 'Android validation requires packageName, productToken, and accessToken',
2469
+ 'Android validation requires google.sku, google.packageName, google.purchaseToken, and google.accessToken',
2419
2470
  );
2420
2471
  }
2421
2472
  return validateReceiptAndroid({
2422
- packageName: androidOptions.packageName,
2423
- productId: sku,
2424
- productToken: androidOptions.productToken,
2425
- accessToken: androidOptions.accessToken,
2426
- isSub: androidOptions.isSub ?? <span class="branch-1 cbranch-no" title="branch not covered" >undefined,</span>
2473
+ packageName: google.packageName,
2474
+ productId: google.sku,
2475
+ productToken: google.purchaseToken,
2476
+ accessToken: google.accessToken,
2477
+ isSub: google.isSub ?? <span class="branch-1 cbranch-no" title="branch not covered" >undefined,</span>
2427
2478
  });
2428
2479
  }
2429
2480
  &nbsp;
@@ -2503,7 +2554,7 @@ export {<span class="fstat-no" title="function not covered" >ExpoIapConsole}</sp
2503
2554
  <div class='footer quiet pad2 space-top1 center small'>
2504
2555
  Code coverage generated by
2505
2556
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
2506
- at 2025-12-07T08:40:10.740Z
2557
+ at 2025-12-13T16:00:09.743Z
2507
2558
  </div>
2508
2559
  <script src="../prettify.js"></script>
2509
2560
  <script>