import { native } from 'cc'; import { IAPImpl, IAPProductsResult, IAPResult } from './IAPImpl'; export class IOSIAP extends IAPImpl { private seed = 0; private listening = false; private pending = new Map void; reject: (error: Error) => void; timer: ReturnType }>(); private listeners = new Set<(transaction: IAPResult) => void>(); private listen(): void { if (this.listening) return; native.jsbBridgeWrapper.addNativeEventListener('iap.response', payload => { let response: any; try { response = JSON.parse(payload); } catch { return; } if (response.method === 'transaction') { for (const listener of this.listeners) { try { listener(response.data); } catch (error) { console.error('[IAP] Transaction listener failed', error); } } return; } const pending = this.pending.get(response.requestId); if (!pending) return; clearTimeout(pending.timer); this.pending.delete(response.requestId); if (response.success) pending.resolve(response.data); else pending.reject(new Error(response.error || 'IAP request failed')); }); this.listening = true; } private request(method: string, params: object = {}): Promise { this.listen(); const requestId = `${Date.now()}-${++this.seed}`; return new Promise((resolve, reject) => { const timer = setTimeout(() => { this.pending.delete(requestId); reject(new Error('IAP 请求超时;不代表支付失败,请查询未完成交易,勿直接重复购买。')); }, 180000); this.pending.set(requestId, { resolve, reject, timer }); try { native.jsbBridgeWrapper.dispatchEventToNative('iap.request', JSON.stringify({ requestId, method, params })); } catch (error) { clearTimeout(timer); this.pending.delete(requestId); reject(error); } }); } init(productIds: string[]): Promise { if (!productIds.length || productIds.some(id => typeof id !== 'string' || !id.trim())) { return Promise.reject(new Error('商品 ID 不能为空。')); } return this.request('init', { productIds: [...new Set(productIds)] }); } purchase(productId: string): Promise { return this.request('purchase', { productId }); } restore(): Promise { return this.request('restore'); } getPendingTransactions(): Promise { return this.request('pending'); } async finishTransaction(transactionId: string): Promise { if (!transactionId) throw new Error('交易 ID 不能为空。'); await this.request('finish', { transactionId }); } onTransaction(listener: (transaction: IAPResult) => void): () => void { this.listen(); this.listeners.add(listener); return () => { this.listeners.delete(listener); }; } }