Tauri 插件 IAP
用于In-App Pushers(IAP)的Tauri插件,支持订阅iOS(StoreKit 2),Android(Google Play Billing),Windows(微软商店)和macOS(StoreKit 2).
特征
- 详细定价的查询产品和订阅
- 具有平台特色的订阅
- 恢复以前的购买
- 获取购买历史
- 检查产品所有权和订阅状况
- 通过事件实时购买状态更新
- 自动交易核实( iOS)
- 对介绍性和免费审判的支助
- 使用模糊的账户/身份证明防止欺诈(Android)
- 跟踪的 App 账户符号支持( iOS)
- 自动发价符选择( Android)
- 带有平分模式的订阅升级/下级(Android)
平台支持
- iOS系统: StoreKit 2 (需要iOS 15.0+) (中文(简体) )
- 机器人: Google Play Billing 图书馆 v 9.0.0
- 窗口: 微软存储 API (Windows 10/11)
- 马科斯: StoreKit 2 (需要macOS 13.0+) (中文(简体) )
安装
安装 JavaScript 软件包 :
npm install @choochmeque/tauri-plugin-iap-api
# or
yarn add @choochmeque/tauri-plugin-iap-api
# or
pnpm add @choochmeque/tauri-plugin-iap-api
在您的 Tauri 工程中添加插件 Cargo.toml数字 :
[dependencies]
tauri-plugin-iap = "0.10"
配置您的插件权限 capabilities/default.json数字 :
{
"permissions": [
"iap:default"
]
}
在您的 Tauri 应用程序中注册插件 :
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_iap::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
示例应用
示例应用程序在 examples/iap-demo 目录。 该示例展示了所有具有UI的IAP核心功能:
- 以定价方式获取和显示产品
- 采购产品和订阅
- 恢复以前的购买
- 检查产品所有权状况
- 实时采购更新通知
运行示例
cd examples/iap-demo
# Install dependencies
pnpm install
# Run in development mode
pnpm tauri dev
# Build for production
pnpm tauri build
重要内容: 该应用程序必须经过适当的代号来测试IAP功能:
- iOS/macOS 系统:StoryKit要求代码签名. 配置在Xcode或通过Tauri的配置签名.
- 机器人:在你的APK/AAB上签名,并加放出键盘用于生产测试.
- 窗口: App必须与Microsoft Store关联并签名提交 Store.
示例应用为每个 IAP 特性提供了内置文档的全功能演示,使得它易于理解如何将插件整合到您自己的应用程序中.
使用量
Java 脚本/ Type 脚本
import {
getProducts,
purchase,
restorePurchases,
acknowledgePurchase,
consumePurchase,
getProductStatus,
onPurchaseUpdated,
PurchaseState
} from '@choochmeque/tauri-plugin-iap-api';
// Get available products
const products = await getProducts(['subscription_id_1', 'subscription_id_2'], 'subs');
// Check if user owns a specific product
const status = await getProductStatus('subscription_id_1', 'subs');
if (status.isOwned && status.purchaseState === PurchaseState.PURCHASED) {
console.log('User has active subscription');
if (status.isAutoRenewing) {
console.log('Subscription will auto-renew');
}
}
// Purchase a subscription or in-app product
// Simple purchase (will use first available offer on Android if not specified)
const purchaseResult = await purchase('subscription_id_1', 'subs');
// With specific offer token (Android)
const purchaseResult = await purchase('subscription_id_1', 'subs', {
offerToken: product.subscriptionOfferDetails[0].offerToken
});
// With fraud prevention (Android)
const purchaseResult = await purchase('subscription_id_1', 'subs', {
obfuscatedAccountId: 'hashed_account_id',
obfuscatedProfileId: 'hashed_profile_id'
});
// With app account token (iOS - must be valid UUID)
const purchaseResult = await purchase('subscription_id_1', 'subs', {
appAccountToken: '550e8400-e29b-41d4-a716-446655440000'
});
// Upgrade/downgrade subscription (Android, Billing Library 9.0+)
import { SubscriptionReplacementMode } from '@choochmeque/tauri-plugin-iap-api';
const upgraded = await purchase('premium_subscription', 'subs', {
offerToken: 'premium_offer_token',
oldProductId: currentSubscription.productId,
subscriptionReplacementMode: SubscriptionReplacementMode.WITH_TIME_PRORATION
});
// Restore purchases (specify product type)
const restored = await restorePurchases('subs');
// Acknowledge a non-consumable purchase (subscriptions, durables).
// No-op on iOS/macOS — StoreKit auto-finishes transactions.
await acknowledgePurchase(purchaseResult.purchaseToken);
// Consume a consumable purchase (credits, coins) so it can be re-bought.
// No-op on iOS/macOS — StoreKit auto-allows re-purchase.
await consumePurchase(purchaseResult.purchaseToken);
// Listen for purchase updates
const listener = await onPurchaseUpdated((purchase) => {
console.log('Purchase updated:', purchase);
});
// Stop listening
await listener.unregister();
锈
use tauri_plugin_iap::{IapExt, PurchaseRequest, PurchaseStateValue, Result};
// Get available products
let products = app.iap()
.get_products(
vec!["subscription_id_1".into(), "subscription_id_2".into()],
"subs".into(),
)
.await?;
// Check if user owns a specific product
let status = app.iap()
.get_product_status("subscription_id_1".into(), "subs".into())
.await?;
if status.is_owned && status.purchase_state == Some(PurchaseStateValue::Purchased) {
println!("User has active subscription");
if status.is_auto_renewing == Some(true) {
println!("Subscription will auto-renew");
}
}
// Purchase a subscription or in-app product
// Simple purchase (will use first available offer on Android if not specified)
let purchase_result = app.iap()
.purchase(PurchaseRequest {
product_id: "subscription_id_1".into(),
product_type: "subs".into(),
options: None,
})
.await?;
// Restore purchases (specify product type)
let restored = app.iap().restore_purchases("subs".into()).await?;
// Acknowledge a non-consumable purchase (subscriptions, durables).
// No-op on iOS/macOS — StoreKit auto-finishes transactions.
app.iap().acknowledge_purchase(purchase_result.purchase_token).await?;
平台设置
iOS 设置
- 在 App Store 连接中配置您的应用程序
- 创建有适当定价的订阅产品
- 在 Xcode 中的应用程序中添加内购能力 :
- 在 Xcode 中打开您的工程
- 选择目标
- 转到“ 签名能力( C) ”
- 单击“ +” 并添加“ 在购买中”
- 测试沙盒账户
Android 设置
- 将您的应用程序添加到 Google 播放控制台
- 在 Google 游戏控制台创建订阅产品
- 配置您的应用程序的计费权限( 已经包含在插件中)
- 测试账户或沙盒环境
窗口设置
- 在微软伙伴中心注册您的应用程序
- 创建附加产品(消耗品、耐用品或订阅品)
- 将您的应用程序与微软商店关联
- 用 Windows 沙盒环境进行测试
macOS 设置
- 在 App Store 连接中配置您的应用程序
- 创建有定价的订阅或应用程序购买产品
- 配置签名代码
tauri.conf.json数字 :{ "bundle": { "macOS": { "signingIdentity": "Developer ID Application: Your Name (TEAM_ID)", "entitlements": "path/to/entitlements.plist" } } } - 添加 StoreKit 所需的权限( 创建)
entitlements.plist:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.app-sandbox</key> <true/> <key>com.apple.security.network.client</key> <true/> </dict> </plist> - 测试沙盒账户或 StoreKit 配置文件
- 重要: App 必须签名才能使用 StoreKit API
API 参考
getProducts(productIds: string[], productType: 'subs' | 'inapp')
从商店获取产品细节.
回返情况:
products: 产品对象阵列:productId: 产品标识符title: 显示名称description: 产品说明productType: 产品类型formattedPrice: 本地化价格字符串subscriptionOfferDetails: (仅订阅) 报价组合
purchase(productId: string, productType: 'subs' | 'inapp' = 'subs', options?: PurchaseOptions)
启动采购流程,加强欺诈预防和账户管理选项.
参数:
productId: 要购买的产品productType: 产品类型(订阅的"子",一次性购买的"应用"),默认为"子"options: 可选购买参数:offerToken: (Android) 具体的购买报价. 如果不提供,则使用第一个可用报价obfuscatedAccountId: (Android) 防止欺诈的Hashed账户IDobfuscatedProfileId: (Android)Hashed profile ID 用于预防欺诈appAccountToken: (iOS)用于账户跟踪和预防欺诈的UUID字符串oldProductId: (Android) 现有订阅用于升级/下级替换的产品ID(Billing Library 9.0+)subscriptionReplacementMode: (Android) 使用SubscriptionReplacementModeenum - (英语)WITH_TIME_PRORATION, (中文(简体) ),CHARGE_PRORATED_PRICE, (中文(简体) ),WITHOUT_PRORATION, (中文(简体) ),CHARGE_FULL_PRICE, (中文(简体) ),DEFERRED, (中文(简体) ),KEEP_EXISTING(违约)WITH_TIME_PRORATION(中文(简体) )
回返情况: 有交易细节的购买对象
restorePurchases(productType: 'subs' | 'inapp' = 'subs')
查询并返回所有活动的购买.
参数:
productType: 要还原的产品类型 ('subs' 或' inapp'), 默认为'subs'
getPurchaseHistory()
返回完整的购买历史 .
acknowledgePurchase(purchaseToken: string)
确认非消耗性购买(订阅、耐用)。 在Android上,这需要在3天内完成,或者谷歌自动退款购买. iOS,macOS,和Windows上没有 -op. 使用 consumePurchase 换成消耗品.
consumePurchase(purchaseToken: string)
消费了一种可消费的购买(信用,硬币,宝石),因此可以再购买. 安卓电话 BillingClient.consumeAsync(); 视窗调用 StoreContext.ReportConsumableFulfillmentAsync 与数量 1. iOS和macOS上的禁用- StoreKit自动取款机回购. 永远不要给两者打电话 acknowledgePurchase 财务报告和审定财务报表 consumePurchase 同一个购买物.
getProductStatus(productId: string, productType: 'subs' | 'inapp' = 'subs')
检查特定产品的所有权和订阅状况.
参数:
productId: 要检查的产品标识符productType: 产品类型 ("子"或"inapp"),默认为"子"
回返情况: 产品状态对象:
productId: 产品标识符isOwned: 用户目前是否拥有产品purchaseState: 当前状态(PURCHASED=0, CANCELED=1, PENDING=2)purchaseTime: 产品购买时(时间戳)expirationTime: (仅订阅) 订阅到期时isAutoRenewing: (仅订阅) 是否启用自动更新isAcknowledged:购买是否得到承认purchaseToken: 用于购买交易的托肯
onPurchaseUpdated(callback: (purchase: Purchase) => void): Promise<PluginListener>
购买状态变化的听觉 .
回返情况: A 类 PluginListener 带有对象 unregister() 停止倾听的方法.
平台之间的差异
iOS (StoreKit 2) (英语)
- 自动检查交易
- 不需要人工确认
- 支助介绍性提议和宣传性提议
- 交易更新自动被观察到
- 需要iOS 15.0+ (英语)
Android (谷歌玩比林) (Google Play Billing) (英语)
- 要求在3天内进行人工确认
- 支持每个产品的多种订阅报价
- 订阅购买所需出价
- 更详细的定价阶段信息
视窗(微软存储)
- 存储器处理的自动确认
- 支持消耗品、耐用品和订阅
- 订阅时使用 SKU 更改
macOS (StoreKit 2) (StoreKit 2) (英语)
- 与 iOS 相同的 StoreKit 2 API
- 自动检查交易
- 不需要人工确认
- 需要 macOS 13.0+
- App 必须是代号( StoreKit 需要有效签名)
测试
iOS系统
- 使用沙盒测试账户
- 物理设备测试(订阅在模拟器上效果不佳)
- 在设置 > App Store > Sandbox 账户中清除购买历史
机器人
- 上传您的应用程序到内部测试轨道
- 在 Google 游戏控制台中添加测试账户
- 使用测试支付方法的测试
窗口
- 使用 Microsoft Store 沙盒环境
- 在伙伴中心配置测试账户
- 使用 Windows Dev Center 测试支付方法
- 确保应用程序与 Store 上市相关
马科斯
- 使用沙盒测试账户( 与 iOS 相同)
- 使用 StoreKit 配置文件进行本地测试
- 使用 StoreKit 必须使用代码
- 在系统设置 > App Store > Sandbox 账户中清除购买历史
解决问题
dyld: Library not loaded: @rpath/libswift_Concurrency.dylib
此错误发生于 MACOSX_DEPLOYMENT_TARGET 位于13.0以下。 Tauri在调试模式下默认为11.0.
备选案文1: 添加 .cargo/config.toml 对您的项目:
[env]
MACOSX_DEPLOYMENT_TARGET = "13.0"
备选案文2: 运行时设置环境变量 :
MACOSX_DEPLOYMENT_TARGET="13.0" pnpm tauri dev