import { ErrorCode, useIAP } from 'expo-iap' import { useEffect } from 'react' import { Platform } from 'react-native' import { Toast } from '@/@share/components' type UseIOSPurchaseOptions = { skus: string[] onPurchaseSuccess?: (purchase: any) => Promise onPurchaseError?: (error: any) => void onProductsFetched?: (products: any[]) => void } /** * iOS 专用的 IAP Hook * 在非 iOS 平台返回空实现,避免不必要的初始化 */ export function useIOSPurchase(options: UseIOSPurchaseOptions) { const { skus, onPurchaseSuccess, onPurchaseError, onProductsFetched } = options const isIOS = Platform.OS === 'ios' // iOS 平台使用真实的 IAP const { connected, products, fetchProducts, requestPurchase, finishTransaction } = useIAP({ onPurchaseSuccess: async (purchase) => { if (!isIOS) return console.log('✅ Purchase successful:', purchase) // 执行自定义成功回调 if (onPurchaseSuccess) { await onPurchaseSuccess(purchase) } // 完成交易(消耗型商品) await finishTransaction({ purchase, isConsumable: true }) }, onPurchaseError: (error) => { if (!isIOS) return // 用户取消不显示错误 if (error.code !== ErrorCode.UserCancelled) { console.error('❌ Purchase failed:', error) if (onPurchaseError) { onPurchaseError(error) } else { Toast.show({ title: '购买失败,请稍后重试' }) } } }, onError: (error) => { console.log('❌ IAP Error:', error) }, }) // 连接后自动获取商品 useEffect(() => { if (!isIOS || !connected) return console.log('🔗 IAP connected, fetching products...', connected) console.log('📦 SKUs:', skus) fetchProducts({ skus, type: 'in-app' }) .then((result) => { if (!result?.products?.length) { console.warn('⚠️ No products returned. Check App Store Connect configuration.') } if (onProductsFetched && result?.products) { onProductsFetched(result.products) } }) .catch((error) => { console.error('❌ Failed to fetch products:', error) Toast.show({ title: '获取商品信息失败' }) }) }, [isIOS, connected, skus]) // 非 iOS 平台返回空实现 if (!isIOS) { return { connected: false, products: [], requestPurchase: async () => { console.warn('IAP is only supported on iOS') }, } } return { connected, products, requestPurchase: async (productId: string) => { if (!connected) { Toast.show({ title: 'App Store 未连接' }) return } if (!products?.length) { Toast.show({ title: '商品信息加载中,请稍后' }) return } await requestPurchase({ request: { apple: { sku: productId }, }, type: 'in-app', }) }, } }