import { NativeModules, NativeEventEmitter, EmitterSubscription, Platform } from 'react-native'; import Broadcaster from './utils/broadcaster'; const { FastWechat: RNFastWechat } = NativeModules; const emitter = new NativeEventEmitter(RNFastWechat); const event = 'wechat'; export type WechatPayParams = { appId: string; sign: string; partnerId: string; prepayId: string; nonceStr: string; timestamp: string; } const ERR_OK = 0; const ERR_COMM = -1; const ERR_USER_CANCEL = -2; const ERR_SENT_FAILED = -3; const ERR_AUTH_DENIED = -4; const ERR_UNSUPPORT = -5; const ERR_BAN = -6; const CHANNEL_PAY = 'pay'; export default class FastWechat { private subscription?: EmitterSubscription; private static instance: FastWechat | null = null; public static get shared() { if (this.instance == null) { this.instance = new FastWechat(); } return this.instance; } private static KMap: any = { 'appid': 'appId', 'partnerid': 'partnerId', 'prepayid': 'prepayId', 'noncestr': 'nonceStr', 'timestamp': 'timestamp', 'sign': 'sign', } constructor() { if (this.subscription != undefined) { emitter.removeAllListeners(event); } this.subscription = emitter.addListener(event, (event) => { let { type, code } = event; if (type === CHANNEL_PAY) { Broadcaster.send(CHANNEL_PAY, code); } }) } private async __init(appId: string, iosUniversalLinks?: string) { return new Promise((res, rej) => { (Platform.OS === 'android' ? RNFastWechat.init(appId) : RNFastWechat.init(appId, iosUniversalLinks)).then((rs: boolean) => { res(rs) }).catch((e: any) => { rej(e) }) }) } private async __isInstalled() { return new Promise((res, rej) => { RNFastWechat.isInstalled().then((rs: any) => { if (rs == 1 || rs == true) { res(true); } else { res(false); } }).catch((e:any) => { rej(e); }) }); } private async __pay(params: WechatPayParams) { const isInstalled = await this.__isInstalled(); if(!isInstalled) throw new Error('未安装微信'); RNFastWechat.pay(params); const [subscription, result] = await new Promise<[any, any]>((res) => { const _subscription = Broadcaster.subscribe(CHANNEL_PAY, (rs) => { res([_subscription, rs]); }); }); if (subscription?.remove) subscription?.remove(); if (result == ERR_OK || result == -666) { return true; } if (Platform.OS == 'android') { // -666 : 支付中断,用户主动从后台切回应用;也应从服务端查询支付结果 if (result == ERR_USER_CANCEL) { throw new Error('支付已取消') } if (result == ERR_AUTH_DENIED) { throw new Error('发送被拒绝') } if (result == ERR_UNSUPPORT) { throw new Error('支付不支持') } } else { if (result == ERR_COMM) { throw new Error('签名错误或未注册、未正确设置AppID或其他异常') } if (result == ERR_USER_CANCEL) { throw new Error('支付已取消') } } throw new Error('未知支付错误') } static async init(appId: string, iosUniversalLinks?: string) { return FastWechat.shared.__init(appId, iosUniversalLinks) } static async pay(params: WechatPayParams) { return FastWechat.shared.__pay(params); } static async payWithoutConvertion(params: string | Record) { let ps: any = {}; let psrParams: Record = {}; if (typeof params == 'string') { try { psrParams = JSON.parse(params); } catch (error) { throw Error("参数异常、请检查参数类型以及内容"); } } else { psrParams = params; } let psrParamsProps = Object.keys(psrParams); for (let k of ['appid', 'partnerid', 'prepayid', 'noncestr', 'timestamp', 'sign']) { if (psrParamsProps.indexOf(k) == -1) { throw Error(`参数缺失 [${k}]`); } ps[FastWechat.KMap[k]] = psrParams[k]; } return FastWechat.shared.__pay(ps!); } static async isInstalled() { return FastWechat.shared.__isInstalled(); } }