@choochmeque/tauri-plugin-iap-api 0.8.0 → 0.9.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 CHANGED
@@ -112,6 +112,7 @@ import {
112
112
  purchase,
113
113
  restorePurchases,
114
114
  acknowledgePurchase,
115
+ consumePurchase,
115
116
  getProductStatus,
116
117
  onPurchaseUpdated,
117
118
  PurchaseState
@@ -161,9 +162,14 @@ const upgraded = await purchase('premium_subscription', 'subs', {
161
162
  // Restore purchases (specify product type)
162
163
  const restored = await restorePurchases('subs');
163
164
 
164
- // Acknowledge a purchase (Android only, iOS auto-acknowledges)
165
+ // Acknowledge a non-consumable purchase (subscriptions, durables).
166
+ // No-op on iOS/macOS — StoreKit auto-finishes transactions.
165
167
  await acknowledgePurchase(purchaseResult.purchaseToken);
166
168
 
169
+ // Consume a consumable purchase (credits, coins) so it can be re-bought.
170
+ // No-op on iOS/macOS — StoreKit auto-allows re-purchase.
171
+ await consumePurchase(purchaseResult.purchaseToken);
172
+
167
173
  // Listen for purchase updates
168
174
  const listener = await onPurchaseUpdated((purchase) => {
169
175
  console.log('Purchase updated:', purchase);
@@ -276,7 +282,10 @@ Queries and returns all active purchases.
276
282
  Returns the complete purchase history.
277
283
 
278
284
  ### `acknowledgePurchase(purchaseToken: string)`
279
- Acknowledges a purchase (required on Android within 3 days, no-op on iOS).
285
+ Acknowledges a non-consumable purchase (subscriptions, durables). On Android this is required within 3 days or Google auto-refunds the purchase. No-op on iOS, macOS, and Windows. Use `consumePurchase` instead for consumables.
286
+
287
+ ### `consumePurchase(purchaseToken: string)`
288
+ Consumes a consumable purchase (credits, coins, gems) so it can be purchased again. On Android calls `BillingClient.consumeAsync()`; on Windows calls `StoreContext.ReportConsumableFulfillmentAsync` with quantity 1. No-op on iOS and macOS — StoreKit auto-allows re-purchase. Never call both `acknowledgePurchase` and `consumePurchase` for the same purchase token.
280
289
 
281
290
  ### `getProductStatus(productId: string, productType: 'subs' | 'inapp' = 'subs')`
282
291
  Checks the ownership and subscription status of a specific product.
@@ -351,6 +360,28 @@ Listens for purchase state changes.
351
360
  3. App must be code-signed to use StoreKit
352
361
  4. Clear purchase history in System Settings > App Store > Sandbox Account
353
362
 
363
+ ## Troubleshooting
364
+
365
+ <details>
366
+ <summary><code>dyld: Library not loaded: @rpath/libswift_Concurrency.dylib</code></summary>
367
+
368
+ This error occurs when `MACOSX_DEPLOYMENT_TARGET` is below 13.0. Tauri defaults to 11.0 in debug mode.
369
+
370
+ **Option 1:** Add `.cargo/config.toml` to your project:
371
+
372
+ ```toml
373
+ [env]
374
+ MACOSX_DEPLOYMENT_TARGET = "13.0"
375
+ ```
376
+
377
+ **Option 2:** Set the environment variable when running:
378
+
379
+ ```bash
380
+ MACOSX_DEPLOYMENT_TARGET="13.0" pnpm tauri dev
381
+ ```
382
+
383
+ </details>
384
+
354
385
  ## License
355
386
 
356
387
  [MIT](LICENSE)
@@ -104,12 +104,6 @@ export interface PurchaseHistoryRecord {
104
104
  export interface GetPurchaseHistoryResponse {
105
105
  history: PurchaseHistoryRecord[];
106
106
  }
107
- /**
108
- * Response from acknowledging a purchase
109
- */
110
- export interface AcknowledgePurchaseResponse {
111
- success: boolean;
112
- }
113
107
  /**
114
108
  * Purchase state enumeration
115
109
  */
@@ -259,21 +253,47 @@ export declare function restorePurchases(productType?: "subs" | "inapp"): Promis
259
253
  */
260
254
  export declare function getPurchaseHistory(): Promise<GetPurchaseHistoryResponse>;
261
255
  /**
262
- * Acknowledge a purchase (Android only).
263
- * Purchases must be acknowledged within 3 days or they will be refunded.
264
- * iOS automatically acknowledges purchases.
256
+ * Acknowledge a non-consumable purchase (subscriptions, durable products).
257
+ *
258
+ * On Android this calls `BillingClient.acknowledgePurchase()` and is required
259
+ * within 3 days of purchase or Google will auto-refund. On iOS, macOS, and
260
+ * Windows this is a no-op — those stores handle acknowledgment automatically.
261
+ *
262
+ * For consumable products (credits, coins, gems) call {@link consumePurchase}
263
+ * instead. Never call both for the same purchase token.
265
264
  *
266
265
  * @param purchaseToken - Purchase token from the transaction
267
- * @returns Promise resolving to acknowledgment status
266
+ * @throws Rejects if acknowledgment fails (e.g., Android billing client error)
268
267
  * @example
269
268
  * ```typescript
270
- * const result = await acknowledgePurchase(purchase.purchaseToken);
271
- * if (result.success) {
272
- * console.log('Purchase acknowledged');
273
- * }
269
+ * await acknowledgePurchase(purchase.purchaseToken);
270
+ * ```
271
+ */
272
+ export declare function acknowledgePurchase(purchaseToken: string): Promise<void>;
273
+ /**
274
+ * Consume a purchased consumable product so it can be purchased again.
275
+ *
276
+ * On Android this calls `BillingClient.consumeAsync()`, which acknowledges the
277
+ * purchase and removes ownership from the user's account. On Windows this calls
278
+ * `StoreContext.ReportConsumableFulfillmentAsync` with quantity 1. On iOS and
279
+ * macOS this is a no-op — StoreKit auto-allows re-purchase once `purchase()`
280
+ * has finished the transaction.
281
+ *
282
+ * Use this for consumables (credits, coins, gems). For non-consumables and
283
+ * subscriptions call {@link acknowledgePurchase} instead. Never call both for
284
+ * the same purchase token.
285
+ *
286
+ * @param purchaseToken - Purchase token from the transaction
287
+ * @throws Rejects if consumption fails (e.g., Android billing client error,
288
+ * Windows network/server error, or invalid token on Windows)
289
+ * @example
290
+ * ```typescript
291
+ * const result = await purchase('credits_100', 'inapp');
292
+ * await consumePurchase(result.purchaseToken);
293
+ * // user can now buy credits_100 again
274
294
  * ```
275
295
  */
276
- export declare function acknowledgePurchase(purchaseToken: string): Promise<AcknowledgePurchaseResponse>;
296
+ export declare function consumePurchase(purchaseToken: string): Promise<void>;
277
297
  /**
278
298
  * Get the current status of a product for the user.
279
299
  * Checks if the product is owned, expired, or available for purchase.
package/dist-js/index.cjs CHANGED
@@ -138,22 +138,54 @@ async function getPurchaseHistory() {
138
138
  return await core.invoke("plugin:iap|get_purchase_history");
139
139
  }
140
140
  /**
141
- * Acknowledge a purchase (Android only).
142
- * Purchases must be acknowledged within 3 days or they will be refunded.
143
- * iOS automatically acknowledges purchases.
141
+ * Acknowledge a non-consumable purchase (subscriptions, durable products).
142
+ *
143
+ * On Android this calls `BillingClient.acknowledgePurchase()` and is required
144
+ * within 3 days of purchase or Google will auto-refund. On iOS, macOS, and
145
+ * Windows this is a no-op — those stores handle acknowledgment automatically.
146
+ *
147
+ * For consumable products (credits, coins, gems) call {@link consumePurchase}
148
+ * instead. Never call both for the same purchase token.
144
149
  *
145
150
  * @param purchaseToken - Purchase token from the transaction
146
- * @returns Promise resolving to acknowledgment status
151
+ * @throws Rejects if acknowledgment fails (e.g., Android billing client error)
147
152
  * @example
148
153
  * ```typescript
149
- * const result = await acknowledgePurchase(purchase.purchaseToken);
150
- * if (result.success) {
151
- * console.log('Purchase acknowledged');
152
- * }
154
+ * await acknowledgePurchase(purchase.purchaseToken);
153
155
  * ```
154
156
  */
155
157
  async function acknowledgePurchase(purchaseToken) {
156
- return await core.invoke("plugin:iap|acknowledge_purchase", {
158
+ await core.invoke("plugin:iap|acknowledge_purchase", {
159
+ payload: {
160
+ purchaseToken,
161
+ },
162
+ });
163
+ }
164
+ /**
165
+ * Consume a purchased consumable product so it can be purchased again.
166
+ *
167
+ * On Android this calls `BillingClient.consumeAsync()`, which acknowledges the
168
+ * purchase and removes ownership from the user's account. On Windows this calls
169
+ * `StoreContext.ReportConsumableFulfillmentAsync` with quantity 1. On iOS and
170
+ * macOS this is a no-op — StoreKit auto-allows re-purchase once `purchase()`
171
+ * has finished the transaction.
172
+ *
173
+ * Use this for consumables (credits, coins, gems). For non-consumables and
174
+ * subscriptions call {@link acknowledgePurchase} instead. Never call both for
175
+ * the same purchase token.
176
+ *
177
+ * @param purchaseToken - Purchase token from the transaction
178
+ * @throws Rejects if consumption fails (e.g., Android billing client error,
179
+ * Windows network/server error, or invalid token on Windows)
180
+ * @example
181
+ * ```typescript
182
+ * const result = await purchase('credits_100', 'inapp');
183
+ * await consumePurchase(result.purchaseToken);
184
+ * // user can now buy credits_100 again
185
+ * ```
186
+ */
187
+ async function consumePurchase(purchaseToken) {
188
+ await core.invoke("plugin:iap|consume_purchase", {
157
189
  payload: {
158
190
  purchaseToken,
159
191
  },
@@ -209,6 +241,7 @@ async function onPurchaseUpdated(callback) {
209
241
  }
210
242
 
211
243
  exports.acknowledgePurchase = acknowledgePurchase;
244
+ exports.consumePurchase = consumePurchase;
212
245
  exports.getProductStatus = getProductStatus;
213
246
  exports.getProducts = getProducts;
214
247
  exports.getPurchaseHistory = getPurchaseHistory;
package/dist-js/index.js CHANGED
@@ -136,22 +136,54 @@ async function getPurchaseHistory() {
136
136
  return await invoke("plugin:iap|get_purchase_history");
137
137
  }
138
138
  /**
139
- * Acknowledge a purchase (Android only).
140
- * Purchases must be acknowledged within 3 days or they will be refunded.
141
- * iOS automatically acknowledges purchases.
139
+ * Acknowledge a non-consumable purchase (subscriptions, durable products).
140
+ *
141
+ * On Android this calls `BillingClient.acknowledgePurchase()` and is required
142
+ * within 3 days of purchase or Google will auto-refund. On iOS, macOS, and
143
+ * Windows this is a no-op — those stores handle acknowledgment automatically.
144
+ *
145
+ * For consumable products (credits, coins, gems) call {@link consumePurchase}
146
+ * instead. Never call both for the same purchase token.
142
147
  *
143
148
  * @param purchaseToken - Purchase token from the transaction
144
- * @returns Promise resolving to acknowledgment status
149
+ * @throws Rejects if acknowledgment fails (e.g., Android billing client error)
145
150
  * @example
146
151
  * ```typescript
147
- * const result = await acknowledgePurchase(purchase.purchaseToken);
148
- * if (result.success) {
149
- * console.log('Purchase acknowledged');
150
- * }
152
+ * await acknowledgePurchase(purchase.purchaseToken);
151
153
  * ```
152
154
  */
153
155
  async function acknowledgePurchase(purchaseToken) {
154
- return await invoke("plugin:iap|acknowledge_purchase", {
156
+ await invoke("plugin:iap|acknowledge_purchase", {
157
+ payload: {
158
+ purchaseToken,
159
+ },
160
+ });
161
+ }
162
+ /**
163
+ * Consume a purchased consumable product so it can be purchased again.
164
+ *
165
+ * On Android this calls `BillingClient.consumeAsync()`, which acknowledges the
166
+ * purchase and removes ownership from the user's account. On Windows this calls
167
+ * `StoreContext.ReportConsumableFulfillmentAsync` with quantity 1. On iOS and
168
+ * macOS this is a no-op — StoreKit auto-allows re-purchase once `purchase()`
169
+ * has finished the transaction.
170
+ *
171
+ * Use this for consumables (credits, coins, gems). For non-consumables and
172
+ * subscriptions call {@link acknowledgePurchase} instead. Never call both for
173
+ * the same purchase token.
174
+ *
175
+ * @param purchaseToken - Purchase token from the transaction
176
+ * @throws Rejects if consumption fails (e.g., Android billing client error,
177
+ * Windows network/server error, or invalid token on Windows)
178
+ * @example
179
+ * ```typescript
180
+ * const result = await purchase('credits_100', 'inapp');
181
+ * await consumePurchase(result.purchaseToken);
182
+ * // user can now buy credits_100 again
183
+ * ```
184
+ */
185
+ async function consumePurchase(purchaseToken) {
186
+ await invoke("plugin:iap|consume_purchase", {
155
187
  payload: {
156
188
  purchaseToken,
157
189
  },
@@ -206,4 +238,4 @@ async function onPurchaseUpdated(callback) {
206
238
  return await addPluginListener("iap", "purchaseUpdated", callback);
207
239
  }
208
240
 
209
- export { PurchaseState, SubscriptionReplacementMode, acknowledgePurchase, getProductStatus, getProducts, getPurchaseHistory, initialize, onPurchaseUpdated, purchase, restorePurchases };
241
+ export { PurchaseState, SubscriptionReplacementMode, acknowledgePurchase, consumePurchase, getProductStatus, getProducts, getPurchaseHistory, initialize, onPurchaseUpdated, purchase, restorePurchases };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@choochmeque/tauri-plugin-iap-api",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "license": "MIT",
5
5
  "author": "You",
6
6
  "description": "A Tauri v2 plugin that enables In-App Purchases (IAP)",
@@ -40,10 +40,10 @@
40
40
  "@vitest/coverage-v8": "^4.0.13",
41
41
  "@vitest/ui": "^4.0.13",
42
42
  "happy-dom": "^20.0.10",
43
- "prettier": "3.8.1",
43
+ "prettier": "3.8.3",
44
44
  "rollup": "^4.9.6",
45
45
  "tslib": "^2.6.2",
46
- "typescript": "^5.3.3",
46
+ "typescript": "^6.0.2",
47
47
  "vitest": "^4.0.13"
48
48
  },
49
49
  "scripts": {