134 lines
4.4 KiB
JavaScript
134 lines
4.4 KiB
JavaScript
import assert from 'assert';
|
||
let _PAY_STATE = '';
|
||
export function registerGetPayStateResult(payState) {
|
||
_PAY_STATE = payState;
|
||
}
|
||
export default class WechatPay {
|
||
wpProduct;
|
||
constructor(wpProduct) {
|
||
this.wpProduct = wpProduct;
|
||
}
|
||
decodeRefundNotification(params, body) {
|
||
throw new Error('Method not implemented.');
|
||
}
|
||
getAccountEntity() {
|
||
return ['wpAccount', this.wpProduct.wpAccountId];
|
||
}
|
||
async getAccountAmount(context) {
|
||
const [wpAccount] = await context.select('wpAccount', {
|
||
data: {
|
||
id: 1,
|
||
price: 1,
|
||
},
|
||
filter: {
|
||
id: this.wpProduct.wpAccountId,
|
||
}
|
||
}, { dontCollect: true });
|
||
return wpAccount.price;
|
||
}
|
||
calcTransferTax(price) {
|
||
const { wpAccount } = this.wpProduct;
|
||
const { allowWithdrawTransfer, withdrawTransferLossRatio } = wpAccount;
|
||
assert(allowWithdrawTransfer);
|
||
if (typeof withdrawTransferLossRatio !== 'number') {
|
||
throw new Error('渠道的withdrawTransferLossRatio未设置');
|
||
}
|
||
return [Math.round(price * withdrawTransferLossRatio / 100), 'wpAccount', wpAccount.id];
|
||
}
|
||
calcRefundTax(price) {
|
||
const { wpAccount } = this.wpProduct;
|
||
const refundCompensateRatio = typeof this.wpProduct.refundCompensateRatio === 'number' ? this.wpProduct.refundCompensateRatio : wpAccount.refundCompensateRatio;
|
||
const taxLossRatio = typeof this.wpProduct.taxLossRatio === 'number' ? this.wpProduct.taxLossRatio : wpAccount.taxLossRatio;
|
||
// 返回taxLossRatio * refundCompensateRatio / 100
|
||
if (typeof taxLossRatio !== 'number') {
|
||
throw new Error('渠道的taxLossRatio未设置');
|
||
}
|
||
if (typeof refundCompensateRatio !== 'number') {
|
||
throw new Error('渠道的refundCompensateRatio未设置');
|
||
}
|
||
const value = Math.round(price * taxLossRatio * refundCompensateRatio / 100 / 100);
|
||
return [-value, 'wpAccount', wpAccount.id];
|
||
}
|
||
calcPayTax(price) {
|
||
const { wpProduct } = this;
|
||
const taxLossRatio = wpProduct.taxLossRatio || wpProduct.wpAccount.taxLossRatio;
|
||
assert(typeof taxLossRatio === 'number', '微信渠道的手续费率未配置');
|
||
return [Math.round(price * taxLossRatio / 100), 'wpAccount', wpProduct.wpAccountId];
|
||
}
|
||
async refund(refund, context) {
|
||
return {
|
||
externalId: Math.random().toString(),
|
||
};
|
||
}
|
||
async getRefundState(refund) {
|
||
const r = Math.random();
|
||
if (r < 0.5) {
|
||
return ['refunded', undefined];
|
||
}
|
||
return ['failed', {
|
||
reason: '微信觉得你长得太丑了,就不想给你退款,让你去深圳找马化腾',
|
||
}];
|
||
}
|
||
decodePayNotification(params, body) {
|
||
throw new Error("Method not implemented.");
|
||
}
|
||
/**
|
||
* 参照微信支付prepay接口模拟返回
|
||
* @param pay
|
||
* @param data
|
||
* @param context
|
||
*/
|
||
async prepay(pay, data, context) {
|
||
switch (this.wpProduct.type) {
|
||
case 'app':
|
||
case 'jsapi':
|
||
case 'mp': {
|
||
const prepayId = Math.random().toString();
|
||
data.externalId = prepayId;
|
||
data.meta = {
|
||
prepayId,
|
||
};
|
||
break;
|
||
}
|
||
case 'h5': {
|
||
const h5Url = Math.random().toString();
|
||
data.externalId = h5Url;
|
||
data.meta = {
|
||
h5Url,
|
||
};
|
||
break;
|
||
}
|
||
case 'native': {
|
||
const codeUrl = Math.random().toString();
|
||
data.externalId = codeUrl;
|
||
data.meta = {
|
||
codeUrl,
|
||
};
|
||
break;
|
||
}
|
||
}
|
||
;
|
||
data.timeoutAt = Date.now() + 7000 * 1000; // 微信官方文档过期时间2小时,提前一点
|
||
}
|
||
async getState(pay) {
|
||
if (_PAY_STATE) {
|
||
return [_PAY_STATE, {}];
|
||
}
|
||
const r = Math.random();
|
||
if (r < 0.3) {
|
||
return ['paying', {}];
|
||
}
|
||
else if (r > 0.95) {
|
||
return ['closed', {}];
|
||
}
|
||
return ['paid', {
|
||
successAt: Date.now(),
|
||
}];
|
||
}
|
||
getRefundableAt(successAt) {
|
||
return successAt + 24 * 3600 * 1000;
|
||
}
|
||
async close(pay) {
|
||
}
|
||
}
|