index.obj.js 6.8 KB
Newer Older
VK1688's avatar
VK1688 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
/**
 * uni-pay-co 统一支付云对象
 */

// 加载服务
const service = require('./service');
// 加载全局错误码
const { UniCloudError, isUniPayError, ERROR } = require('./common/error');
// 加载全局中间件
const middleware = require('./middleware/index');
// 加载uniId公共模块
const uniIdCommon = require('uni-id-common');

module.exports = {
	/**
	 * 中间件(请求前执行)
	 */
	async _before() {
		const params = this.getParams();
		let clientInfo;
		if (params && params[0] && params[0].clientInfo) {
			clientInfo = params[0].clientInfo;
		} else {
			clientInfo = this.getClientInfo();
		}

		// 挂载uni-id实例到this上,方便后续调用
		this.uniIdCommon = uniIdCommon.createInstance({
			clientInfo
		});

		// 国际化开始
		const i18n = uniCloud.initI18n({
			locale: clientInfo.locale || 'zh-Hans',
			fallbackLocale: 'zh-Hans',
			messages: require('./lang/index')
		})
		this.t = i18n.t.bind(i18n);
		// 国际化结束

		// 挂载中间件
		this.middleware = {}
		for (const mwName in middleware) {
			this.middleware[mwName] = middleware[mwName].bind(this);
		}
		const methodName = this.getMethodName();
		// 支付回调接口没有token,不需要获取用户信息
		if (methodName !== "payNotify") {
			// 尝试从token获取用户信息
			await this.middleware.auth(false);
			// 通用权限校验模块
			await this.middleware.accessControl();
		}
		// 设置全局获取userId公共函数(可在此云对象的任意其他函数内通过 this.getUserId() 获取当前登录用户的id
		this.getUserId = () => {
			return this.authInfo && this.authInfo.uid ? this.authInfo.uid : undefined;
		}
	},
	/**
	 * 中间件(请求后执行)
	 */
	_after(error, result) {
		if (error) {
			if (error.errCode) {
				let errCode = error.errCode
				if (!isUniPayError(errCode)) {
					// 如果不是插件预设的错误码,则原样返回错误信息
					return error;
				}
				return new UniCloudError({
					code: errCode,
					message: error.errMsg || this.t(errCode, error.errMsgValue),
				});
			}
			throw error
		}
		return result;
	},

	/**
	 * 创建支付订单
	 */
	async createOrder(data) {
		let {
			provider, // 支付供应商 如 wxpay alipay 参考 https://uniapp.dcloud.net.cn/api/plugins/provider.html#
			total_fee, // 订单总金额,单位为分,100等于1元
			openid, // 发起支付的用户openid
			order_no, // 业务系统订单号 建议控制在20-28位(不可以是24位,24位在阿里云空间可能会有问题)(可重复,代表1个业务订单会有多次付款的情况)
			out_trade_no, // 支付插件订单号(需控制唯一,不传则由插件自动生成)
			description, // 支付描述,如:uniCloud个人版包月套餐
			type, // 订单类型 goods:订单付款 recharge:余额充值付款 vip:vip充值付款 等等,可自定义
			qr_code, // true 强制开启二维码支付模式
			custom, // 自定义参数(不会发送给第三方支付服务器)(由于custom在前端调用时是不可信任的,因此此参数后续需要优化)
			other, // 其他请求参数(会发送给第三方支付服务器)
			clientInfo, // 兼容云对象调用云对象模式
			cloudInfo, // 兼容云对象调用云对象模式
			wxpay_virtual, // 仅用于微信虚拟支付
		} = data;

		if (!clientInfo) clientInfo = this.getClientInfo();
		if (!cloudInfo) cloudInfo = this.getCloudInfo();

		// 获取当前登录的user_id
		let user_id = this.getUserId();

		let res = await service.pay.createOrder({
			provider,
			total_fee,
			user_id,
			openid,
			order_no,
			out_trade_no,
			description,
			type,
			qr_code,
			custom,
			other,
			clientInfo,
			cloudInfo,
			wxpay_virtual,
		});

		return res;
	},
	/**
	 * 接收支付异步通知
	 */
	async payNotify(data) {
		const httpInfo = this.getHttpInfo();
		const clientInfo = this.getClientInfo();
		const cloudInfo = this.getCloudInfo();
		return service.pay.paymentNotify({
			httpInfo,
			clientInfo,
			cloudInfo
		});
	},
	/**
	 * 查询支付状态
	 */
	async getOrder(data) {
		let {
			out_trade_no, // 插件订单号
			transaction_id, // 第三方支付交易单号
			await_notify = false, // 是否需要等待异步通知执行完成,若为了响应速度,可以设置为false,若需要等待异步回调执行完成,则设置为true
		} = data;

		res = await service.pay.getOrder({
			out_trade_no,
			transaction_id,
			await_notify
		});

		return res;
	},

	/**
	 * 发起退款
	 * 此api只有admin角色可以访问
	 */
	async refund(data) {
		let {
			out_trade_no, // 插件订单号
			out_refund_no, // 插件退款订单号
			refund_desc, // 退款描述
			refund_fee, // 退款金额
		} = data;

		res = await service.pay.refund({
			out_trade_no,
			out_refund_no,
			refund_desc,
			refund_fee,
		});

		return res;
	},

	/**
	 * 查询退款(查询退款情况)
	 */
	async getRefund(data) {
		let {
			out_trade_no, // 插件订单号
		} = data;

		res = await service.pay.getRefund({
			out_trade_no,
		});

		return res;
	},

	/**
	 * 关闭订单(只有订单未支付时,才可以关闭,关闭后,用户即使在付款页面也无法付款)
	 */
	async closeOrder(data) {
		let {
			out_trade_no, // 插件订单号
		} = data;

		res = await service.pay.closeOrder({
			out_trade_no,
		});

		return res;
	},

	/**
	 * 根据code获取openid
	 */
	async getOpenid(data = {}) {
		let {
			provider,
			code,
			clientInfo, // 兼容云对象调用云对象模式
		} = data;

		if (!clientInfo) clientInfo = this.getClientInfo();

		res = await service.pay.getOpenid({
			provider,
			code,
			clientInfo
		});

		return res;
	},

	/**
	 * 获取当前支持的支付方式
	 */
	async getPayProviderFromCloud() {
		return await service.pay.getPayProviderFromCloud();
	},

	/**
	 * 获取支付配置内的appid(主要用于获取获取微信公众号的appid,用以获取code)
	 */
	async getProviderAppId(data) {
		let {
			provider,
			provider_pay_type
		} = data;
		// 注意,前往不要直接把 conifg 内的所有内容返回给前端
		let conifg = service.pay.getConfig();
		try {
			return {
				errorCode: 0,
				appid: conifg[provider][provider_pay_type].appId,
			}
		} catch (err) {
			return {
				errorCode: 0,
				appid: null
			};
		}
	},
	
	/**
	 * 验证iosIap苹果内购支付凭据
	 */
	async verifyReceiptFromAppleiap(data) {
		let {
			out_trade_no,
			transaction_receipt,
			transaction_identifier,
		} = data;
		return await service.pay.verifyReceiptFromAppleiap({
			out_trade_no,
			transaction_receipt,
			transaction_identifier
		});
	},
	
	/**
	 * 接收微信小程序虚拟支付异步通知
	 */
	async wxpayVirtualNotify(data) {
		const httpInfo = this.getHttpInfo();
		const clientInfo = this.getClientInfo();
		const cloudInfo = this.getCloudInfo();
		return service.pay.wxpayVirtualNotify({
			httpInfo,
			clientInfo,
			cloudInfo
		});
	},
	
}