expo-alipay-sdk
Version:
Alipay SDK for Expo and React Native - Payment integration. Official Alipay payment solution with iOS & Android support. 支付宝支付功能集成
165 lines (147 loc) • 4.71 kB
JavaScript
// main index.js
;
import { DeviceEventEmitter, NativeModules, Platform } from 'react-native';
import { EventEmitter } from 'events';
let isAppRegistered = false;
const { Alipay } = NativeModules;
// Event emitter to dispatch request and response from Alipay.
const emitter = new EventEmitter();
DeviceEventEmitter.addListener('Alipay_Resp', (resp) => {
emitter.emit(resp.type, resp);
});
DeviceEventEmitter.addListener('Alipay_Req', (resp) => {
emitter.emit(resp.type, resp);
});
function wrapRegisterApp(nativeFunc) {
if (!nativeFunc) {
return undefined;
}
return (...args) => {
if (isAppRegistered) {
return Promise.resolve(true);
}
isAppRegistered = true;
return new Promise((resolve, reject) => {
nativeFunc.apply(null, [
...args,
(error, result) => {
if (!error) {
return resolve(result);
}
if (typeof error === 'string') {
return reject(new Error(error));
}
reject(error);
},
]);
});
};
}
function wrapApi(nativeFunc) {
if (!nativeFunc) {
return undefined;
}
return (...args) => {
if (!isAppRegistered) {
return Promise.reject(new Error('registerApp required.'));
}
return new Promise((resolve, reject) => {
nativeFunc.apply(null, [
...args,
(error, result) => {
if (!error) {
return resolve(result);
}
if (typeof error === 'string') {
return reject(new Error(error));
}
reject(error);
},
]);
});
};
}
/**
* `addListener` inherits from `events` module
* @method addListener
* @param {String} eventName - the event name
* @param {Function} trigger - the function when event is fired
*/
export const addListener = emitter.addListener.bind(emitter);
/**
* `once` inherits from `events` module
* @method once
* @param {String} eventName - the event name
* @param {Function} trigger - the function when event is fired
*/
export const once = emitter.once.bind(emitter);
/**
* `removeAllListeners` inherits from `events` module
* @method removeAllListeners
* @param {String} eventName - the event name
*/
export const removeAllListeners = emitter.removeAllListeners.bind(emitter);
/**
* @method registerApp
* @param {String} appId - the app id
* @param {String} universalLink - universal link (iOS only)
* @return {Promise}
*/
export const registerApp = wrapRegisterApp(Alipay.registerApp);
/**
* 支付
* @method pay
* @param {String} orderInfo - 支付订单信息字符串(由服务端生成)
* @return {Promise}
*/
export function pay(orderInfo) {
return new Promise((resolve, reject) => {
if (!isAppRegistered) {
return reject(new Error('registerApp required.'));
}
Alipay.pay(orderInfo, (error) => {
if (error) {
return reject(new Error(error));
}
});
emitter.once('PayResult.Resp', (resp) => {
if (resp.resultStatus === '9000') {
resolve(resp);
} else {
reject(new AlipayError(resp));
}
});
});
}
/**
* 获取 SDK 版本号
* @method getVersion
* @return {Promise<String>}
*/
export const getVersion = wrapApi(Alipay.getVersion);
/**
* 判断支付宝是否已安装
* @method isAlipayInstalled
* @return {Promise<Boolean>}
*/
export const isAlipayInstalled = wrapApi(Alipay.isAlipayInstalled);
/**
* promises will reject with this error when API call finish with an error.
*/
export class AlipayError extends Error {
constructor(resp) {
const message = resp.memo || resp.resultStatus || 'Unknown error';
super(message);
this.name = 'AlipayError';
this.code = resp.resultStatus;
this.result = resp.result;
this.memo = resp.memo;
// avoid babel's limition about extending Error class
// https://github.com/babel/babel/issues/3083
if (typeof Object.setPrototypeOf === 'function') {
Object.setPrototypeOf(this, AlipayError.prototype);
} else {
this.__proto__ = AlipayError.prototype;
}
}
}